TCP hole punching
| This article does not cite any references or sources. Please help improve this article by adding citations to reliable sources. Unsourced material may be challenged and removed. (March 2010) |
|
|
This article provides insufficient context for those unfamiliar with the subject. Please help improve the article with a good introductory style. (November 2011) |
|
|
This article may be too technical for most readers to understand. Please help improve this article to make it understandable to non-experts, without removing the technical details. The talk page may contain suggestions. (November 2011) |
TCP hole punching is a commonly-used NAT traversal technique, for sending 2-way messages between nodes in an Internet computer network. The term "NAT traversal" is a general term for techniques that establish and maintain TCP/IP network and/or TCP connections traversing network-address-translation (NAT) gateways.
NAT traversal techniques are typically required for client-to-client networking applications, especially peer-to-peer and Voice-over-IP (VoIP) deployments.
Contents |
[edit] Description
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.
[edit] Network Drawing
-
-
Peer A ←→ Gateway A ← .. Network .. → Gateway B ←→ Peer B
-
[edit] Types of NAT
The availability of the TCP-hole-punching technique depends on the type of computer port allocation used by the NAT. When two peers, A and B, instantiate TCP connections by binding to local ports Pa and Pb, respectively, they need to know the remote endpoint NAT port in order to make the connection.
A NAT port allocation can be one of the two:
- predictable: the gateway uses a simple algorithm to map the local port to the NAT port. Most of the time a NAT will use port preservation, which is to say that the local port is mapped to the same port on the NAT.
- non predictable: the gateways uses an algorithm that is either random or too impractical to predict.
Connection matrix representing the different cases:
-
A predictable A non-predictable B predictable YES YES B non-predictable YES NO
-
- YES: the connection will work all the time
- NO: the connection will almost never work
[edit] Techniques
[edit] Methods of port Prediction
- Two sequential internal port-allocation connections, from A to X, are both received sequentially by X. Hence, they are predictable by X.
- Consistent translation is found when 2 connections, from A to X, are sent from the same internal port-A and different ports on X. If X sees same external port-A in both connections, then the translation is considered consistent, and also predictable by X.
[edit] Sequence/Acknowledgment numbers negotiation
Because both parties are connecting to each other (e.g., 2x 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
Because some packets (syn, rst) MUST not reach the other host, as it would corrupt the connection setup in progress, then there is the 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 Exceeded message
- i = i + 1, loop
Loop until "ICMP TTL Exceeded" messages are no longer received. The own NAT host has been traversed. The LOW TTL Value = i + 1.
If the NAT host supports "ICMP TTL Exceeded" messages to internal hosts, then the RST reply from buddy can be inspected. The 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.
- Using standard Berkeley socket library.
- Sniffing thread on the wire for SYN sequence numbers.