udp穿透nat原理及实现:P2P的UDP穿透NAT的原理和实现--增强篇(附源代码)

关键词: P2P UDP NAT 原理 穿透 Traveral Symmetric Cone
原始作者: Hwycheng Leo([email protected])
源码下载:
http://www.ppcn.net/upload/2005_08/05080112299104.rar
参考:
http://midcom-p2p.sourceforge.net/draft-ford-midcom-p2p-01.txt

P2P的UDP穿透NAT原理和实现(shootingstars)

文章介绍说明:

有关UDP穿透NAT中文资料在网络上是很少仅有<<P2P的UDP穿透NAT原理和实现(shootingstars)>>这篇文章有实际参考价值本人近两年来也直从事P2P方面开发工作比较有代表性是个人开发BitTorrent下载软件Software - FlashBT(变态快车). 对P2P下载或者P2P开发感兴趣朋友可以访问软件Software官方主页: http://www.hwysoft.com/chs/ 下载看看说不定有收获写这篇文章主要目是懒再每次单独回答些网友提问, 次性写下来, 即节省了自己时间也方便了对于P2PUDP穿透感兴趣网友阅读和理解对此有兴趣和经验朋友可以给我发邮件或者访问我个人Blog留言: http://hwycheng.blogchina.com.
您可以自由转载此篇文章但是请保留此介绍说明

再次感谢shootingstars网友早期贡献. 表示谢意

------------------------------------------------------------------------------------------------------------

NAT(The IP Network Address Translator) 概念和意义是什么?

NAT, 中文翻译为网络地址转换具体详细信息可以访问RFC 1631 - http://www.faqs.org/rfcs/rfc1631.html, 这是对于NAT定义和解释最权威描述网络术语都是很抽象和艰涩除非是专业人士否则很难从字面中来准确理解NAT含义

要想完全明白NAT 作用我们必须理解IP地址两大分类类是私有IP地址在这里我们称作内网IP地址类是非私有IP地址在这里我们称作公网IP地址有关IP地址概念和作用介绍参见我篇文章: http://hwycheng.blogchina.com/2402121.html

内网IP地址: 是指使用A/B/C类中私有地址, 分配IP地址在全球不惧有唯也因此无法被其它外网主机直接访问
公网IP地址: 是指具有全球唯IP地址能够直接被其它主机访问

NAT 最初是为使用内网IP地址计算机提供通过少数几台具有公网IP地址计算机访问外部网络功能NAT 负责将某些内网IP地址计算机向外部网络发出IP数据包源IP地址转换为NAT自己公网IP地址IP地址不变, 并将IP数据包转发给路由器最终到达外部计算机同时负责将外部计算机返回IP数据包IP地址转换为内网IP地址源IP地址不变并最终送达到内网中计算机


: NAT 实现了私有IP计算机分享几个公网IP地址访问Internet功能

随着网络普及IPv4局限性暴露出来公网IP地址成为种稀缺资源此时NAT 功能局限也暴露出来个公网IP地址某个时间只能由台私有IP地址计算机使用于是NAPT(The IP Network Address/Port Translator)应运而生NAPT实现了多台私有IP地址计算机可以同时通过个公网IP地址来访问Internet功能这在很大程度上暂时缓解了IPv4地址资源紧张

NAPT 负责将某些内网IP地址计算机向外部网络发出TCP/UDP数据包源IP地址转换为NAPT自己公网IP地址源端口转为NAPT自己个端口IP地址和端口不变, 并将IP数据包发给路由器最终到达外部计算机同时负责将外部计算机返回IP数据包IP地址转换内网IP地址端口转为内网计算机端口源IP地址和源端口不变并最终送达到内网中计算机

图 2: NAPT 实现了私有IP计算机分享个公网IP地址访问Internet功能
 
在我们工作和生活中, NAPT作用随处可见绝大部分公司网络架构都是通过1至N台支持NAPT路由器来实现公司所有计算机连接外部Internet网络包括本人在写这篇文章时候也是在家中使用台IBM笔记本通过台宽带连接台式机来访问Internet我们本篇文章主要讨论NAPT问题

NAPT(The IP Network Address/Port Translator) 为何阻碍了P2P软件Software应用?

通过NAPT 上网特点决定了只能由NAPT内计算机主动向NAPT外部主机发起连接外部主机想直接和NAPT内计算机直接建立连接是不被允许IM(即时通讯)而言这意味着由于NAPT内计算机和NAPT外计算机只能通过服务器中转数据来进行通讯对于P2P方式下载而言意味着NAPT内计算机不能接收到NAPT外部连接导致连接数用过少下载速度很难上去因此P2P软件Software必须要解决个问题就是要能够在程度上解决NAPT内计算机不能被外部连接问题

NAT(The IP Network Address Translator) 进行UDP穿透原理是什么?

TCP/IP传输时主要用到TCP和UDP协议TCP协议是可靠面向连接传输协议UDP是不可靠无连接协议根据TCP和UDP协议实现原理对于NAPT来进行穿透主要是指UDP协议TCP协议也有可能但是可行性非常小要求更高我们此处不作讨论如果感兴趣可以到Google上搜索有些文章对这个问题做了探讨性描述下面我们来看看利用UDP协议来穿透NAPT原理是什么:


图 3: NAPT 是如何将私有IP地址UDP数据包和公网主机进行透明传输

UDP协议包经NAPT透明传输介绍说明:

NAPT为每个Session分配个NAPT自己端口号依据此端口号来判断将收到公网IP主机返回TCP/IP数据包转发给那台内网IP地址计算机在这里Session是虚拟UDP通讯并不需要建立连接但是对于NAPT而言确要有个Session概念存在NAPT对于UDP协议包透明传输面临个重要问题就是如何处理这个虚拟Session我们都知道TCP连接Session以SYN包开始以FIN包结束NAPT可以很容易获取到TCP Session生命周期并进行处理但是对于UDP而言就麻烦了NAPT并不知道转发出去UDP协议包是否到达了目主机也没有办法知道而且鉴于UDP协议特点可靠很差因此NAPT必须强制维持Session存在以便等待将外部送回来数据并转发给曾经发起请求内网IP地址计算机NAPT具体如何处理UDP Session超时呢?区别厂商提供设备对于NAPT实现不近相同也许几分钟也许几个小时些NAPT实现还会根据设备忙碌状态进行智能计算超时时间长短


图 4: NAPT 将内部发出UDP协议包源地址和源端口改变传输给公网IP主机

图 5: NAPT 将收到公网IP主机返回UDP协议包地址和目端口改变传输给内网IP计算机
现在我们大概明白了NAPT如何实现内网计算机和外网主机间透明通讯现在来看下我们最关心问题就是NAPT是依据什么策略来判断是否要为个请求发出UDP数据包建立Session呢?主要有下几个策略:

A. 源地址(内网IP地址)区别忽略其它原因, 在NAPT上肯定对应区别Session
B. 源地址(内网IP地址)相同源端口区别忽略其它原因则在NAPT上也肯定对应区别Session
C. 源地址(内网IP地址)相同源端口相同地址(公网IP地址)相同端口区别则在NAPT上肯定对应同个Session
D. 源地址(内网IP地址)相同源端口相同地址(公网IP地址)区别忽略目端口则在NAPT上是如何处理Session呢?

D情况正式我们关心和要讨论问题依据目地址(公网IP地址)对于Session建立决定方式我们将NAPT设备划分为两大类:

Symmetric NAPT:
对于到同个IP地址任意端口连接分配使用同个Session; 对于到区别IP地址, 任意端口连接使用区别Session.
我们称此种NAPT为 Symmetric NAPT. 也就是只要本地绑定UDP端口相同 发出IP地址区别则会建立区别Session.


图 6: Symmetric 英文意思是对称多个端口对应多个主机平行对称!

Cone NAPT:
对于到同个IP地址任意端口连接分配使用同个Session; 对于到区别IP地址任意端口连接也使用同个Session.
我们称此种NAPT为 Cone NAPT. 也就是只要本地绑定UDP端口相同 发出地址不管是否相同 都使用同个Session.


图 7: Cone 英文意思是锥个端口对应多个主机是不是像个锥子?

现在绝大多数NAPT属于后者即Cone NAT本人在测试过程中只好使用了台日本Symmetric NAT还好不是自己我从不买日货, 希望看这篇文章朋友也自觉不要购买日本东西Win9x/2K/XP/2003系统自带NAPT也是属于 Cone NAT这是值庆幸我们要做UDP穿透只能在Cone NAT间进行只要有台不是Cone NAT对不起UDP穿透没有希望了服务器转发吧后面会做详细分析!

下面我们再来分析下NAPT 工作时些数据结构在这里我们将真正介绍说明UDP可以穿透Cone NAT依据这里描述数据结构只是为了介绍说明原理不具有实际参考价值真正感兴趣可以阅读Linux中有关NAT实现部分源码真正NAT实现也没有利用数据库呵呵为了速度!

Symmetric NAPT 工作时端口映射数据结构如下:

内网信息表:

[NAPT 分配端口] [ 内网IP地址 ] [ 内网端口 ] [ 外网IP地址 ] [ SessionTime 开始时间 ]

PRIMARY KEY( [NAPT 分配端口] ) -> 表示依据[NAPT 分配端口]建立主键必须唯且建立索引加快查找.
UNIQUE( [ 内网IP地址 ], [ 内网端口 ] ) -> 表示这两个字段联合起来不能重复.
UNIQUE( [ 内网IP地址 ], [ 内网端口 ], [ 外网IP地址 ] ) -> 表示这 3个字段联合起来不能重复.

映射表:

[NAPT 分配端口] [ 外网端口 ]

UNIQUE( [NAPT 分配端口], [ 外网端口 ] ) -> 表示这两个字段联合起来不能重复.

Cone NAPT 工作时端口映射数据结构如下:

内网信息表:

[NAPT 分配端口] [ 内网IP地址 ] [ 内网端口 ] [ SessionTime 开始时间 ]

PRIMARY KEY( [NAPT 分配端口] ) -> 表示依据[NAPT 分配端口]建立主键必须唯且建立索引加快查找.
UNIQUE( [ 内网IP地址 ], [ 内网端口 ] ) -> 表示这两个字段联合起来不能重复.

外网信息表:

[ wid 主键标识 ] [ 外网IP地址 ] [ 外网端口 ]

PRIMARY KEY( [ wid 主键标识 ] ) -> 表示依据[ wid 主键标识 ]建立主键必须唯且建立索引加快查找.
UNIQUE( [ 外网IP地址 ], [ 外网端口 ] ) -> 表示这两个字段联合起来不能重复.

映射表: 实现对多

[NAPT 分配端口] [ wid 主键标识 ]

UNIQUE( [NAPT 分配端口], [ wid 主键标识 ] ) -> 表示这两个字段联合起来不能重复.
UNIQUE( [ wid 主键标识 ] ) -> 标识此字段不能重复.

看完了上面数据结构是更明白了还是更晕了? 呵呵! 多想会儿就会明白了通过NAT,内网计算机计算机向外连结是很容易NAPT会自动处理我们应用根本不必关心它是如何处理那么外部计算机想访问内网中计算机如何实现呢?我们来看下下面流程:

c 是台在NAPT后面内网计算机s是台有外网IP地址计算机c 主动向 s 发起连接请求NAPT依据上面描述规则在自己数据结构中记录下来建立个Session. 然后 c 和 s 的间就可以实现双向透明数据传输了如下面所示:

   c[192.168.0.6:1827] <-> [priv ip: 192.168.0.1]NAPT[pub ip: 61.51.99.86:9881] <-> s[61.51.76.102:8098]

由此可见台外网IP地址计算机想和NAPT后面内网计算机通讯条件就是要求NAPT后面内网计算机主动向外网IP地址计算机发起个UDP数据包外网IP地址计算机利用收到UDP数据包获取到NAPT外网IP地址和映射端口以后就可以和内网IP计算机透明进行通讯了
   
现在我们再来分析下我们最关心两个NAPT后面内网计算机如何实现直接通讯呢? 两者都无法主动发出连接请求谁也不知道对方NAPT公网IP地址和NAPT上面映射端口号所以我们要靠个公网IP地址服务器帮助两者来建立连接当两个NAPT后面内网计算机分别连接了公网IP地址服务器后服务器可以从收到UDP数据包中获取到这两个NAPT设备公网IP地址和这两个连接建立Session映射端口两个内网计算机可以从服务器上获取到对方NAPT设备公网IP地址和映射端口了

我们假设两个内网计算机分别为A和B对应NAPT分别为AN和BN 如果A在获取到B对应BNIP地址和映射端口后迫不急待向这个IP
地址和映射端口发送了个UDP数据包会有什么情况发生呢?依据上面原理和数据结构我们会知道AN会在自己数据结构中生成条记录标识个新Session存在BN在收到数据包后从自己数据结构中查询没有找到相关记录因此将包丢弃B是个慢性子此时才慢吞吞向着ANIP地址和映射端口发送了个UDP数据包结果如何呢?当然是我们期望结构了AN在收到数据包后从自己数据结构中查找到了记录所以将数据包进行处理发送给了AA 再次向B发送数据包时切都时畅通无阻了OK, 大工告成!且慢这时对于Cone NAPT而言对于Symmetric NAPT呢?呵呵自己分析下吧...

NAPT(The IP Network Address/Port Translator) 进行UDP穿透具体情况分析!

首先明确将NAPT设备按照上面介绍说明分为: Symmetric NAPT 和 Cone NAPT, Cone NAPT 是我们需要Win9x/2K/XP/2003 自带NAPT也为Cone NAPT

种情况, 双方都是Symmetric NAPT:

此情况应给不存在什么问题肯定是不支持UDP穿透

第 2种情况, 双方都是Cone NAPT:

此情况是我们需要可以进行UDP穿透

第 3种情况, 个是Symmetric NAPT, 个是Cone NAPT:

此情况比较复杂但我们按照上面描述和数据机构进行下分析也很容易就会明白了, 分析如下,

假设: A -> Symmetric NAT, B -> Cone NAT

1. A 想连接 B, A 从服务器那儿获取到 B NAT地址和映射端口, A 通知服务器服务器告知 B ANAT地址和映射端口, B 向 A 发起连接A 肯定无法接收到此时 A 向 B 发起连接 A 对应NAT建立了个新Session分配了个新映射端口 B NAT 接收到UDP包后在自己映射表中查询无法找到映射项因此将包丢弃了

2. B 想连接 A, B 从服务器那儿获取到 A NAT地址和映射端口, B 通知服务器, 服务器告知 A BNAT地址和映射端口,A 向 B 发起连接, A 对应NAT建立了个新Session分配了个新映射端口B肯定无法接收到此时 B 向 A 发起连接, 由于 B 无法获取 A 建立Session映射端口仍是使用服务器上获取映射端口进行连接 因此 A NAT在接收到UDP包后在自己映射表中查询无法找到映射项, 因此将包丢弃了

根据以上分析只有当连接两端NAT都为Cone NAT情况下才能进行UDP内网穿透互联


NAPT(The IP Network Address/Port Translator) 进行UDP穿透如何进行现实验证和分析!

需要网络结构如下:

3个NAT后面内网机器两个外网服务器其中两台Cone NAPT台 Symmetric NAPT

验证思路方法:

可以使用本提供源码编译然后分别运行服务器和客户端修改过后源码增加了客户端的间直接通过IP地址和端口发送消息命令利用此命令你可以手动验证NAPT穿透情况为了方便操作推荐你使用个远程登陆软件Software可以直接在台机器上操作所有相关计算机这样很方便个人就可以完成所有工作了呵呵本人就是这么完成欢迎有兴趣和经验朋友来信批评指正共同进步


Tags:  udpnat udp穿透 udp穿透nat udp穿透nat原理及实现

延伸阅读

最新评论

发表评论