aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2010-07-15 11:09:04 -0400
committerPatrick McHardy <kaber@trash.net>2010-07-15 11:09:04 -0400
commitfac42a9a922fe5eb87cac0b597010afb81e7ffe9 (patch)
tree96763bdcfcc4e4b9cafbeeeb8c63c27bdbfc0ce4
parentcca5cf91c789f3301cc2541a79c323c53be5a8e1 (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>
-rw-r--r--net/netfilter/nf_conntrack_proto_tcp.c10
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;