const std = @import("std"); const network = @import("network"); const logger = std.log.scoped(.udp2udp2udp); fn incomingAddr(args_it: anytype) !network.EndPoint { const addr_string = args_it.next().?; const port_string = args_it.next().?; const port = try std.fmt.parseInt(u16, port_string, 10); const zig_addr = try std.net.Address.parseIp(addr_string, port); const socklen = zig_addr.getOsSockLen(); return network.EndPoint.fromSocketAddress(&zig_addr.any, socklen); } const WantedMode = enum { send, recv }; const AddrTuple = struct { from: network.EndPoint, to: network.EndPoint }; const Mode = union(enum) { send: AddrTuple, recv: AddrTuple }; pub fn main() !void { try network.init(); defer network.deinit(); var gpa = std.heap.GeneralPurposeAllocator(.{}){}; defer { _ = gpa.deinit(); } const allocator = gpa.allocator(); var args_it = try std.process.argsWithAllocator(allocator); defer args_it.deinit(); _ = args_it.skip(); const from = try incomingAddr(&args_it); const to = try incomingAddr(&args_it); std.log.info("taking udp from: {s}", .{from}); std.log.info("spitting udp to: {s}", .{to}); logger.info("init udp", .{}); var from_sock = try network.Socket.create(.ipv4, .udp); defer from_sock.close(); try from_sock.enablePortReuse(true); try from_sock.bind(from); var to_sock = try network.Socket.create(.ipv4, .udp); defer to_sock.close(); var receive_buffer: [2048]u8 = undefined; while (true) { const reader = from_sock.reader(); const received_bytes = try reader.read(&receive_buffer); const bytes = receive_buffer[0..received_bytes]; const sent_bytes = try to_sock.sendTo(to, bytes); if (sent_bytes != received_bytes) { logger.warn( "tried to send {d} bytes, actually sent {d}", .{ received_bytes, sent_bytes }, ); } } }