• 1.       NAT分类
    2.       UDP hole punching
    3.       同一个NAT后面的情况
  • 此文档说明如何进行伪装、透明代理、端口转发,和基于Linux 2.4内核其他类型的 网络地址转换(Network Address Translations)。
    1. 简介 欢迎,亲爱的读者。 你将要深入迷人的(有时是令人厌烦的)NAT世界:网络地址转换,这篇HOWTO可以成为你的Linux2.4内核及其以后的准确指南。 在Linux2.4(内核版本),引入了一个叫"netfilter"的部分,专门用于拆分(mangling) (IP)包的。他上一层提供NAT,是完全依靠以前的内核制作的。
  • 一些基本的VoIP元素
    媒体网关(Media Gateway):主要扮演将语音讯号转换成为IP封包的角色。
    媒体网关控制器(Media Gateway Controller):又称为Gate Keeper或Call Server。主要负责管理讯号传输与转换的工作。
    语音服务器:主要提供电话不通、占线或忙线时的语音响应服务。
    信号网关器(Signaling Gateway):主要工作是在交换过程中进行相关控制,以决定通话建立与否,以及提供相关应用的增值服务。

    媒体网关(MG)的分类
    中继媒体网关(TG):用于完成与PSTN/PLMN电话交换机的中继连接,将电话交换机PCM中继中的64kbit/s的语音信号转换为IP包。
    信令网关(SG):用于完成与PSTN/PLMN电话交换机的信令连接,将电话交换机采用的基于TDM电路的七号信令信息转换为IP包。
    接入网关(AG):提供模拟用户线接口,用于直接将普通电话用户接入到软交换网中,可为用户提供PSTN提供的所有业务,如电话业务、拨号上网业务等,它直接将用户数据及用户线信令封装在IP包中。

    IAD(Integrated Access Device)综合接入设备
    一类IAD同时提供模拟用户线和以太网接口,分别用于普通电话机的接入和计算机设备的接入,适用于分别利用电话机使用电话业务、利用计算机使用数据业务的用户.
    另一类IAD仅提供以太网接口,用于计算机设备的接入,适用于利用计算机同时使用电话业务和数据业务的用户,此时需在用户计算机设备中安装专用的“软电话软件”。

    PBX,即程控交换机。PBX是现代办公常用的电话通讯管理手段的一种,使电话管理者可集团性管理外线来电与内线呼出。
    PBX设备一般由外线口与内线口构成,外线指接入集团电话中的外线总数,内线是为员工所安排的的电话数量。PBX的外线口是FXO,内线口是FXS。
    FXO,外部交换局,英文全称是Foreign Exchange Office。是中继接口,一般与局用机或上一级交换机的分机端口对接,给上一级交换机提供一个出局路由,能实现环路远程汇接功能。
    FXS,外部交换站,英文全称为Foreign Exchange Station。是话机终端接口,一般接下一级交换机的中继端口或电话机,为下一级交换机的分机提供一个出局路由来拨打IP电话。


    会话质量包括哪些因素呢?
    a.延迟:round-trip delay不能超过300ms.
    b.抖动:关键在于保证延迟的一致性,解决方法是使用jitter buffers.
    c.包丢失:包丢失率不能超过5%;
    重传策略:1.退后n帧;2.选择性重传。
    d.语音编码技术:很多,较常用的如G.711,比特率64kbps。

    管理与优先级:例如,当有一个大文件传输占用网络带宽时不会出现队列中的语音包拥塞就是一项关键的工作。

    VoIP有哪些应用呢?
    a.基于IP的PBX:将企业的电话系统和计算机网络合二为一;
    b.IP Voice Mail;
    c.Hosted PBX solutions;
    d.IP call centers:即客服中心;

    IP协议相关
    Indentification用来标识属于同一个datagram的fragments;
    Flags域表示一个数据报是否能够再分,如果此数据报已分段则表示是否为最后一个fregment;
    Fragment Offset用于在目的端段的按序合成;
    Time to Live(TTL)实际上不是时间,而是允许经过的最大段数(hops);
    Protocol中TCP的值为6,UDP的值为17;

    TCP协议相关
    将数据流分成segments,每个segment加上一个TCP头;
    如果一个segment的sequence number为100且包含150 octets(=byte),则下一个segment的序列号为250;
    URG:是否包含紧急数据;
    ACK:acknowledgement;
    PSH:Push function,说明数据应该被立即发送到接收方;
    RST:出现错误并中止一个会话;
    SYN:建立数据传输时用在初始信息中;(即此flag设为1)
    FIN:正常的结束会话。
    window field:当TCP收到数据并发送一个ACK时,使用此域说明可用的空缓存空间。

    UDP协议相关
    Source Port是可选的,除非发送方期望得到一个回应;

    为什么Voice over UDP,not TCP呢?
    UDP的包丢失完全在可以忍受的范围内;
    由于对延迟极度敏感,而TCP的重传机制会带来不可忍受的延迟,这在通信中是致命的;
    包丢失率只要小于5%就不会对通话质量产生太大影响;
    事实上,使用UDP时大多数包都经过相同的路由;
    QOS技术也会不断成熟以不断改进通话质量。

    网关:例如在北京拨打一个到旧金山的长途电话,在北京,一个普通的公共电话通过 PSTN接入本地网关,本地网关对数据进行特定的压缩算法处理,组织成包含主、被叫号码、时间、通话信息等数据的IP分组,并分析被叫号码,根据路由表, 把它映 射成为一个IP地址,通过路由选择,发往该IP地址(如旧金山)对应的远端网关。 而在被叫方旧金山,远端网关接收北京本地网关传输过来的IP数据分组,进行相反过程的解压缩,再发往其本地端的PSTN网。这样,就实现了两地的实时通 信。而其 所包含的通信费用仅为北京本地普通电话费+Internet通信费+旧金山本地电话费。

     

    RTP相关
    --------------------------
    | IP | UDP | RTP | Data |
    --------------------------
    包含time-stamp
    RTCP包用于质量反馈的传输;
    RTP会话和RTCP会话总是同时开始;
    RTP的默认端口号是5004,RTCP是5005;
    RTP中的payload type用来表示各种不同的编码标准,7bit,35-71及77-95待定,96-127动态,72-76保留;
    RTP header:
    Version(V)当前版本为2;
    Padding(P)当P=1时表示包含一个或多个填充字节以进行32bit对齐;
    EXtension(X)是否包括头部扩展;
    CSRC Count(CC)CSRC的个数;
    Marker(M)用于支持silence suppression,在一个talkspurt的第一个包中设成1;
    Payload Type(PT)一般来说每个单独的RTP包只包含一种载荷的编码格式,但是也有意外,比如RED profile就包含多种编码格式,此时每种编码的载荷由额外的头部管理,PT值仅仅表示这是一个RED载荷,具体可参考RFC 2198;
    Sequence Number 一个会话开始时设置为一个随机值,之后每个RTP包中此值依次加1,用于检测包丢失及接收方排序;
    Timestamp 记录了负载中第一个字节的采样时间,用于计算延迟和抖动;初始值为随机值,根据连续两次RTP包之间进行的采样数递增;
    Synchronization Soruce(SSRC)表示负责设置序列号和时间戳的实体,通常是RTP包的发送者。标识是随机选择的所以与网络地址无关。另外,如果RTP流来自一个混合器,则SSRC表示此混合器而不是媒体源;
    Contributing Source(CSRC)用于当RTP流来自一个mixer时表示此mixer后的媒体源。
    RTP Header Extensions:X域值为1时有效,此时payload的前几个字节做为具有特殊含义的扩展头部,紧跟在CSRC域之后。

    Mixers
    合成多路媒体流:鉴于带宽问题mixer将4路64kbps的RTP流合成为一条单独的64kbps的流。
    调整数据格式:如在一个高速连接的会话中出现一个低速的连接接入者,mixer可能会对其使用低带宽的编码机制;
    设置时间戳的值。

    Traslators
    仅做媒体格式转换之用,不是一个SS(Synchronization Source)。

    RTCP相关
    能够在会话参与者之间进行周期性的控制信息交换,主要目的是提供质量相关的反馈。通过使用RTCP和IP多播机制,可以进行第三方的监视和检测。
    RTCP定义了5种不同类型的RTCP包:
    1.Sender Report(SR)用来中继发送和接收统计;
    2.Receiver Report(RR)只接收而不发送媒体流的参与者发送的接收统计;
    3.Source Description(SDES)包含某一特定会话参与者的一个或多个描述。必须包含一个唯一的canonical name(CNAME)用于标识会话的参与者,它不同于SSRC,因为当主机reset后SSRC的值可能会发生改变。再者,如果在一个给定的会话中,发 送者同时发送音频和视频的两路RTP流,则这两种媒体流有不同的SSRC值但是却有相同的CNAME;
    4.BYE 表示一个会话中的参与中止;
    5.APP 用于调查特定的媒体类型和应用信息,不过RTCP没有明确APP包的详细内容。

    事实上,总是两个或多个RTCP包被捆绑成一个混合包发送出去的。所有的RTCP包都必须以一个SR或RR开始,都必须包含至少一个SDES,即使在SDES之间加上一个空的SR或RR。
    Compound Packet举例:(发送者离开此次会话)
    H:Header D:Data
    -------------------------------------------------------------
    | SR H | SR D | SDES H | SDES D | BYE H | BYE D |
    -------------------------------------------------------------

    RTCP Sender Report(SR)
    由三部分组成:header,sender information和多个Report Block
    1.header:
    RC域,表示含有多少个receiption report blocks,5bit,一个SR之后最多可以跟31个RR blocks。当RR多于31个时只需在最后一个RR后再跟一个SR即可;
    Payload Type(TP)的值为200;

    2.Sender info:
    SSRC of sender 发送者的SSRC;
    NTP Timestamp 两个字,第一个表示整数部分,第二个表示小数部分,以1900年1月1日00:00时为参照时间,单位是秒,小数部分精确到200皮秒,此版本的网络时间 协议2036年到期,在此之间应该会有新的版本,此时间戳信息来自于一个时间服务器,这个服务器通过NTP协议在网络上传播计时信息;
    RTP Timestamp 同时包含RTP和NTP时间戳是为了使接收方更好的于发送方保持同步;
    Sender's packet count 记录从会话开始到此RTCP包发出这之间所传输的RTP包的总数,只有当发送者的SSRC值改变时此项才重置;
    Sender's octet count 记录从会话开始到此RTCP包发出这之间所传输的载荷字节的总数,只有当发送者的SSRC值改变时此项才重置;

    3.RR Blocks:(RR用于反馈RTP包的接收情况)
    SSRC_n 表示与此RR块相关的会话参与者的源标识;
    Fractioin lost (8bit)表示包的丢失率是多少,即丢失的包的数量除以期望的包的数量,丢失的包的数量可以通过每次检查RTP包头中的Sequence Nmuber统计出来;
    Cumulative number of packets lost (24bit)从会话开始至今丢失的包的总数;
    Extended highest sequence number receirved (32bit)低16位表示最近收到的RTP包的序列号,一般情况下高16位全为0,但如果收到的某一个发送源的序列号出现循环,则在它的相应RR段中此 高16位值表示已循环的次数;
    Interarrival jitter 对RTP包到达不一致性的估计;
    Last SR Timestamp(LSR) 表示所接收到的此RR块对应的SSRC发送的最后一个SR中64-bit NTP时间戳的中间32位,以告知它所发送的SR是否已经被收到;
    Delay Since Last SR (DLSR)从收到最后一个SR到此RR块被发出经历的时间,精确到1/65536秒。

    RR包包括header,发送者SSRC以及Report Blocks,基本与SR相同,只是header中的PT值为201。

    RTCP Source Description Packet (SDES)相关
    必须存在于每一个RTCP混合包中,由一个header和0个或多个chunk组成,header中的PT值为202,SC的值表示chunk的个数;
    每个chunk包括一个SSRC或CSRC值,之后是一些SDES项,比如email地址、电话号码、姓名等等,但是有一个项是必需的,即CNAME,它的形式为user@host

    RTCP BYE Packet
    PT值为203,SC表示SSRC或CSRC的数量,在这之后有个length域表示文本字符串的字节数,length域之后是以文本字符储存的离开会话的原因。

    Application-Defined RTCP Packet略

    其中,Skype使用的是第三和第四中方式!


    一、NAT/ALG 方式

    普通NAT是通过修改UDP或TCP报文头部地址信息实现地址的转换,但对于VOIP应用,在TCP/UDP净载中也需带地址信息,ALG方式是指在私网中的VOIP终端在净载中填写的是其私网地址,此地址信息在通过NAT时被修改为NAT上对外的地址。

    此 时当然要求ALG功能驻留在NAT/Firewall设备中,要求这些设备本身具备应用识别的智能。支持IP 语音和视频协议(H323、SIP、MGCP/H248)的识别和对NAT/Firewall的控制,同时每增加一种新的应用都将需要对 NAT/Firewall进行升级。

    在安全要求上还需要作一些折衷,因为ALG 不能识别加密后的报文内容,所以必须保证报文采用明文传送,这使得报文在公网中传送时有很大的安全隐患。
    NAT/ALG是支持VOIP NAT穿透的一种最简单的方式,但由于网络实际情况是已部署了大量的不支持此种特性的NAT/FW设备,因此,实际应用中,很难采用这种方式。

    二、MIDCOM 方式

    与NAT/ALG 不同的是,MIDCOM的基本框架是采用可信的第三方(MIDCOM Agent)对Middlebox (NAT/FW)进行控制,VOIP协议的识别不由Middlebox完成,而是由外部的MIDCOM Agent完成,因此VOIP使用的协议对Middlebox是透明的 。

    由于识别应用协议的功能从Middlebox移到外部的 MIDCOM Agent上,根据MIDCOM 的构,在不需要更改Middlebox基本特性的基础上,通过对MIDCOM Agent的升级就可以支持更多的新业务,这是相对NAT/ALG方式的一个很大的优势。

    在VOIP实际应用中,Middlebox 功能可驻留在NAT/Firewall,通过软交换设备(即MIDCOM Agent)对IP语音和视频协议(H323、SIP、MGCP/H248)的识别和对NAT/Firewall的控制,来完成VOIP应用穿越 NAT/Firewall 。
    在安全性上,MIDCOM方式可支持控制报文的加密,可支持媒体流的加密,因此安全性比较高。

    如 果在软交换设备上实现对SIP/H323/MGCP/H248协议的识别,就只需在软交换和NAT/FW设备上增加MIDCOM协议即可,而且以后新的应 用业务识别随着软交换的支持而支持,此方案是一种比较有前途的解决方案,但要求现有的NAT/FW设备需升级支持MIDCOM协议,从这一点上来说,对已 大量布署的NAT/FW设备来说,也是很困难的,同NAT/ALG方式有相同的问题。

    三、STUN 方式

    解 决穿透NAT问题的另一思路是,私网中的VOIP终端通过某种机制预先得到出口NAT上的对外地址,然后在净载中所填写的地址信息直接填写出口NAT上的 对外地址,而不是私网内终端的私有IP地址,这样净载中的内容在经过NAT时就无需被修改了,只需按普通NAT流程转换报文头的IP地址即可,净载中的 IP地址信息和报文头地址信息是一致的。STUN协议就是基于此思路来解决应用层地址的转换问题。

    STUN的全称是Simple Traversal of UDP Through Network Address Translators,即UDP对NAT的简单穿越方式。 应用程序(即STUN CLIENT)向NAT外的STUN SERVER通过UDP发送请求STUN 消息,STUN SERVER收到请求消息,产生响应消息,响应消息中携带请求消息的源端口,即STUN CLIENT在NAT上对应的外部端口。然后响应消息通过NAT发送给STUN CLIENT,STUN CLIENT通过响应消息体中的内容得知其NAT上的外部地址,并将其填入以后呼叫协议的UDP负载中,告知对端,本端的RTP接收地址和端口号为NAT 外部的地址和端口号。由于通过STUN协议已在NAT上预先建立媒体流的NAT映射表项,故媒体流可顺利穿越NAT。

    STUN协议最 大的优点是无需现有NAT/FW设备做任何改动。由于实际应用中,已有大量的NAT/FW,并且这些NAT/FW并不支持VoIP的应用,如果用 MIDCOM或NAT/ALG方式来解决此问题,需要替换现有的NAT/FW,这是不太容易的。而采用STUN方式无需改动NAT/FW,这是其最大优 势,同时STUN方式可在多个NAT串联的网络环境中使用,但MIDCOM方式则无法实现对多级NAT的有效控制。

    STUN的局限性 在于需要VOIP终端支持STUN CLIENT的功能,同时STUN并不适合支持TCP连接的穿越,因此不支持H323。另外STUN方式不支持对防火墙的穿越,不支持对称NAT (Symmetric NAT)类型(在安全性要求较高的企业网中,出口NAT通常是这种类型)穿越。

    四、TURN方式

    TURN 方式解决NAT问题的思路与STUN相似,也是私网中的VOIP终端通过某种机制预先得公网上的服务地址(STUN方式得到的地址为出口NAT上外部地 址,TURN方式得到地址为TURN Server上的公网地址),然后在报文净载中所要求的地址信息就直接填写该公网地址。
    TURN的全称 为Traversal Using Relay NAT,即通过Relay方式穿越NAT。TURN应用模型通过分配TURN Server的地址和端口作为私网中VOIP终端对外的接受地址和端口,即私网终端发出的报文都要经过TURN Server进行Relay转发,这种方式除了具有STUN方式的优点外,还解决了STUN应用无法穿透对称NAT(Symmetric NAT)以及类似的Firewall设备的缺陷,同时TURN支持基于TCP的应用,如H323协议。此外TURN Server控制分配地址和端口,能分配RTP/RTCP地址对(RTCP端口号为RTP端口号加1)作为私网终端用户的接受地址,避免了STUN方式中 出口NAT对RTP/RTCP地址端口号的任意分配,使得客户端无法收到对端发来的RTCP报文(对端发RTCP报文时,目的端口号缺省按RTP端口号加 1发送)。
    TURN的局限性在于需要VOIP终端支持TURN Client,这一点同STUN一样对网络终端有要求。此外,所有报文都必须经过TURN Server转发,增大了包的延迟和丢包的可能性。

  • NAT的完全分析及其UDP穿透的完全解决方案
     
    一:基本术语
    防火墙
    防火墙限制了私网与公网的通信,它主要是将(防火墙)认为未经授权的的包丢弃,防火墙只是检验包的数据,并不修改数据包中的IP地址和TCP/UDP端口信息。
    网络地址转换(NAT)
    当有数据包通过时,网络地址转换器不仅检查包的信息,还要将包头中的IP地址和端口信息进行修改。以使得处于NAT之后的机器共享几个仅有的公网IP地址(通常是一个)。网络地址转换器主要有两种类型.
    P2P应用程序
    P2P应用程序是指,在已有的一个公共服务器的基础上,并分别利用自己的私有地址或者公有地址(或者两者兼备)来建立一个端到端的会话通信。
    P2P防火墙
    P2P防火墙是一个提供了防火墙的功能的P2P代理,但是不进行地址转换.
    P2P-NAT
    P2P-NAT 是一个 P2P代理,提供了NAT的功能,也提供了防火墙的功能,一个最简的P2P代理必须具有锥形NAT对Udp通信支持的功能,并允许应用程序利用Udp打洞技术建立强健的P2P连接。
    回环转换
    NAT的私网内部机器想通过公共地址来访问同一台局域网内的机器的时,NAT设备等价于做了两次NAT的事情,在包到达目标机器之前,先将私有地址转换为公网地址,然后再将公网地址转换回私有地址。我们把具有上叙转换功能的NAT设备叫做“回环转换”设备。
     
    二:NAT分类
    可以分为基础NAT网络地址和端口转换(NAPT)两大类
    (一):基础NAT
    基础NAT 将私网主机的私有IP地址转换成公网IP地址,但并不将TCP/UDP端口信息进行转换。基础NAT一 般用在当NAT拥有很多公网IP地址的时候,它将公网IP地址与内部主机进行绑定,使得外部可以用公网IP地址访问内部主机。(实际上是只将IP转换, 192.168.0.23 <-> 210.42.106.35,这与直接设置IP地址为公网IP还是有一定区别的,特别是对于企业来说,外部的信息都要经过统一防火墙才能到达内部,但是内 部主机又可以使用公网IP)
    (二):网络地址和端口转换 (NAPT)
    这是最普遍的情况,网络地址/端口转换器检查、修改包的IP地址和TCP/UDP端口信息,这样,更多的内部主机就可以同时使用一个公网IP地址。
    请参考[RFC1631]和[RFC2993]及[RFC2663]这三个文档了解更多的NAT分类和术语信息。另外,关于NAPT的分类和术语,[RFC2663]做了更多的定义。当一个内部网主机通过NAT打开一个“外出”的TCP或UDP会话时,NAPT分配给这个会话一个公网IP和端口,用来接收外网的响应的数据包,并经过转换通知内部网的主机。这样做的效果是,NAPT[私有IP:私有端口][公网IP:公网端口]之间建立了一个端口绑定。
    端口绑定指定了NAPT将在这个会话的生存期内进行地址转换任务。这中间存在一个这样的问题,如果P2P应用程序从内部网络的一个[私有IP地址:端口]对同时发出多条会话给不同的外网主机,那么NAT会怎样处理呢?这又可以分为锥形NAT (CONE NAT)对称NAT (SYMMTRIC NAT)两大类来考虑:
    A.锥形NAT
    (为什么叫做锥形呢?请看以下图形,终端和外部服务器,都通过NAT分派的这个绑定地址对来传送信息,就象一个漏斗一样,筛选并传递信息)
     
      当建立了一个 [私有IP:端口]-[公网IP:端口] 端口绑定之后,对于来自同一个[私有IP:端口]会话,锥形NAT服务器允许发起会话的应用程序 重复使用这个端口绑定,一直到这个会话结束才解除(端口绑定)。
      例如,假设 Client A(IP地址信息如上图所示)通过一个锥形NAT 同时发起两个外出的连接,它使用同一个内部端口(10.0.0.1:1234)给公网的两台不同的服务器,S1和S2。锥形NAT 只分配一个公网IP和端口(155.99.25.11:62000)给这个两个会话,通过地址转换可以确保 Client使用端口的“同一性”(即这个Client只使用这个端口)。而基础NATs和防火墙却不能修改经过的数据包端口号,它们可以看作是锥形 NAT的精简版本。
    进一步分析可以将CONE NAT受限制锥形NAT (RESTRICT CONE)端口受限锥形NAT (PORT RESTRICT CONE) 三大类,以下是详细论述: 分为全双工锥形NAT (FULL CONE) ,
    1.全双工锥形NAT
    当内部主机发出一个“外出”的连接会话,就会创建了一个公网/私网 地址,一旦这个地址对被创建,全双工锥形NAT会接收随后任何外部端口传入这个公共端口地址的通信。因此,全双工锥形NAT有时候又被称为"混杂"NAT。
    2.受限制锥形NAT
    受限制的锥形NAT 会对传入的数据包进行筛选,当内部主机发出“外出”的会话时,NAT会记录这个外部主机的IP地址信息,所以,也只有这些有记录的外部IP地址,能够将信 息传入到NAT内部,受限制的锥形NAT 有效的给防火墙提炼了筛选包的原则——即限定只给那些已知的外部地址“传入”信息到NAT内部。
    3.端口受限锥形NAT
    端口受限制的锥形NAT,与受限制的锥形NAT不同的是:它同时记录了外部主机的IP地址和端口信息,端口受限制的锥形NAT给内部节点提供了同一级别的保护,在维持端口“同一性”过程中,将会丢弃对称NAT传回的信息。
    B.对称NAT
    对称NAT,与Cone NAT是大不相同的,并不对会话进行端口绑定,而是分配一个全新的公网端口 给每一个新的会话。
    还是上面那个例子:如果 Client A (10.0.0.1:1234)同时发起两个 "外出" 会话,分别发往S1和S2。对称Nat会分配公共地址155.99.25.11:62000给Session1,然后分配另一个不同的公共地址 155.99.25.11:62001给Session2。对称Nat能够区别两个不同的会话并进行地址转换,因为在 Session1 和 Session2中的外部地址是不同的,正是因为这样,Client端的应用程序就迷失在这个地址转换边界线了,因为这个应用程序每发出一个会话都会使用 一个新的端口,无法保障只使用同一个端口了。
    TCP 和UDP通信中,(到底是使用同一个端口,还是分配不同的端口给同一个应用程序),锥形NAT和对称NAT各有各的理由。当然锥形NAT在根据如何公平地 将NAT接受的连接直达一个已创建的地址对上有更多的分类。这个分类一般应用在Udp通信(而不是Tcp通信上),因为NATs和防火墙阻止了试图无条件 传入的TCP连接,除非明确设置NAT不这样做。
    三:NAT对session的处理
    以下分析NAPT是依据什么策略来判断是否要为一个请求发出的UDP数据包建立Session的.主要有一下几个策略:
    A. 源地址(内网IP地址)不同,忽略其它因素, 在NAPT上肯定对应不同的Session
    B. 源地址(内网IP地址)相同,源端口不同,忽略其它的因素,则在NAPT上也肯定对应不同的Session
    C. 源地址(内网IP地址)相同,源端口相同,目的地址(公网IP地址)相同,目的端口不同,则在NAPT上肯定对应同一个Session
    D. 源地址(内网IP地址)相同,源端口相同,目的地址(公网IP地址)不同,忽略目的端口,则在NAPT上是如何处理Session的呢?
    A,B,C三种情况的都是比较简单的,可以很容易的实现.而D的情况就比较复杂了.所以D情况才是我们要重点关心和讨论的问题。
    四:完全解决方案
    以下针对四种SESSION与四种NAT的完全解决方案,为了方便将使用以下缩写形式:
    C代表 CONE NAT
    S代表SYMMETRIC NAT,
    FC代表 FULL CONE NAT,
    RC代表 RESTRICT CONE NAT,
    PC 代表 PORT RESTRICT CONE NAT.
    首先依据CLIENT (客户)端在NAT后 的个数不同可以分为两大类:
    TYPE ONE :一个在NAT后 + 一个在公网中.
    这种情况下可以分为两大类:
    A. S VS 公网:此种情况下,由于公网的地址在一个SESSION内是不变的,所以可以打洞是可以成功的.
    B. C VS 公网: 与上面类似,这种情口下打洞是可以成功的.
    TYPE TWO:两个客户都在NAT后面.
    这种情况下也可以细分为两大类:
    A. 其中一个NAT 是 S(SYMMETRIC NAT) 的,既:S VS C或者是S VS S .
    下面论证这种情口下按照常规打洞是行不通的,在常规打洞中,所有的客户首先登陆到一个服务器上去.服务器记录下每个客户的[公网IP:端口],然后在打洞过程中就使用这个记录的值,然而对于S的NAT来说,它并不绑定[私网IP:端口][公网IP:端口]的映射.所以在不同的SESSION中,NAT将会重新分配一对[公网IP:端口].这样一来对于S型的NAT来说打洞的[公网IP:端口]与登记在服务器上的[公网IP:端口]是不同的.而且也没有办法将打洞的[公网IP:端口]通知到另一个位于NAT下的客户端, 所以打洞是不会成功的.然而如果另一个客户端是在公网时,打洞是可以的.前面已经论证了这种情况.
    这种情况下的解决方案是只能通过端口预测来进行打洞,具体解决方法如下:例如(以两个都是S型的为例) NAT A 分配了它自己的UDP端口62000用来保持 客户端A 服务器S的通信会话 NAT B 也分配了31000端口用来保持客户端B服务器S 的通信会话通过与 服务器S的对话客户端A 和 客户端B都相互知道了对方所映射的真实IP和端口
     客户端A发送一条UDP消息到138.76.29.7:31001(请注意到端口号的增加)同时客户端B发送一条UDP消息到155.99.25.11:62001如果NAT A 和NAT B继续分配端口给新的会话,并且从A-S和B-S的会话时间消耗得并不多的话,那么一条处于客户端A和客户端B之间的双向会话通道就建立了。
     客户端A发出的消息送达B导致了NAT A打开了一个新的会话,并且我们希望NAT A将会指派62001端口给这个新的会话,因为62001是继62000NAT会自动指派给 从服务器S客户端A之间的新会话的端口号;类似的,客户端B发出的消息送达A导致了 NAT B打开了一个新的会话,并且我们希望 NAT B将会指派31001这个端口给新的会话;如果两个客户端都正确的猜测到了对方新会话被指派的端口号,那么这个 客户端A-客户端B的双向连接就被打通了。其结果如下图所示:
    明显的,有许多因素会导致这个方法失败:如果这个预言的新端口(62001和31001) 恰好已经被一个不相关的会话所使用,那么NAT就会跳过这个端口号,这个连接就会宣告失败;如果两个NAT有时或者总是不按照顺序来生成新的端口号,那么这个方法也是行不通的
    如果隐藏在NATA后的一个不同的客户端X(或者在NAT B后)打开了一个新的“外出”UDP 连接,并且无论这个连接的目的如何;只要这个动作发生在客户端A 建立了与服务器S的连接之后客户端A 与 客户端B 建立连接之前;那么这个无关的客户端X 就会趁人不备地“偷” 到这个我们渴望分配的端口。所以,这个方法变得如此脆弱而且不堪一击,只要任何一个NAT方包含以上碰到的问题,这个方法都不会奏效。
    在处于 cone NAT 系列的网络环境中这个方法还是实用的;如果有一方为 cone NAT 而另外一方为 symmetric NAT,那么应用程序就应该预先发现另外一方的 NAT 是什么类型,再做出正确的行为来处理通信,这样就增大了算法的复杂度,并且降低了在真实网络环境中的普适性。
        最后,如果P2P的一方处在两级或者两级以上的NAT下面,并且这些NATS 接近这个客户端是SYMMETRIC NAT的话,端口号预言是无效的!
    因此,并不推荐使用这个方法来写新的P2P应用程序,这也是历史的经验和教训!
    B. 两个都是CONE NAT型.
    这种情况下可以分为六大类型:
    A: FC + FC
    B: FC + RC
    C: FC + PC
    D: PC + RC
    E: PC + PC
    F: RC + RC
    虽然有这么多种情况,但是由于CONE NAT 的特性,所以还是很好办的,因为对于CONE NAT 来说,在同一个SESSION中它会绑定一对[私网IP:端口][公网IP:端口]的映射,所以它们打洞用的[公网IP:端口]与登记在服务器上的[公网IP:端口]是一致的,所以打洞是可以行的通的.
    综上所述,就已经完全的概括了所有类型的NAT之间的可能的通信情况了.并且都提供了可行的解决方案.
    五:对前一阶段的总结
    1.前一阶段使用的打洞方法是有缺陷的,它只适应于两个都是FULL CONE NAT的类型的CLIENT(客户端).以下论证它不适应于两个都是CONE NAT的类型中的
    B: FC + RC
    C: FC + PC
    D: PC + RC
    E: PC + PC
    F: RC + RC
    这五种情况.
    因为对于受限的NAT它登记了外出包的[IP地址&端口],它仅仅接受这些已登记地址发过来的包,所以它们报告服务器的端口只能接受来自服务器的包.不能接受来自另一客户端的包.所以前一阶段的打洞方法是不可行的.
    六: 存在的问题
    按照理论.NAT将在一定时间后关闭UDP的一个映射,所以为了保持与服务器能够一直通信,服务器必须要发送UDP心跳包,来保持映射不被关闭.这就需要一个合适的时间值.