summaryrefslogtreecommitdiff
path: root/src/Client.zig
diff options
context:
space:
mode:
authorRobby Zambito <contact@robbyzambito.me>2025-09-23 16:16:12 -0400
committerRobby Zambito <contact@robbyzambito.me>2025-09-23 16:22:57 -0400
commitb06cb6dadac809322b6a293fbedf401870028d6e (patch)
tree4f53d71d846f6a0aed6b0f95199d45b2c35bf8e6 /src/Client.zig
parentb8313e4fa4ced3462e2fadaa123c917fcb063c18 (diff)
it works well!
Diffstat (limited to 'src/Client.zig')
-rw-r--r--src/Client.zig238
1 files changed, 97 insertions, 141 deletions
diff --git a/src/Client.zig b/src/Client.zig
index 0c82129..86b08d4 100644
--- a/src/Client.zig
+++ b/src/Client.zig
@@ -30,166 +30,60 @@ pub fn deinit(self: *Self) void {
/// Used for relay messages and connection handshake.
/// Assumes Client .init has been called.
-fn broadcastInitialInterestMessage(self: *Self, msg_bytes: []align(@alignOf(SaprusMessage)) u8) !void {
+fn broadcastInitialInterestMessage(self: *Self, msg_bytes: []u8) !void {
const writer = self.writer;
- // const EthernetHeaders = packed struct {
- // dest_mac: @Vector(6, u8),
-
- // src_mac: @Vector(6, u8),
-
- // ether_type: u16,
- // };
-
- const IpHeaders = packed struct {
- _: u8 = 0x45,
- // ip_version: u4,
- // header_length: u4 = 0,
- type_of_service: u8 = 0,
- total_length: u16 = 0x04,
-
- identification: u16 = 0,
- __: u16 = 0x0,
- // ethernet_flags: u3 = 0,
- // fragment_offset: u13 = 0,
- ttl: u8 = 0,
- protocol: u8 = 0,
-
- header_checksum: @Vector(2, u8) = .{ 0, 0 },
- src_ip: @Vector(4, u8),
-
- dest_ip: @Vector(4, u8),
- };
-
- const UdpHeaders = packed struct {
- src_port: @Vector(2, u8),
-
- dest_port: @Vector(2, u8),
- length: u16,
- checksum: @Vector(2, u8) = .{ 0, 0 },
- };
-
- // const total_len = ((@bitSizeOf(IpHeaders) + @bitSizeOf(UdpHeaders)) / 8) + msg_bytes.len;
- const total_len = 130;
+ const total_len = ((@bitSizeOf(EthernetHeaders) + @bitSizeOf(IpHeaders) + @bitSizeOf(UdpHeaders)) / 8) + msg_bytes.len;
std.debug.assert(writer.buffer.len >= total_len);
_ = writer.consumeAll();
- // var ether_headers: EthernetHeaders = .{
- // .dest_mac = .{ 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff },
- // // .src_mac = .{ 0xee, 0xee, 0xee, 0xee, 0xee, 0xee },
- // .src_mac = blk: {
- // var output_bytes: [6]u8 = undefined;
- // // const r_bytes = try writer.writableArray(6);
- // self.rand.bytes(&output_bytes);
- // break :blk output_bytes;
- // },
- // .ether_type = 0x0800,
- // };
-
- var ip_headers: IpHeaders = .{
+ const ether_headers: EthernetHeaders = .{
+ .dest_mac = .{ 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff },
+ .src_mac = .{ 0xee, 0xee, 0xee, 0xee, 0xee, 0xee },
+ // .src_mac = blk: {
+ // var output_bytes: [6]u8 = undefined;
+ // // const r_bytes = try writer.writableArray(6);
+ // self.rand.bytes(&output_bytes);
+ // break :blk output_bytes;
+ // },
+ .ether_type = 0x0800,
+ };
+
+ // @compileLog((@bitSizeOf(EthernetHeaders) / 8));
+ const ip_headers: IpHeaders = .{
// .ip_version = 0x4,
// .header_length = 0x5,
- // .total_length = 130, //@intCast(total_len - 8), // 8 is the ethernet frame length (macs + type)
- .total_length = 0x00,
+ .total_length = @intCast(total_len - 92),
.ttl = 0x64,
.protocol = 0x11,
.src_ip = .{ 0xff, 0x02, 0x03, 0x04 },
.dest_ip = .{ 0xff, 0xff, 0xff, 0xff },
};
- var udp_headers: UdpHeaders = .{
- .src_port = .{ 0, 0x01 },
- .dest_port = .{ 0xb8, 0x22 },
+ const udp_headers: UdpHeaders = .{
+ .src_port = 0xbbbb,
+ .dest_port = 8888,
.length = @intCast(msg_bytes.len),
};
- _ = &ip_headers;
- _ = &udp_headers;
- // _ = &ether_headers;
-
- // _ = try writer.write(&@as([@bitSizeOf(UdpHeaders) / 8]u8, @bitCast(headers)));
-
- // std.mem.byteSwapAllFields(EthernetHeaders, &ether_headers);
- // try writer.writeStruct(ether_headers, native_endian);
-
- std.mem.byteSwapAllFields(IpHeaders, &ip_headers);
- try writer.writeStruct(ip_headers, native_endian);
-
- // std.mem.byteSwapAllFields(UdpHeaders, &udp_headers);
- // try writer.writeStruct(udp_headers, native_endian);
-
- // // Ensure buffer is large enough
- // std.debug.assert(writer.buffer.len > 38 + msg_bytes.len);
-
- // // Ensure writer is clean
- // writer.consumeAll();
-
- // // Destination MAC addr to FF:FF:FF:FF:FF:FF
- // try writer.write();
-
- // // Source MAC to random bytes
- // {
- // }
-
- // // 96 bits
-
- // // Set EtherType to IPv4
- // try writer.write(.{ 0x08, 0x00 });
- // // 112 bits
+ try ether_headers.write(writer);
+ try ip_headers.write(writer);
+ try udp_headers.write(writer);
- // // Set IPv4 version to 4
- // try writer.writeByte(0x45);
+ // Saprus
+ const msg_target_bytes = try writer.writableSlice(msg_bytes.len);
+ @memcpy(msg_target_bytes, msg_bytes);
+ var msg_target: *align(1) SaprusMessage = try .bytesAsValue(msg_target_bytes);
+ try msg_target.networkFromNativeEndian();
- // // 120 bits
-
- // // Unset section (Version, IHL, ToS)
- // writer.advance(2);
-
- // // 136 bits
-
- // // Total length
- // try write.writeInt(u16, 38 + msg_bytes.len);
-
- // // Destination broadcast
- // writer.splatByte(0xff, 0x22 - 0x1e);
-
- // var packet_bytes: [_]u8 = comptime blk: {
- // var b: [max_message_size]u8 = @splat(0);
-
- // for (0x1e..0x22) |i| {
- // b[i] = 0xff;
- // }
-
- // // Set TTL
- // b[0x16] = 0x40;
-
- // // Set IPv4 protocol to UDP
- // b[0x17] = 0x11;
-
- // // Set interest filter value to 8888.
- // b[0x24] = 0x22;
- // b[0x25] = 0xb8;
- // break :blk &b;
- // };
- var msg: *SaprusMessage = try .bytesAsValue(msg_bytes);
- try msg.networkFromNativeEndian();
- defer msg.nativeFromNetworkEndian() catch unreachable;
-
- // std.debug.print("headers: {x}\n", .{@as([@bitSizeOf(UdpHeaders) / 8]u8, @bitCast(headers))});
std.debug.print("bytes: {x}\n", .{writer.buffer[0..writer.end]});
- _ = try writer.write(msg_bytes);
-
- // The byte position within the packet that the saprus message starts at.
- // const saprus_start_byte = 42;
- // @memcpy(packet_bytes[saprus_start_byte .. saprus_start_byte + msg_bytes.len], msg_bytes);
- // _ = 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 {
- const msg: *SaprusMessage = try .bytesAsValue(msg_bytes);
+fn broadcastSaprusMessage(msg_bytes: []u8, udp_port: u16) !void {
+ const msg: *align(1) SaprusMessage = try .bytesAsValue(msg_bytes);
try msg.networkFromNativeEndian();
defer msg.nativeFromNetworkEndian() catch unreachable;
@@ -222,7 +116,7 @@ pub fn sendRelay(self: *Self, payload: []const u8, dest: [4]u8) !void {
.relay,
base64Enc.calcSize(payload.len),
)];
- const msg: *SaprusMessage = .init(.relay, msg_bytes);
+ const msg: *align(1) SaprusMessage = .init(.relay, msg_bytes);
const relay = (try msg.getSaprusTypePayload()).relay;
relay.dest = dest;
@@ -238,15 +132,15 @@ fn randomPort(self: Self) u16 {
pub fn sendInitialConnection(
self: Self,
payload: []const u8,
- output_bytes: []align(@alignOf(SaprusMessage)) u8,
+ output_bytes: []u8,
initial_port: u16,
-) !*SaprusMessage {
+) !*align(1) SaprusMessage {
const dest_port = self.randomPort();
const msg_bytes = output_bytes[0..try SaprusMessage.calcSize(
.connection,
base64Enc.calcSize(payload.len),
)];
- const msg: *SaprusMessage = .init(.connection, msg_bytes);
+ const msg: *align(1) SaprusMessage = .init(.connection, msg_bytes);
const connection = (try msg.getSaprusTypePayload()).connection;
connection.src_port = initial_port;
@@ -261,7 +155,7 @@ pub fn sendInitialConnection(
pub fn connect(self: Self, payload: []const u8) !?SaprusConnection {
const initial_port = self.randomPort();
- var initial_conn_res: ?*SaprusMessage = null;
+ var initial_conn_res: ?*align(1) SaprusMessage = null;
var sock = try network.Socket.create(.ipv4, .udp);
defer sock.close();
@@ -294,6 +188,68 @@ pub fn connect(self: Self, payload: []const u8) !?SaprusConnection {
return null;
}
+const EthernetHeaders = struct {
+ dest_mac: @Vector(6, u8),
+
+ src_mac: @Vector(6, u8),
+
+ ether_type: u16,
+
+ fn write(hdr: @This(), writer: *std.Io.Writer) !void {
+ try writer.writeInt(u48, @bitCast(hdr.dest_mac), .big);
+ try writer.writeInt(u48, @bitCast(hdr.src_mac), .big);
+ try writer.writeInt(u16, hdr.ether_type, .big);
+ }
+};
+
+const IpHeaders = struct {
+ _: u8 = 0x45,
+ // ip_version: u4,
+ // header_length: u4 = 0,
+ type_of_service: u8 = 0,
+ total_length: u16 = 0x04,
+
+ identification: u16 = 0,
+ __: u16 = 0x0,
+ // ethernet_flags: u3 = 0,
+ // fragment_offset: u13 = 0,
+ ttl: u8 = 0,
+ protocol: u8 = 0,
+
+ header_checksum: @Vector(2, u8) = .{ 0, 0 },
+ src_ip: @Vector(4, u8),
+
+ dest_ip: @Vector(4, u8),
+
+ fn write(hdr: @This(), writer: *std.Io.Writer) !void {
+ try writer.writeInt(u8, 0x45, .big); // ip version and header length
+ try writer.writeByte(hdr.type_of_service);
+ try writer.writeInt(u16, hdr.total_length, .big);
+ try writer.writeInt(u16, hdr.identification, .big);
+ try writer.writeInt(u16, 0x00, .big); // ethernet flags and fragment offset
+ try writer.writeByte(hdr.ttl);
+ try writer.writeByte(hdr.protocol);
+ try writer.writeInt(u16, @bitCast(hdr.header_checksum), .big);
+ try writer.writeInt(u32, @bitCast(hdr.src_ip), .big);
+ try writer.writeInt(u32, @bitCast(hdr.dest_ip), .big);
+ }
+};
+
+const UdpHeaders = packed struct {
+ src_port: u16,
+
+ dest_port: u16,
+ length: u16,
+ checksum: @Vector(2, u8) = .{ 0, 0 },
+
+ fn write(hdr: @This(), writer: *std.Io.Writer) !void {
+ try writer.writeInt(u16, hdr.src_port, .big);
+ try writer.writeInt(u16, hdr.dest_port, .big);
+ try writer.writeInt(u16, hdr.length, .big);
+ try writer.writeInt(u16, @bitCast(hdr.checksum), .big);
+ }
+};
+
const SaprusMessage = @import("message.zig").Message;
const SaprusConnection = @import("Connection.zig");