net/tcp: support OTW check and response with an empty acknowledgment segment

According RFC793,p72~p73 In states from ESTABLISHED to LASTACK:"If the ACK acks something not yet sent (SEG.ACK > SND.NXT) then send an ACK, drop the segment, and return"

Signed-off-by: wenquan1 <wenquan1@xiaomi.com>
This commit is contained in:
wenquan1
2025-08-25 13:34:49 +08:00
committed by Xiang Xiao
parent facb9d4e65
commit 8ead446ee4
2 changed files with 31 additions and 14 deletions
+1 -1
View File
@@ -55,7 +55,7 @@ static void tcp_close_work(FAR void *param)
FAR struct tcp_conn_s *conn = (FAR struct tcp_conn_s *)param;
conn->flags &= ~TCP_CLOSE_ARRANGED;
if (conn->crefs == 0)
if (conn->crefs == 0 && conn->tcpstateflags == TCP_CLOSED)
{
/* Stop the network monitor for all sockets */
+30 -13
View File
@@ -992,8 +992,9 @@ found:
* data, calculate RTT estimations, and reset the retransmission timer.
*/
if ((tcp->flags & TCP_ACK) != 0 && conn->tx_unacked > 0)
if ((tcp->flags & TCP_ACK) != 0)
{
uint32_t lasttxunacked = conn->tx_unacked;
uint32_t unackseq;
uint32_t ackseq;
int timeout;
@@ -1035,7 +1036,17 @@ found:
{
/* Calculate the new number of outstanding, unacknowledged bytes */
conn->tx_unacked = unackseq - ackseq;
if (conn->tx_unacked < unackseq - ackseq)
{
/* old ack */
tcp_send(dev, conn, TCP_ACK, tcpiplen);
return;
}
else
{
conn->tx_unacked = unackseq - ackseq;
}
}
else
{
@@ -1045,20 +1056,24 @@ found:
* bytes
*/
if ((conn->tcpstateflags & TCP_STATE_MASK) == TCP_ESTABLISHED ||
(conn->tcpstateflags & TCP_STATE_MASK) == TCP_CLOSE_WAIT)
{
nwarn("WARNING: ackseq > unackseq\n");
nwarn("sndseq=%" PRIu32 " tx_unacked=%" PRIu32
" unackseq=%" PRIu32 " ackseq=%" PRIu32 "\n",
tcp_getsequence(conn->sndseq),
(uint32_t)conn->tx_unacked,
unackseq, ackseq);
/* RFC793,p72~p73 In states from ESTABLISHED to LASTACK:"If the
* ACK acks something not yet sent (SEG.ACK > SND.NXT) then send
* an ACK, drop the segment, and return."
*/
conn->tx_unacked = 0;
if ((conn->tcpstateflags & TCP_STATE_MASK) >= TCP_ESTABLISHED &&
(conn->tcpstateflags & TCP_STATE_MASK) <= TCP_LAST_ACK)
{
tcp_send(dev, conn, TCP_ACK, tcpiplen);
return;
}
}
if (lasttxunacked == 0)
{
goto skip_rtt;
}
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
#ifdef CONFIG_NET_SENDFILE
if (!conn->sendfile)
@@ -1127,6 +1142,8 @@ found:
tcp_update_retrantimer(conn, timeout);
}
skip_rtt:
/* Check if the sequence number of the incoming packet is what we are
* expecting next. If not, we send out an ACK with the correct numbers
* in, unless we are in the SYN_RCVD state and receive a SYN, in which
@@ -1269,7 +1286,7 @@ found:
conn->isn = tcp_getsequence(tcp->ackno);
tcp_setsequence(conn->sndseq, conn->isn);
conn->sent = 0;
conn->sndseq_max = 0;
conn->sndseq_max = conn->isn;
#endif
conn->tx_unacked = 0;
tcp_snd_wnd_init(conn, tcp);