TCP hole punching
From Wikipedia, the free encyclopedia
This article may require cleanup to meet Wikipedia's quality standards. Please improve this article if you can. (April 2008) |
NAT traversal through TCP hole punching is a method for establishing bidirectional TCP connections between Internet hosts in private networks using NAT. It does not work with all types of NATs as their behavior is not standardized.
Consider:
Contents |
[edit] Network Drawing
iHostA <-..-> Na <- .. eHostX .. -> Nb <-..-> iHostB
Legend: iHostA == Internal Host at site A iHostB == Internal Host at site B Na == Nat Router at site A Nb == Nat Router at site B
The inventors of NATBlaster distinguished 6 cases described as (iHostA port allocation, iHostB port allocation, Loose Source Routing available)
[edit] Cases
- Case 1: (predictable, predictable, LSR)
- Case 2: (predictable, predictable, no LSR)
- Case 3: (random, predictable, LSR)
- Case 4: (random, predictable, no LSR)
- Case 5: (random, random, LSR)
- Case 6: (random, random, no LSR)
Cases 2 and 4 were implemented, with case2 as reported reliable openings, and case4 as reported with high probability. The LSR situations (case1,3,5) were not implemented because Loose Source Routing is most of the time blocked by Internet routers. Case 6 was not implemented and could only be solved by port-scanning methods (a costly 4,161,669,121 combinations to try!).
Luckily most p2p connections are of case2 or case4.
[edit] Techniques
- Port Prediction
- Seq + Ack numbers negotiation
- Low TTL Value determination
[edit] Methods of port Prediction
- Two sequential internal port allocation connections from A to X are received sequential by X. Hence predictable by X.
- Consistent translation is found when 2 connections from A to X are send from same internal portA and different ports on X. If X sees same external portA in both connections the translation is considered consistent, and also predictable by X.
[edit] Seq + Ack numbers negotiation
Because both parties are connection TO each other (e.g 2 x CONNECT(), no LISTEN(), ACCEPT(), etc) to generate OUTBOUND traffic there is however a problem with:
- TCP Sequence numbers
- Acknowledgment numbers
The required state is just like after the three-way-handshake: Each host must have an acknowledge number == other sequence number + 1. This is achieved through Sequence and Acknowledgement Number coordination.
[edit] Low TTL Value determination
As some packets (syn, rst) MUST not receive the other host, as it would corrupt the connection setup in progress, we need to apply a trick with the TTL values. The Low TTL value is used to generate outbound packets that will open up the NAT, but will never reach the other host.
The Low TTL is calculated as follow:
- Send SYN with TTL of i=1
- Wait for ICMP TTL Exceed message
- i=i+1, loop
....
-
-
- Until ICMP Exceed messages are no longer received. The own NAT host has been traversed. LOW TTL Value = i+1
- If the NAT host supports ICMP Exceed messages to internal hosts, the RST reply from buddy can be inspected. LOW TTL Value = i - 1
-
[edit] OS Support
- Setting LOW TTL Value with setsockopt() using IP_TTL option
- Socket options must not be persistent: After successful connection, seq + ack number negotiation, the TTL value must be normalized with setsockopt() again.
- Standard berkely socket library.
- Sniffing thread on the wire for SYN sequence numbers
[edit] See also
- NUTSS (Relies on spoofing packets!)
- Hole punching
[edit] External links
- Natcheck
- [http:// NATBlaster]