China Open source community
站内导航:
站内排行前50热点文章

精华文章  GDB调试精粹及使用实例
普通文章  STL中map用法详解
精华文章  负载均衡软件比较(Hapr...
普通文章  头文件的重复引用
普通文章  递归函数的调用过程
普通文章  TCP三次握手/四次挥手详解
普通文章  贪心策略的理论基础——...
普通文章  BMH算法原理与实现(模...
普通文章  排列组合与回溯算法
普通文章  DP动态规划
精华文章  Android线程模型
普通文章  Linux socket编程之套接字
普通文章  Linux内核中的红黑树
精华文章  linux下使用minicom的几...
普通文章  Java开源Html解析类库
精华文章  enum类型的本质
普通文章  memcached server LRU ...
普通文章  linux设置环境变量的方法
普通文章  android核心模块及相关...
普通文章  linux源代码包(.tar.g...
普通文章  L.A.M.P配置过程
普通文章  在ubuntu9.10下安装QT4...
普通文章  C/C++程序员常见面试题...
普通文章  gcc编译过程概述
普通文章  python的memcache和jso...
普通文章  应用程序二进制接口---ABI
普通文章  linux内核编译问题
普通文章  Java多线程实现简单实例
普通文章  Python程序员常用的IDE...
普通文章  brk和sbrk详述
普通文章  优化C语言代码(程序员必...
普通文章  python非贪婪,多行匹配...
普通文章  函数指针传递和全局指针...
普通文章  Unix操作系统的历史演变
普通文章  网络编程之C10K问题
普通文章  发行版发布:CentOS 5.4
普通文章  在windows中构建gtk开发...
普通文章  i++循环与i--循环的执行...
普通文章  关于Qvariant类--万能的...
普通文章  Debian sudo 设置
普通文章  busybox1.15.x 交叉编译
普通文章  关于僵死进程zombie
普通文章  递归思想的妙用
普通文章  判断链表是否存在环并找...
普通文章  Android Porting Exper...
普通文章  关于/etc/bashrc和$HOM...
普通文章  [翻译]Django初窥
普通文章  Python list的排序
普通文章  Django实现大数据量分页...
普通文章  Debug方式取代printf满...

 
 
 
当前位置: 首页 >> 网络协议与安全 >> P2P之NAT类型检测方法
 
 

P2P之NAT类型检测方法

作者:      来源:zz     发表时间:2006-11-25     浏览次数:      字号:    

P2P的NAT研究
第一部分:NAT介绍
第二部分:NAT类型检测

第一部分: NAT介绍
各种不同类型的NAT(according to RFC)
Full Cone NAT:
内网主机建立一个UDP socket(LocalIP:LocalPort) 第一次使用这个socket给外部主机发送数据时NAT会给其分配一个公网(PublicIP:PublicPort),以后用这个socket向外面任何主机发送数据都将使用这对(PublicIP:PublicPort)。此外,任何外部主机只要知道这个(PublicIP:PublicPort)就可以发送数据给(PublicIP:PublicPort),内网的主机就能收到这个数据包
Restricted Cone NAT:
内网主机建立一个UDP socket(LocalIP:LocalPort) 第一次使用这个socket给外部主机发送数据时NAT会给其分配一个公网(PublicIP:PublicPort),以后用这个socket向外面任何主机发送数据都将使用这对(PublicIP:PublicPort)。此外,如果任何外部主机想要发送数据给这个内网主机,只要知道这个(PublicIP:PublicPort)并且内网主机之前用这个socket曾向这个外部主机IP发送过数据。只要满足这两个条件,这个外部主机就可以用自己的(IP,任何端口)发送数据给(PublicIP:PublicPort),内网的主机就能收到这个数据包
Port Restricted Cone NAT:
内网主机建立一个UDP socket(LocalIP:LocalPort) 第一次使用这个socket给外部主机发送数据时NAT会给其分配一个公网(PublicIP:PublicPort),以后用这个socket向外面任何主机发送数据都将使用这对(PublicIP:PublicPort)。此外,如果任何外部主机想要发送数据给这个内网主机,只要知道这个(PublicIP:PublicPort)并且内网主机之前用这个socket曾向这个外部主机(IP,Port)发送过数据。只要满足这两个条件,这个外部主机就可以用自己的(IP,Port)发送数据给(PublicIP:PublicPort),内网的主机就能收到这个数据包
Symmetric NAT:
内网主机建立一个UDP socket(LocalIP,LocalPort),当用这个socket第一次发数据给外部主机1时,NAT为其映射一个(PublicIP-1,Port-1),以后内网主机发送给外部主机1的所有数据都是用这个(PublicIP-1,Port-1),如果内网主机同时用这个socket给外部主机2发送数据,第一次发送时,NAT会为其分配一个(PublicIP-2,Port-2), 以后内网主机发送给外部主机2的所有数据都是用这个(PublicIP-2,Port-2).如果NAT有多于一个公网IP,则PublicIP-1和PublicIP-2可能不同,如果NAT只有一个公网IP,则Port-1和Port-2肯定不同,也就是说一定不能是PublicIP-1等于 PublicIP-2且Port-1等于Port-2。此外,如果任何外部主机想要发送数据给这个内网主机,那么它首先应该收到内网主机发给他的数据,然后才能往回发送,否则即使他知道内网主机的一个(PublicIP,Port)也不能发送数据给内网主机,这种NAT无法实现UDP-P2P通信。

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

第一步:检测客户端是否有能力进行UDP通信以及客户端是否位于NAT后?
客户端建立UDP socket然后用这个socket向服务器的(IP-1,Port-1)发送数据包要求服务器返回客户端的IP和Port, 客户端发送请求后立即开始接受数据包,要设定socket Timeout(300ms),防止无限堵塞. 重复这个过程若干次。如果每次都超时,无法接受到服务器的回应,则说明客户端无法进行UDP通信,可能是防火墙或NAT阻止UDP通信,这样的客户端也就不能P2P了(检测停止)。
当客户端能够接收到服务器的回应时,需要把服务器返回的客户端(IP,Port)和这个客户端socket的(LocalIP,LocalPort)比较。如果完全相同则客户端不在NAT后,这样的客户端具有公网IP可以直接监听UDP端口接收数据进行通信(检测停止)。否则客户端在NAT后要做进一步的NAT类型检测(继续)。

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

第三步:检测客户端NAT是否是Symmetric NAT?
客户端建立UDP socket然后用这个socket向服务器的(IP-1,Port-1)发送数据包要求服务器返回客户端的IP和Port, 客户端发送请求后立即开始接受数据包,要设定socket Timeout(300ms),防止无限堵塞. 重复这个过程直到收到回应(一定能够收到,因为第一步保证了这个客户端可以进行UDP通信)。
用同样的方法用一个socket向服务器的(IP-2,Port-2)发送数据包要求服务器返回客户端的IP和Port。
比较上面两个过程从服务器返回的客户端(IP,Port),如果两个过程返回的(IP,Port)有一对不同则说明客户端为Symmetric NAT,这样的客户端无法进行UDP-P2P通信(检测停止)。否则是Restricted Cone NAT,是否为Port Restricted Cone NAT有待检测(继续)。

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

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

编辑 webmaster

 
 
 
评论
 
 
发表
 
姓名: QQ:
性别: MSN:
E-mail: 主页:
评分: 1 2 3 4 5
评论内容:
验证码:
  
  • 请遵守《互联网电子公告服务管理规定》及中华人民共和国其他各项有关法律法规。
  • 严禁发表危害国家安全、损害国家利益、破坏民族团结、破坏国家宗教政策、破坏社会稳定、侮辱、诽谤、教唆、淫秽等内容的评论 。
  • 用户需对自己在使用本站服务过程中的行为承担法律责任(直接或间接导致的)。
  • 本站管理员有权保留或删除评论内容。
  • 评论内容只代表网友个人观点,与本网站立场无关。
  •  
    中国源码网 - www.YuanMa.org - 中国 开放源代码+编程 社区