From d4239929882ce6d5cdd97d658726b7fa2663fd16 Mon Sep 17 00:00:00 2001 From: Zhe Weng Date: Wed, 1 Feb 2023 20:07:47 +0800 Subject: [PATCH] net/tcp: Regard snd_wnd update as ACKDATA Receiving an ACK indicating TCP Window Update will not set ACKDATA flag (because tx_unacked is 0) in our TCP stack. Then this ACK won't let us send anything after receiving it, even if it updates snd_wnd. So we need to check whether we can send data immediately when our snd_wnd is updated (especially from 0), otherwise we will only send next data after timer expiry. Signed-off-by: Zhe Weng --- net/tcp/tcp_input.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/net/tcp/tcp_input.c b/net/tcp/tcp_input.c index b398cd74f6a..07dbede40e4 100644 --- a/net/tcp/tcp_input.c +++ b/net/tcp/tcp_input.c @@ -48,6 +48,7 @@ #if defined(CONFIG_NET) && defined(CONFIG_NET_TCP) #include +#include #include #include #include @@ -198,7 +199,7 @@ static void tcp_snd_wnd_init(FAR struct tcp_conn_s *conn, ninfo("snd_wnd init: wl1 %" PRIu32 "\n", conn->snd_wl1); } -static void tcp_snd_wnd_update(FAR struct tcp_conn_s *conn, +static bool tcp_snd_wnd_update(FAR struct tcp_conn_s *conn, FAR struct tcp_hdr_s *tcp) { uint32_t ackseq = tcp_getsequence(tcp->ackno); @@ -254,7 +255,11 @@ static void tcp_snd_wnd_update(FAR struct tcp_conn_s *conn, conn->snd_wl1 = seq; conn->snd_wl2 = ackseq; conn->snd_wnd = wnd; + + return true; } + + return false; } #ifdef CONFIG_NET_TCP_OUT_OF_ORDER @@ -1141,7 +1146,16 @@ found: if ((tcp->flags & TCP_ACK) != 0 && (conn->tcpstateflags & TCP_STATE_MASK) != TCP_SYN_RCVD) { - tcp_snd_wnd_update(conn, tcp); + if (tcp_snd_wnd_update(conn, tcp)) + { + /* Window updated, set the acknowledged flag. */ + + flags |= TCP_ACKDATA; + + /* Reset the retransmission timer. */ + + tcp_update_retrantimer(conn, conn->rto); + } } /* Do different things depending on in what state the connection is. */