diff --git a/src/main.zig b/src/main.zig index 847f2c8..c3747d1 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const net = std.net; const hexdump = @import("./hexdump.zig").print_hex; const AutoArrayHashMap = std.AutoArrayHashMap; const allocator = std.mem.Allocator; @@ -9,24 +10,7 @@ const ipc = @cImport({ @cInclude("libipc.h"); }); -// // Return type of callback functions when switching. -// 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); -// +// enum cb_event_types { CB_NO_ERROR, CB_ERROR, CB_FD_CLOSING, CB_IGNORE }; // TODO: noreturn error function: print a error message then crash. // TODO: connection to the proxied service @@ -35,23 +19,41 @@ const ipc = @cImport({ // TODO: find why "in" and "out" functions are detected as // returning "[*c]u8" while they should be returning u8. +const IPC_MAX_MESSAGE_SIZE = 100_000; const stdout = std.io.getStdOut().writer(); var context : ?*anyopaque = undefined; + // 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 {}; - return 1; + var stream: net.Stream = .{ .handle = origin }; + 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))); -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 {}; - return 1; + const slice = buffer[0..buflen]; + 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"; @@ -82,7 +84,7 @@ pub fn connection_and_link(client_fd : i32) !void // Returned "char" is a cb_event_types enum. 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) { try stdout.print("Impossible to set the callbacks {} -> {s}\n", .{client_fd, proxied_service}); return error.CannotAddCallbacks; @@ -95,7 +97,6 @@ pub fn connection_and_link(client_fd : i32) !void pub fn disconnection_and_unlink(fd : i32) !void { try stdout.print("Disconnection of user ({})\n", .{fd}); - } 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.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.SWITCH_RX => try stdout.print("SWITCH_RX\n", .{}), // Message received from a switched FD. - ipc.SWITCH_TX => try stdout.print("SWITCH_TX\n", .{}), // Message sent to a switched fd. + ipc.SWITCH_RX => {}, // Message received from a switched fd. + ipc.SWITCH_TX => {}, // Message sent to a switched fd. else => try stdout.print("ELSE CASE\n", .{}), // Should never happen. } }