srctree

Gregory Mullen parent a452a7e8 694adea6
add default timeout 30ms and retry upstream

src/network.zig added: 35, removed: 4, total 31
@@ -2,6 +2,10 @@ pub const Peer = struct {
addr: std.net.Address,
sock: std.posix.socket_t,
 
const Options = struct {
recv_timeout_us: ?u32 = null,
};
 
/// TODO ipv6
pub fn init(addr_ip: [4]u8, port: u16) !Peer {
const up: Peer = .{
@@ -14,12 +18,24 @@ pub const Peer = struct {
return up;
}
 
pub fn connect(addr_ip: [4]u8, port: u16) !Peer {
pub fn connectOptions(addr_ip: [4]u8, port: u16, opts: Options) !Peer {
const up: Peer = try .init(addr_ip, port);
try std.posix.connect(up.sock, &up.addr.any, up.addr.getOsSockLen());
if (opts.recv_timeout_us) |rcvto| {
try std.posix.setsockopt(
up.sock,
sys.SOCKET,
sys.RCVTIMEO,
asBytes(&sys.timeval{ .sec = 0, .usec = rcvto }),
);
}
return up;
}
 
pub fn connect(addr_ip: [4]u8, port: u16) !Peer {
return try connectOptions(addr_ip, port, .{ .recv_timeout_us = 30000 });
}
 
pub fn listen(addr_ip: [4]u8, port: u16) !Peer {
const up: Peer = try .init(addr_ip, port);
try std.posix.bind(up.sock, &up.addr.any, up.addr.getOsSockLen());
@@ -54,5 +70,11 @@ pub const Peer = struct {
};
 
const std = @import("std");
const sys = struct {
const timeval = std.os.linux.timeval;
const SOCKET = std.os.linux.SOL.SOCKET;
const RCVTIMEO = std.os.linux.SO.RCVTIMEO;
};
const asBytes = std.mem.asBytes;
const nativeToBig = std.mem.nativeToBig;
const bytesToValue = std.mem.bytesToValue;
 
src/server.zig added: 35, removed: 4, total 31
@@ -114,7 +114,16 @@ fn core(
//log.info("bounce", .{});
try upstream.send(in_msg);
var relay_buf: [1024]u8 = undefined;
const b_cnt = try upstream.recv(&relay_buf);
const b_cnt = upstream.recv(&relay_buf) catch |err| again: switch (err) {
error.WouldBlock => {
try upstream.send(in_msg);
break :again upstream.recv(&relay_buf) catch |err2| {
log.err("unable to communicate with upstream {} timed out twice", .{upstream.addr});
return err2;
};
},
else => return err,
};
const relayed = relay_buf[0..b_cnt];
log.info("bounce received {}", .{b_cnt});
log.debug("bounce data {any}", .{relayed});