Skip to content

Commit 44cfceb

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 4b1c034 commit 44cfceb

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
@@ -2554,6 +2554,7 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt)
25542554

25552555
conn_ack(conn, + 1);
25562556
tcp_out(conn, FIN | ACK);
2557+
conn_seq(conn, + 1);
25572558
next = TCP_LAST_ACK;
25582559
verdict = NET_OK;
25592560
tcp_setup_last_ack_timer(conn);
@@ -2578,6 +2579,7 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt)
25782579

25792580
conn_ack(conn, + len + 1);
25802581
tcp_out(conn, FIN | ACK);
2582+
conn_seq(conn, + 1);
25812583
next = TCP_LAST_ACK;
25822584
tcp_setup_last_ack_timer(conn);
25832585
break;
@@ -2757,11 +2759,12 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt)
27572759
break;
27582760
case TCP_CLOSE_WAIT:
27592761
tcp_out(conn, FIN);
2762+
conn_seq(conn, + 1);
27602763
next = TCP_LAST_ACK;
27612764
tcp_setup_last_ack_timer(conn);
27622765
break;
27632766
case TCP_LAST_ACK:
2764-
if (th && FL(&fl, ==, ACK, th_seq(th) == conn->ack)) {
2767+
if (th && FL(&fl, ==, ACK, th_ack(th) == conn->seq)) {
27652768
tcp_send_timer_cancel(conn);
27662769
do_close = true;
27672770
verdict = NET_OK;

0 commit comments

Comments
 (0)