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;