mirror of
https://github.com/apache/nuttx.git
synced 2026-08-01 20:28:58 +00:00
|
Some checks are pending
MemBrowse Memory Report / changes-filter (push) Waiting to run
MemBrowse Memory Report / load-targets (push) Waiting to run
MemBrowse Memory Report / identical (push) Blocked by required conditions
MemBrowse Memory Report / analyze (push) Blocked by required conditions
tcp_start_monitor() is called from accept() (net/inet/inet_sockif.c) for
each newly accepted connection. When the peer had already closed the
connection before accept() ran, the monitor takes an early-return path so
that any read-ahead data buffered on the connection can still be drained;
it returns OK in that case. accept() (net/socket/accept.c) then marks the
new socket _SF_CONNECTED unconditionally.
If the peer aborts the connection with an RST immediately after the
three-way handshake completes (for example any close with SO_LINGER
{1, 0}), the connection is moved to TCP_CLOSED with no buffered data, yet
accept() still hands back a socket that reports _SS_ISCONNECTED. A
subsequent blocking send() on that socket passes the connected check,
registers a send callback and waits on its semaphore forever: the only
TCP_ABORT event was delivered before the callback existed, and no further
ACK, POLL or disconnect event is generated for a closed connection, so the
waiter is never woken.
Any server that writes before reading can hit this; the telnet daemon
(netutils/telnetd) is one example, where the accepted session task blocks
in send() and never completes.
Only return OK from the already-closed path when there is actually
read-ahead data to drain. Otherwise the connection is dead, so fall
through to the -ENOTCONN return: accept() then fails cleanly instead of
handing back a socket wedged on a connection that will never make progress.
The graceful-close-with-pending-data case (the reason the OK path exists)
is preserved by the conn->readahead check.
Signed-off-by: Ricard Rosson <ricard@groundbits.com>
Assisted-by: Claude (Anthropic Claude Code)
|
||
|---|---|---|
| .. | ||
| CMakeLists.txt | ||
| Kconfig | ||
| Make.defs | ||
| tcp.h | ||
| tcp_accept.c | ||
| tcp_appsend.c | ||
| tcp_backlog.c | ||
| tcp_callback.c | ||
| tcp_cc.c | ||
| tcp_close.c | ||
| tcp_conn.c | ||
| tcp_connect.c | ||
| tcp_devpoll.c | ||
| tcp_dump.c | ||
| tcp_finddev.c | ||
| tcp_getsockopt.c | ||
| tcp_input.c | ||
| tcp_ioctl.c | ||
| tcp_ipselect.c | ||
| tcp_listen.c | ||
| tcp_monitor.c | ||
| tcp_netpoll.c | ||
| tcp_notifier.c | ||
| tcp_recvfrom.c | ||
| tcp_recvwindow.c | ||
| tcp_send.c | ||
| tcp_send_buffered.c | ||
| tcp_send_unbuffered.c | ||
| tcp_sendfile.c | ||
| tcp_seqno.c | ||
| tcp_setsockopt.c | ||
| tcp_shutdown.c | ||
| tcp_timer.c | ||
| tcp_txdrain.c | ||
| tcp_wrbuffer.c | ||