The proxy works and prints hexdump of clients' input.

dev
Philippe PITTOLI 2024-06-18 13:28:22 +02:00
parent 1832065fa0
commit 03e1fa59dc
1 changed files with 29 additions and 28 deletions

View File

@ -1,4 +1,5 @@
const std = @import("std"); const std = @import("std");
const net = std.net;
const hexdump = @import("./hexdump.zig").print_hex; const hexdump = @import("./hexdump.zig").print_hex;
const AutoArrayHashMap = std.AutoArrayHashMap; const AutoArrayHashMap = std.AutoArrayHashMap;
const allocator = std.mem.Allocator; const allocator = std.mem.Allocator;
@ -9,24 +10,7 @@ const ipc = @cImport({
@cInclude("libipc.h"); @cInclude("libipc.h");
}); });
// // Return type of callback functions when switching. // enum cb_event_types { CB_NO_ERROR, CB_ERROR, CB_FD_CLOSING, CB_IGNORE };
// enum cb_event_types {
// CB_NO_ERROR = 0 // No error. A message was generated.
// , CB_ERROR = 1 // Generic error.
// , CB_FD_CLOSING = 2 // The fd is closing.
// , CB_IGNORE = 3 // The message should be ignored (protocol specific).
// };
//
// int ipc_write (void* ctx, int servicefd, char* mcontent, uint32_t mlen);
// int ipc_read_fd (void* ctx, int fd, char* buffer, size_t* buflen);
// int ipc_read (void* ctx, size_t index, char* buffer, size_t* buflen);
// void ipc_context_timer (void* ctx, int timer);
// int ipc_close (void* ctx, size_t index);
// int ipc_close_all (void* ctx);
//
// // Switch functions (for "protocol" services, such as TCPd).
// int ipc_add_external (void* ctx, int newfd);
//
// TODO: noreturn error function: print a error message then crash. // TODO: noreturn error function: print a error message then crash.
// TODO: connection to the proxied service // TODO: connection to the proxied service
@ -35,23 +19,41 @@ const ipc = @cImport({
// TODO: find why "in" and "out" functions are detected as // TODO: find why "in" and "out" functions are detected as
// returning "[*c]u8" while they should be returning u8. // returning "[*c]u8" while they should be returning u8.
const IPC_MAX_MESSAGE_SIZE = 100_000;
const stdout = std.io.getStdOut().writer(); const stdout = std.io.getStdOut().writer();
var context : ?*anyopaque = undefined; var context : ?*anyopaque = undefined;
// char (*in (int orig, const char *payload, uint32_t *mlen)) // char (*in (int orig, const char *payload, uint32_t *mlen))
pub fn in(origin : c_int, _ : [*c]const u8, _ : [*c]u32) callconv(.C) [*c]u8 // why this return type?! pub fn in(origin : c_int, buffer : [*c]u8, buflen : [*c]usize) callconv(.C) [*c]u8 // why this return type?!
{ {
stdout.print("we are IN origin is {}\n", .{origin}) catch {}; var stream: net.Stream = .{ .handle = origin };
return 1; buflen.* = stream.read(buffer[0..buflen.*]) catch { return 1; };
// Let's handle this as a disconnection.
if (buflen.* == 0) { return 2; }
// Error: received message should be bigger than that!
if (buflen.* <= 4) { return 1; }
const slice = buffer[0..buflen.*];
stdout.print("Message received from {}\n", .{origin}) catch {};
hexdump("message just received", slice) catch {};
return 0;
} }
// char (*out(int dest, char *payload, uint32_t mlen))); // char (*out(int dest, char *payload, uint32_t mlen)));
pub fn out(dest_fd : c_int, _ : [*c]u8, _ : u32) callconv(.C) [*c]u8 // why this return type?! pub fn out(dest_fd : c_int, buffer : [*c]const u8, buflen : usize) callconv(.C) [*c]u8 // why this return type?!
{ {
stdout.print("we are OUT target is {}\n", .{dest_fd}) catch {}; const slice = buffer[0..buflen];
return 1; stdout.print("Message to send to {}\n", .{dest_fd}) catch {};
hexdump("message to send", slice) catch {};
var stream = net.Stream{ .handle = dest_fd };
_ = stream.write(slice) catch { return 1; };
return 0;
} }
var proxy_name : [:0]const u8 = "proxy"; var proxy_name : [:0]const u8 = "proxy";
@ -82,7 +84,7 @@ pub fn connection_and_link(client_fd : i32) !void
// Returned "char" is a cb_event_types enum. // Returned "char" is a cb_event_types enum.
try stdout.print("Hello we will put some callbacks\n", .{}); try stdout.print("Hello we will put some callbacks\n", .{});
ret = ipc.ipc_set_switch_callbacks (context, client_fd, in, out); ret = ipc.ipc_set_switch_callbacks (context, client_fd, in, null); // only print hexdump of input
if (ret != 0) { if (ret != 0) {
try stdout.print("Impossible to set the callbacks {} -> {s}\n", .{client_fd, proxied_service}); try stdout.print("Impossible to set the callbacks {} -> {s}\n", .{client_fd, proxied_service});
return error.CannotAddCallbacks; return error.CannotAddCallbacks;
@ -95,7 +97,6 @@ pub fn connection_and_link(client_fd : i32) !void
pub fn disconnection_and_unlink(fd : i32) !void pub fn disconnection_and_unlink(fd : i32) !void
{ {
try stdout.print("Disconnection of user ({})\n", .{fd}); try stdout.print("Disconnection of user ({})\n", .{fd});
} }
pub fn message_rx(_ : i32, buffer : [100_000]u8, buflen : u64) !void pub fn message_rx(_ : i32, buffer : [100_000]u8, buflen : u64) !void
@ -155,8 +156,8 @@ pub fn main() !void {
ipc.MESSAGE_TX => try message_tx(origin_fd), // Message sent. ipc.MESSAGE_TX => try message_tx(origin_fd), // Message sent.
ipc.TIMER => try stdout.print("TIMER\n", .{}), // Timeout in the poll(2) function. ipc.TIMER => try stdout.print("TIMER\n", .{}), // Timeout in the poll(2) function.
ipc.EXTERNAL => try stdout.print("EXTERNAL\n", .{}), // Message received from a non IPC socket. ipc.EXTERNAL => try stdout.print("EXTERNAL\n", .{}), // Message received from a non IPC socket.
ipc.SWITCH_RX => try stdout.print("SWITCH_RX\n", .{}), // Message received from a switched FD. ipc.SWITCH_RX => {}, // Message received from a switched fd.
ipc.SWITCH_TX => try stdout.print("SWITCH_TX\n", .{}), // Message sent to a switched fd. ipc.SWITCH_TX => {}, // Message sent to a switched fd.
else => try stdout.print("ELSE CASE\n", .{}), // Should never happen. else => try stdout.print("ELSE CASE\n", .{}), // Should never happen.
} }
} }