unicorn_screams/src/main.zig

80 lines
2.5 KiB
Zig

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();
const BUFSIZE = 4;
const Buffer = struct {
raw_data: [2048]u8,
message: []u8,
};
var receive_buffers: [BUFSIZE]Buffer = undefined;
var receive_buffer_index: usize = 0;
const reader = from_sock.reader();
while (true) : (receive_buffer_index += 1) {
const array_index = receive_buffer_index % BUFSIZE;
const raw_data = &receive_buffers[array_index].raw_data;
const received_bytes = try reader.read(raw_data);
receive_buffers[array_index].message = raw_data[0..received_bytes];
if (receive_buffer_index > BUFSIZE) {
const index_to_send = (receive_buffer_index - BUFSIZE - 1) % BUFSIZE;
const bytes_to_send = receive_buffers[index_to_send].message;
const sent_bytes = try to_sock.sendTo(to, bytes_to_send);
if (sent_bytes != received_bytes) {
logger.warn(
"tried to send {d} bytes, actually sent {d}",
.{ received_bytes, sent_bytes },
);
}
}
}
}