Skip to content

Commit b4f2a4f

Browse files
rluboscvinayak
authored andcommitted
[nrf fromtree] net: tcp: Fix ACK check in LAST_ACK state
The final ACK check during passive close was wrong - we should not compare its SEQ number with the ACK number we've sent last, but rather compare the ACK number it acknowledges matches our current SEQ number on the connection. This ensures, that the ACK received is really acknowledging the FIN packet we've sent from our side, and is not just some earlier retransmission. Currently the latter could be the case, and we've closed the connection prematurely. In result, when the real "final ACK" arrived, the TCP stack replied with RST. Subsequently, we should increment the SEQ number on the connection after sending FIN packet, so that we are able to identify final ACK correctly, just as it's done in active close cases. Signed-off-by: Robert Lubos <[email protected]> (cherry picked from commit 7207f35)
1 parent 19e45a0 commit b4f2a4f

File tree

1 file changed

+4
-1
lines changed

1 file changed

+4
-1
lines changed

subsys/net/ip/tcp.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2728,6 +2728,7 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt)
27282728

27292729
conn_ack(conn, + 1);
27302730
tcp_out(conn, FIN | ACK);
2731+
conn_seq(conn, + 1);
27312732
next = TCP_LAST_ACK;
27322733
verdict = NET_OK;
27332734
tcp_setup_last_ack_timer(conn);
@@ -2752,6 +2753,7 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt)
27522753

27532754
conn_ack(conn, + len + 1);
27542755
tcp_out(conn, FIN | ACK);
2756+
conn_seq(conn, + 1);
27552757
next = TCP_LAST_ACK;
27562758
tcp_setup_last_ack_timer(conn);
27572759
break;
@@ -2931,11 +2933,12 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt)
29312933
break;
29322934
case TCP_CLOSE_WAIT:
29332935
tcp_out(conn, FIN);
2936+
conn_seq(conn, + 1);
29342937
next = TCP_LAST_ACK;
29352938
tcp_setup_last_ack_timer(conn);
29362939
break;
29372940
case TCP_LAST_ACK:
2938-
if (th && FL(&fl, ==, ACK, th_seq(th) == conn->ack)) {
2941+
if (th && FL(&fl, ==, ACK, th_ack(th) == conn->seq)) {
29392942
tcp_send_timer_cancel(conn);
29402943
do_close = true;
29412944
verdict = NET_OK;

0 commit comments

Comments
 (0)