diff options
| author | user <user@clank> | 2026-09-22 17:12:41 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-09-22 17:12:41 +0200 |
| commit | e23fb93141be593cfd45c2bf8669f71e5aac9bbd (patch) | |
| tree | a7f16c8670b8e0a7d52a50b6087ee1ae59aff0a9 /include | |
| parent | kernel: per-process sleep - two sleepers used to deadlock each other (diff) | |
| download | gbos-e23fb93141be593cfd45c2bf8669f71e5aac9bbd.tar.gz gbos-e23fb93141be593cfd45c2bf8669f71e5aac9bbd.tar.xz gbos-e23fb93141be593cfd45c2bf8669f71e5aac9bbd.zip | |
net: passive open (listen/accept) + own sockets + close promptly
The stack could only ever dial out. Two new ops give it an ear:
- listen(sock, port): sockets demux on LOCAL PORT alone, so the listener IS
the connection - the SYN fills in the peer and the socket becomes the
connection. One at a time, re-armed by listening again after close, which
is all a 4-socket table can honestly promise. A second client's SYN is
dropped in silence; its retransmit is taken once we are free (~1s), so
three parallel clients complete in 0.1/1.1/2.1s.
- accept(sock): one RX pump per call, never blocks (like recv_nb), so a
server keeps its own main loop and stays killable.
- TCP_LISTEN/TCP_SYNRCVD in tcp_in: answer a SYN with SYN+ACK, become
established on the handshake's ACK, and process any data that ACK carries.
tcp_peer_is_current tells a peer's retransmitted SYN from a newcomer's.
Without it, "any SYN in SYNRCVD is a retransmission" let a second client
*hijack* a connection mid-request: the first client got its SYN+ACK, sent
its GET twice, and was never answered (found in a tcpdump of two parallel
curls).
listen() also refuses a port another socket already holds - two sockets on
one port silently black-hole the second listener, since demux takes the
first match.
Sockets now record the pid that opened them (SK_OWNER) and exit *and* kill
release them: with 4 slots, a few killed irc/nc/httpd runs used to leave the
box unable to open a socket at all until reboot.
tcp_close stops settling the moment the peer's FIN/ACK arrives instead of
burning its whole pump budget. It otherwise sits in FINWAIT for about a
second, and a server that closes and re-listens drops the next client's SYN
in that window: every request after the first paid a SYN retransmit.
1.1s -> 0.1s per request.
Diffstat (limited to 'include')
0 files changed, 0 insertions, 0 deletions
