Skip to content

Commit 82b72cb

Browse files
Florian Westphalummakynes
authored andcommitted
netfilter: conntrack: re-init state for retransmitted syn-ack
TCP conntrack assumes that a syn-ack retransmit is identical to the previous syn-ack. This isn't correct and causes stuck 3whs in some more esoteric scenarios. tcpdump to illustrate the problem: client > server: Flags [S] seq 1365731894, win 29200, [mss 1460,sackOK,TS val 2083035583 ecr 0,wscale 7] server > client: Flags [S.] seq 145824453, ack 643160523, win 65535, [mss 8952,wscale 5,TS val 3215367629 ecr 2082921663] Note the invalid/outdated synack ack number. Conntrack marks this syn-ack as out-of-window/invalid, but it did initialize the reply direction parameters based on this packets content. client > server: Flags [S] seq 1365731894, win 29200, [mss 1460,sackOK,TS val 2083036623 ecr 0,wscale 7] ... retransmit... server > client: Flags [S.], seq 145824453, ack 643160523, win 65535, [mss 8952,wscale 5,TS val 3215368644 ecr 2082921663] and another bogus synack. This repeats, then client re-uses for a new attempt: client > server: Flags [S], seq 2375731741, win 29200, [mss 1460,sackOK,TS val 2083100223 ecr 0,wscale 7] server > client: Flags [S.], seq 145824453, ack 643160523, win 65535, [mss 8952,wscale 5,TS val 3215430754 ecr 2082921663] ... but still gets a invalid syn-ack. This repeats until: server > client: Flags [S.], seq 145824453, ack 643160523, win 65535, [mss 8952,wscale 5,TS val 3215437785 ecr 2082921663] server > client: Flags [R.], seq 145824454, ack 643160523, win 65535, [mss 8952,wscale 5,TS val 3215443451 ecr 2082921663] client > server: Flags [S], seq 2375731741, win 29200, [mss 1460,sackOK,TS val 2083115583 ecr 0,wscale 7] server > client: Flags [S.], seq 162602410, ack 2375731742, win 65535, [mss 8952,wscale 5,TS val 3215445754 ecr 2083115583] This syn-ack has the correct ack number, but conntrack flags it as invalid: The internal state was created from the first syn-ack seen so the sequence number of the syn-ack is treated as being outside of the announced window. Don't assume that retransmitted syn-ack is identical to previous one. Treat it like the first syn-ack and reinit state. Signed-off-by: Florian Westphal <[email protected]> Acked-by: Jozsef Kadlecsik <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]>
1 parent cc4f9d6 commit 82b72cb

File tree

1 file changed

+12
-0
lines changed

1 file changed

+12
-0
lines changed

net/netfilter/nf_conntrack_proto_tcp.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,18 @@ static bool tcp_in_window(struct nf_conn *ct,
571571
sender->td_maxwin = (win == 0 ? 1 : win);
572572

573573
tcp_options(skb, dataoff, tcph, sender);
574+
} else if (tcph->syn && dir == IP_CT_DIR_REPLY &&
575+
state->state == TCP_CONNTRACK_SYN_SENT) {
576+
/* Retransmitted syn-ack, or syn (simultaneous open).
577+
*
578+
* Re-init state for this direction, just like for the first
579+
* syn(-ack) reply, it might differ in seq, ack or tcp options.
580+
*/
581+
tcp_init_sender(sender, receiver,
582+
skb, dataoff, tcph,
583+
end, win);
584+
if (!tcph->ack)
585+
return true;
574586
}
575587

576588
if (!(tcph->ack)) {

0 commit comments

Comments
 (0)