diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Client.zig | 19 | ||||
-rw-r--r-- | src/RawSocketWriter.zig | 45 | ||||
-rw-r--r-- | src/main.zig | 5 | ||||
-rw-r--r-- | src/root.zig | 1 |
4 files changed, 57 insertions, 13 deletions
diff --git a/src/Client.zig b/src/Client.zig index 8b2f71f..37ef3ac 100644 --- a/src/Client.zig +++ b/src/Client.zig @@ -2,13 +2,13 @@ const base64Enc = std.base64.Base64Encoder.init(std.base64.standard_alphabet_cha const base64Dec = std.base64.Base64Decoder.init(std.base64.standard_alphabet_chars, '='); rand: Random, -socket: gcat.nic.RawSocket, +writer: *std.Io.Writer, const Self = @This(); const max_message_size = 2048; -pub fn init(interface_name: [:0]const u8) !Self { +pub fn init(writer: *std.Io.Writer) !Self { var prng = Random.DefaultPrng.init(blk: { var seed: u64 = undefined; try posix.getrandom(mem.asBytes(&seed)); @@ -16,16 +16,14 @@ pub fn init(interface_name: [:0]const u8) !Self { }); const rand = prng.random(); - const socket: gcat.nic.RawSocket = try .init(interface_name); - return .{ .rand = rand, - .socket = socket, + .writer = writer, }; } pub fn deinit(self: *Self) void { - self.socket.deinit(); + self.writer.flush() catch {}; } /// Used for relay messages and connection handshake. @@ -70,16 +68,14 @@ fn broadcastInitialInterestMessage(self: *Self, msg_bytes: []align(@alignOf(Sapr const saprus_start_byte = 42; @memcpy(packet_bytes[saprus_start_byte .. saprus_start_byte + msg_bytes.len], msg_bytes); - try self.socket.linkLayer().send(packet_bytes[0 .. saprus_start_byte + msg_bytes.len]); + const writer = self.writer; + _ = try writer.write(packet_bytes[0 .. saprus_start_byte + msg_bytes.len]); + try writer.flush(); } // fn broadcastSaprusMessage(msg_bytes: []align(@alignOf(SaprusMessage)) u8) !void {} fn broadcastSaprusMessage(msg_bytes: []align(@alignOf(SaprusMessage)) u8, udp_port: u16) !void { - if (false) { - var foo: gcat.nic.RawSocket = try .init("enp7s0"); // /proc/net/dev - defer foo.deinit(); - } const msg: *SaprusMessage = try .bytesAsValue(msg_bytes); try msg.networkFromNativeEndian(); defer msg.nativeFromNetworkEndian() catch unreachable; @@ -194,4 +190,3 @@ const posix = std.posix; const mem = std.mem; const network = @import("network"); -const gcat = @import("gatorcat"); diff --git a/src/RawSocketWriter.zig b/src/RawSocketWriter.zig new file mode 100644 index 0000000..dfbb874 --- /dev/null +++ b/src/RawSocketWriter.zig @@ -0,0 +1,45 @@ +const std = @import("std"); +const gcat = @import("gatorcat"); +const Writer = @This(); +const assert = std.debug.assert; + +interface: std.Io.Writer, +socket: gcat.nic.RawSocket, +alloc: std.mem.Allocator, + +fn drain(io_w: *std.Io.Writer, data: []const []const u8, splat: usize) std.Io.Writer.Error!usize { + const w: *Writer = @alignCast(@fieldParentPtr("interface", io_w)); + const buffered = io_w.buffered(); + var res: usize = 0; + if (buffered.len > 0) { + w.socket.linkLayer().send(buffered) catch return error.WriteFailed; + _ = io_w.consumeAll(); + } + + for (data[0 .. data.len - 1]) |d| { + w.socket.linkLayer().send(d) catch return error.WriteFailed; + res += d.len; + } + + if (splat > 0 and data[data.len - 1].len > 0) { + var splatBuffer: std.ArrayList(u8) = .empty; + defer splatBuffer.deinit(w.alloc); + for (0..splat) |_| { + splatBuffer.appendSlice(w.alloc, data[data.len - 1]) catch return error.WriteFailed; + } + w.socket.linkLayer().send(splatBuffer.items) catch return error.WriteFailed; + } + + return res; +} + +pub fn init(interface_name: [:0]const u8, buffer: []u8, alloc: std.mem.Allocator) !Writer { + return .{ + .interface = .{ + .vtable = &.{ .drain = drain }, + .buffer = buffer, + }, + .socket = try .init(interface_name), + .alloc = alloc, + }; +} diff --git a/src/main.zig b/src/main.zig index 947375f..8d0e2d5 100644 --- a/src/main.zig +++ b/src/main.zig @@ -46,7 +46,9 @@ pub fn main() !void { return clap.helpToFile(.stderr(), clap.Help, ¶ms, .{}); } - var client = try SaprusClient.init("enp7s0"); + var sock_buffer: [2048]u8 = undefined; + var rawSocketWriter: RawSocketWriter = try .init("enp7s0", &sock_buffer, gpa); // /proc/net/dev + var client = try SaprusClient.init(&rawSocketWriter.interface); defer client.deinit(); if (res.args.relay) |r| { @@ -90,5 +92,6 @@ const ArrayList = std.ArrayList; const zaprus = @import("zaprus"); const SaprusClient = zaprus.Client; const SaprusMessage = zaprus.Message; +const RawSocketWriter = zaprus.RawSocketWriter; const clap = @import("clap"); diff --git a/src/root.zig b/src/root.zig index 6f45130..b7c2795 100644 --- a/src/root.zig +++ b/src/root.zig @@ -1,5 +1,6 @@ pub const Client = @import("Client.zig"); pub const Connection = @import("Connection.zig"); +pub const RawSocketWriter = @import("RawSocketWriter.zig"); const msg = @import("message.zig"); |