Use Client as var type instead of singleton

This commit is contained in:
2025-05-11 13:52:22 -04:00
parent 14ed0bc3f3
commit 56b6b8a386
2 changed files with 31 additions and 28 deletions

View File

@@ -1,29 +1,36 @@
const base64Enc = std.base64.Base64Encoder.init(std.base64.standard_alphabet_chars, '='); const base64Enc = std.base64.Base64Encoder.init(std.base64.standard_alphabet_chars, '=');
const base64Dec = std.base64.Base64Decoder.init(std.base64.standard_alphabet_chars, '='); const base64Dec = std.base64.Base64Decoder.init(std.base64.standard_alphabet_chars, '=');
var rand: ?Random = null; rand: Random,
var socket: ?gcat.nic.RawSocket = null; socket: gcat.nic.RawSocket,
const Self = @This();
const max_message_size = 2048; const max_message_size = 2048;
pub fn init() !void { pub fn init(interface_name: [:0]const u8) !Self {
var prng = Random.DefaultPrng.init(blk: { var prng = Random.DefaultPrng.init(blk: {
var seed: u64 = undefined; var seed: u64 = undefined;
try posix.getrandom(mem.asBytes(&seed)); try posix.getrandom(mem.asBytes(&seed));
break :blk seed; break :blk seed;
}); });
rand = prng.random(); const rand = prng.random();
socket = try .init("enp7s0"); const socket: gcat.nic.RawSocket = try .init(interface_name);
return .{
.rand = rand,
.socket = socket,
};
} }
pub fn deinit() void { pub fn deinit(self: *Self) void {
socket.?.deinit(); self.socket.deinit();
} }
/// Used for relay messages and connection handshake. /// Used for relay messages and connection handshake.
/// Assumes Client .init has been called. /// Assumes Client .init has been called.
fn broadcastInitialInterestMessage(msg_bytes: []align(@alignOf(SaprusMessage)) u8) !void { fn broadcastInitialInterestMessage(self: *Self, msg_bytes: []align(@alignOf(SaprusMessage)) u8) !void {
var packet_bytes: [max_message_size]u8 = comptime blk: { var packet_bytes: [max_message_size]u8 = comptime blk: {
var b: [max_message_size]u8 = @splat(0); var b: [max_message_size]u8 = @splat(0);
@@ -63,7 +70,7 @@ fn broadcastInitialInterestMessage(msg_bytes: []align(@alignOf(SaprusMessage)) u
const saprus_start_byte = 42; const saprus_start_byte = 42;
@memcpy(packet_bytes[saprus_start_byte .. saprus_start_byte + msg_bytes.len], msg_bytes); @memcpy(packet_bytes[saprus_start_byte .. saprus_start_byte + msg_bytes.len], msg_bytes);
try socket.?.linkLayer().send(packet_bytes[0 .. saprus_start_byte + msg_bytes.len]); try self.socket.linkLayer().send(packet_bytes[0 .. saprus_start_byte + msg_bytes.len]);
} }
// fn broadcastSaprusMessage(msg_bytes: []align(@alignOf(SaprusMessage)) u8) !void {} // fn broadcastSaprusMessage(msg_bytes: []align(@alignOf(SaprusMessage)) u8) !void {}
@@ -100,7 +107,7 @@ fn broadcastSaprusMessage(msg_bytes: []align(@alignOf(SaprusMessage)) u8, udp_po
_ = try sock.sendTo(dest_addr, msg_bytes); _ = try sock.sendTo(dest_addr, msg_bytes);
} }
pub fn sendRelay(payload: []const u8, dest: [4]u8) !void { pub fn sendRelay(self: *Self, payload: []const u8, dest: [4]u8) !void {
var buf: [max_message_size]u8 align(@alignOf(SaprusMessage)) = undefined; var buf: [max_message_size]u8 align(@alignOf(SaprusMessage)) = undefined;
const msg_bytes = buf[0..try SaprusMessage.calcSize( const msg_bytes = buf[0..try SaprusMessage.calcSize(
.relay, .relay,
@@ -112,24 +119,20 @@ pub fn sendRelay(payload: []const u8, dest: [4]u8) !void {
relay.dest = dest; relay.dest = dest;
_ = base64Enc.encode(relay.getPayload(), payload); _ = base64Enc.encode(relay.getPayload(), payload);
try broadcastInitialInterestMessage(msg_bytes); try self.broadcastInitialInterestMessage(msg_bytes);
} }
fn randomPort() u16 { fn randomPort(self: Self) u16 {
var p: u16 = 0; return self.rand.intRangeAtMost(u16, 1024, 65000);
if (rand) |r| {
p = r.intRangeAtMost(u16, 1024, 65000);
} else unreachable;
return p;
} }
pub fn sendInitialConnection( pub fn sendInitialConnection(
self: Self,
payload: []const u8, payload: []const u8,
output_bytes: []align(@alignOf(SaprusMessage)) u8, output_bytes: []align(@alignOf(SaprusMessage)) u8,
initial_port: u16, initial_port: u16,
) !*SaprusMessage { ) !*SaprusMessage {
const dest_port = randomPort(); const dest_port = self.randomPort();
const msg_bytes = output_bytes[0..try SaprusMessage.calcSize( const msg_bytes = output_bytes[0..try SaprusMessage.calcSize(
.connection, .connection,
base64Enc.calcSize(payload.len), base64Enc.calcSize(payload.len),
@@ -146,8 +149,8 @@ pub fn sendInitialConnection(
return msg; return msg;
} }
pub fn connect(payload: []const u8) !?SaprusConnection { pub fn connect(self: Self, payload: []const u8) !?SaprusConnection {
const initial_port = randomPort(); const initial_port = self.randomPort();
var initial_conn_res: ?*SaprusMessage = null; var initial_conn_res: ?*SaprusMessage = null;
@@ -165,7 +168,7 @@ pub fn connect(payload: []const u8) !?SaprusConnection {
try sock.bind(bind_addr); try sock.bind(bind_addr);
var sent_msg_bytes: [max_message_size]u8 align(@alignOf(SaprusMessage)) = undefined; var sent_msg_bytes: [max_message_size]u8 align(@alignOf(SaprusMessage)) = undefined;
const msg = try sendInitialConnection(payload, &sent_msg_bytes, initial_port); const msg = try self.sendInitialConnection(payload, &sent_msg_bytes, initial_port);
var response_buf: [max_message_size]u8 align(@alignOf(SaprusMessage)) = undefined; var response_buf: [max_message_size]u8 align(@alignOf(SaprusMessage)) = undefined;
_ = try sock.receive(&response_buf); // Ignore message that I sent. _ = try sock.receive(&response_buf); // Ignore message that I sent.
@@ -174,7 +177,7 @@ pub fn connect(payload: []const u8) !?SaprusConnection {
initial_conn_res = try .networkBytesAsValue(response_buf[0..len]); initial_conn_res = try .networkBytesAsValue(response_buf[0..len]);
// Complete handshake after awaiting response // Complete handshake after awaiting response
try broadcastSaprusMessage(msg.asBytes(), randomPort()); try broadcastSaprusMessage(msg.asBytes(), self.randomPort());
if (false) { if (false) {
return initial_conn_res.?; return initial_conn_res.?;

View File

@@ -42,23 +42,23 @@ pub fn main() !void {
}; };
defer res.deinit(); defer res.deinit();
try SaprusClient.init();
defer SaprusClient.deinit();
if (res.args.help != 0) { if (res.args.help != 0) {
return clap.help(std.io.getStdErr().writer(), clap.Help, &params, .{}); return clap.help(std.io.getStdErr().writer(), clap.Help, &params, .{});
} }
var client = try SaprusClient.init("enp7s0");
defer client.deinit();
if (res.args.relay) |r| { if (res.args.relay) |r| {
const dest = parseDest(res.args.dest); const dest = parseDest(res.args.dest);
try SaprusClient.sendRelay( try client.sendRelay(
if (r.len > 0) r else "Hello darkness my old friend", if (r.len > 0) r else "Hello darkness my old friend",
dest, dest,
); );
// std.debug.print("Sent: {s}\n", .{r}); // std.debug.print("Sent: {s}\n", .{r});
return; return;
} else if (res.args.connect) |c| { } else if (res.args.connect) |c| {
_ = SaprusClient.connect(if (c.len > 0) c else "Hello darkness my old friend") catch |err| switch (err) { _ = client.connect(if (c.len > 0) c else "Hello darkness my old friend") catch |err| switch (err) {
error.WouldBlock => null, error.WouldBlock => null,
else => return err, else => return err,
}; };