diff options
| author | user <user@clank> | 2026-07-17 19:45:13 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-07-17 19:45:13 +0200 |
| commit | 4f038ecad87777bc1d74f8f93f267da8cd396446 (patch) | |
| tree | 28332e362bb8c1c75e97483af21c51cc13cffdac /c/sock.h | |
| parent | docs: investigation notes for the idle link-socket drop (open bug) (diff) | |
| download | gbos-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 '')
| -rw-r--r-- | c/sock.h | 6 |
1 files changed, 6 insertions, 0 deletions
@@ -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; |
