|
|
楼主 |
发表于 2005-6-28 20:34:13
|
显示全部楼层
Ford, Srisuresh & Kegel [Page 9]
Internet-Draft P2P applications across middleboxes October 2003
3.2. Connection reversal
The second technique works if only one of the clients is behind a
middlebox. For example, suppose client A is behind a NAT but client
B has a globally routable IP address, as in the following diagram:
Server S
18.181.0.31:1235
|
|
+----------------------+----------------------+
| |
NAT A |
155.99.25.11:62000 |
| |
| |
Client A Client B
10.0.0.1:1234 138.76.29.7:1234
Client A has private IP address 10.0.0.1, and the application is
using TCP port 1234. This client has established a connection with
server S at public IP address 18.181.0.31 and port 1235. NAT A has
assigned TCP port 62000, at its own public IP address 155.99.25.11,
to serve as the temporary public endpoint address for A's session
with S: therefore, server S believes that client A is at IP address
155.99.25.11 using port 62000. Client B, however, has its own
permanent IP address, 138.76.29.7, and the peer-to-peer application
on B is accepting TCP connections at port 1234.
Now suppose client B would like to initiate a peer-to-peer
communication session with client A. B might first attempt to
contact client A either at the address client A believes itself to
have, namely 10.0.0.1:1234, or at the address of A as observed by
server S, namely 155.99.25.11:62000. In either case, however, the
connection will fail. In the first case, traffic directed to IP
address 10.0.0.1 will simply be dropped by the network because
10.0.0.1 is not a publicly routable IP address. In the second case,
the TCP SYN request from B will arrive at NAT A directed to port
62000, but NAT A will reject the connection request because only
outgoing connections are allowed.
After attempting and failing to establish a direct connection to A,
client B can use server S to relay a request to client A to initiate
a "reversed" connection to client B. Client A, upon receiving this
relayed request through S, opens a TCP connection to client B at B's
public IP address and port number. NAT A allows the connection to
proceed because it is originating inside the firewall, and client B
can receive the connection because it is not behind a middlebox.
Ford, Srisuresh & Kegel [Page 10]
Internet-Draft P2P applications across middleboxes October 2003
A variety of current peer-to-peer systems implement this technique.
Its main limitation, of course, is that it only works as long as only
one of the communicating peers is behind a NAT: in the increasingly
common case where both peers are behind NATs, the method fails.
Because connection reversal is not a general solution to the problem,
it is NOT recommended as a primary strategy. Applications may choose
to attempt connection reversal, but should be able to fall back
automatically on another mechanism such as relaying if neither a
"forward" nor a "reverse" connection can be established.
3.3. UDP hole punching
The third technique, and the one of primary interest in this
document, is widely known as "UDP Hole Punching." UDP hole punching
relies on the properties of common firewalls and cone NATs to allow
appropriately designed peer-to-peer applications to "punch holes"
through the middlebox and establish direct connectivity with each
other, even when both communicating hosts may lie behind middleboxes.
This technique was mentioned briefly in section 5.1 of RFC 3027 [NAT-
PROT], and has been informally described elsewhere on the Internet
[KEGEL] and used in some recent protocols [TEREDO, ICE]. As the name
implies, unfortunately, this technique works reliably only with UDP.
We will consider two specific scenarios, and how applications can be
designed to handle both of them gracefully. In the first situation,
representing the common case, two clients desiring direct peer-to-
peer communication reside behind two different NATs. In the second,
the two clients actually reside behind the same NAT, but do not
necessarily know that they do.
3.3.1. Peers behind different NATs
Suppose clients A and B both have private IP addresses and lie behind
different network address translators. The peer-to-peer application
running on clients A and B and on server S each use UDP port 1234. A
and B have each initiated UDP communication sessions with server S,
causing NAT A to assign its own public UDP port 62000 for A's session
with S, and causing NAT B to assign its port 31000 to B's session
with S, respectively.
Server S
18.181.0.31:1234
|
|
+----------------------+----------------------+
| |
NAT A NAT B
Ford, Srisuresh & Kegel [Page 11]
Internet-Draft P2P applications across middleboxes October 2003
155.99.25.11:62000 138.76.29.7:31000
| |
| |
Client A Client B
10.0.0.1:1234 10.1.1.3:1234
Now suppose that client A wants to establish a UDP communication
session directly with client B. If A simply starts sending UDP
messages to B's public address, 138.76.29.7:31000, then NAT B will
typically discard these incoming messages (unless it is a full cone
NAT), because the source address and port number does not match those
of S, with which the original outgoing session was established.
Similarly, if B simply starts sending UDP messages to A's public
address, then NAT A will typically discard these messages.
Suppose A starts sending UDP messages to B's public address, however,
and simultaneously relays a request through server S to B, asking B
to start sending UDP messages to A's public address. A's outgoing
messages directed to B's public address (138.76.29.7:31000) cause NAT
A to open up a new communication session between A's private address
and B's public address. At the same time, B's messages to A's public
address (155.99.25.11:62000) cause NAT B to open up a new
communication session between B's private address and A's public
address. Once the new UDP sessions have been opened up in each
direction, client A and B can communicate with each other directly
without further burden on the "introduction" server S.
The UDP hole punching technique has several useful properties. Once
a direct peer-to-peer UDP connection has been established between two
clients behind middleboxes, either party on that connection can in
turn take over the role of "introducer" and help the other party
establish peer-to-peer connections with additional peers, minimizing
the load on the initial introduction server S. The application does
not need to attempt to detect explicitly what kind of middlebox it is
behind, if any [STUN], since the procedure above will establish peer-
to-peer communication channels equally well if either or both clients
do not happen to be behind a middlebox. The hole punching technique
even works automatically with multiple NATs, where one or both
clients are removed from the public Internet via two or more levels
of address translation.
3.3.2. Peers behind the same NAT
Now consider the scenario in which the two clients (probably
unknowingly) happen to reside behind the same NAT, and are therefore
located in the same private IP address space. Client A has
established a UDP session with server S, to which the common NAT has
assigned public port number 62000. Client B has similarly
Ford, Srisuresh & Kegel [Page 12]
Internet-Draft P2P applications across middleboxes October 2003
established a session with S, to which the NAT has assigned public
port number 62001.
Server S
18.181.0.31:1234
|
|
NAT
A-S 155.99.25.11:62000
B-S 155.99.25.11:62001
|
+----------------------+----------------------+
| |
Client A Client B
10.0.0.1:1234 10.1.1.3:1234
Suppose that A and B use the UDP hole punching technique as outlined
above to establish a communication channel using server S as an
introducer. Then A and B will learn each other's public IP addresses
and port numbers as observed by server S, and start sending each
other messages at those public addresses. The two clients will be
able to communicate with each other this way as long as the NAT
allows hosts on the internal network to open translated UDP sessions
with other internal hosts and not just with external hosts. We refer
to this situation as "loopback translation," because packets arriving
at the NAT from the private network are translated and then "looped
back" to the private network rather than being passed through to the
public network. For example, when A sends a UDP packet to B's public
address, the packet initially has a source IP address and port number
of 10.0.0.1:124 and a destination of 155.99.25.11:62001. The NAT
receives this packet, translates it to have a source of
155.99.25.11:62000 (A's public address) and a destination of
10.1.1.3:1234, and then forwards it on to B. Even if loopback
translation is supported by the NAT, this translation and forwarding
step is obviously unnecessary in this situation, and is likely to add
latency to the dialog between A and B as well as burdening the NAT.
The solution to this problem is straightforward, however. When A and
B initially exchange address information through server S, they
should include their own IP addresses and port numbers as "observed"
by themselves, as well as their addresses as observed by S. The
clients then simultaneously start sending packets to each other at
each of the alternative addresses they know about, and use the first
address that leads to successful communication. If the two clients
are behind the same NAT, then the packets directed to their private
addresses are likely to arrive first, resulting in a direct
communication channel not involving the NAT. If the two clients are
behind different NATs, then the packets directed to their private
Ford, Srisuresh & Kegel [Page 13]
Internet-Draft P2P applications across middleboxes October 2003
addresses will fail to reach each other at all, but the clients will
hopefully establish connectivity using their respective public
addresses. It is important that these packets be authenticated in
some way, however, since in the case of different NATs it is entirely
possible for A's messages directed at B's private address to reach
some other, unrelated node on A's private network, or vice versa.
3.3.3. Peers separated by multiple NATs
In some topologies involving multiple NAT devices, it is not
possible for two clients to establish an "optimal" P2P route between
them without specific knowledge of the topology. Consider for
example the following situation.
Server S
18.181.0.31:1234
|
|
NAT X
A-S 155.99.25.11:62000
B-S 155.99.25.11:62001
|
|
+----------------------+----------------------+
| |
NAT A NAT B
192.168.1.1:30000 192.168.1.2:31000
| |
| |
Client A Client B
10.0.0.1:1234 10.1.1.3:1234
Suppose NAT X is a large industrial NAT deployed by an internet
service provider (ISP) to multiplex many customers onto a few public
IP addresses, and NATs A and B are small consumer NAT gateways
deployed independently by two of the ISP's customers to multiplex
their private home networks onto their respective ISP-provided IP
addresses. Only server S and NAT X have globally routable IP
addresses; the "public" IP addresses used by NAT A and NAT B are
actually private to the ISP's addressing realm, while client A's and
B's addresses in turn are private to the addressing realms of NAT A
and B, respectively. Each client initiates an outgoing connection to
server S as before, causing NATs A and B each to create a single
public/private translation, and causing NAT X to establish a
public/private translation for each session.
Now suppose clients A and B attempt to establish a direct peer-to-
|
|