From 774994b951d932d2968305eee4d9b20340a63c71 Mon Sep 17 00:00:00 2001 From: Alexander Lunev Date: Fri, 11 Feb 2022 17:59:26 +0300 Subject: [PATCH] net/tcp: support for FIN+ACK case in tcp send event handlers --- net/tcp/tcp_send_buffered.c | 54 +++++++++++++++++------------------ net/tcp/tcp_send_unbuffered.c | 4 +-- net/tcp/tcp_sendfile.c | 4 +-- 3 files changed, 28 insertions(+), 34 deletions(-) diff --git a/net/tcp/tcp_send_buffered.c b/net/tcp/tcp_send_buffered.c index dfa008b7cb..91312b16c6 100644 --- a/net/tcp/tcp_send_buffered.c +++ b/net/tcp/tcp_send_buffered.c @@ -384,45 +384,19 @@ static uint16_t psock_send_eventhandler(FAR struct net_driver_s *dev, ninfo("flags: %04x\n", flags); /* The TCP_ACKDATA, TCP_REXMIT and TCP_DISCONN_EVENTS flags are expected to - * appear here strictly one at a time + * appear here strictly one at a time, except for the FIN + ACK case. */ DEBUGASSERT((flags & TCP_ACKDATA) == 0 || (flags & TCP_REXMIT) == 0); - DEBUGASSERT((flags & TCP_DISCONN_EVENTS) == 0 || - (flags & TCP_ACKDATA) == 0); DEBUGASSERT((flags & TCP_DISCONN_EVENTS) == 0 || (flags & TCP_REXMIT) == 0); - /* Check for a loss of connection */ - - if ((flags & TCP_DISCONN_EVENTS) != 0) - { - ninfo("Lost connection: %04x\n", flags); - - /* We could get here recursively through the callback actions of - * tcp_lost_connection(). So don't repeat that action if we have - * already been disconnected. - */ - - if (_SS_ISCONNECTED(conn->sconn.s_flags)) - { - /* Report not connected */ - - tcp_lost_connection(conn, conn->sndcb, flags); - } - - /* Free write buffers and terminate polling */ - - psock_lost_connection(conn, !!(flags & NETDEV_DOWN)); - return flags; - } - /* If this packet contains an acknowledgment, then update the count of * acknowledged bytes. */ - else if ((flags & TCP_ACKDATA) != 0) + if ((flags & TCP_ACKDATA) != 0) { FAR struct tcp_wrbuffer_s *wrb; FAR struct tcp_hdr_s *tcp; @@ -602,6 +576,30 @@ static uint16_t psock_send_eventhandler(FAR struct net_driver_s *dev, } } + /* Check for a loss of connection */ + + if ((flags & TCP_DISCONN_EVENTS) != 0) + { + ninfo("Lost connection: %04x\n", flags); + + /* We could get here recursively through the callback actions of + * tcp_lost_connection(). So don't repeat that action if we have + * already been disconnected. + */ + + if (_SS_ISCONNECTED(conn->sconn.s_flags)) + { + /* Report not connected */ + + tcp_lost_connection(conn, conn->sndcb, flags); + } + + /* Free write buffers and terminate polling */ + + psock_lost_connection(conn, !!(flags & NETDEV_DOWN)); + return flags; + } + /* Check if we are being asked to retransmit data */ else if ((flags & TCP_REXMIT) != 0) diff --git a/net/tcp/tcp_send_unbuffered.c b/net/tcp/tcp_send_unbuffered.c index 10ec05d068..f7dafa39f0 100644 --- a/net/tcp/tcp_send_unbuffered.c +++ b/net/tcp/tcp_send_unbuffered.c @@ -210,13 +210,11 @@ static uint16_t tcpsend_eventhandler(FAR struct net_driver_s *dev, flags, pstate->snd_acked, pstate->snd_sent); /* The TCP_ACKDATA, TCP_REXMIT and TCP_DISCONN_EVENTS flags are expected to - * appear here strictly one at a time + * appear here strictly one at a time, except for the FIN + ACK case. */ DEBUGASSERT((flags & TCP_ACKDATA) == 0 || (flags & TCP_REXMIT) == 0); - DEBUGASSERT((flags & TCP_DISCONN_EVENTS) == 0 || - (flags & TCP_ACKDATA) == 0); DEBUGASSERT((flags & TCP_DISCONN_EVENTS) == 0 || (flags & TCP_REXMIT) == 0); diff --git a/net/tcp/tcp_sendfile.c b/net/tcp/tcp_sendfile.c index 3af0a7a2db..535dbcc0d8 100644 --- a/net/tcp/tcp_sendfile.c +++ b/net/tcp/tcp_sendfile.c @@ -164,13 +164,11 @@ static uint16_t sendfile_eventhandler(FAR struct net_driver_s *dev, flags, pstate->snd_acked, pstate->snd_sent); /* The TCP_ACKDATA, TCP_REXMIT and TCP_DISCONN_EVENTS flags are expected to - * appear here strictly one at a time + * appear here strictly one at a time, except for the FIN + ACK case. */ DEBUGASSERT((flags & TCP_ACKDATA) == 0 || (flags & TCP_REXMIT) == 0); - DEBUGASSERT((flags & TCP_DISCONN_EVENTS) == 0 || - (flags & TCP_ACKDATA) == 0); DEBUGASSERT((flags & TCP_DISCONN_EVENTS) == 0 || (flags & TCP_REXMIT) == 0);