diff options
author | Patrick McHardy <kaber@trash.net> | 2007-02-07 18:05:33 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-02-08 15:39:10 -0500 |
commit | a09113c2c8ec59a5cc228efa5869aade2b8f13f7 (patch) | |
tree | df582dfa453cb8e1c6eb397062f60d69508c38fe /net/ipv4 | |
parent | 6fecd1985116fb08bdee3b9db6719e159fe5e43d (diff) |
[NETFILTER]: tcp conntrack: do liberal tracking for picked up connections
Do liberal tracking (only RSTs need to be in-window) for connections picked
up without seeing a SYN to deal with window scaling. Also change logging
of invalid packets not to log packets accepted by liberal tracking to avoid
spamming the logs.
Based on suggestion from James Ralston <ralston@pobox.com>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/netfilter/ip_conntrack_proto_tcp.c | 40 |
1 files changed, 15 insertions, 25 deletions
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c index 06e4e8a6dd9f..c34f48fe5478 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c | |||
@@ -50,12 +50,9 @@ static DEFINE_RWLOCK(tcp_lock); | |||
50 | If it's non-zero, we mark only out of window RST segments as INVALID. */ | 50 | If it's non-zero, we mark only out of window RST segments as INVALID. */ |
51 | int ip_ct_tcp_be_liberal __read_mostly = 0; | 51 | int ip_ct_tcp_be_liberal __read_mostly = 0; |
52 | 52 | ||
53 | /* When connection is picked up from the middle, how many packets are required | 53 | /* If it is set to zero, we disable picking up already established |
54 | to pass in each direction when we assume we are in sync - if any side uses | ||
55 | window scaling, we lost the game. | ||
56 | If it is set to zero, we disable picking up already established | ||
57 | connections. */ | 54 | connections. */ |
58 | int ip_ct_tcp_loose __read_mostly = 3; | 55 | int ip_ct_tcp_loose __read_mostly = 1; |
59 | 56 | ||
60 | /* Max number of the retransmitted packets without receiving an (acceptable) | 57 | /* Max number of the retransmitted packets without receiving an (acceptable) |
61 | ACK from the destination. If this number is reached, a shorter timer | 58 | ACK from the destination. If this number is reached, a shorter timer |
@@ -694,11 +691,10 @@ static int tcp_in_window(struct ip_ct_tcp *state, | |||
694 | before(sack, receiver->td_end + 1), | 691 | before(sack, receiver->td_end + 1), |
695 | after(ack, receiver->td_end - MAXACKWINDOW(sender))); | 692 | after(ack, receiver->td_end - MAXACKWINDOW(sender))); |
696 | 693 | ||
697 | if (sender->loose || receiver->loose || | 694 | if (before(seq, sender->td_maxend + 1) && |
698 | (before(seq, sender->td_maxend + 1) && | 695 | after(end, sender->td_end - receiver->td_maxwin - 1) && |
699 | after(end, sender->td_end - receiver->td_maxwin - 1) && | 696 | before(sack, receiver->td_end + 1) && |
700 | before(sack, receiver->td_end + 1) && | 697 | after(ack, receiver->td_end - MAXACKWINDOW(sender))) { |
701 | after(ack, receiver->td_end - MAXACKWINDOW(sender)))) { | ||
702 | /* | 698 | /* |
703 | * Take into account window scaling (RFC 1323). | 699 | * Take into account window scaling (RFC 1323). |
704 | */ | 700 | */ |
@@ -743,15 +739,13 @@ static int tcp_in_window(struct ip_ct_tcp *state, | |||
743 | state->retrans = 0; | 739 | state->retrans = 0; |
744 | } | 740 | } |
745 | } | 741 | } |
746 | /* | ||
747 | * Close the window of disabled window tracking :-) | ||
748 | */ | ||
749 | if (sender->loose) | ||
750 | sender->loose--; | ||
751 | |||
752 | res = 1; | 742 | res = 1; |
753 | } else { | 743 | } else { |
754 | if (LOG_INVALID(IPPROTO_TCP)) | 744 | res = 0; |
745 | if (sender->flags & IP_CT_TCP_FLAG_BE_LIBERAL || | ||
746 | ip_ct_tcp_be_liberal) | ||
747 | res = 1; | ||
748 | if (!res && LOG_INVALID(IPPROTO_TCP)) | ||
755 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, | 749 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, |
756 | "ip_ct_tcp: %s ", | 750 | "ip_ct_tcp: %s ", |
757 | before(seq, sender->td_maxend + 1) ? | 751 | before(seq, sender->td_maxend + 1) ? |
@@ -762,8 +756,6 @@ static int tcp_in_window(struct ip_ct_tcp *state, | |||
762 | : "ACK is over the upper bound (ACKed data not seen yet)" | 756 | : "ACK is over the upper bound (ACKed data not seen yet)" |
763 | : "SEQ is under the lower bound (already ACKed data retransmitted)" | 757 | : "SEQ is under the lower bound (already ACKed data retransmitted)" |
764 | : "SEQ is over the upper bound (over the window of the receiver)"); | 758 | : "SEQ is over the upper bound (over the window of the receiver)"); |
765 | |||
766 | res = ip_ct_tcp_be_liberal; | ||
767 | } | 759 | } |
768 | 760 | ||
769 | DEBUGP("tcp_in_window: res=%i sender end=%u maxend=%u maxwin=%u " | 761 | DEBUGP("tcp_in_window: res=%i sender end=%u maxend=%u maxwin=%u " |
@@ -1105,8 +1097,6 @@ static int tcp_new(struct ip_conntrack *conntrack, | |||
1105 | 1097 | ||
1106 | tcp_options(skb, iph, th, &conntrack->proto.tcp.seen[0]); | 1098 | tcp_options(skb, iph, th, &conntrack->proto.tcp.seen[0]); |
1107 | conntrack->proto.tcp.seen[1].flags = 0; | 1099 | conntrack->proto.tcp.seen[1].flags = 0; |
1108 | conntrack->proto.tcp.seen[0].loose = | ||
1109 | conntrack->proto.tcp.seen[1].loose = 0; | ||
1110 | } else if (ip_ct_tcp_loose == 0) { | 1100 | } else if (ip_ct_tcp_loose == 0) { |
1111 | /* Don't try to pick up connections. */ | 1101 | /* Don't try to pick up connections. */ |
1112 | return 0; | 1102 | return 0; |
@@ -1127,11 +1117,11 @@ static int tcp_new(struct ip_conntrack *conntrack, | |||
1127 | conntrack->proto.tcp.seen[0].td_maxwin; | 1117 | conntrack->proto.tcp.seen[0].td_maxwin; |
1128 | conntrack->proto.tcp.seen[0].td_scale = 0; | 1118 | conntrack->proto.tcp.seen[0].td_scale = 0; |
1129 | 1119 | ||
1130 | /* We assume SACK. Should we assume window scaling too? */ | 1120 | /* We assume SACK and liberal window checking to handle |
1121 | * window scaling */ | ||
1131 | conntrack->proto.tcp.seen[0].flags = | 1122 | conntrack->proto.tcp.seen[0].flags = |
1132 | conntrack->proto.tcp.seen[1].flags = IP_CT_TCP_FLAG_SACK_PERM; | 1123 | conntrack->proto.tcp.seen[1].flags = IP_CT_TCP_FLAG_SACK_PERM | |
1133 | conntrack->proto.tcp.seen[0].loose = | 1124 | IP_CT_TCP_FLAG_BE_LIBERAL; |
1134 | conntrack->proto.tcp.seen[1].loose = ip_ct_tcp_loose; | ||
1135 | } | 1125 | } |
1136 | 1126 | ||
1137 | conntrack->proto.tcp.seen[1].td_end = 0; | 1127 | conntrack->proto.tcp.seen[1].td_end = 0; |