UDP连接下的穿透技术
UDP
User Datagram Protocol,用户数据报协议,与TCP一样位于传输层。
UDP服务于很多知名应用层协议,比如网络文件系统NFS、简单网络管理协议SNMP、域名系统DNS、简单文件传输系统TFTP、动态主机配置协议DHCP、路由信息协议RIP。
中继(Relaying)
两个NAT后方的客户端主机A和B可以与一个拥有永久公网IP地址的主机C进行通信,由C转发A和B之间的数据报来达成A和B通信的目的。
但是这样会消耗服务器C的处理能力和网络带宽,且时延会增加。
反向连接
一台客户端主机B拥有公网IP,客户端主机A位于NAT后,其有一个有公网IP主机S。A和S保持一定的心跳连接。
A想连接B时,直接访问B的IP即可。
B想连接A时,B向S发送反向连接请求,S在与A的心跳连接中发送B的中继连接请求,A收到B的中继连接请求后直接访问B的IP即可。
打洞技术
P2P主机在不同的NAT后面
如下图,两个客户端主机在两个不同的NAT设备后方。因为对称形NAT暂时并没有完美的打洞方案,所以我们假设两个不同的NAT设备是完全锥形NAT、地址受限锥形NAT、端口受限锥形NAT的一种,两个NAT种类可以不同。
A与Server连接时,NAT A分配了一个外网地址155.156.157.158:6200;
B与Server连接时,NAT B分配了一个外网地址185.186.187.188:5200;
现假设A与B想要直接建立一个UDP通信会话,如果A直接向NAT B的185.186.187.188:5200发送一个UDP数据包,那么NAT B会直接将其丢弃,因为A发送的数据包的<源IP、源Port>与Server的不一致。(除非NAT B是一个全锥形NAT)。同样地,B向A直接发送信息也会被NAT A丢弃。
假如A向B的外网地址发送UDP消息的同时也向Server发了一个中继消息转发给B,B收到来自Server的中继消息后,主动向A的外网地址发送UDP消息。
此时,NAT A会建立如下映射(以最严格的端口受限锥形NAT为例):
源地址 | NAT | 目的地址 |
---|---|---|
10.1.1.1:1234 | 155.156.157.158:6200 | 185.186.187.188:5200 |
185.186.187.188:5200 | 155.156.157.158:6200 | 10.1.1.1:1234 |
NAT B主动向A的外网地址发送UDP消息会建立如下映射(以最严格的端口受限锥形NAT为例):
源地址 | NAT | 目的地址 |
---|---|---|
10.2.2.2:1234 | 185.186.187.188:5200 | 155.156.157.158:6200 |
155.156.157.158:6200 | 185.186.187.188:5200 | 10.2.2.2:1234 |
这时,A再向B发送消息,会被NAT A进行转换,并被NAT B的映射<155.156.157.158:6200 , 185.186.187.188:5200, 10.2.2.2:1234>所转换并发给B。
B向A发送的消息也会被NAT B,并被NAT A的映射<185.186.187.188:5200 , 155.156.157.158:6200, 10.1.1.1:1234>所转换并发给A。
可以看到,只要NAT A和NAT B是完全锥形NAT、地址受限锥形NAT、端口受限锥形NAT的一种即可。
如果NAT A或NAT B是对称形NAT,暂时并没有完美的解决方案。
P2P主机在相同的NAT后面
如下图,两个客户端主机在两个相同的NAT设备后方。
可以使用**「P2P主机在不同的NAT后面」**提出的打洞方法进行打洞。
打洞成功后,NAT接收到A和B的消息后经过两次映射会直接转发给B和A,这种情况称为“回环翻译”(loop back translation)。
如果A和B知道双方处于同一个内网,可以直接通信从而减轻NAT的负担。
P2P主机由多层NAT分开
这种情况下,要依赖「P2P主机在不同的NAT后面」的打洞方法并依靠最上方的NAT的回环翻译功能实现打洞。