📄 daima.txt
字号:
The method works by analyzing the behavior of the NAT and attempting
to predict the public port numbers it will assign to future sessions.
Consider again the situation in which two clients, A and B, each
behind a separate NAT, have each established UDP connections with a
permanently addressable server S:
Server S
18.181.0.31:1234
|
|
+----------------------+----------------------+
| |
Symmetric NAT A Symmetric NAT B
Ford, Srisuresh & Kegel [Page 15]
Internet-Draft P2P applications across middleboxes October 2003
A-S 155.99.25.11:62000 B-S 138.76.29.7:31000
| |
| |
Client A Client B
10.0.0.1:1234 10.1.1.3:1234
NAT A has assigned its own UDP port 62000 to the communication
session between A and S, and NAT B has assigned its port 31000 to the
session between B and S. By communicating through server S, A and B
learn each other's public IP addresses and port numbers as observed
by S. Client A now starts sending UDP messages to port 31001 at
address 138.76.29.7 (note the port number increment), and client B
simultaneously starts sending messages to port 62001 at address
155.99.25.11. If NATs A and B assign port numbers to new sessions
sequentially, and if not much time has passed since the A-S and B-S
sessions were initiated, then a working bi-directional communication
channel between A and B should result. A's messages to B cause NAT A
to open up a new session, to which NAT A will (hopefully) assign
public port number 62001, because 62001 is next in sequence after the
port number 62000 it previously assigned to the session between A and
S. Similarly, B's messages to A will cause NAT B to open a new
session, to which it will (hopefully) assign port number 31001. If
both clients have correctly guessed the port numbers each NAT assigns
to the new sessions, then a bi-directional UDP communication channel
will have been established as shown below.
Server S
18.181.0.31:1234
|
|
+----------------------+----------------------+
| |
NAT A NAT B
A-S 155.99.25.11:62000 B-S 138.76.29.7:31000
A-B 155.99.25.11:62001 B-A 138.76.29.7:31001
| |
| |
Client A Client B
10.0.0.1:1234 10.1.1.3:1234
Obviously there are many things that can cause this trick to fail.
If the predicted port number at either NAT already happens to be in
use by an unrelated session, then the NAT will skip over that port
number and the connection attempt will fail. If either NAT sometimes
or always chooses port numbers non-sequentially, then the trick will
fail. If a different client behind NAT A (or B respectively) opens
up a new outgoing UDP connection to any external destination after A
(B) establishes its connection with S but before sending its first
Ford, Srisuresh & Kegel [Page 16]
Internet-Draft P2P applications across middleboxes October 2003
message to B (A), then the unrelated client will inadvertently
"steal" the desired port number. This trick is therefore much less
likely to work when either NAT involved is under load.
Since in practice a P2P application implementing this trick would
still need to work if the NATs are cone NATs, or if one is a cone NAT
and the other is a symmetric NAT, the application would need to
detect beforehand what kind of NAT is involved on either end [STUN]
and modify its behavior accordingly, increasing the complexity of the
algorithm and the general brittleness of the network. Finally, port
number prediction has no chance of working if either client is behind
two or more levels of NAT and the NAT(s) closest to the client are
symmetric. For all of these reasons, it is NOT recommended that new
applications implement this trick; it is mentioned here for
historical and informational purposes.
3.5. Simultaneous TCP open
There is a method that can be used in some cases to establish direct
peer-to-peer TCP connections between a pair of nodes that are both
behind existing middleboxes. Most TCP sessions start with one
endpoint sending a SYN packet, to which the other party responds with
a SYN-ACK packet. It is possible and legal, however, for two
endpoints to start a TCP session by simultaneously sending each other
SYN packets, to which each party subsequently responds with a
separate ACK. This procedure is known as a "simultaneous open."
If a middlebox receives a TCP SYN packet from outside the private
network attempting to initiate an incoming TCP connection, the
middlebox will normally reject the connection attempt by either
dropping the SYN packet or sending back a TCP RST (connection reset)
packet. If, however, the SYN packet arrives with source and
destination addresses and port numbers that correspond to a TCP
session that the middlebox believes is already active, then the
middlebox will allow the packet to pass through. In particular, if
the middlebox has just recently seen and transmitted an outgoing SYN
packet with the same addresses and port numbers, then it will
consider the session active and allow the incoming SYN through. If
clients A and B can each correctly predict the public port number
that its respective middlebox will assign the next outgoing TCP
connection, and if each client initiates an outgoing TCP connection
with the other client timed so that each client's outgoing SYN passes
through its local middlebox before either SYN reaches the opposite
middlebox, then a working peer-to-peer TCP connection will result.
Unfortunately, this trick may be even more fragile and timing-
sensitive than the UDP port number prediction trick described above.
First, unless both middleboxes are simple firewalls or implement cone
Ford, Srisuresh & Kegel [Page 17]
Internet-Draft P2P applications across middleboxes October 2003
NAT behavior on their TCP traffic, all the same things can go wrong
with each side's attempt to predict the public port numbers that the
respective NATs will assign to the new sessions. In addition, if
either client's SYN arrives at the opposite middlebox too quickly,
then the remote middlebox may reject the SYN with a RST packet,
causing the local middlebox in turn to close the new session and make
future SYN retransmission attempts using the same port numbers
futile. Finally, even though support for simultaneous open is
technically a mandatory part of the TCP specification [TCP], it is
not implemented correctly in some common operating systems. For this
reason, this trick is likewise mentioned here only for historical
reasons; it is NOT recommended for use by applications. Applications
that require efficient, direct peer-to-peer communication over
existing NATs should use UDP.
4. Application design guidelines
4.1. What works with P2P middleboxes
Since UDP hole punching is the most efficient existing method of
establishing direct peer-to-peer communication between two nodes
that are both behind NATs, and it works with a wide variety of
existing NATs, it is recommended that applications use this
technique if efficient peer-to-peer communication is required,
but be prepared to fall back on simple relaying when direct
communication cannot be established.
4.2. Peers behind the same NAT
In practice there may be a fairly large number of users who
have not two IP addresses, but three or more. In these cases,
it is hard or impossible to tell which addresses to send to
the registration server. The applications should send all its
addresses, in such a case.
4.3. Peer discovery
Applications sending packets to several addresses to discover
which one is best to use for a given peer may become a
significant source of 'space junk' littering the net, as the
peer may have chosen to use routable addresses improperly as
an internal LAN (e.g. 11.0.1.1, which is assigned to the DOD).
Thus applications should exercise caution when sending the
speculative hello packets.
4.4. TCP P2P applications
Ford, Srisuresh & Kegel [Page 18]
Internet-Draft P2P applications across middleboxes October 2003
The sockets API, used widely by application developers, is
designed with client-server applications in mind. In its
native form, only a single socket can bind to a TCP or UDP
port. An application is not allowed to have multiple
sockets binding to the same port (TCP or UDP) to initiate
simultaneous sessions with multiple external nodes (or)
use one socket to listen on the port and the other sockets
to initiate outgoing sessions.
The above single-socket-to-port bind restriction is not a
problem however with UDP, because UDP is a datagram based
protocol. UDP P2P application designers could use a single
socket to send as well as receive datagrams from multiple
peers using recvfrom() and sendto() calls.
This is not the case with TCP. With TCP, each incoming and
outgoing connection is to be associated with a separate
socket. Linux sockets API addresses this problem with the
aid of SO_REUSEADDR option. On FreeBSD and NetBSD, this
option does not seem to work; but, changing it to use the
BSD-specific SetReuseAddress call (which Linux doesn't
have and isn't in the Single Unix Standard) seems to work.
Win32 API offers an equivalent SetReuseAddress call.
Using any of the above mentioned options, an application
could use multiple sockets to reuse a TCP port. Say, open
two TCP stream sockets bound to the same port, do a
listen() on one and a connect() from the other.
4.5. Use of midcom protocol
If the applications know the middleboxes they would be
traversing and these middleboxes implement the midcom
protocol, applications could use the midcom protocol to
ease their way through the middleboxes.
For example, P2P applications require that NAT middleboxes
preserve end-point port bindings. If midcom is supported on
the middleboxes, P2P applications can exercise control over
port binding (or address binding) parameters such as lifetime,
maxidletime, and directionality so the applications can both
connect to external peers as well as receive connections from
external peers; and do not need to send periodic keep-alives to
keep the port binding alive. When the application no longer needs
the binding, the application could simply dismantle the binding,
also using the midcom protocol.
5. NAT Design Guidelines
Ford, Srisuresh & Kegel [Page 19]
Internet-Draft P2P applications across middleboxes October 2003
This section discusses considerations in the design of network
address translators, as they affect peer-to-peer applications.
5.1. Deprecate the use of symmetric NATs
Symmetric NATs gained popularity with client-server
applications such as web browsers, which only need to initiate
outgoing connections. However, in the recent times, P2P
applications such as Instant messaging and audio conferencing
have been in wide use. Symmetric NATs do not support the
concept of retaining endpoint identity and are not suitable
for P2P applications. Deprecating symmetric NATs is
recommended to support P2P applications.
A P2P-middlebox must implement Cone NAT behavior for UDP
traffic, allowing applications to establish robust P2P
connectivity using the UDP hole punching technique.
Ideally, a P2P-middlebox should also allow applications to
make P2P connections via both TCP and UDP.
5.2. Add incremental cone-NAT support to symmetric NAT devices
One way for a symmetric NAT device to extend support to P2P
applications would be to divide its assignable port
namespace, reserving a portion of its ports for one-to-one
sessions and a different set of ports for one-to-many
sessions.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -