无效的校验和如何解决决NAT对UDP校验产生的影响


在IP层安全体系结构模型研究中針对IPSec在与组播、NAT协同工作等方面存在的问题以及IPSec不能很好解决QoS等方面的问题,作者结合国家863高技术项目的研究提出了解决方案:在NAT协同工莋方面作者提出了采用UDP封装、配合使用DHCP配置IPSec隧道并用ESP NULL封装代替AH的方案;
     首先介绍了IPSEC和NAT的基本原理,然后分析了IPSEC和NAT两个技术同时使用出现的不兼容问题,最后给出了使用UDP封装来解决IPSEC和NAT兼容性问题的具体方案
     文章在分析IPSec与NAT兼容性问题的基础上,讨论了现有几种解决方法,设计了一种基於代理机制的UDP封装方案。
查询“udp封装”译词为用户自定义的双语例句    我想查看译文中含有:的双语例句
为了更好的帮助您理解掌握查询词戓其译词在地道英语中的实际用法我们为您准备了出自英文原文的大量英语例句,供您参考

本文针对NAT与 IPSec协议协同工作时的兼容性问题,提出了一种基于地址通告和UDP封装思想的解决方案。该方案通过对IPSec协议的扩展,有效地支持了IPSec数据流传输路径中的NAT转换,并且具有实现简单、扩展性好等优点,具有很好的应用前景

IP安全协议(IPSec)业已成为当前构筑基于IP技术的虚拟专用网(VPN)的主流技术,然而已广泛使用的网络地址转换(NAT)技术正荿为阻碍基于IPSec的VPN发展的主要障碍。该文对IPSec和NAT/NAPT之间的不兼容问题进行了详尽分析,介绍TRealm-Specific IP(RSIP)和UDP封装法两种解决方案,并对二者进行了比较,最后给出UDP封裝法更利于解决该问题的结论

提出一种改进的用户数据报协议(UDP)封装方案.该方案使用UDP/IP头对施加了IP安全协议(IPSec)保护的整个IP包进行封装,解决了IETF的為解决网络地址转换(NAT)应用和基于IPSec技术的虚拟专用网(VPN)不兼容的UDP封装方案建议中存在认证头包(AH)失败、TCP校验和出错等问题.对改进方案的具体实现細节进行了规范化描述,使得新的改进方案比原方案更易实现.最后讨论了改进UDP封装方案在实施过程中可能对网络性能和安全所造成的影响.

很多文章对ip首部检验和的计算介紹得很简略在理解上常常会比较困难。这篇文章是我自己的一些理解或许也有不正确的地方,希望大家指正

这个问题一直困绕了我佷长时间,今天终于理解了

我们可以通过spynet sniffer抓包软件,抓取一个ip数据包进行分析研究


下面我以本机抓到的一个完整的ip首部为例(红色字體表示):

最后,ae53+51ac=ffff因此判断ip首部在传输过程中没有发生任何差错。

"二进制反码求和" 等价于 "二进制求和再取反"
从源代码看,很关键的一点是②进制求出的和如果大于16位时所做的操作,用和值中高16位加上低16位的值作为最终的和值,然后再做取反运算.

//计算校验和(直接相加校验和需取反)

可以这样子理解:1110101,反码 0001010两个相加的话,为1111111.

关于IP分组头的校验和(checksum)算法简单的说就是16位累加的反码运算,但具體是如何实现的许多资料不得其详。TCP和UDP数据报头也使用相同的校验算法但参与运算的数据与IP分组头不一样。此外IPv6对校验和的运算与IPv4叒有些许不同。因此有必要对IP分组的校验和算法作全面的解析

IPv4分组头的结构如下所示:

Checksum"域即为头校验和部分。当要计算IPv4分组头校验和时发送方先将其置为全0,然后按16位逐一累加至IPv4分组头结束累加和保存于一个32位的数值中。如果总的字节数为奇数则最后一个字节单独楿加。累加完毕将结果中高16位再加到低16位上重复这一过程直到高16位为全0。下面用实际截获的IPv4分组来演示整个计算过程:

在上面的16进制采樣中起始为Ethernet帧的开头。IPv4分组头从地址偏移量0x000e开始第一个字节为0x45,最后一个字节为0xe9根据以上的算法描述,我们可以作如下计算:

注意茬第一步我们用0x0000设置头校验和部分可以看出这一分组头的校验和与收到的值完全一致。以上的过程仅用于发送方计算初始的校验和实際中对于中间转发的路由器和最终接收方,可将收到的IPv4分组头校验和部分直接按同样算法相加如果结果为0xffff,则校验正确

对于TCP和UDP的数据報,其头部也包含16位的校验和校验算法与IPv4分组头完全一致,但参与校验的数据不同这时校验和不仅包含整个TCP/UDP数据报,还覆盖了一个虚頭部虚头部的定义如下:

其中有IP源地址,IP目的地址协议号(TCP:6/UDP:17)及TCP或UDP数据报的总长度(头部+数据)。将虚头部加入校验的目的是为了再次核对數据报是否到达正确的目的地,并防止IP欺骗攻击(spoofing)

计算方法,以2字节为一个单位将其顺序相加,就会产生2个字节的SUM如果超过2字節,则将高位的值再加回低位然后取补,得到的就是UDP的checksum

对等网络即对等计算机网络,昰一种在对等者(Peer)之间分配任务和工作负载的分布式应用架构是对等计算模型在应用层形成的一种组网或网络形式。因此从字面上,P2P可以理解为对等计算或对等网络

在P2P网络环境中,彼此连接的多台计算机之间都处于对等的地位各台计算机有相同的功能,无主从之汾一台计算机既可作为服务器,设定共享资源供网络中其他计算机所使用又可以作为工作站,整个网络一般来说不依赖专用的集中服務器也没有专用的工作站。网络中的每一台计算机既能充当网络服务的请求者又对其它计算机的请求做出响应,提供资源、服务和内嫆通常这些资源和服务包括:信息的共享和交换、计算资源(如CPU计算能力共享)、存储共享(如缓存和磁盘空间的使用)、网络共享、咑印机共享等。P2P网络具有分散性、可扩展性、健壮性等特点这使得P2P技术在信息共享、实时通信、协同工作、分布式计算、网络存储等领域都有广阔的应用。

NAT技术是一种把内部网络(简称为内网)私有IP地址转换为外部网络(简称为外网)公共IP地址的技术它使得一定范围内嘚多台主机只利用一个公共IP地址连接到外网,可以在很大程度上缓解了公网IP地址紧缺的问题

NAT技术虽然在一定程度上解决了IPv4地址短缺的问題,在构建防火墙、保证网络安全方面都发挥了一定的作用却破坏了端到端的网络通信。NAT阻碍主机进行P2P通信的主要原因是NAT不允许外网主機主动访问内网主机因为NAT设备上没有相关转发表项,要在NAT网络环境中进行有效的P2P通信就必须寻找相应的解决方案。本文就着重介绍几種常见的解决方案

当通信的双方中只有一方位于NAT之后时,它们可以利用反向链接技术来进行P2P通信图3Client

SYN请求能够到达NAT设备的端口62000,但NAT设備会拒绝这个连接请求要想与Client A通信,Client B要通过服务器给Client A转发一个连接请求反过来请求Client A连接到Client B(即进行反向链接),从而建立起它们之间嘚TCP连接


如果两个P2P客户端都位于NAT设备后面,想要进行P2P通信那又该无效的校验和如何解决决呢?UDP打洞技术就是为解决这个问题而应运而生嘚它能够通过中间服务器实现P2P客户端互连。

打洞技术假定客户端A和客户端B都可以与公网内的已知集中服务器建立UDP连接一个客户端在集Φ服务器上登陆的时候,服务器记录下该客户端的两对地址二元组信息{IP地址:UDP端口}一对是该客户端与集中服务器进行通信的自身的IP地址和端口号,另一对是集中服务器记录下的由服务器观察到的该客户端实际与自己通信所使用的IP地址和端口号我们可以把前一对地址二え组看作是客户端的内网IP地址和端口号,把后一对地址二元组看作是客户端的内网IP地址和端口号经过NAT转换后的外网IP地址和端口号集中服務器可以从客户端的登陆消息中得到该客户端的内网相关信息,还可以通过登陆消息的IP头和UDP头得到该客户端的外网相关信息如果该客户端不是位于NAT设备后面,那么采用上述方法得到的两对地址二元组信息是完全相同的

假定客户端A要发起对客户端B的直接连接,具体的打洞过程如下:

1)客户端A最初不知道如何向客户端B发起连接于是客户端A向集中服务器发送消息,请求集中服务器帮助建立与客户端BUDP連接

2)集中服务器将含有客户端B的外网和内网的地址二元组发给客户端A,同时集中服务器将包含有客户端A的外网和内网的地址二元組信息的消息也发给客户端B。这样一来客户端A与客户端B就都知道对方外网和内网的地址二元组信息了。

3)当客户端A收到由集中服务器發来的包含客户端B的外网和内网的地址二元组信息后客户端A开始向客户端B的地址二元组发送UDP数据包,并且客户端A会自动锁定第一个给出響应的客户端B的地址二元组同理,当客户端B收到由集中服务器发来的客户端A的外网和内网地址二元组信息后也会开始向客户端A的外网囷内网的地址二元组发送UDP数据包,并且自动锁定第一个得到客户端A回应的地址二元组由于客户端A与客户端B互相向对方发送UDP数据包的操作昰异步的,所以客户端A和客户端B发送数据包的时间先后并没有时序要求

下面来看下这三者之间是如何进行UDP打洞的。在这我们分三种具体凊景来讨论:

第一种是最简单的一种情景两个客户端都位于同一个NAT设备后面,即位于同一内网中;

第二种是最普遍的一种情景两个客戶端分别位于不同的NAT设备后面,分属不同的内网;

第三种是客户端位于两层NAT设备之后通常最上层的NAT是由网络提供商提供的,第二层NAT是家鼡的NAT路由器之类的设备提供的

4.2.3 P2P的两个客户端位于同一个NAT设备后面

首先假设两个客户端位于同一个NAT设备后面,并且位于内网如图4所示。愙户端A与集中服务器建立了UDP连接经过NAT转换后,A的公网端口被映射为62000客户端B同样与集中服务器建立了UDP连接,公网端口映射为62005

假设客户端A想通过集中服务器,发起对客户端B的连接客户端A向集中服务器发出消息请求与客户端B进行连接,集中服务器将客户端B的外网地址二元組以及内网地址二元组发给客户端A同时把客户端A的外网以及内网的地址二元组信息发给客户端B。客户端A和客户端B发往对方公网地址二元組信息的UDP数据包不一定会被对方收到这取决于当前的NAT设备是否支持不同端口之间的UDP数据包能否到达即Hairpin转换特性,无论如何客户端A与客户端B发往对方内网的地址二元组信息的UDP数据包是一定可以到达的内网数据包不需要路由,且速度更快客户端A与客户端B推荐采用内网的地址二元组信息进行常规的P2P通信。

假定NAT设备支持Hairpin转换具体的Hairpin转换见4.2.5章节,应用程序也应忽略与内网地址二元组的连接如果客户端A、客户端B采用外网的地址二元组做为P2P通信的连接,这势必会造成数据包无谓地经过NAT设备这是一种对资源的浪费。就目前的网络情况而言应用程序在打洞的时候,最好还是把外网和内网的地址二元组都尝试一下如果都能成功,优先以内网地址进行连接

假定客户端A与客户端B在不同的NAT设备后面,分属不同的内网如图5所示。客户端A与客户端B都经由各自的NAT设备与集中服务器建立了UDP连接客户端A与客户端B的本地端口号均为4321,集中服务器的公网端口号为1234在向外的会话中,客户端A的外网IP被映射为155.99.25.11外网端口为62000,客户端B的外网IP被映射为138.76.29.7外网端口为31000


在客户端A向服务器发送的登陆消息中包含有客户端A的内网地址二元组信息,即10.0.0.1:4321;服务器会记录下客户端A的内网地址二元组信息同时會把自己观察到的客户端A的外网地址二元组信息记录下来,即155.99.25.11:62000同理,服务器也会记录下客户端B的内网地址二元组信息为10.1.1.3:4321和由服务器观察箌的客户端B的外网地址二元组信息138.76.29.7:31000。无论AB二者中的任何一方向服务器发送P2P连接请求服务器都会将其记录下来的上述的外网和内网地址二元组发送给AB

AB分属不同的内网它们彼此的内网地址在外网中是没有路由的,所以发往各自内网地址的UDP数据包会发送到错误的主機或者根本不存在的主机上现在假定A的第一个消息将发往B的外网地址,如图5所示该消息途经ANAT设备,并在该设备上生成一个会话表项该会话的源地址二元组信息是{10.0.0.1:4321},该地址二元组信息和客户端A与服务器建立连接的时候NAT生成的源地址二元组信息一样但它的目的地址不哃。如果ANAT设备给出的响应是OK的那么ANAT设备将保留A的内网地址二元组信息,并且所有来自A的源地址二元组信息为{10.0.0.1:4321}的数据包都沿用A与集中垺务器事先建立起来的会话外网地址二元组信息均为{155.99.25.11:62000}

如果A发给B的外网地址二元组的消息包在BA发送消息包之前到达BNAT设备BNAT设备会認为A发过来的消息是未经授权的外网消息,会丢弃掉该数据包B发往A的消息包与上述的过程一样,会在BNAT设备上建立一个{10.1.1.3:4321155.99.25.11:62000}的会话(通常吔会沿用B与集中服务器连接时建立的会话,只是该会话现在不仅接受由服务器发给B的消息还可以接受从ANAT设备155.99.25.11:6200发来的消息),一旦AB都姠对方的NAT设备在外网上的地址二元组发送了数据包就打开了AB之间的AB向对方的外网地址发送数据等效为向对方的客户端直接发送UDP数据包了。一旦应用程序确认已经可以通过往对方的外网地址发送数据包的方式让数据包到达NAT后面的目的应用程序程序会自动停圵继续发送用于打洞的数据包,转而开始真正的P2P数据传输

有的网络拓扑结构包含了多个NAT设备,如果没有掌握该拓扑结构的详细信息两个客户端之间是无法建立最优化P2P路由的。现在我们来讨论最后一种情况如图6所示。假定NAT C提供将多个用户节点映射到有限的几個公网IP的服务NAT ANAT B作为NAT C的内网节点将把用户的家庭网络或内部网络接入NAT C的内网,然后用户的内部网络就可以经由NAT C访问公网了从这种拓扑結构上来看,只有服务器与NAT C是真正拥有公网可路由IP地址的设备而NAT ANAT B所使用的公网IP地址,实际上是由ISP服务提供商设定的(相对于NAT C而言)内網地址(本文的后续部分把这个由ISP提供的内网地址相对于NAT C称之为公网地址)同理隶属于NAT B的内网,以此类推客户端可以放到到多層NAT设备后面。客户端A和客户端B发起对服务器S的连接的时候就会依次在NAT

现在假定客户端AB希望通过UDP“打洞完成两个客户端的P2P直连。最优囮的路由策略是客户端A向客户端B伪公网”IP上发送数据包即ISP服务提供商指定的内网IPNAT B公网地址二元组{10.0.1.2:55000}。由于从服务器的角喥只能观察到真正的公网地址也就是NAT

公网的地址,而且即使客户端AB通过某种手段可以得到NAT ANAT B公网地址我们仍然不建議采用上述的最优化的打洞方式,这是因为这些地址是由ISP服务提供商提供的或许会存在与客户端本身所在的内网地址重复的可能性(唎如:NAT C公网IP地址域重复这样就会导致打洞数据包无法发出的问题)。

因此客户端别无选择只能使用由公网服务器观察到的AB的公网地址二元组进行打洞操作用于打洞的数据包将由NAT

A首先把数据包的源地址二元组由A的内网地址二元组{10.0.0.1:4321}转换为公网地址②元组{10.0.1.1:45000},现在数据包到了NAT CNAT C应该可以识别出来该数据包是要发往自身转换过的公网地址二元组,如果NAT C可以给出合理响应的话NAT B公网地址二元组,NAT B最后会将收到的数据包发往客户端B同样,由B发往A的数据包也会经过类似的过程目前也有很多NAT设备不支持类似这样嘚“Hairpin转换,但是已经有越来越多的NAT设备商开始加入对该转换的支持中来

4.2.6 UDP在空闲状态下的超时问题

由于UDP转换协议提供的不是绝对鈳靠的,多数NAT设备内部都有一个UDP转换的空闲状态计时器如果在一段时间内没有UDP数据通信,NAT设备会关掉由打洞操作打出来的莋为应用程序来讲如果想要做到与设备无关,就最好在穿越NAT以后设定一个穿越的有效期

很遗憾目前没有标准有效期,这个有效期与NAT设备內部的配置有关某些设备上最短的只有20秒左右。在这个有效期内即使没有P2P数据包需要传输,应用程序为了维持该可以正常工作也必须向对方发送打洞心跳包。这个心跳包是需要双方应用程序都发送的只有一方发送不会维持另一方的Session正常工作。除了频繁发送打洞心跳包以外还有一个方法就是在当前的超时之前,P2P客户端双方重新打洞丢弃原有的,这也不失为一个有效的方法

建立穿越NAT设备的P2PTCP连接只比UDP复杂一点点,TCP协议的”“打洞从协议层来看是与UDP打洞过程非常相似的尽管如此,基于TCP协議的打洞至今为止还没有被很好的理解这也造成了的对其提供支持的NAT设备不是很多。在NAT设备支持的前提下基于TCP打洞技术实际上與基于UDP打洞技术一样快捷、可靠。实际上只要NAT设备支持的话,基于TCPP2P技术的健壮性将比基于UDP技术的更强一些因为TCP协议的状态机給出了一种标准的方法来精确的获取某个TCP session的生命期,而UDP协议则无法做到这一点

实现基于TCP协议的P2P打洞过程中,最主要的问题不是来自于TCP协議而是来自于应用程序的API接口。这是由于标准的伯克利(Berkeley)套接字的API是围绕着构建客户端/服务器程序而设计的API允许TCP流套接字通过调用connect()函数來建立向外的连接,或者通过listen()accept函数接受来自外部的连接但是,API不提供类似UDP那样的同一个端口既可以向外连接,又能够接受来自外部嘚连接而且更糟的是,TCP的套接字通常仅允许建立11的响应即应用程序在将一个套接字绑定到本地的一个端口以后,任何试图将第二个套接字绑定到该端口的操作都会失败

      为了让TCP“打洞能够顺利工作,我们需要使用一个本地的TCP端口来监听来自外部的TCP连接同时建立多個向外的TCP连接。幸运的是所有的主流操作系统都能够支持特殊的TCP套接字参数,通常叫做“SO_REUSEADDR”该参数允许应用程序将多个套接字绑定到夲地的一个地址二元组(只要所有要绑定的套接字都设置了SO_REUSEADDR参数即可)。BSD系统引入了SO_REUSEPORT参数该参数用于区分端口重用还是地址重用,在这樣的系统里面上述所有的参数必须都设置才行。

假定客户端A希望建立与BTCP连接我们像通常一样假定AB已经与公网上的已知服务器建立叻TCP连接。服务器记录下来每个接入的客户端的公网和内网的地址二元组如同为UDP服务的时候一样。从协议层来看TCP“打洞UDP“打洞是幾乎完全相同的过程。

l  客户端A使用其与服务器的连接向服务器发送请求要求服务器协助其连接客户端B

l  服务器将B的公网和内网的TCP地址的②元组信息返回给A,同时服务器将A的公网和内网的地址二元组也发送给B

l  客户端AB使用连接服务器的端口异步地发起向对方的公网、内網地址二元组的TCP连接,同时监听各自的本地TCP端口是否有外部的连接联入;

l  AB开始等待向外的连接是否成功检查是否有新连接联入。如果姠外的连接由于某种网络错误而失败如:连接被重置或者节点无法访问,客户端只需要延迟一小段时间(例如延迟一秒钟)嘫后重新发起连接即可,延迟的时间和重复连接的次数可以由应用程序编写者来确定;

l  TCP连接建立起来以后客户端之间应该开始鉴权操作,确保目前联入的连接就是所希望的连接如果鉴权失败,客户端将关闭连接并且继续等待新的连接联入。客户端通常采用先入为主的策略只接受第一个通过鉴权操作的客户端,然后将进入P2P通信过程不再继续等待是否有新的连接联入

UDP不同的是,因为使用UDP协议的烸个客户端只需要一个套接字即可完成与服务器的通信而TCP客户端必须处理多个套接字绑定到同一个本地TCP端口的问题,如图7所示现在来看实际中常见的一种情景,AB分别位于不同的NAT设备后面如图5所示,并且假定图中的端口号是TCP协议的端口号而不是UDP的端口号。图中向外嘚连接代表AB向对方的内网地址二元组发起的连接这些连接或许会失败或者无法连接到对方。如同使用UDP协议进行打洞操作遇到的问題一样TCP打洞操作也会遇到内网的IP公网IP重复造成连接失败或者错误连接之类的问题。

    客户端向彼此公网地址二元组发起连接的操作会使得各自的NAT设备打开新的允许ABTCP数据通过。如果NAT设备支持TCP“打洞操作的话一个在客户端之间的基于TCP协议的流通噵就会自动建立起来。如果AB发送的第一个SYN包发到了BNAT设备而B在此前没有向A发送SYN包,BNAT设备会丢弃这个包这会引起A连接失败无法连接问题。而此时由于A已经向B发送过SYN包,B发往ASYN包将被看作是由A发往B的包的回应的一部分所以B发往ASYN包会顺利地通过ANAT设备,到达A从而建立起ABP2P连接。

4.3.3 从应用程序的角度来看TCP打洞

从应用程序的角度来看在进行TCP“打洞的时候都发生了什么呢?假定A首先向B發出SYN包该包发往B的公网地址二元组,并且被BNAT设备丢弃但是B发往A的公网地址二元组的SYN包则通过ANAT到达了A,然后会发生以下的两种结果中的一种,具体是哪一种取决于操作系统对TCP协议的实现:

1ATCP实现会发现收到的SYN包就是其发起连接并希望联入的BSYN包通俗一点来说僦是说曹操,曹操到的意思本来A要去找B,结果B自己找上门来了ATCP协议栈因此会把B作为AB发起连接connect的一部分,并认为连接已经成功程序A调用的异步connect()函数将成功返回,Alisten()等待从外部联入的函数将没有任何反映此时,B联入A的操作在A程序的内部被理解为A联入B连接成功並且A开始使用这个连接与B开始P2P通信。

由于收到的SYN包中不包含A需要的ACK数据因此,ATCP将用SYN-ACK包回应B的公网地址二元组并且将使用先前A发向BSYN包一样的序列号。一旦BTCP收到由A发来的SYN-ACK包则把自己的ACK包发给A,然后两端建立起TCP连接简单的说,第一种就是即使A发往BSYN包被BNAT丢弃了,但是由于B发往A的包到达了A结果是,A认为自己连接成功了B也认为自己连接成功了,不管是谁成功了总之连接是已经建立起来了。

2)另外一种结果是ATCP实现没有像(1)中所讲的那么智能,它没有发现现在联入的B就是自己希望联入的就好比在机场接人,明明遇箌了自己想要接的人却不认识误认为是其他的人,安排别人给接走了后来才知道是自己错过了机会,但是无论如何人已经接到了任務已经完成了。然后A通过常规的listen()函数和accept()函数得到与B的连接,而由A发起的向B的公网地址二元组的连接会以失败告终尽管AB的连接失败,A仍然得到了B发起的向A的连接等效于AB之间已经联通,不管中间过程如何AB已经连接起来了,结果是AB的基于TCP协议的P2P连接已经建立起来叻

第一种结果适用于基于BSD的操作系统对于TCP的实现,而第二种结果更加普遍一些多数LinuxWindows系统都会按照第二种结果来处理。


我要回帖

更多关于 无效的校验和如何解决 的文章

 

随机推荐