diff options
| author | user <user@clank> | 2026-09-22 21:54:03 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-09-22 21:54:03 +0200 |
| commit | dcd1f1320c102f9cc4cff7eee387ec538304f7d1 (patch) | |
| tree | e0b48e345c8d34a5f110378e795b8690120ebd55 /src/syscall.asm | |
| parent | build: rebuild every object when include/*.inc changes (diff) | |
| download | gbos-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.asm | 2 |
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] |
