diff options
author | Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> | 2018-04-21 13:43:48 +0200 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2018-04-27 00:39:29 +0200 |
commit | 72d4d3e3980702809509586d36015b7c3c51fad4 (patch) | |
tree | 0b50708c4b2c4183f0230ba603393ecd8a85145a /net/netfilter/nf_conntrack_proto_tcp.c | |
parent | 25eb0ea7174c6e84f21fa59dccbddd0318b17b12 (diff) | |
download | linux-72d4d3e3980702809509586d36015b7c3c51fad4.tar.gz linux-72d4d3e3980702809509586d36015b7c3c51fad4.tar.bz2 linux-72d4d3e3980702809509586d36015b7c3c51fad4.zip |
netfilter: Fix handling simultaneous open in TCP conntrack
Dominique Martinet reported a TCP hang problem when simultaneous open was used.
The problem is that the tcp_conntracks state table is not smart enough
to handle the case. The state table could be fixed by introducing a new state,
but that would require more lines of code compared to this patch, due to the
required backward compatibility with ctnetlink.
Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Reported-by: Dominique Martinet <asmadeus@codewreck.org>
Tested-by: Dominique Martinet <asmadeus@codewreck.org>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/netfilter/nf_conntrack_proto_tcp.c')
-rw-r--r-- | net/netfilter/nf_conntrack_proto_tcp.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c index e97cdc1cf98c..8e67910185a0 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c @@ -981,6 +981,17 @@ static int tcp_packet(struct nf_conn *ct, return NF_ACCEPT; /* Don't change state */ } break; + case TCP_CONNTRACK_SYN_SENT2: + /* tcp_conntracks table is not smart enough to handle + * simultaneous open. + */ + ct->proto.tcp.last_flags |= IP_CT_TCP_SIMULTANEOUS_OPEN; + break; + case TCP_CONNTRACK_SYN_RECV: + if (dir == IP_CT_DIR_REPLY && index == TCP_ACK_SET && + ct->proto.tcp.last_flags & IP_CT_TCP_SIMULTANEOUS_OPEN) + new_state = TCP_CONNTRACK_ESTABLISHED; + break; case TCP_CONNTRACK_CLOSE: if (index == TCP_RST_SET && (ct->proto.tcp.seen[!dir].flags & IP_CT_TCP_FLAG_MAXACK_SET) |