All of lore.kernel.org
 help / color / mirror / Atom feed
From: Patrick McHardy <kaber@trash.net>
To: Phil Oester <kernel@linuxace.com>
Cc: Harald Welte <laforge@netfilter.org>,
	Rusty Russell <rusty@rustcorp.com.au>,
	netfilter-devel@lists.netfilter.org
Subject: Re: [PATCH] Fix NAT TCP sequence adjustment
Date: Mon, 18 Apr 2005 03:42:38 +0200	[thread overview]
Message-ID: <4263108E.1030707@trash.net> (raw)
In-Reply-To: <20050406044806.GA9711@linuxace.com>

Phil Oester wrote:
> On Mon, Apr 04, 2005 at 01:47:16PM -0700, Phil Oester wrote:
> 
>>So as it stands, only retransmits on positive sizediff are handled
>>properly.  But my original check to compensate for this was flawed,
>>since seq != correction_pos when entering adjust_tcp_sequence - but
>>it does seem clear we cannot blindly -= offset_after.
> 
> 
> I've become more convinced that this is the correct approach.  Anticipating
> that you will too, below is an updated patch with comments added.

I have a strong feeling that it is wrong. As you correctly pointed
out, my previous attempt to argue about its correctness was based on
the wrong assumption that offset_before < offset_after, while this is
only one possible case. So let's try again.

The sequence number is adjusted like this:

         if (after(ntohl(tcph->seq), this_way->correction_pos))
                 newseq = ntohl(tcph->seq) + this_way->offset_after;
         else
                 newseq = ntohl(tcph->seq) + this_way->offset_before;

and we need the original sequence number to determine whether this
is a retransmission and, if not, to store it as new correction_pos:

         /* SYN adjust. If it's uninitialized, or this is after last
          * correction, record it: we don't handle more than one
          * adjustment in the window, but do deal with common case of a
          * retransmit */
         if (this_way->offset_before == this_way->offset_after
             || before(this_way->correction_pos, seq)) {
                     this_way->correction_pos = seq;
                     this_way->offset_before = this_way->offset_after;
                     this_way->offset_after += sizediff;
         }

We have six cases to consider (2.3. is the interesting one):

1. offset_before < offset_after
  1.1. tcph->seq - offset_before <= correction_pos

   Since offset_before < offset_after, tcph->seq - offset_after is also
   before correction_pos and the original sequence number must have been
   tcph->seq - offset_before.

   Using offset_after results in an incorrect sequence number, but the
   packet is still correctly identified as a retransmission.

  1.2. tcph->seq - offset_after > correction_pos

   Since offset_before < offset_after, tcph->seq - offset_before is also
   after correction_pos and the original sequence number must have been
   tcph->seq - offset_after.

   Using offset_after is obviously correct.

  1.3. tcph->seq - offset_before > correction_pos &&
       tcph->seq - offset_after <= correction_pos

   In this case we can't determine whether the packet is a retransmission
   and what the original sequence number was.

   Using offset_after results in an incorrect sequence number when
   really offset_before was used, but the packet is still correctly
   detected as a retransmission.

2. offset_after < offset_before
  2.1. tcph->seq - offset_after <= correction_pos

   Since offset_after < offset_before, tcph->seq - offset_before is also
   before correction_pos and the original sequence number must have been
   tcph->seq - offset_before.

   Using offset_after results in an incorrect sequence number, but the
   packet is still correctly identified as a retransmission.

  2.2. tcph->seq - offset_before > correction_pos

   Since offset_after < offset_before, tcph->seq - offset_after is also
   after correction_pos and the original sequence number must have been
   tcph->seq - offset_after.

   Using offset_after is obviously correct.

  2.3. tcph->seq - offset_after > correction_pos &&
       tcph->seq - offset_before <= correction_pos

   In this case we can't determine whether the packet is a retransmission
   and what the original sequence number was.

   Using offset_after results in an incorrect sequence number when
   really offset_before was used. Unlike in 1.3., in this case the
   packet is (by precondition) _not_ correctly identified as
   a retransmission and causes a false positive.


It is impossible to handle the last case without more information,
since it is correct in some cases, in some it isn't.

So it looks like we need to store this information in the skb. We
don't have much choice, nfcache and about 29 bits in nfctinfo are
available. nfctinfo could be split in two u16 fields to avoid changes
to lots of unrelated code, nfcache should die IMO.

Any other ideas?

Regards
Patrick

  reply	other threads:[~2005-04-18  1:42 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-04-02 20:24 [PATCH] Fix NAT TCP sequence adjustment Phil Oester
2005-04-03 12:26 ` Milos Wimmer
2005-04-03 19:26 ` Patrick McHardy
2005-04-03 23:53   ` Phil Oester
2005-04-04  4:40     ` Phil Oester
2005-04-04  8:27       ` Patrick McHardy
2005-04-04 20:47         ` Phil Oester
2005-04-05  7:32           ` Patrick McHardy
2005-04-05 13:33             ` Patch lifetime " Amin Azez
2005-04-10 20:49               ` Harald Welte
2005-04-06  4:48           ` Phil Oester
2005-04-18  1:42             ` Patrick McHardy [this message]
2005-04-19  0:58               ` Phil Oester
2005-04-20 15:03                 ` Patrick McHardy
2005-04-20 15:53                   ` Phil Oester
2005-04-20 16:07                     ` Patrick McHardy
2005-04-20 17:24                       ` Phil Oester
2005-04-20 17:50                         ` Patrick McHardy
2005-04-20 18:25                           ` Phil Oester
2005-04-20 21:39                             ` Martijn Lievaart
2005-04-21  1:41                               ` Patrick McHardy
2005-04-21  1:38                             ` Patrick McHardy
2005-04-21 12:31                               ` Milos Wimmer
2005-04-21 12:32                                 ` Patrick McHardy
2005-04-21 13:31                               ` Jonas Berlin
2005-04-21 23:01                                 ` Patrick McHardy
2005-04-27  0:44         ` Rusty Russell
2005-04-27 10:27           ` Patrick McHardy
2005-05-31  9:17 ` Rusty Russell
2005-05-31 13:02   ` Patrick McHardy
2005-05-31 13:48     ` Rusty Russell
2005-05-31 14:35       ` Patrick McHardy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4263108E.1030707@trash.net \
    --to=kaber@trash.net \
    --cc=kernel@linuxace.com \
    --cc=laforge@netfilter.org \
    --cc=netfilter-devel@lists.netfilter.org \
    --cc=rusty@rustcorp.com.au \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.