aboutsummaryrefslogtreecommitdiffstats
path: root/src/syscall.asm
diff options
context:
space:
mode:
authoruser <user@clank>2026-09-22 21:54:03 +0200
committeruser <user@clank>2026-09-22 21:54:03 +0200
commitdcd1f1320c102f9cc4cff7eee387ec538304f7d1 (patch)
treee0b48e345c8d34a5f110378e795b8690120ebd55 /src/syscall.asm
parentbuild: rebuild every object when include/*.inc changes (diff)
downloadgbos-dcd1f1320c102f9cc4cff7eee387ec538304f7d1.tar.gz
gbos-dcd1f1320c102f9cc4cff7eee387ec538304f7d1.tar.xz
gbos-dcd1f1320c102f9cc4cff7eee387ec538304f7d1.zip
net: one socket per client - four-tuple demux, spawning accept, bounded close
A server could only ever hold ONE connection, which makes an ircd pointless: listen() turned the listener into the connection, and net_find_tcp demuxed on local port alone, so two clients on 6667 were indistinguishable. - net_find_tcp now matches an established socket on the full four-tuple (local port + peer IP + peer port) and only falls back to a LISTENing socket when none matches. - A SYN at a listener no longer consumes it: tcp_spawn_conn clones a new socket (local port + owning pid, so exit/kill still reclaims it) and the listener keeps listening. accept() returns that socket; closing it leaves the listener alone. A full table drops the SYN, and the client's retransmit is taken once a slot frees. - tcp_peer_is_current preserves BC: net_find_tcp scans with the socket index there, and the compare needs BC for the rx buffer base. Without this the scan died at the first mismatching socket, so a second client's handshake ACK never reached its socket and it hung in SYNRCVD - tcpdump showed our SYN+ACK going out and the client's NICK retransmitted five times into silence. - listen() only conflicts with another LISTENER on the port; connections share it by design now. - MAX_SOCKS 4 -> 6 (listener + 3 clients + 2 spare; 537 bytes of WRAM0 still free), and SK_ACC marks a spawned connection as not yet accepted. tcp_close's settle is also time-boxed to ~250 ms of real time. It counted PUMPS (8 x 8000), which is ~30s of wall clock when the peer never answers - invisible with well-behaved peers, but a daemon refusing a client that stayed connected froze itself, and every other client with it, for half a minute. httpd keeps its listener open across requests now, so the next client's SYN is accepted immediately instead of being dropped between close and re-listen: three parallel clients go 0.1/1.1/2.1s -> 0.4/1.0/0.1s.
Diffstat (limited to '')
-rw-r--r--src/syscall.asm2
1 files changed, 1 insertions, 1 deletions
diff --git a/src/syscall.asm b/src/syscall.asm
index e0961bc..0ed9f85 100644
--- a/src/syscall.asm
+++ b/src/syscall.asm
@@ -282,7 +282,7 @@ ENDR
; (TimerISR can carry between the two byte reads, which would otherwise read
; $01FF out of a counter going $00FF -> $0100).
; -----------------------------------------------------------------------------
-ticks16:
+ticks16::
ld a, [wTicks+1]
ld h, a
ld a, [wTicks]