From d78bf367407abf91993aba688ce7e8a4191583bc Mon Sep 17 00:00:00 2001 From: "chao.an" Date: Fri, 7 Aug 2020 17:32:55 +0800 Subject: [PATCH] net/tcp: fix tcp socket close timeout if loss wireless connection In the current net stack implementation, there is no mechanism for notifying the loss of the wireless connection, if the network is disconnected then application sends data packets through tcp, the tcp_timer will keep retrying fetch the ack for awhile, the connection status will not be able to be switched timely. Change-Id: I84d1121527edafc6ee6ad56ba164838694e7e11c Signed-off-by: chao.an --- net/netdev/netdev_carrier.c | 5 +++++ net/tcp/tcp_send_buffered.c | 13 +++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/net/netdev/netdev_carrier.c b/net/netdev/netdev_carrier.c index 1c882f5022..43717b2605 100644 --- a/net/netdev/netdev_carrier.c +++ b/net/netdev/netdev_carrier.c @@ -105,6 +105,11 @@ int netdev_carrier_off(FAR struct net_driver_s *dev) { dev->d_flags &= ~IFF_RUNNING; netlink_device_notify(dev); + + /* Notify clients that the network has been taken down */ + + devif_dev_event(dev, NULL, NETDEV_DOWN); + return OK; } diff --git a/net/tcp/tcp_send_buffered.c b/net/tcp/tcp_send_buffered.c index 78d535bb83..c58ed1e3f1 100644 --- a/net/tcp/tcp_send_buffered.c +++ b/net/tcp/tcp_send_buffered.c @@ -205,7 +205,8 @@ static void psock_writebuffer_notify(FAR struct tcp_conn_s *conn) ****************************************************************************/ static inline void psock_lost_connection(FAR struct socket *psock, - FAR struct tcp_conn_s *conn) + FAR struct tcp_conn_s *conn, + bool abort) { FAR sq_entry_t *entry; FAR sq_entry_t *next; @@ -245,6 +246,14 @@ static inline void psock_lost_connection(FAR struct socket *psock, conn->sent = 0; conn->sndseq_max = 0; + + /* Force abort the connection. */ + + if (abort) + { + conn->tx_unacked = 0; + conn->tcpstateflags = TCP_CLOSED; + } } } @@ -503,7 +512,7 @@ static uint16_t psock_send_eventhandler(FAR struct net_driver_s *dev, /* Free write buffers and terminate polling */ - psock_lost_connection(psock, conn); + psock_lost_connection(psock, conn, !!(flags & NETDEV_DOWN)); return flags; }