kernel/net: free TCP sockets closed before the handshake completes (#620)
Summary: socket_close() skipped both tcp_disconnect and socket_free for any TCP socket that was not yet in the SS_ISCONNECTED state, leaking the socket structure and leaving it on the net_sockets list forever. Details: The SS_ISCONNECTED gate in socket_close covered only fully established connections. A socket closed while in SYN_SENT, SYN_RECEIVED or LISTEN, or one that never connected at all, fell through to a bare `ret`: it was neither disconnected nor freed. The 4 KiB socket structure and its two ring buffers stayed allocated, the socket kept its place on net_sockets, its timers kept being decremented by tcp_timer_640ms, and SOCKET.TID kept pointing at a thread that was about to exit. A browser or any other application that opens connections which fail to establish (refused, filtered, or simply cancelled by the user) leaked one socket per attempt. The gate is not needed: tcp_disconnect dispatches on the TCB state itself and jumps straight to tcp_close -- which calls socket_free -- whenever t_state is below TCPS_ESTABLISHED. Dropping the test therefore routes the not-yet-synchronized cases to exactly the cleanup they were missing, and leaves the established path untouched. The SS_ISDISCONNECTING test is kept, so a second close() on a socket already shutting down is still a no-op. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Reviewed-on: #620 Reviewed-by: hidnplayr <hidnplayr@gmail.com> Reviewed-by: Mikhail Frolov <mixa.frolov2003@gmail.com>
This commit was merged in pull request #620.
This commit is contained in:
@@ -780,8 +780,6 @@ socket_close:
|
||||
|
||||
cmp [eax + SOCKET.Protocol], IP_PROTO_TCP
|
||||
jne .free
|
||||
test [eax + SOCKET.state], SS_ISCONNECTED
|
||||
jz @f
|
||||
test [eax + SOCKET.state], SS_ISDISCONNECTING
|
||||
jnz @f
|
||||
call tcp_disconnect
|
||||
|
||||
Reference in New Issue
Block a user