diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2010-07-15 11:09:04 -0400 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2010-07-15 11:09:04 -0400 |
commit | fac42a9a922fe5eb87cac0b597010afb81e7ffe9 (patch) | |
tree | 96763bdcfcc4e4b9cafbeeeb8c63c27bdbfc0ce4 /net | |
parent | cca5cf91c789f3301cc2541a79c323c53be5a8e1 (diff) |
netfilter: nf_ct_tcp: fix flow recovery with TCP window tracking enabled
This patch adds the missing bits to support the recovery of TCP flows
without disabling window tracking (aka be_liberal). To ensure a
successful recovery, we have to inject the window scale factor via
ctnetlink.
This patch has been tested with a development snapshot of conntrackd
and the new clause `TCPWindowTracking' that allows to perform strict
TCP window tracking recovery across fail-overs.
With this patch, we don't update the receiver's window until it's not
initiated. We require this to perform a successful recovery. Jozsef
confirmed in a private email that this spotted a real issue since that
should not happen.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Acked-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/netfilter/nf_conntrack_proto_tcp.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c index 802dbffae8b4..c4c885dca3bd 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c | |||
@@ -585,8 +585,16 @@ static bool tcp_in_window(const struct nf_conn *ct, | |||
585 | * Let's try to use the data from the packet. | 585 | * Let's try to use the data from the packet. |
586 | */ | 586 | */ |
587 | sender->td_end = end; | 587 | sender->td_end = end; |
588 | win <<= sender->td_scale; | ||
588 | sender->td_maxwin = (win == 0 ? 1 : win); | 589 | sender->td_maxwin = (win == 0 ? 1 : win); |
589 | sender->td_maxend = end + sender->td_maxwin; | 590 | sender->td_maxend = end + sender->td_maxwin; |
591 | /* | ||
592 | * We haven't seen traffic in the other direction yet | ||
593 | * but we have to tweak window tracking to pass III | ||
594 | * and IV until that happens. | ||
595 | */ | ||
596 | if (receiver->td_maxwin == 0) | ||
597 | receiver->td_end = receiver->td_maxend = sack; | ||
590 | } | 598 | } |
591 | } else if (((state->state == TCP_CONNTRACK_SYN_SENT | 599 | } else if (((state->state == TCP_CONNTRACK_SYN_SENT |
592 | && dir == IP_CT_DIR_ORIGINAL) | 600 | && dir == IP_CT_DIR_ORIGINAL) |
@@ -680,7 +688,7 @@ static bool tcp_in_window(const struct nf_conn *ct, | |||
680 | /* | 688 | /* |
681 | * Update receiver data. | 689 | * Update receiver data. |
682 | */ | 690 | */ |
683 | if (after(end, sender->td_maxend)) | 691 | if (receiver->td_maxwin != 0 && after(end, sender->td_maxend)) |
684 | receiver->td_maxwin += end - sender->td_maxend; | 692 | receiver->td_maxwin += end - sender->td_maxend; |
685 | if (after(sack + win, receiver->td_maxend - 1)) { | 693 | if (after(sack + win, receiver->td_maxend - 1)) { |
686 | receiver->td_maxend = sack + win; | 694 | receiver->td_maxend = sack + win; |