`
yangzb
  • 浏览: 3464827 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

JAVA UDP打洞必备知识点---NAT

    博客分类:
  • Java
阅读更多

一、引言

  RFCl631以及相关RFC定义的网络地址翻译器(NAT)是一种将IP地址从一个编址域(realm)映射到另外一个编址域的方法,如最典型的应 用是把RFCl918定义的私有IP地址映射到Internet所使用的公有IP地址。虽然NAT技术已经得到广泛应用,但它是一把双刃剑,在带来节省 IPv4地址空间等好处的同时,破坏了Internet最基本的“端到端的透明性”的设计理念,增加了网络的复杂性,阻碍了业务的创新。

  IETF一直主张利用IPv6技术解决地址短缺问题,因此IETF虽然出版了几个与NAT相关的RFC,但对NAT技术(尤其是穿越问题)一直没有系 统的标准化工作,如SIP和MobileIP就是NAT出现后设计的一些协议,都未考虑到NAT的穿越问题。最近,业界意识到Internet在短期内不 可能过渡到IPv6,IPv4和IPv6将长期并存,NAT以及NAT-PT(NAT-协议翻译)将继续得到长期应用,因此NAT相关问题开始引起了 IETF和ITU-T等相关国际标准化组织的关注。中国通信标准化协会IP与多媒体工作委员会也正在积极参与ITU-TSGl6组的相关活动,加紧制定中 国的多媒体业务NAT穿越标准。本文介绍NAT穿越问题的重要组成部分:NAT的类型。

  二、NAT的类型

  从功能上看,主要有以下几种典型的NAT(RFC2663)(见图1):

  

  

  1.传统NAT(Traditional NAT)

  在多数情况下,传统NAT允许位于内部网络的主机(采用RFCl918地址)透明地访问外部网络中的主机,把从外部网络到内部网络的访问作为一种特 例,为事先选择好的特定内部主机做静态地址映射。外部网络中主机的IP地址在外部网络以及内部网络中是惟一的和有效的,但内部网络主机的IP地址只有在内 部网络中才是惟一的,在外部网络中不一定有效。换言之,NAT不会向外部编址域通告内部网络的地址,但有可能向内部网络通告外部网络的地址。内部网络使用 的地址一定不能与外部网络的地址重叠,任何一个地址是一个内部地址或外部地址,不能同时是内部和外部地址。

  有关传统NAT的详细描述见RFCl631和RFC3022。传统NAT包括基本NAT和NAPT两大类。

  (1)基本NAT

  NAT拥有多个公开IP地址,当位于内部网络的主机向外部主机发起会话请求时,把内部地址翻译成全球惟一的公开IP地址。对于从内部网络中外出的IP 包,翻译源IP地址以及相关的字段,如IP/TCP/UDP/ICMP头校验和。对于进入内部网络的IP包,翻译目的IP地址以及与上面所罗列的相关字 段。如果内部网络中主机的数目不大于NAT所拥有的公开IP地址的数目,则可以保证每个内部地址都可以映射到一个公开的IP地址,否则允许同时连接到外部 网络的内部主机的数目会受到NAT公开IP地址数量的限制。可以使用静态映射的方式,把特定内部主机映射为一个特定的全球惟一的地址,保证了外部对内部主 机的访问。一个内部主机可以利用相同的地址映射同时发起多个会话。

  (2)NAPT

  NAPT(网络地址端口翻译)把“基本NAT”翻译的概念延伸了一步,翻译地址的同时也翻译传输层标志(如TCP/UDP的端口号,ICMP的查询 ID),从而把多个内部主机的传输层标志复用为一个惟一的外部地址。NAPT使得一组主机可以共享一个惟一的外部地址。在实际使用中可以把NAPT和基本 NAT结合起来,将一组外部地址与端口翻译关联起来。

  对于从内部网络向外的访问请求,NAPT翻译源IP地址、源传输层标志以及相关的字段,如IP,TCP,UDP和ICMP头校验和。对于进入内部网络 的包,翻译目的IP地址、目的传输层标志以及IP层和传输层头校验和。传输层标志可以是TCP/UDP端口号或ICMP查询ID中的任意一种。

  2.双向NAT(Bi-directionaINAT,Two-WayNAT)

  当使用双向NAT(Bi-directionaINAT或Two-WayNAT)时,可以从内部网络向外部网络发起会话请求,也可以从外部网络向内部 网络发起会话请求。当在外出或进入任何一个方向上建立连接时,把内部网络地址静态或动态绑定到全局惟一的地址上。这里假设位于内部网络和外部网络之间的名 字空间(FQDN,Fully Qualified DomainNames)是端到端惟一的,因为只有这样才能够使得位于外部编址域的主机利用域名系统(DNS)访问内部网络的主机。在双向NAT上必须部 署DNS-ALG(DNS应用层网关,DNS-Application LevelGateway),以处理名字到地址的映射。当一个DNS包需要穿越内部和外部编址域时,DNS-ALG必须能够将DNS查询和响应消息中的内 部地址翻译成外部地址,或把外部地址翻译成内部地址。

  3.两次NAT(Twice NAT)

  两次NAT是NAT的一个变种,它同时修改源和目的地址。这与前面的传统NAT和双向NAT(BiDirectional)都不同,前面的两种NAT只翻译源或者目的地址(端口)。

  两次NAT在内部编址域和外部编址域存在冲突时非常有用。典型例子之一是当一个站点(不恰当地)使用已分配给其它机构的公开IP地址对其内部主机进行 编址时;例子之二是当一个站点从一家运营商换到另外一家运营商,同时希望(在内部)保留前一家运营商分配的地址时(而前一家运营商可能会在一段时间后将这 些地址重新分配给其它人使用)。在这些情况下,非常关键的一点就是外部网络的主机可能会分配得到以前已分配给内部主机的同一地址。如果该地址碰巧出现在某 个包中,则应该将它转发给内部主机,而不是通过NAT转发给外部编址域。两次NAT通过同时翻译IP包的源和目的地址,试图桥接这些编址域,解决了地址冲 突的问题。

  4.多宿主NAT(Multihomed NAT)

  使用NAT会带来很多问题(RFC2993)。比如,NAT设备要为经过它的会话维护状态信息,而一个会话的请求和响应必须通过同一NAT设备做路 由,因此通常要求允许NAT末梢域边界路由器必须是惟一的,所有的IP包要么发起,要么终结在该域。但这种配置将NAT设备变成了可能的单点故障点。

  为了让一个内部网络能够在某个NAT链路故障的情况下,也可以保持与外部网络的连通性,通常希望内部网络到相同或不同的ISP具有多条连接(多宿主的),希望经过相同或不同的NAT设备。

  又如,多个NAT设备或多条链路使用同一NAT,共享相同的NAT配置能够为相互之间提供故障备份。在这种情况下,有必要让备份NAT设备交换状态信息,以便当主NAT出现故障时,备份NAT能够担负起透明地保持会话的能力。

  三、传统NAT的类型

  目前,市场上使用最多的是传统NAT设备,尤其是NAPT设备。传统NAT(内部地址,端口)与(内部地址,端口)的映射方式主要有以下几种典型类型(RFC3489)(见图2):

  

  

  图2

  传统NAI的类型

  1.克隆NAT(CloneNAT)

  当在(私有IP,私有端口)与(公开IP.公开端口)已经建立了一个端口映射表后,克隆NAT将为随后从相同的私有地址和端口号发起的呼叫重复使用该映射,条件是只要使用映射(有时业叫绑定)的会话至少有一个继续保持激活状态。

  从图3可以看出,客户A分别从相同的内部地址和端口号(10.0.0.1:1234)同时发起两个会话请求到服务器1和服务器2,因为这两个请求来自 相同的内部地址和端口,所以克隆NAT将为这两个不同的会话请求分配相同的公开端点号(100.100. 100.100:62000),以保证客户A的“身份”能够在经过翻译后仍然保持一致。NAT和防火墙不翻译端口号,因此也是克隆方式的NAT。根据克隆 时受到的限制大小,又可以把克隆NAT分为以下三种:

  

  

  图3

  克隆NAT

  (1)全克隆(Full Cone)

  首先,把所有来自相同内部IP地址和端口的请求映射到相同的外部1P地址和端口。其次,任何一个外部主机通过把一个TP包发送给已得到映射的外部IP地址的方式,都能够把该包发送给该内部主机。

  (2)限制性克隆(Restricted Cone)

  把所有来自相同内部IP地址和端口号的请求映射到相同的外部IP地址和端口。与全克隆NAT方式不同,只有当内部主机以前曾经给IP地址为x的外部主机发送过一个包时,IP地址为x的该外部主机才能够把一个IP包发送给该内部主机。

  (3)端口限制性克隆(Port Restricted Cone)

  端口限制性克隆与限制性克隆类似,只是限制中多了端口号。特别是,一个外部主机可以发送一个源IP地址和源端口号分别为(x,P)的IP包给外部主 机,只有当内部主机以前曾经给IP地址为x,端口号为P的外部主机发送过一个包时,IP地址为X的该外部主机才能够把一个源端口号为P的IP包发送给该内 部主机。

  2.对称NAT

  对称式NAT(symmetricNAT)是指把所有来自相同内部IP地址和端口号,到特定目的1P地址和端口号的请求映射到相同的外部TP地址和端 口。如果同一主机使用不同的源地址和端口对,发送的目的地址不同,则使用不同的映射。只有收到了一个IP包的外部主机才能够向该内部主机发送回一个UDP 包。对称式的NAT不保证所有会话中的(私有地址,私有端口)和(公开IP,公开端口)之间绑定的一致性。相反,它为每个新的会话分配一个新的端口号。

  从图4可以看出,假如客户A分别从相同的内部地址和端口号(10.0.0.1:1234)同时发起两个会话请求到服务器1和服务器2,对称NAT可能 会为这两个来自相同地点的会话请求分配不相同的公开端点号,如把100 100. 100.100:62000分配给会话1,把100 100.100.100:62001分配给会话2。因为这两个会话的有一个端点不同,所以虽然在翻译的过程中客户A的身份发生了变化,但NAT仍然能够正 确工作。

    

分享到:
评论
2 楼 supermagician 2013-09-15  
这里有demo代码,可看看是怎么实现的。
http://download.csdn.net/detail/supermagician/5945753
1 楼 yangzb 2011-05-05  
网络上的大多数UDP原理研究分析后,自己总结了下面的结果.

1、client A 登录 通过http服务器 webservices 验证成功获取自身信息与好友

列表信息等。

2、Http服务器登记client A的NAT后的IP地址与端口

3、Client B登录 通过http服务器 webservices 验证成功获取自身信息与好友列

表信息等。

4、Http服务器登记client B的NAT后的IP地址与端口

5、Client A想发送消息给Client B,向HTtp服务器获取Client B的在线IP地址

6、Client A获得Client B的IP地址后并发送UDP信息到Client B

7、Client A与Client B请求失败,信息丢失,此时Client A报告Http服务器要求

服务器帮忙对Client B进行通知

8、Http服务器接到此命令后,将Client A的IP地址发给Client B,要求他连接

9、Client B收到HTTP服务器的信息后发送请求到 Client A

10、由于此时Client A NAT已经存在Clinet B的session,所以此时 Client A与

Client B建立链接成功。

11、Client A发送消息到 Client B成功,不经HTTP服务器中转

总结:换句话说就是HTTP服务器启动了“和事老”的功能。为不信任的两个人发

出命令从而使他们达到了一种互相承认而此建立链接关系

其中最主要的是Server 的一个方法就是发送消息到被打洞的客户端

客户端发送消息需要判断该消息是否发送成功,不成功则要求请求打洞.若成功则不需要要求打洞!

客户端在接收到服务器的打洞指令后,则作出UDP发送响应

相关推荐

Global site tag (gtag.js) - Google Analytics