aboutsummaryrefslogtreecommitdiffstats
path: root/c/sock.h
diff options
context:
space:
mode:
authoruser <user@clank>2026-07-17 19:45:13 +0200
committeruser <user@clank>2026-07-17 19:45:13 +0200
commit4f038ecad87777bc1d74f8f93f267da8cd396446 (patch)
tree28332e362bb8c1c75e97483af21c51cc13cffdac /c/sock.h
parentdocs: investigation notes for the idle link-socket drop (open bug) (diff)
downloadgbos-4f038ecad87777bc1d74f8f93f267da8cd396446.tar.gz
gbos-4f038ecad87777bc1d74f8f93f267da8cd396446.tar.xz
gbos-4f038ecad87777bc1d74f8f93f267da8cd396446.zip
net: unbreak ping against hosts that intermittently drop ICMP
Pinging sl0p.foo through gbhub looked hung: DNS resolved, then nothing. Packet-tracing showed the echo request leaving the hub's TUN and eth0 correctly NATed every time - but 80.78.19.56 blackholes ICMP for all ids in windows of tens of seconds (provider rate limiting). One lost reply wedged ping for minutes because net_recv's pump-counted timeout is effectively unbounded at native emulation speed. Two fixes: - NET_RECVNB (op 8): non-blocking recv - one RX pump, $FE if nothing buffered, same delivery/EOF semantics as NET_RECV otherwise. ping now waits <=~2s per seq (net_recv_nb + msleep loop), prints 'seq=N timeout' and moves on, like real ping. - ICMP echo id was hardcoded $1234 for every GB, every boot, so all sessions produced byte-identical flows - hostile to NAT conntrack (keyed on icmp id). wNetEchoId is now our host octet + rDIV timing noise sampled at DHCP lease, distinct per GB and per boot. Verified: 8 back-to-back native-speed gbhub runs, zero hangs; a run that hit a blackhole window printed seq=1 timeout then recovered to 3/4 received. GB<->GB ping and DNS/DHCP unaffected.
Diffstat (limited to 'c/sock.h')
-rw-r--r--c/sock.h6
1 files changed, 6 insertions, 0 deletions
diff --git a/c/sock.h b/c/sock.h
index 9e4dd40..876e85c 100644
--- a/c/sock.h
+++ b/c/sock.h
@@ -42,6 +42,12 @@ static unsigned char net_recv(unsigned char s, void *buf, unsigned char max) {
_nr.op = 3; _nr.sock = s; _nr.buf = (unsigned char *)buf; _nr.len = max;
return sys_net(&_nr);
}
+/* non-blocking recv: one RX pump -> length, 0xFE if nothing buffered yet,
+ 0 on TCP EOF. Loop it with msleep() to own your timeout (see ping). */
+static unsigned char net_recv_nb(unsigned char s, void *buf, unsigned char max) {
+ _nr.op = 8; _nr.sock = s; _nr.buf = (unsigned char *)buf; _nr.len = max;
+ return sys_net(&_nr);
+}
/* set the local (source) port - needed so UDP replies demux back to us */
static unsigned char net_bind(unsigned char s, unsigned int port) {
_nr.op = 5; _nr.sock = s;