文章转自:http://blog.csdn.net/ustcgy/article/details/5652268
1. NAT简介
前面的文章说到了针对IP不足的许多技术,但这些技术基本都不会增加可用的IP地址数.NAT(Network Address Translation)又称"网络地址转换",它是一种把内部私有网络地址翻译成合法网络IP地址的技术,个人认为该技术是解决IP地址不足最有效的方法.它是一个IETF(Internet Engineering Task Force,Internet工程任务组)标准.
简单地说,NAT就是在局域网内部使用私有地址(前面文章说到过每类IP地址都有私有地址),而当内部节点要与外部网络进行通讯时,就在网关(可以理解为出口)处将内部地址替换成公用地址,从而在公网(internet)上正常使用.通过这种方法,您可以只申请一个合法IP地址,就把整个局域网中的计算机接入Internet中.
2. NAT类型
NAT有三种类型:静态NAT(Static NAT),动态地址NAT(Pooled NAT),网络地址端口转换NAPT.
其中静态NAT设置起来最为简单和最容易实现的一种,内部网络中的每个主机都被永久映射成外部网络中的某个合法的地址.而动态地址NAT则是在外部网络中定 义了一系列的合法地址,采用动态分配的方法映射到内部网络.NAPT则是把内部地址映射到外部网络的一个IP地址的不同端口上.
网络地址端口转换NAPT(Network Address Port Translation)是人们比较熟悉的一种转换方式,NAPT普遍应用于接入设备中,它可以将中小型的网络隐藏在一个合法的IP地址后面.这个优点在小型办公室内非常实用,通过从ISP处申请的一个IP地址,将多个连接通过NAPT接入Internet.
2.1 NAPT类型:
NAPT主要分两大类:锥形NAT和对称NAT.
2.1.1 锥形NAT(Cone NAT):
Cone NAT的特点或者它区别与Symmetric NAT的特性是,通过地址转换可以确保Client使用端口的"同一性",即这个Client只使用这个端口.
Server S1 Server S2
18.181.0.31:1235 138.76.29.7:1235
| |
| |
+----------------------+----------------------+
|
^ Session 1 (A-S1) ^ | ^ Session 2 (A-S2) ^
| 18.181.0.31:1235 | | | 138.76.29.7:1235 |
v 155.99.25.11:62000 v | v 155.99.25.11:62000 v
|
Cone NAT
155.99.25.11
|
^ Session 1 (A-S1) ^ | ^ Session 2 (A-S2) ^
| 18.181.0.31:1235 | | | 138.76.29.7:1235 |
v 10.0.0.1:1234 v | v 10.0.0.1:1234 v
|
Client A
10.0.0.1:1234
如上图,假设Client A通过一个锥形NAT同时发起两个外出的连接,它使用同一个内部端口(10.0.0.1:1234)给公网的两台不同的服务器S1和S2.锥形NAT只分配一个公网IP和端口(155.99.25.11:62000)给这个两个会话.
对称NAT,与Cone NAT是大不相同的,并不对会话进行端口绑定,而是分配一个全新的公网端口给每一个新的会话.
Server S1 Server S2
18.181.0.31:1235 138.76.29.7:1235
| |
| |
+----------------------+----------------------+
|
^ Session 1 (A-S1) ^ | ^ Session 2 (A-S2) ^
| 18.181.0.31:1235 | | | 138.76.29.7:1235 |
v 155.99.25.11:62000 v | v 155.99.25.11:62001 v
|
Symmetric NAT
155.99.25.11
|
^ Session 1 (A-S1) ^ | ^ Session 2 (A-S2) ^
| 18.181.0.31:1235 | | | 138.76.29.7:1235 |
v 10.0.0.1:1234 v | v 10.0.0.1:1234 v
|
Client A
10.0.0.1:1234
如上图,如果Client A同时发起两个会话到S1和S2,对称NAT会分配公共地址155.99.25.11:62000给Session1,然后分配另一个不同的公共地址155.99.25.11:62001给Session2.对称NAT能够区别两个不同的会话并进行地址转换,应用程序每发出一个会话都会使用一个新的端口.
2.2 锥形NAT类型:
锥形NAT在根据如何能创建端到端有效连接上有更多的分类.这个分类一般应用在Udp通信(而不是Tcp通信上),因为NATs和防火墙阻止了试图无条件传入的TCP连接,除非明确设置NAT不这样做.这些分类如下:
完全锥形(Full Cone):
在一个完全锥形NAT中,任务主机A都可以通过主机B映射在NAT上的外部地址发包给内部主机B.(A可在公网也可在内网,以下也是).
受限锥形(Restricted Cone):
在一个受限锥形NAT,只有内部主机B向其发送过包的主机A才可以对这个内部主机B发包(通过主机B映射在NAT上的外部地址).
端口受限锥形(Port Restricted Cone):
端口受限锥形NAT与受限锥形NAT类似,但是增加了对端口的限制,如内部主机B向一个端口为q的主机A发送过包,那么只有从这个主机A的端口q发出的包才能被发送到内部主机B上去。
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).此外,如果任何外部主机A想要发送数据给这个内网主机B,只要知道B向A发送数据时NAT为其映射的(PublicIP:PublicPort),并且B之前用这个socket曾向这个外部主机A发送过数据.满足这两个条件,这个外部主机A就可以用自己的(IP,任何端口)发送数据给(PublicIP:PublicPort),内网的主机就能收到这个数据包.这种NAT无法实现UDP-P2P通信,这个以后会介绍到.
4. NAPT具体类型检测
前提条件:有一个公网的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是否是Symmetric NAT还是Cone 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通信(检测停止).否则是Cone NAT,具体Cone NAT类型有待进一步检测(继续).
第三步:检测客户端NAT是否是Full Cone NAT?
客户端建立UDP socket然后用这个socket向服务器的(IP-1,Port-1)发送数据包要求服务器用另一对(IP-2,Port-2)响应客户端的请求往回发一个数据包,客户端发送请求后立即开始接受数据包,要设定socket Timeout(300ms),防止无限堵塞. 重复这个过程若干次.如果能够接受到服务器从(IP-2,Port-2)返回的应答UDP包,则说明客户端是一个Full Cone NAT.(检测停止).如果每次都超时,无法接受到服务器的回应,则说明客户端的NAT不是一个Full 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.