Server S1                                     Server S2
        18.181.0.31:1235                              138.76.29.7:1235
               |                                             |
               |                                             |
               +----------------------+----------------------+
                                      |
          ^  Session 1 (A-S1)  ^      |      ^  Session 2 (A-S2)  ^
          |  18.181.0.31:1235  |      |      |  138.76.29.7:1235  |
          v 155.99.25.11:62000 v      |      v 155.99.25.11:62000 v
                                      |
                                   Cone NAT
                                 155.99.25.11
                                      |
          ^  Session 1 (A-S1)  ^      |      ^  Session 2 (A-S2)  ^
          |  18.181.0.31:1235  |      |      |  138.76.29.7:1235  |
          v   10.0.0.1:1234    v      |      v   10.0.0.1:1234    v
                                      |
                                   Client A
                                10.0.0.1:1234Symmetric NAT
对称的NAT(Symmetric NAT),与Cone NAT有明显差别,在所有会话期间中不会保持绑定(私有IP,私有端口)和(公共IP,公共端口)的端口不变。相反,它会为每个新对话重新分配一个新的公共端口。
举例来说,设想客户A从同样端口上要发起两个外部对话,一个和S1连接,另一个和S2连接。Symmetric NAT可能会为第一个会话分配一个公共的端点 155.99.25.11:62000,而为第二个会话分配一个不同的公共端点155.99.25.11:62001。为了地址转换,NAT可以区分这两个会话传输的目的,因为和这些会话有关的外部端点(就是S1、S2)是不同的,甚至在通过地址转换时丢失了客户端的目的标示。(即丢了S1、S2的IP地址NAT也知道如何区分,我是这么理解的,可能有误。)           Server S1                                     Server S2
        18.181.0.31:1235                              138.76.29.7:1235
               |                                             |
               |                                             |
               +----------------------+----------------------+
                                      |
          ^  Session 1 (A-S1)  ^      |      ^  Session 2 (A-S2)  ^
          |  18.181.0.31:1235  |      |      |  138.76.29.7:1235  |
          v 155.99.25.11:62000 v      |      v 155.99.25.11:62001 v
                                      |
                                 Symmetric NAT
                                 155.99.25.11
                                      |
          ^  Session 1 (A-S1)  ^      |      ^  Session 2 (A-S2)  ^
          |  18.181.0.31:1235  |      |      |  138.76.29.7:1235  |
          v   10.0.0.1:1234    v      |      v   10.0.0.1:1234    v
                                      |
                                   Client A
                                10.0.0.1:1234Cone NAT和Symmetric NAT之间的比较与TCP/UDP之间的比较有些类似。(TCP需要绑定,UDP不需要,Cone NAT需要绑定,Symmetric NAT不需要)按照NAT从已知的公共IP,公共端口接收的数据限制,Cone NAT可以更进一步的进行分类。这种分类通常都是UDP连接的,因为NAT和防火墙会拒绝任何无条件的TCP连接,除非明确地以别的方式配置。 Full Cone NAT
在给一个新的外部会话建立了一个公共/私有的端口绑定后,一个full cone NAT就可以通过这个公共端口从公网上的任何外部端点接收数据通讯了。Full cone NAT也常常叫做"混合"NAT。Restricted Cone NAT
当网络主机发一个或者几个数据包给外部主机后,一个受限的cone NAT(Restricted Cone NAT)才会接受来自这个外部(源)IP地址的数据包。受限的cone NAT有效的运用了防火墙的原理,拒绝没有要求的数据,只接收已知道的外部IP地址传来的数据。(偏开原文,大意就是网络主机需要发一个请求给外部IP地址要求要数据,NAT才会接收这个外部IP地址传来的数据,不然不接收。)Port-Restricted Cone NAT
一个端口受限的cone NAT(Port-Restricted Cone NAT),也是这样,只接收那些网络主机曾经发给一个外部IP地址和端口相匹配的数据。一个Port-Restricted cone NAT可以和对称 NAT一样(symmetric NAT),保护内部节点不接收未被请求的数据包,但是保持一个私有端口在连接过程中不变。
(偏开原文,即不仅请求的IP和外部发来数据的IP是一样的,PORT也要是一样,这样才接收数据。对称NAT也有这个效果,但这种cone NAT保持端口不变,而对称NAT要变端口号的)。最后,在这篇文档中我们定义一些新的术语来给middleboxes中有关P2P的行为进行分类:P2P-Application
在这篇文档中P2P-Application被当做一个应用程序,在那些参与P2P连接的并在一个公共的登录服务器注册的终端运行,可以是一个私有端点,也可以是一个公共端点,或者两者都是,并建立一个初步的会话。P2P-Middlebox
P2P- Middlebox就是允许P2P应用程序交换数据的的middlebox。P2P-firewall
一个P2P-防火墙就是提供防火墙功能的P2P- Middlebox,但不具备地址映射功能。

解决方案 »

  1.   

    P2P-NAT
    P2P-NAT就是提供NAT功能,也提供防火墙功能的P2P- Middlebox。一台P2P- Middlebox必须为UDP传输至少提供Cone NAT功能,允许应用程序使用UDP建立完整的P2P连接。
       
    loopback translation(自环映射)
    当一台位于私有域的主机,它的NAT试图用此主机在公网的映射地址连接其他位于同样NAT后的其他主机,相当于NAT装置在数据包上做了两次NAT转换。在数据报到达目标主机之前,源主机的私有端点被转换成NAT分配的公共端点,然后把目标主机的公共端点转换成目标主机的私有端点。我们在上面提到的地址转换用一台NAT装置完成就称为"Loopback translation"。3. 用middleboxes进行P2P通讯的技术
    这段文章详细的回顾一下使用现有的middlebox实现P2P通讯的技术,主要从应用程序或协议设计上来述说。3.1 Relaying(传输)
    最可靠的,但是效率最低的,实现P2P通讯的方法就是在传输过程中,把P2P通讯看成向C/S通讯的网络一样。例如,推想2个客户主机,A和B,各自发起一个TCP或UDP的连接,连接到一个大家都知道的拥有固定IP地址的服务器S上。客户主机都在各自的私有网络中,但是它们各自的middlebox不允许自己的客户端可以直接和其它主机连接。
                                    Server S
                                       |
                                       |
                +----------------------+----------------------+
                |                                             |
              NAT A                                         NAT B
                |                                             |
                |                                             |
             Client A                                      Client B不能直接连接,两个客户端就使用S服务器进行消息的传递。例如,要发送一条信息到客户端B,客户端A以C/S连接方式简单的发送一条信息到S服务器,然后S服务器使用已经和客户端B建立的C/S连接发送这条信息到客户端B。这种方法的优势在于只要两个客户端都连在服务器上,它就是有效的。它的明显缺点是它需要了服务器的处理并占用了带宽,而且即使服务器的网络状况良好,也有一定的通讯滞后问题。TRUN协议[TURN]定义了这种P2P应用的相关方法。3.2 逆向连接 (Connection reversal)
    第二种技术是在只有一个客户位于middlebox后的条件下运用的。举例来说, 推想客户A在 NAT 后面但是客户 B 有一个全球有效的 IP 地址, 参照下面图表:                                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客户A有一个私有IP地址10.0.0.1,并且一个应用程序使用TCP端口1234。这个客户端和服务器S的公网IP地址18.181.0.31和端口1235建立了一个连接。NAT A为了客户端A和服务器S的会话,临时分配了一个终端地址,其TCP端口62000,它自己的IP地址是155.99.25.11:因此,服务器S认为客户端A用的是IP地址155.99.25.11,端口是62000。然而,客户端B有着自己的固定IP地址,138.76.29.7,并且在它上面的P2P应用程序可以在端口1234接收TCP连接。现在推想客户端B想要与客户端A建立一个P2P连接会话。B可能用客户端A本身的地址,即10.0.0.1:1234,也可能用在服务器S上得到到的地址,155,99.25.11:62000,去尝试连接。然而无论在哪一种情况下,连接都会失败。第一种情况下,指向IP地址10.0.0.1的通讯包会被丢弃,因为10.0.0.1不是一个公网固定IP地址。第二种情况下,来自客户端B的TCP SYN请求包将会到达NAT A的62000端口,但NAT A将会拒绝这个请求,因为NAT A只允许向外发送数据。在尝试和客户端A建立直接连接失败后,客户端B会利用服务器S传递一个请求,让客户端A去主动连接客户。客户端A在通过服务器S接收到传递的请求后,会使用客户端B的公共IP地址和端口建立一个TCP连接。 因为这个连接是在防火墙内部发起的,所以NAT A允许这个连接建立,而客户端B也能接收这个连接,因为它并不处于middlebox后面。当前实现P2P系统的一种技术,它有一个主要的局限性,就是它只能允许P2P中一方在NAT后面:而两方都在NAT后面的情况是很常见的,这种方法就会失败。因为这种逆向连接并不是解决问题的普遍方法,通常不推荐这个方法。应用程序可以选择试一试逆向连接,但当"向前"或"逆向"都不能建立连接时,应用程序应该能够自动的可以选择另外的连接机制,比如relaying(即3.1说的)。3.3 UDP hole punching
    第三种技术,也是这篇文章的一个重要点之一,就是被称为"UDP Hole Punching"的技术。当两个需要通讯的主机可能都在middlebox后面的时候,UDP hole punching依赖于cone NAT和普通防火墙的一些特性,允许合适的P2P应用程序以"punch holes"方式通过middlebox并且建立彼此之间直接的连接。这种技术在RFC 3027[NAT- PORT]的5.1节中简要的提及,并且在英特网[KEGEL]非证实的提到,也在最近的一些协议[TEREDO, ICE]中用到。正如名字中的所提到的,这种技术只能用于UDP连接。我们将会考虑两个特别情况,并且考虑应用程序如何完善的处理两者之间的握手连接。第一种情况下,也是较为普通的情况,两个在不通的NAT后面的客户端要求直接的进行P2P连接。第二种情况,两台客户端位于同一个NAT后面,但不能肯定(两台客户端位于同一个NAT后面)。3.3.1 位于不同NAT后面(Peers behind different NATs)
    假设客户端A和B都有自己的私有IP地址,也都位于不同的NAT后面。P2P应用程序在A、B和服务器S上运行,用的都是UDP端口1234。A和B各自和服务器S建立UDP通讯连接,使NAT A为A的连接分配一个自己的公共端口62000,而NAT B为B的连接分配的是31000端口。                                Server S
                                18.181.0.31:1234
                                       |
                                       |
                +----------------------+----------------------+
                |                                             |
              NAT A                                         NAT B
        155.99.25.11:62000                            138.76.29.7:31000
                |                                             |
                |                                             |
             Client A                                      Client B
          10.0.0.1:1234                                 10.1.1.3:1234