← Back to team overview

p2psp team mailing list archive

Re: NAT Traversal Set of rules implementation

 

Hi Vicente,

thank you very much for your replies.

On 24.07.2015 09:04, Vicente Gonzalez wrote:
>
>     Currently for each arriving peer, the splitter temporarily stores
>     the peer's socket, address and 3 source ports (local, to splitter,
>     to monitor) until it is encorporated.
>
>
> A question. How is determined the port that the arriving peer will use
> to communicate with the monitor? I see the example you sent attached,
> but it is not clear for me.
Before disconnecting the TCP socket to the splitter, the arriving peer
sends UDP hello packets to the splitter and the monitor. The monitor
then forwards the packet together with the source port of the peer to
the splitter. So combining the directly received and the forwarded hello
packets, the splitter gets to know both source ports of the peer.


On 24.07.2015 09:22, Vicente Gonzalez wrote:
> On Thu, Jul 23, 2015 at 10:32 PM Max Mertens <max.mail@xxxxxxxxxx
> <mailto:max.mail@xxxxxxxxxx>> wrote:
>
>     So something seems to be wrong in the NAT simulation. As packets
>     are sent continuously between the peers to the correct ports,
>     either I completely overlooked something or there has to be a bug
>     in the linux netfilter/masquerading modules. The python network
>     stack or the virtual machines cannot be the reason because the
>     issue is NAT type specific. What do you think about this?
>
>
> Hi again,
>
> could be a problem of network congestion (using UDP sometimes routers
> and NAT devices drop packets if they arrive without pause)? Maybe a
> time-stamp in the debug outputs (such as the one you sent in your
> previous email) could help.
>
> Sorry, now I have not any other idea ...
>
> Regards,
> Vicente.
Ok, I checked this and apparently the packets get transmitted to each
other NAT correctly. But network congestion really could happen in
real-world application, when there is heavy UDP traffic and therefore a
noticeable packet loss.
Using iptables logging I checked all packets sent between the peers and
noticed that the peers receive each other's packets only if they once
sent two packets exactly simultaneously. This seems to happen because
for the iptables MASQUERADING policy, the NAT hole is directly closed
when an ICMP Destination Unreachable packet is received (which is the
case if there is no NAT hole at the other peer).
So if the connection does not work, it looks like this:

  * peer 1 sends a packet to peer 2, a NAT entry at peer 1 is created
  * the NAT of peer 2 rejects the packet with a ICMP Destination
    Unreachable packet, as there is no NAT entry
  * the NAT of peer 1 receives the ICMP packet and removes the NAT entry
  * peer 2 sends a packet to peer 1, a NAT entry at peer 2 is created
  * the NAT of peer 1 rejects the packet with a ICMP Destination
    Unreachable packet, as there is no NAT entry
  * the NAT of peer 2 receives the ICMP packet and removes the NAT entry

When the two peers send packets nearly simultaneously, it looks like this:

  * peer 1 sends a packet to peer 2, a NAT entry at peer 1 is created
  * peer 2 sends a packet to peer 1, a NAT entry at peer 2 is created
  * the NAT of peer 2 routes the packet to peer 2, as there is a NAT
    entry, and marks the connection as "assured"
  * the NAT of peer 1 routes the packet to peer 1, as there is a NAT
    entry, and marks the connection as "assured"

So for these types of NATs we have to ensure that the hello packets are
sent about at the same time (or that the time between hello packets
slightly differs each time) so that at some point the connection can be
established. Luckily when connecting over the internet, there are some
delays (ping) involved, so we have more time when the NAT entry is open,
and chances are better that the connection works.
For testing, we theoretically could just take the results from the PRCN
NAT, as the only difference between PRCN and SYMPP is the local source
port at the peer, which does not make a difference at all. Though it
would be great to know if this NAT behaviour actually exists in real NAT
implementations, and if this has to be addressed by sending hello
packets more often or in a burst-like style (e.g. send 100 packets with
20ms between each, and then pause for 1 second).


Another thing I noticed is that the sequentially allocating NAT type
cannot be simulated by iptables rules. I thought that the rules
currently stated in the nts_doc branch would work like this, but
apparently the source port is only increased if a completely new socket
is used for the connection to another peer. So now we have a few options
to solve this:
1. find another possibility to simulate this NAT behaviour (e.g. a
specific router distribution running on the virtual machine); or I could
try to alter the iptables NAT code and build a kernel module reflecting
the wanted behaviour (iptables code seems not too complicated, though I
do not know if this is possible at all)
2. change the peer code (just for testing) to somehow force the
allocation of the next port number (e.g. bind to another port or
something similar)
3. test this situation on a real NAT with this behaviour: do you have
such a NAT or do you know where this could exist?
4. do not test this NAT type, as the NAT type detection and source port
prediction is somehow trivial and easy to verify by reading the code
What do you think is the best step to take?

Thanks,
Max


Follow ups

References