aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter
diff options
context:
space:
mode:
authorJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2007-10-11 17:35:52 -0400
committerDavid S. Miller <davem@davemloft.net>2007-10-11 17:35:52 -0400
commit17311393f969090ab060540bd9dbe7dc885a76d5 (patch)
treecc8f9a460679870c51b194c8927f998b243a98f7 /net/netfilter
parentd71fce6b932d83e0a1caa49dfa5a536fd50f07c9 (diff)
[NETFILTER]: nf_conntrack_tcp: fix connection reopening
With your description I could reproduce the bug and actually you were completely right: the code above is incorrect. Somehow I was able to misread RFC1122 and mixed the roles :-(: When a connection is >>closed actively<<, it MUST linger in TIME-WAIT state for a time 2xMSL (Maximum Segment Lifetime). However, it MAY >>accept<< a new SYN from the remote TCP to reopen the connection directly from TIME-WAIT state, if it: [...] The fix is as follows: if the receiver initiated an active close, then the sender may reopen the connection - otherwise try to figure out if we hold a dead connection. Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> Tested-by: Krzysztof Piotr Oledzki <ole@ans.pl> Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/netfilter')
-rw-r--r--net/netfilter/nf_conntrack_proto_tcp.c35
1 files changed, 14 insertions, 21 deletions
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index df718e7c7ee..c7075345971 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -831,6 +831,20 @@ static int tcp_packet(struct nf_conn *conntrack,
831 tuple = &conntrack->tuplehash[dir].tuple; 831 tuple = &conntrack->tuplehash[dir].tuple;
832 832
833 switch (new_state) { 833 switch (new_state) {
834 case TCP_CONNTRACK_SYN_SENT:
835 if (old_state < TCP_CONNTRACK_TIME_WAIT)
836 break;
837 if (conntrack->proto.tcp.seen[!dir].flags &
838 IP_CT_TCP_FLAG_CLOSE_INIT) {
839 /* Attempt to reopen a closed connection.
840 * Delete this connection and look up again. */
841 write_unlock_bh(&tcp_lock);
842 if (del_timer(&conntrack->timeout))
843 conntrack->timeout.function((unsigned long)
844 conntrack);
845 return -NF_REPEAT;
846 }
847 /* Fall through */
834 case TCP_CONNTRACK_IGNORE: 848 case TCP_CONNTRACK_IGNORE:
835 /* Ignored packets: 849 /* Ignored packets:
836 * 850 *
@@ -879,27 +893,6 @@ static int tcp_packet(struct nf_conn *conntrack,
879 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 893 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
880 "nf_ct_tcp: invalid state "); 894 "nf_ct_tcp: invalid state ");
881 return -NF_ACCEPT; 895 return -NF_ACCEPT;
882 case TCP_CONNTRACK_SYN_SENT:
883 if (old_state < TCP_CONNTRACK_TIME_WAIT)
884 break;
885 if ((conntrack->proto.tcp.seen[dir].flags &
886 IP_CT_TCP_FLAG_CLOSE_INIT)
887 || after(ntohl(th->seq),
888 conntrack->proto.tcp.seen[dir].td_end)) {
889 /* Attempt to reopen a closed connection.
890 * Delete this connection and look up again. */
891 write_unlock_bh(&tcp_lock);
892 if (del_timer(&conntrack->timeout))
893 conntrack->timeout.function((unsigned long)
894 conntrack);
895 return -NF_REPEAT;
896 } else {
897 write_unlock_bh(&tcp_lock);
898 if (LOG_INVALID(IPPROTO_TCP))
899 nf_log_packet(pf, 0, skb, NULL, NULL,
900 NULL, "nf_ct_tcp: invalid SYN");
901 return -NF_ACCEPT;
902 }
903 case TCP_CONNTRACK_CLOSE: 896 case TCP_CONNTRACK_CLOSE:
904 if (index == TCP_RST_SET 897 if (index == TCP_RST_SET
905 && ((test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status) 898 && ((test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)