【札记】NAT类型

GimmeS 2011-08-03

【札记_http://www.ppcn.net/n4366c38p2.aspx】

STUN标准中,根据内部终端的地址(P:p)到NAT出口的公网地址(A:b)的影射方式,把NAT分为四种类型:

1.FullCone:来自相同的内部地址的请求消息映射为相同的外部地址,与外部地址(目的地址)无关。映射关系为P:p↔A:b,任何外部主机可通过(A:b)发送到数据到(P:p)上。

2.RestrictedCone:来自相同的内部地址的请求消息映射为相同的外部地址,返回的数据只接受该内部节点曾发数据的那个目的计算机地址X。映射关系为P:p↔A:b↔X,只有来自X的数据包才可通过(A:b)发送到数据到(P:p)上。

3.PortRestrictedCone:来自相同的内部地址的请求消息映射为相同的外部地址,返回的数据只接受该内部节点曾发数据的那个目的地址X:x。映射关系为P:p↔A:b↔X:x,只有来自X:x的数据包才可通过(A:b)发送到数据到(P:p)上。

4.Symmetric(对称)NAT:只有来自相同的内部地址(P:p),并且发送到同一个地址(X:x)的请求消息,才被映射为相同的外部地址(A:b),返回的数据只接受该内部节点曾发数据的那个目的地址X:x。映射关系为P:p↔A:b↔X:x,当(P:p)访问(Y:y)时,映射为P:p↔B:c↔Y:y。

【NAT类型探测_http://blog.csdn.net/formiss/article/details/4922705】

第二部:NAT类型检测

前提条件:有一个公网的Server并且绑定了两个公网IP(IP-1,IP-2)。这个Server做UDP监听(IP-1,Port-1),(IP-2,Port-2)并根据客户端的要求进行应答。

第一步:检测客户端是否有能力进行UDP通信以及客户端是否位于NAT后?

客户端建立UDPsocket然后用这个socket向服务器的(IP-1,Port-1)发送数据包要求服务器返回客户端的IP和Port,客户端发送请求后立即开始接受数据包,要设定socketTimeout(300ms),防止无限堵塞.重复这个过程若干次。如果每次都超时,无法接受到服务器的回应,则说明客户端无法进行UDP通信,可能是防火墙或NAT阻止UDP通信,这样的客户端也就不能P2P了(检测停止)。

当客户端能够接收到服务器的回应时,需要把服务器返回的客户端(IP,Port)和这个客户端socket的(LocalIP,LocalPort)比较。如果完全相同则客户端不在NAT后,这样的客户端具有公网IP可以直接监听UDP端口接收数据进行通信(检测停止)。否则客户端在NAT后要做进一步的NAT类型检测(继续)。

第二步:检测客户端NAT是否是FullConeNAT?

客户端建立UDPsocket然后用这个socket向服务器的(IP-1,Port-1)发送数据包要求服务器用另一对(IP-2,Port-2)响应客户端的请求往回发一个数据包,客户端发送请求后立即开始接受数据包,要设定socketTimeout(300ms),防止无限堵塞.重复这个过程若干次。如果每次都超时,无法接受到服务器的回应,则说明客户端的NAT不是一个FullConeNAT,具体类型有待下一步检测(继续)。如果能够接受到服务器从(IP-2,Port-2)返回的应答UDP包,则说明客户端是一个FullConeNAT,这样的客户端能够进行UDP-P2P通信(检测停止)。

第三步:检测客户端NAT是否是SymmetricNAT?

客户端建立UDPsocket然后用这个socket向服务器的(IP-1,Port-1)发送数据包要求服务器返回客户端的IP和Port,客户端发送请求后立即开始接受数据包,要设定socketTimeout(300ms),防止无限堵塞.重复这个过程直到收到回应(一定能够收到,因为第一步保证了这个客户端可以进行UDP通信)。

用同样的方法用一个socket向服务器的(IP-2,Port-2)发送数据包要求服务器返回客户端的IP和Port。

比较上面两个过程从服务器返回的客户端(IP,Port),如果两个过程返回的(IP,Port)有一对不同则说明客户端为SymmetricNAT,这样的客户端无法进行UDP-P2P通信(检测停止)。否则是RestrictedConeNAT,是否为PortRestrictedConeNAT有待检测(继续)。

第四步:检测客户端NAT是否是RestrictedConeNAT还是PortRestrictedConeNAT?

客户端建立UDPsocket然后用这个socket向服务器的(IP-1,Port-1)发送数据包要求服务器用IP-1和一个不同于Port-1的端口发送一个UDP数据包响应客户端,客户端发送请求后立即开始接受数据包,要设定socketTimeout(300ms),防止无限堵塞.重复这个过程若干次。如果每次都超时,无法接受到服务器的回应,则说明客户端是一个PortRestrictedConeNAT,如果能够收到服务器的响应则说明客户端是一个RestrictedConeNAT。以上两种NAT都可以进行UDP-P2P通信。

注:以上检测过程中只说明了可否进行UDP-P2P的打洞通信,具体怎么通信一般要借助于RendezvousServer。另外对于SymmetricNAT不是说完全不能进行UDP-P2P达洞通信,可以进行端口预测打洞,不过不能保证成功。

相关推荐