面向P2P通信的UDP Hole Punching技术研究与实现
摘 要 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先尝试使用对方私有端点地址进行通信,失败的情况下,再使用公用端点地址。
图1
需要指出的是,并不是任何的NAT设备都支持这上述的“穿透”过程。一个“友好”的NAT设备必须是“非对称”的:客户端的私有端点地址被NAT设备“翻译”成公用端点地址后,客户端再使用此私有端点地址向其它目的端点地址发送数据报,NAT设备并不会因为目的端点地址的改变而改变映射的公用端点地址,否则,C1、C2获取的对方端点地址因为“映射”改变而失效。同时,对于复杂的具有多层NAT设备的网络环境,NAT设备也需提供
3 基于UDP Hole Punching的实现
图2
本文基于.Net框架开发一个轻量级的面向对象类库,完整的实现UDP Hole Punching 的穿透过程。图2是类库(灰底框)分层结构,描述了类库边界以及体系结构。其中NAT Client/Server API 层是类库对外提供的服务器与客户端的编程接口;NAT Traversal Layer是整个类库的核心,处理UDP Hole Punching过程中的各种情境,建立客户端之间“直接”连接等;Asynchronous UDP Socket是基于UDP的异步收发套接字,为上下层收发数据。
图3是整个实现的部分类图(限于篇幅省略了方法与属性)。下面是部分类功能的简单描述:
(1)客户端:NATClient 是客户端的用户接口,负责客户端的登陆、登出,向下层转发字节形式的用户数据,同时向上层传递接收到的用户数据;ConnectionManager是整个客户端的核心,它是客户端多个UDP套接字的管理器,负责启动穿透过程,接收来自其它客户端、服务器的各种消息以及作出相应响应。MessageBufferQueue与QueueWithTimer是发送到其它客户端的用户数据缓存区,放入缓存区内的数据如果在一个很小的时间间隔内还没发送出去,将通知客户端发送失败。NATSessionManager与NATSession负责管理其它客户端的端点地址(包括客户端的私有、公用端点地址);RegisterUtility具有向服务器注册本地UDP套接字的功能,它能探测出客户端到服务器之间NAT设备的端点地址映射保持时间长短,动态调整UDP套接字注册间隔,从而减少客户端、服务器的负担。
(2)服务器:NATServer负责客户端消息的处理,比如注册消息,请求客户端的端点地址,通知客户端准备接收来自其它客户端的用户数据等;ClientMapTable 与SocketMapItem 存放、管理客户端注册的UDP套接字端点地址。
(3) 其它:根据UDP Hole Punching穿透过程中的各种情境,需要定义多种的消息类型,具有各自的消息负载格式,表1是各种消息类功能说明。
4 结束语
现实的网络环境中,NAT是一个普遍存在现象,基于P2P通信的应用程序要求参与客户端的通信对等性,造成多数通信终端无法“直接的”收发数据,因此NAT穿透是基于P2P通信的应用系统必须首要解决的问题。目前,由于NAT设备的多样性,还没有一种技术可以“完全”有效解决NAT穿透过程中的各种问题,因此一个健壮的基于P2P通信的系统,需要结合运用多种穿透方法,使得通信终端可以畅通无阻的进行“交流”。
参考文献
[1] B. Ford,P. Srisuresh,D. Kegel. Peer-to-Peer Communication Across Network Address Translators .USENIX Annual Technical Conference,April 2005
Zhou Hu . NAT Traversal Techniques and Peer-to-Peer Applications. HUT T-110.551 Seminar on Internetworking,2005
B. Ford,P. Srisuresh, .Peer-to-Peer (P2P) communication across middleboxes. IETF,October 2003
K. Egevang,P. Francis. The IP Network Address Translator. IETF .May,1994
上一篇:在线探测技术与应用