nuttx/net/tcp
Ricard Rosson aeaa13227e
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
net/tcp: don't accept a reset connection as connected (fixes send hang)
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)
2026-07-28 15:25:47 -03:00
..
CMakeLists.txt net: migrate to SPDX identifier 2024-09-12 01:08:11 +08:00
Kconfig net/tcp: add kconfig to support retransmission at a fixed time 2025-12-27 21:35:00 +08:00
Make.defs net: migrate to SPDX identifier 2024-09-12 01:08:11 +08:00
tcp.h !sys/types.h: change time_t and clock_t to int64_t to align with other OSes 2026-05-19 16:21:28 +08:00
tcp_accept.c include/debug.h: Move to include/nuttx/debug.h 2026-04-07 07:50:06 -03:00
tcp_appsend.c include/debug.h: Move to include/nuttx/debug.h 2026-04-07 07:50:06 -03:00
tcp_backlog.c include/debug.h: Move to include/nuttx/debug.h 2026-04-07 07:50:06 -03:00
tcp_callback.c include/debug.h: Move to include/nuttx/debug.h 2026-04-07 07:50:06 -03:00
tcp_cc.c include/debug.h: Move to include/nuttx/debug.h 2026-04-07 07:50:06 -03:00
tcp_close.c include/debug.h: Move to include/nuttx/debug.h 2026-04-07 07:50:06 -03:00
tcp_conn.c include/debug.h: Move to include/nuttx/debug.h 2026-04-07 07:50:06 -03:00
tcp_connect.c include/debug.h: Move to include/nuttx/debug.h 2026-04-07 07:50:06 -03:00
tcp_devpoll.c include/debug.h: Move to include/nuttx/debug.h 2026-04-07 07:50:06 -03:00
tcp_dump.c include/debug.h: Move to include/nuttx/debug.h 2026-04-07 07:50:06 -03:00
tcp_finddev.c net: migrate to SPDX identifier 2024-09-12 01:08:11 +08:00
tcp_getsockopt.c include/debug.h: Move to include/nuttx/debug.h 2026-04-07 07:50:06 -03:00
tcp_input.c include/debug.h: Move to include/nuttx/debug.h 2026-04-07 07:50:06 -03:00
tcp_ioctl.c include/debug.h: Move to include/nuttx/debug.h 2026-04-07 07:50:06 -03:00
tcp_ipselect.c include/debug.h: Move to include/nuttx/debug.h 2026-04-07 07:50:06 -03:00
tcp_listen.c include/debug.h: Move to include/nuttx/debug.h 2026-04-07 07:50:06 -03:00
tcp_monitor.c net/tcp: don't accept a reset connection as connected (fixes send hang) 2026-07-28 15:25:47 -03:00
tcp_netpoll.c include/debug.h: Move to include/nuttx/debug.h 2026-04-07 07:50:06 -03:00
tcp_notifier.c include/debug.h: Move to include/nuttx/debug.h 2026-04-07 07:50:06 -03:00
tcp_recvfrom.c include/debug.h: Move to include/nuttx/debug.h 2026-04-07 07:50:06 -03:00
tcp_recvwindow.c include/debug.h: Move to include/nuttx/debug.h 2026-04-07 07:50:06 -03:00
tcp_send.c net/tcp: improve tcp_send_txnotify 2026-04-21 22:13:36 +08:00
tcp_send_buffered.c include/debug.h: Move to include/nuttx/debug.h 2026-04-07 07:50:06 -03:00
tcp_send_unbuffered.c include/debug.h: Move to include/nuttx/debug.h 2026-04-07 07:50:06 -03:00
tcp_sendfile.c include/debug.h: Move to include/nuttx/debug.h 2026-04-07 07:50:06 -03:00
tcp_seqno.c include/debug.h: Move to include/nuttx/debug.h 2026-04-07 07:50:06 -03:00
tcp_setsockopt.c include/debug.h: Move to include/nuttx/debug.h 2026-04-07 07:50:06 -03:00
tcp_shutdown.c include/debug.h: Move to include/nuttx/debug.h 2026-04-07 07:50:06 -03:00
tcp_timer.c !sys/types.h: change time_t and clock_t to int64_t to align with other OSes 2026-05-19 16:21:28 +08:00
tcp_txdrain.c net: replace net_sem*wait with conn_dev_sem*wait to simplify code logic 2026-01-02 07:48:06 -03:00
tcp_wrbuffer.c include/debug.h: Move to include/nuttx/debug.h 2026-04-07 07:50:06 -03:00