You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2026/10/22 11:13:07 UTC

(nuttx) 02/02: net/tcp: Close the connection when keep-alive probes fail.

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 <ra...@railab.me>
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 <ra...@railab.me>
---
 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;