日期:2023-01-24 阅读量:0次 所属栏目:计算机应用
摘 要 NAT(Network Address Translation),即网络地址转换,一定程度上解决了IPv4网络地址匮乏的问题,但也给面向P2P通信的应用程序以及协议造成通信方面的障碍。本文介绍了网络地址转换的基本原理以及其对P2P通信方式造成的冲击,简单概括目前主要的NAT穿透(NAT Traversal)技术,着重分析了UDP Hole Punching的穿透过程,最后给出一个轻量级的实现。
关键词 P2P;NAT 穿透;UDP Hole Punching
1 引言
随着Internet技术的迅猛发展,公网地址变的越来越珍贵,每台计算机都分配一个公网地址显得不切实际。NAT(Network Address Translation)标准出现,一定程度上解决了公网地址紧缺的问题。它是一种把内部私有网络地址翻译成合法网络地址的技术。它允许内部节点在内部网络中使用内部地址,而当内部节点要与外部网络进行通讯时,通过具有NAT功能(通常被集成到路由器、防火墙、ISDN路由器或者单独的NAT设备中)的设备、软件(统称NATs-Network Address Translator)将内部地址替换成公网地址,从而在外部公网上正常使用。NAT根据其转换方式,主要有三种类型:静态NAT、动态地址NAT、网络地址端口转换NAPT。其中静态NAT把内部网络中的每个主机都被永久映射成外部网络中的某个合法的地址。而动态地址NAT则是在外部网络中定义了一系列的合法地址,采用动态分配的方法映射到内部网络。NAPT是把内部地址映射到外部网络的一个IP地址的不同端口上,该地址映射会在NAT设备上保持一定的时间,NAPT是最常见的NAT类型,因为它允许私有网络后的主机共享一个公用IP地址,有效的节省了费用。无论是哪种NAT类型,从传输层观察,当内部节点向外部网络发送数据包时,NAT设备都是将数据包中的内部网络IP地址与端口(称作“端点地址”)替换为外部合法的端点地址,反之亦然。
NAT的特质屏蔽了内部网络,所有内部网计算机对于外部网络来说都是不可见的。在C/S 的应用模型中,服务器位于公网中,客户端位于公网或NAT设备后的私有网络,客户端只是主动的与服务器通信,客户端之间并不需要通信,所以NAT在C/S 的应用模型中并不构成问题。但是,面向P2P通信(这里的P2P通信不单单指的是P2P应用程序,任何需要在通信双方“直接互连”的地方,都可称之为P2P通信)的应用系统中,特别的,当需要通信的双方位于NAT设备后的不同私有网络中,任何一方相对与另一方来说都是不可见的,这样造成双方无法建立直接的相互可达的通信连接。
目前,解决这种由于NAT存在造成的通信障碍的主要技术有:UPnP(Universal Plug and Play)、STUN(Simple Traversal of UDP over NATs)以及UDP/TCP Hole Punching等。其中,UDP/TCP Hole Punching技术有效的保持了NAT网络环境的透明性,它不需要了解网络的拓扑信息以及其它特别的软件环境的支持,可以被普通的应用程序实现。实验表明,82%的NAT网络环境支持UDP Hole Punching技术,虽然其引入了冗余的消息传递以及延时,但不失为一个优秀的NAT穿透解决方案。
2 UDP Hole Punching技术研究
UDP Hole Punching的主要思想是:利用一个任何客户端都可达的服务器,在服务器上事先存储、维护客户端的UDP公用端点地址,当双方需要通信时,可以通过服务器的“介绍”获取对方的端点地址,建立“直接”的连接。
图1是一个具有NAT设备的简单网络拓扑图,其中C1,C2位于不同的私有网络中,无法直接通信,但都可以访问Server。下面分析UDP Hole Punching的基本流程:
(1)C1向服务器发出请求,要求与C2建立连接。
(2)服务器向C1,C2发送对方的公用端点地址,公用端点地址是服务器根据C1,C2发送的UDP数据报的源端点地址“观察”到的,即NAT设备“翻译”后的端点地址。
(3)C2接收到C1 的端点地址后,考虑到其所处网络的NAT设备可能具有防火墙功能,利用C1的端点地址作为目的地址,发送“穿洞”UDP数据报,该数据报使得C2网络的NAT设备允许后续的以C1端点地址为源地址的UDP数据报进入其内部网络,像是在NAT设备的防火墙上“穿洞”,对以C1端点地址为源地址的UDP数据报开放“入口”。
(4)C1接收到C2 的端点地址后,以C2的端点地址为目的地址发送“探测”UDP数据报,同样该数据报也使得C1网络的NAT设备上形成“穿洞”。
(5)C2收到C1的“探测”数据报后,向C1发送确认数据报。至此,双方建立互通的UDP连接。
在(2)中,考虑到C1、C2可能处于同一个私有网络中,服务器可以同时发送私有、公用端点地址,然后C1、C2先尝试使用对方私有端点地址进行通信,失败的情况下,再使用公用端点地址。