物联网高并发编程之P2P技术NAT快速理解

物联网高并发编程之P2P技术NAT快速理解

更多物联网高并发编程知识请移步:https://www.yuque.com/shizhiy...
html

前言

P2P技术在现实的应用场景中,主要用于诸如IM(尤为移动端IM)、在线直播、在线教育等(这些应用里的实时音视频功能一般都会涉及到P2P),了解P2P的原理对于开发相关的应用来讲仍是颇有必要的。编程

基础知识

简单介绍一下 详细了解请翻阅他的上下篇文章

什么是NAT?

NAT(Network Address Translation,网络地址转换),也叫作网络掩蔽或者IP掩蔽。NAT是一种网络地址翻译技术,主要是将内部的私有IP地址(private IP)转换成能够在公网使用的公网IP(public IP)。安全

为何会有NAT?

时光回到上个世纪80年代,当时的人们在设计网络地址的时候,以为再怎么样也不会有超过32bits位长即2的32次幂台终端设备连入互联网,再加上增长ip的长度(即便是从4字节增到6字节)对当时设备的计算、存储、传输成本也是至关巨大的。后来逐渐发现IP地址不够用了,而后就NAT就诞生了!(虽然ipv6也是解决办法,但始终普及不开来,并且将来到底ipv6够不够用还是未知)。服务器

所以,NAT技术可以兴起的缘由仍是由于在咱们国家公网IP地址太少了,不够用,因此才会采起这种地址转换的策略。可见,NAT的本质就是让一群机器公用同一个IP,这样就暂时解决了IP短缺的问题。网络

NAT有什么优缺点?

优点其实上面已经刚刚讨论过了,根据定义,比较容易看出,NAT能够同时让多个计算机同时联网,并隐藏其内网IP,所以也增长了内网的网络安全性;此外,NAT对来自外部的数据查看其NAT映射记录,对没有相应记录的数据包进行拒绝,提升了网络安全性。架构

那么,NAT与此同时也带来一些弊端:首先是,NAT设备会对数据包进行编辑修改,这样就下降了发送数据的效率;此外,各类协议的应用各有不一样,有的协议是没法经过NAT的(不能经过NAT的协议仍是蛮多的),这就须要经过穿透技术来解决。咱们后面会重点讨论穿透技术。并发

简单的背景了解事后,下面介绍下NAT实现的主要方式,以及NAT都有哪些类型。


socket

NAT的实现方式

静态NAT

也就是静态地址转换。是指一个公网IP对应一个私有IP,是一对一的转换,同时注意,这里只进行了IP转换,而没有进行端口的转换

image.png


高并发

NAPT

端口多路复用技术。与静态NAT的差异是,NAPT不但要转换IP地址,还要进行传输层的端口转换。具体的表现形式就是,对外只有一个公网IP,经过端口来区别不一样私有IP主机的数据

image.png


测试

NAT的主要类型

对于NAPT咱们主要分为两大类:锥型NAT和对称型NAT


其中锥型NAT又分:彻底锥型,受限锥型和端口受限锥型。

归纳的说:对称型NAT是一个请求对应一个端口;锥型NAT(非对称NAT)是多个请求(外部发向内部)对应一个端口,只要源IP端口不变,不管发往的目的IP是否相同,在NAT上都映射为同一个端口,形象的看起来就像锥子同样。

下面分别介绍这四种类型及其差别:


彻底锥型NAT(Full Cone NAT,后面简称FC)

特色:IP和端口都不受限。

表现形式:未来自内部同一个IP地址同一个端口号(IP_IN_A : PORT_IN_A)的主机监听/请求,映射到公网IP某个端口(IP_OUT_B : PORT_OUT_B)的监听。

任意外部IP地址与端口对其本身公网的IP这个映射后的端口访问(IP_OUT_B : PORT_OUT_B),都将从新定位到内部这个主机(IP_IN_A : PORT_IN_A)。该技术中,基于C/S架构的应用能够在任何一端发起链接。是否是很绕啊。

再简单一点的说,就是,只要客户端,由内到外创建一个映射(NatIP:NatPort -> A:P1)以后,其余IP的主机B或端口A:P2均可以使用这个洞给客户端发送数据。

image.png


受限锥型NAT(Restricted Cone NAT)

特色:IP受限,端口不受限。

表现形式:与彻底锥形NAT不一样的是,在公网映射端口后,并不容许全部IP进行对于该端口的访问,要想通讯必需内部主机对某个外部IP主机发起过链接,而后这个外部IP主机就能够与该内部主机通讯了,但端口不作限制。

举个栗子。当客户端由内到外创建映射(NatIP:NatPort –> A:P1),A机器可使用他的其余端口(P2)主动链接客户端,但B机器则不被容许。由于IP受限啦,可是端口随便。见下图(绿色是容许通讯,红色是禁止通讯)

image.png


端口受限型NAT(Port Restricted Cone NAT)

特色:IP和端口都受限。

表现形式:该技术与受限锥形NAT相比更为严格。除具备受限锥形NAT特性,对于回复主机的端口也有要求。也就是说:只有当内部主机曾经发送过报文给外部主机(假设其IP地址为A且端口为P1)以后,外部主机才能以公网IP:PORT中的信息做为目标地址和目标端口,向内部主机发送UDP报文,同时,其请求报文的IP必须是A,端口必须为P1(使用IP地址为A,端口为P2,或者IP地址为B,端口为P1都将通讯失败)。例子见下图。这一要求进一步强化了对外部报文请求来源的限制,从而较Restrictd Cone更具安全性



image.png


对称型NAT(Symmetric NAT)

特色:对每一个外部主机或端口的会话都会映射为不一样的端口(洞)。

表现形式:只有来自同一内部IP:PORT、且针对同一目标IP:PORT的请求才被NAT转换至同一个公网(外部)IP:PORT,不然的话,NAT将为之分配一个新的外部(公网)IP:PORT。

而且,只有曾经收到过内部主机请求的外部主机才能向内部主机发送数据包。内部主机用同一IP与同一端口与外部多IP通讯。客户端想和服务器A(IP_A:PORT_A)创建链接,是经过NAT映射为NatIP:NatPortA来进行的。而客户端和服务器B(IP_B:PORT_B)创建链接,是经过NAT映射为NatIP:NatPortB来进行的。即同一个客户端和不一样的目标IP:PORT通讯,通过NAT映射后的公网IP:PORT是不一样的。此时,若是B想要和客户端通讯,也只能经过NatIP:NatPortB(也就是紫色的洞洞)来进行,而不能经过NatIP:NatPortA(也就是黄色的洞洞)



image.png


小结

能够看出从类型1至类型4,NAT的限制是愈来愈大的。




NAT路由类型判断

根据上面的介绍,咱们能够了解到,在实际的网络状况中,各个设备所处的网络环境是不一样的。那么,若是这些设备想要进行通讯,首先判断出设备所处的网络类型就是很是重要的一步。

举个例子来讲:对于IM中的实时音视频功能和VoIP软件,对位于不一样NAT内部的主机通讯须要靠服务器来转发完成,这样就会增长服务器的负担。

为了解决这种问题,要尽可能使位于不一样NAT内部的主机创建直接通讯,其中,最重要的一点就是要判断出NAT的类型,而后才能根据NAT的类型,设计出直接通讯方案。否则的话,两个都在NAT的终端怎么通讯呢?咱们不知道对方的内网IP,即便把消息发到对方的网关,而后呢?网关怎么知道这条消息给谁,并且谁容许网关这么作了?

为了解决这个问题,也就是处于内网的主机之间可以穿越它们之间的NAT创建直接通讯,已经提出了许多方法,STUN(Session Traversal Utilities for NAT,NAT会话穿越应用程序)技术就是其中比较重要的一种解决方法,并获得了普遍的应用。在这个部分,咱们将重点介绍下STUN技术的原理。

PS:除此以外,还有UPNP技术,ALG应用层网关识别技术,SBC会话边界控制,ICE交互式链接创建,TURN中继NAT穿越技术等等,本文不一一作介绍。

STUN协议介绍

STUN基本介绍

STUN是一种网络协议,它容许位于NAT(或多重NAT)后的客户端找出本身的公网地址,查出本身位于哪一种类型的NAT以后以及NAT为某一个本地端口所绑定的Internet端端口。这些信息被用来在两个同时处于NAT路由器以后的主机之间创建UDP通讯。该协议由RFC 5389定义。



STUN由三部分组成:

  • STUN客户端;
  • STUN服务器端;
  • NAT路由器。

STUN服务端部署在一台有着两个公网IP的服务器上,大概的结构参考下图。STUN客户端经过向服务器端发送不一样的消息类型,根据服务器端不一样的响应来作出相应的判断,一旦客户端得知了Internet端的UDP端口,通讯就能够开始了



image.png


STUN的检测过程

STUN协议定义了三类测试过程来检测NAT类型:

  • Test1:STUN Client经过端口{IP-C1:Port-C1}向STUN Server{IP-S1:Port-S1}发送一个Binding Request(没有设置任何属性)。STUN Server收到该请求后,经过端口{IP-S1:Port-S1}把它所看到的STUN Client的IP和端口{IP-M1,Port-M1}做为Binding Response的内容回送给STUN Client。
  • Test1#2:STUN Client经过端口{IP-C1:Port-C1}向STUN Server{IP-S2:Port-S2}发送一个Binding Request(没有设置任何属性)。STUN Server收到该请求后,经过端口{IP-S2:Port-S2}把它所看到的STUN Client的IP和端口{IP-M1#2,Port-M1#2}做为Binding Response的内容回送给STUN Client。
  • Test2:STUN Client经过端口{IP-C1:Port-C1}向STUN Server{IP-S1:Port-S1}发送一个Binding Request(设置了Change IP和Change Port属性)。STUN Server收到该请求后,经过端口{IP-S2:Port-S2}把它所看到的STUN Client的IP和端口{IP-M2,Port-M2}做为Binding Response的内容回送给STUN Client。
  • Test3:STUN Client经过端口{IP-C1:Port-C1}向STUN Server{IP-S1:Port-S1}发送一个Binding Request(设置了Change Port属性)。STUN Server收到该请求后,经过端口{IP-S1:Port-S2}把它所看到的STUN Client的IP和端口{IP-M3,Port-M3}做为Binding Response的内容回送给STUN Client。

STUN协议的输出是:

  • 1)公网IP和Port;
  • 2)防火墙是否设置;
  • 3)客户端是否在NAT以后,及所处的NAT的类型。

所以咱们进而整理出,经过STUN协议,咱们能够检测的类型一共有如下七种:

  • A:公开的互联网IP:主机拥有公网IP,而且没有防火墙,可自由与外部通讯;
  • B:彻底锥形NAT;
  • C:受限制锥形NAT;
  • D:端口受限制形NAT;
  • E:对称型UDP防火墙:主机出口处没有NAT设备,但有防火墙,且防火墙规则以下:从主机UDP端口A发出的数据包保持源地址,但只有从以前该主机发出包的目的IP/PORT发出到该主机端口A的包才能经过防火墙;
  • F:对称型NAT;
  • G:防火墙限制UDP通讯。

STUN协议的判断过程

输入和输出准备好后,附上一张维基百科的流程图,就能够描述STUN协议的判断过程了。



image.png

STEP1:检测客户端是否有能力进行UDP通讯以及客户端是否位于NAT后 -- Test1
客户端创建UDP socket,而后用这个socket向服务器的(IP-1,Port-1)发送数据包要求服务器返回客户端的IP和Port,客户端发送请求后当即开始接受数据包。重复几回。

  • 若是每次都超时收不到服务器的响应,则说明客户端没法进行UDP通讯,多是:G防火墙阻止UDP通讯;
  • 若是能收到回应,则把服务器返回的客户端的(IP:PORT)同(Local IP: Local Port)比较:
  •   - 若是彻底相同则客户端不在NAT后,这样的客户端是:A具备公网IP能够直接监听UDP端口接收数据进行通讯或者E。
  •   - 不然客户端在NAT后要作进一步的NAT类型检测(继续)。

STEP2:检测客户端防火墙类型 -- Test2
STUN客户端向STUN服务器发送请求,要求服务器从其余IP和PORT向客户端回复包:

  • 收不到服务器从其余IP地址的回复,认为包前被前置防火墙阻断,网络类型为E;
  • 收到则认为客户端处在一个开放的网络上,网络类型为A。

STEP3:检测客户端NAT是不是FULL CONE NAT -- Test2
客户端创建UDP socket而后用这个socket向服务器的(IP-1,Port-1)发送数据包要求服务器用另外一对(IP-2,Port-2)响应客户端的请求往回发一个数据包,客户端发送请求后当即开始接受数据包。 重复这个过程若干次。

  • 若是每次都超时,没法接受到服务器的回应,则说明客户端的NAT不是一个Full Cone NAT,具体类型有待下一步检测(继续);
  • 若是可以接受到服务器从(IP-2,Port-2)返回的应答UDP包,则说明客户端是一个Full Cone NAT,这样的客户端可以进行UDP-P2P通讯。

STEP4:检测客户端NAT是不是SYMMETRIC NAT -- Test1#2

  • 客户端创建UDP socket而后用这个socket向服务器的(IP-1,Port-1)发送数据包要求服务器返回客户端的IP和Port, 客户端发送请求后当即开始接受数据包。 重复这个过程直到收到回应(必定可以收到,由于第一步保证了这个客户端能够进行UDP通讯)。
  • 用一样的方法用一个socket向服务器的(IP-2,Port-2)发送数据包要求服务器返回客户端的IP和Port。
  • 比较上面两个过程从服务器返回的客户端(IP,Port),若是两个过程返回的(IP,Port)有一对不一样则说明客户端为Symmetric NAT,这样的客户端没法进行UDP-P2P通讯(检测中止)由于对称型NAT,每次链接端口都不同,因此没法知道对称NAT的客户端,下一次会用什么端口。不然是Restricted Cone NAT,是否为Port Restricted Cone NAT有待检测(继续)。

STEP5:检测客户端NAT是Restricted Cone 仍是 Port Restricted Cone -- Test3
客户端创建UDP socket而后用这个socket向服务器的(IP-1,Port-1)发送数据包要求服务器用IP-1和一个不一样于Port-1的端口发送一个UDP 数据包响应客户端, 客户端发送请求后当即开始接受数据包。重复这个过程若干次。若是每次都超时,没法接受到服务器的回应,则说明客户端是一个Port Restricted Cone NAT,若是可以收到服务器的响应则说明客户端是一个Restricted Cone NAT。以上两种NAT均可以进行UDP-P2P通讯。

经过以上过程,至此,就能够分析和判断出客户端是否处于NAT以后,以及NAT的类型及其公网IP,以及判断客户端是否具有P2P通讯的能力了。

相关文章
相关标签/搜索