This is an automated email from the ASF dual-hosted git repository. xiaoxiang781216 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit b01e7e760c612c24a14a738de37e3221190636ac Author: raiden00pl <[email protected]> AuthorDate: Sat Oct 10 17:40:13 2026 +0200 net/tcp: Close the connection when keep-alive probes fail. tcp_timer() only sent TCP_ABORT to the socket and left the connection open. POSIX XSH 2.10.16: "if SO_KEEPALIVE is enabled and the connected socket fails to respond to the keep-alive messages, the connection shall be broken". Close it like a retransmission timeout and return ETIMEDOUT from recv(), defined for a connection that "timed out ... due to a transmission timeout on active connection". Assisted-by: Claude:claude-opus-5-5 Signed-off-by: raiden00pl <[email protected]> --- net/tcp/tcp_recvfrom.c | 7 ++++++- net/tcp/tcp_timer.c | 18 ++++++++++++------ 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/net/tcp/tcp_recvfrom.c b/net/tcp/tcp_recvfrom.c index f708d792d75..b8c6f6a2b2e 100644 --- a/net/tcp/tcp_recvfrom.c +++ b/net/tcp/tcp_recvfrom.c @@ -505,7 +505,12 @@ static uint32_t tcp_recvhandler(FAR struct net_driver_s *dev, tcp_lost_connection(conn, pstate->ir_cb, flags); } - pstate->ir_result = -ENOTCONN; + /* Report a timed out connection (too many retransmissions or + * unanswered keep-alive probes) as ETIMEDOUT. + */ + + pstate->ir_result = (flags & TCP_TIMEDOUT) != 0 ? -ETIMEDOUT : + -ENOTCONN; /* Wake up the waiting thread */ diff --git a/net/tcp/tcp_timer.c b/net/tcp/tcp_timer.c index 1210ba3987e..68e2f5fee44 100644 --- a/net/tcp/tcp_timer.c +++ b/net/tcp/tcp_timer.c @@ -695,18 +695,24 @@ void tcp_timer(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn) if (conn->keepretries >= conn->keepcnt) { - /* Yes... stop the network monitor, closing the - * connection and all sockets associated with the - * connection. + /* Yes... the peer is dead. Close the connection + * as on a retransmission timeout. */ - devif_conn_event(conn->dev, TCP_ABORT, - conn->sconn.list); + conn->tcpstateflags = TCP_CLOSED; + ninfo("TCP state: TCP_CLOSED\n"); - /* We also send a reset packet to the remote host. */ + /* We send a reset packet to the remote host. */ tcp_send(dev, conn, TCP_RST | TCP_ACK, hdrlen); + /* We also call tcp_callback() with TCP_TIMEDOUT to + * inform all sockets and the connection monitor + * that the connection has timed out. + */ + + tcp_callback(dev, conn, TCP_TIMEDOUT); + /* Stop the timer work */ conn->keeptimer = 0;
