← Back to team overview

p2psp team mailing list archive

Re: NAT Traversal Set of rules implementation

 

Hi everyone,

On 11.07.2015 18:16, Max Mertens wrote:
> I suppose that NAT traversal should be possible in all cases except
> between two NATs with indeterminable (i.e. random) port allocation (or
> with NATs with some weird behaviour).
I have to correct myself here: I went through the possible NAT type
combinations and considered different "hello" packet sequences for each
combination, and now I have a more thorough understanding of what is
possible and why:
All considerations are easier if you divide the NAT types into the
following categories:

 1. Not port-restrictive, with a predictable port number¹ (FCN, RCN)
 2. Port-restrictive, with a predictable port number (PRCN, SYMPP, SYMSP)
 3. Port-restrictive, with an unpredictable port number (SYMRP)

(There might exist some symmetric NATs with unpredictable port number
that are not port-restrictive, but I don't think this is a typical
implementation.)
With these basic NAT types, the following combinations will work when
implementing NAT traversal techniques:

    Peer1\2 | 1.  | 2.  | 3.
    =========================
    1.      | *yes* | yes | *yes*
    2.      | yes | yes | no
    3.      | *yes* | no  | no

This is because if either peer (A) is port-restrictive and the other one
(B) has an unpredictable port number, NAT traversal in the direction
(B)->(A) does not work, because you do not know the port number of (B)
to punch a hole in the NAT of (A).
The same table expanded into particular NAT types (FCN and RCN is
basically the same, in our regard):

    Peer1\2 | fcn/rcn | prcn  | sympp | symsp | symrp
    ==================================================
    fcn/rcn | *yes*     | *yes*   | yes   | yes   | *yes*
    prcn    | *yes*     | *yes*   | yes   | yes   | no
    sympp   | yes     | yes   | yes   | yes   | no
    symsp   | yes     | (yes) | (yes) | (yes) | no
    symrp   | *yes*     | no    | no    | no    | no

(Note that, despite the number of rows and columns, the RCN and PRCN
implementations are more frequent than symmetric NATs, according to [1].)
The entries marked in bold are already fully working in the current NTS
implementation. The other "yes" entries will be approached next.
The "no" entries cannot work for any NAT traversal implementation
without a relay server.

The "(yes)" entries do work, but require port prediction of the
sequentially allocating NAT of a peer already in the team. So the (old)
peer has to connect to another port at the splitter or monitor (ideally
2 different ports, to get the source port increment step size) to
predict the public source port that it will be using to communicate with
the new peer. This could be an optional task when the other NAT
combinations are fully working.

> As for the asymmetry I posted this week: I reran the test a few times
> and got different results each time. I think the result should be
> "yes" but somehow a "hello" packet are lost and therefore the
> connection fails. So it seems sending keepalive packets (to open the
> NAT hole in case the "hello" packet gets lost) until the peer has
> joined correctly could improve the situation.
Thinking about the PRCN<->SYMPP case again, it seems that the connection
works if the "hello" packets by the two peers are sent in a certain
order, and the hole punching fails in the other case. So there is a 50%
chance that the connection succeeds. This will be working reliably when
continuous (keepalive) "hello" packets are sent until the connection is
established.

Regards,
Max


¹ For Full Cone NATs and source port preserving NATs, port prediction is
trivial, while for sequential port allocating NATs the prediction is
more difficult/unreliable.

[1] http://www.grothoff.org/christian/pwnat.pdf

Follow ups

References