⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 daima.txt

📁 P2P 编程:UDP穿透NAT的原理与实现(附C++源代码)daima.txt
💻 TXT
📖 第 1 页 / 共 5 页
字号:
   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-



Ford, Srisuresh & Kegel                                        [Page 14]

Internet-Draft     P2P applications across middleboxes      October 2003


   peer UDP connection.  The optimal method would be for client A to
   send messages to client B's public address at NAT B,
   192.168.1.2:31000 in the ISP's addressing realm, and for client B to
   send messages to A's public address at NAT B, namely
   192.168.1.1:30000.  Unfortunately, A and B have no way to learn these
   addresses, because server S only sees the "global" public addresses
   of the clients, 155.99.25.11:62000 and 155.99.25.11:62001.  Even if A
   and B had some way to learn these addresses, there is still no
   guarantee that they would be usable because the address assignments
   in the ISP's private addressing realm might conflict with unrelated
   address assignments in the clients' private realms.  The clients
   therefore have no choice but to use their global public addresses as
   seen by S for their P2P communication, and rely on NAT X to provide
   loopback translation.

3.3.4. Consistent port bindings

   The hole punching technique has one main caveat: it works only if
   both NATs are cone NATs (or non-NAT firewalls), which maintain a
   consistent port binding between a given (private IP, private UDP)
   pair and a (public IP, public UDP) pair for as long as that UDP port
   is in use.  Assigning a new public port for each new session, as a
   symmetric NAT does, makes it impossible for a UDP application to
   reuse an already-established translation for communication with
   different external destinations.  Since cone NATs are the most
   widespread, the UDP hole punching technique is fairly broadly
   applicable; nevertheless a substantial fraction of deployed NATs are
   symmetric and do not support the technique.

3.4. UDP port number prediction

   A variant of the UDP hole punching technique discussed above exists
   that allows peer-to-peer UDP sessions to be created in the presence
   of some symmetric NATs.  This method is sometimes called the "N+1"
   technique [BIDIR] and is explored in detail by Takeda [SYM-STUN].

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -