1.1 现有的穿越NAT实现P2P通信的主要方法
现有的穿越NAT实现P2P通信的主要方法有MidCom方
法,STUN方法,TURN方法和Hole Punching方法。
MidCom (Middlebox communication architecture and framework)[2]方法是通过在第三方实体和NAT之间建立中间盒来通信,使NAT设备变为可控的一种方法。其支持UDP和TCP的穿越,但要求NAT设备具备 Middleboxs功能,否则需要升级或替换。MidCom是IETF提出的通信协议。
STUN (Simple Traversal of UDP Through NATs)[3]是一种UDP报文穿越NAT的方法。该方法的优点是不需更改已有的NAT设备;缺点是只支持UDP不支持TCP穿越,只支持Cone NAT不支持Symmetric NAT。STUN即是总结Dan Kegel等人早先提出的方法而由IETF提出的通信协议,但不知为何作者中没有Dan Kegel的名字。
TURN(Traversal Using Relay NAT)[4]方法是使一方NAT内网的客户端对另一NAT内网客户端的访问通过位于外网的TURN服务器中继(Relay)双方的信息来实现。优点也是不需更改已有的NAT设备,支持UDP和TCP;缺点是所有信息都需要经服务器中继,效率较低。该方法列入Internet协议草案。
Hole Punching方法的做法在RFC3027[7]简略提及,更早时候Dan Kegel在NAT and peer-to-peer networking[5]一文中介绍了这一做法和自己的实际工作, 随后在P2P通信中得到广泛采用。对于UDP报文穿越NATs的P2P通信,在RFC3489中总结为协议STUN。Bryan Ford和Dan Kegel等人则更全面地总结、分析和统计了这一方法的应用,提出了术语Hole Punching,同时把其从支持UDP扩展到支持TCP。该方法不需要更改已有的NAT设备,支持穿越多层NAT,而且因为开出“洞”后,洞直接连通客户端不再需要服务器的中介,故传输效率高;缺点是不支持Symmetric NAT。
1.2 Cone NAT与Symmetric NAT
从内网主机发出报文访问外网目标时,可用四元组[源IP,源端口,目标IP,目标端口]来表示会话:
[私有源地址,私有源端口,全局目标地址,全局目标端口]
↓NAT
[全局源地址,全局源端口,全局目标地址,全局目标端口]
NAT在对不同的私有源地址进行转换的时候,可能转换成同一全局源地址,也可能转换成不同的全局源地址(如果NAT地址池配置有多个全局地址)。
而对于同一私有源地址和端口的转换情况则分为以下几种:
完全Cone NAT 无论目标地址和端口怎样,每次都把该私有源IP地址/端口映射到同一个全局源地址/端口;外网的任何主机都可以发送报文到该映射的全局地址而访问到该内部主机。路由器的静态地址映射就是属于这种。
限制Cone NAT 地址/端口映射的情况同完全Cone NAT的,但外网的主机要访问内网主机,该内网主机必须先发送过报文给该外网主机的地址。
端口限制Cone NAT 地址/端口映射情况同完全Cone NAT的,但外网主机要访问内网主机,该内网主机必须先发送过报文给该外网主机的地址和端口。大多数路由器的NAPT就是属于这种情况。本文后面论及的Cone NAT也是指这种情况。
Symmetric NAT 对不同的目标地址/端口,源私有地址映射到源全局地址不变,但是映射的全局端口会改变。外网主机必须先收到过内网主机的报文,才能访问到该内网主机。一些路由器和防火墙产品的NAT就是属于这种情况。
1.3 UDP报文穿越Cone NAT
如图1所示,假设两台主机Client A和Client B位于不同的NAT之后,网络参数、地址映射和会话亦如图1所标注。UDP报文穿越NAT进行直接通信的过程描述如下。
1.3.1 客户端注册与NAT开洞
Client A 和Client B登录到位于Internet的服务器 Server S,并向服务器注册包括自己的私有IP地址/端口在内的信息,本例分别为192.168.1.1:4321和192.168.2.1:4321。同时Server S从收到的Client A和Client B发来的UDP报文首部中获取二者的NAT全局IP地址/端口信息,本例分别为[201.1.1.1:6200]和[202.1.1.1:3600]。如图1所示。
对UDP报文而言,“IP地址:端口”称为“endpoint”,这里也称其为“插口”,和对TCP报文的称呼一致。
Client A 和Client B在登录服务器S时建立起会话Session A-S和Session B-S,之后服务器S主动发送给这两客户端的报文就能够通过NAT而送达了。会话Session A-S由插口对[192.168.1.1:4321,20.1.1.1:1234]和[201.1.1.1:6200, 20.1.1.1:1234]标识,而Cone NAT 映射私有插口[192.168.1.1:4321]为全局插口[201.1.1.1:6200]。该会话和映射的建立过程就称为开洞(Hole Punching),就像是在NATs上开了一个“洞”, 会话Session A-S就是这洞的标识。同理,Session B-S则是B方NAT洞的标识,如图1 所示。外网主机Server S能通过这两个洞访问内网主机A和B。但这两个洞还不能让主机A和B互访。
图1 位于NAT后的P2P网络拓扑
原文地址:http://hi.baidu.com/bluenet/blog/item/7ce85b0f54b08c2a6059f38a.html