MPTCP协议学习
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MPTCP协议学习相关的知识,希望对你有一定的参考价值。
对MPTCP协议理论部分的学习进行了整理,文中数据包结构的图来自于RFC6824。详见http://www.rfcreader.com/#rfc6824
MPTCP协议学习
MPTCP目的:随着技术的发展许多设备具有了多个网络接口,而TCP依然是一个单线路的协议,在TCP的通信过程中发端和收端都不能随意变换地址。我们可以利用多个网络接口的这一特性来改善性能和有效冗余。
例如:手中的 iPhone 同时开启了 4G 和 WiFi 连接(大多数情况也是这样),这个时候我通过 App Store 更新一个 100M 的软件。按照以往的情况,App Store 的软件更新是会优先通过 WiFi 进行的,44G 在此刻是闲置状态。但是在 Multipath TCP 的支援下,尽管只通过 App Store 更新一个软件,建立起了一个网络连接,但是它却可以同时利用 3G 和 WiFi 建立 Mutlpath 连接,通过多点优化网络下载,且互为备份。假如这个时候 WiFi 断了,以前的情况是,App Store 更新中断,需要人工干预恢复或重新下载。而在 Mutlipath TCP 的优化下,只要 3G 没断,App Store 就能继续更新下载。除非 3G 也断了,才宣告此次连接失败。
而Multipath TCP可以在一条TCP链接中包含多条路径,避免上述问题出现。
简单来说:MPTCP允许在一条TCP链路中建立多个子通道。当一条通道按照三次握手的方式建立起来后,可以按照三次握手的方式建立其他的子通道,这些通道以三次握手建立连接和四次握手解除连接。这些通道都会绑定于MPTCP session,发送端的数据可以选择其中一条通道进行传输。
MPTCP的设计遵守以下两个原则:1. 应用程序的兼容性,应用程序只要可以运行在TCP环境下,就可以在没有任何修改的情况下,运行于MPTCP环境。2. 网络的兼容性,MPTCP兼容其他协议。协议栈中的位置:同TCP一样处于传输层。
头部选项在TCP头部和数据包内容之间,一个TCP包可能没有头部选项,也可能同时有好几个头部选项。TCP头部选项的格式如下,通过kind字段区分不同的头部选项。
TCP数据包格式:
源端口(16) |
目的端口(16) |
||
TCP序号(32) |
|||
捎带的确认(32) |
|||
首部长度(4) |
保留(6) |
FLAG(6) |
窗口尺寸(16) |
TCP校验和(16) |
紧急指针(16) |
||
选项和填充 |
|||
数据 |
TCP选项格式:
在做包解析的时候,根据TCP头部选项的kind值就可以判断该包是否为MPTCP包了。
MPTCP选项的典型结构为
其中,kind字段表示该头部选项为MPTCP头部选项,kind=30。Length字段表示该头部选项的长度,subtype选项表示该MPTCP选项的子类型,剩下的字节则为该子类选项的具体数据。根据subtype值的不同,MPTCP选项的子类型有以下几种:
MPTCP建立连接过程:如图,MPTCP的第一个子通道的建立遵守TCP的三次握手,唯一的区别是每次发送的报文段需要添加MP_CAPABLE的的TCP选项和一个安全用途的key。而子通道的建立依需要四次握手,而TCP选项换成了MP_JOIN。而token是基于key的一个hash值,rand为一个随机数,而HMAC是基于rand的一个has
数据的发送和接收:MPTCP可以选择多条子通道中任意一条来发送数据。MPTCP在发送数据方面和TCP的区别是可以从多条路径中选择一条路径来发送数据,MPTCP在接收数据方面与TCP的区别是子路径对无序包进行重排后。
由于所有的数据会通过不同的子路径发送,在接收端MPTCP需要对数据进行重新排序。因此我们需要数据序号映射。数据序号映射定义从子路径序列空间到数据序列空间的映射。子路径的序列空间是子路径自身的序列号,而数据序列空间维护着所有需发送的数据。如下图
红色子路径上的子路径序号分别是1、2,其数据序号是1000、1002。而下面的蓝色的子路径上的子路径序号和数据序号分别是200,1001。这说明从下面的蓝色子路径已经发送了199个报文,而上面的红色子路径才开始发送。在MPTCP协议定义如下:
MPTCP的接收包过程分为两个阶段:第一、每个子通道依据自身序号来重组报文段;第二、MPTCP的控制模块依据DSN对所有子通道的报文段进行重组。
拥塞控制:
MPTCP的拥塞控制对TCP的拥塞控制的线性增加阶段进行了修改,而慢启动,快速重传、快速恢复都没有改变。每条子路径拥有自己的cwnd,MPTCP的拥塞算法主要关心cwnd的改变。
拥塞算法设计原则:
MPTCP的Throughput 要达到MPTCP中所有子路径中最好的一条路径
MPTCP应该和普通TCP一样从共享资源中获得相同资源
MPTCP中的流量将从拥塞的子路径转移到不拥塞的路径
关于传统TCP协议中的拥塞控制:
几种拥塞控制的方法:慢开始( slow-start )、拥塞避免( congestion avoidance )、快重传( fast retransmit )和快恢复( fast recovery )、选择性应答( selective acknowledgement,SACK)算法。
慢开始算法:当主机开始发送数据时,如果立即所大量数据字节注入到网络,那么就有可能引起网络拥塞,因为现在并不清楚网络的负荷情况。因此,较好的方法是先探测一下,即由小到大逐渐增大发送窗口,也就是说,由小到大逐渐增大拥塞窗口数值。
为了防止拥塞窗口cwnd增长过大引起网络拥塞,还需要设置一个慢开始门限ssthresh状态变量(如何设置ssthresh)。慢开始门限ssthresh的用法如下:
当 cwnd < ssthresh 时,使用上述的慢开始算法。
当 cwnd > ssthresh 时,停止使用慢开始算法而改用拥塞避免算法。
当 cwnd = ssthresh 时,既可使用慢开始算法,也可使用拥塞控制避免算法。
拥塞避免算法:让拥塞窗口cwnd缓慢地增大,即每经过一个往返时间RTT就把发送方的拥塞窗口cwnd加1,而不是加倍。这样拥塞窗口cwnd按线性规律缓慢增长,比慢开始算法的拥塞窗口增长速率缓慢得多。
快重传算法:快重传算法首先要求接收方每收到一个失序的报文段后就立即发出重复确认(为的是使发送方及早知道有报文段没有到达对方)而不要等到自己发送数据时才进行捎带确认。
快重传算法还规定,发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文段M3,而不必继续等待M3设置的重传计时器到期。
与快重传配合使用的还有快恢复算法,其过程有以下两个要点:
<1>. 当发送方连续收到三个重复确认,就执行“乘法减小”算法,把慢开始门限ssthresh减半。这是为了预防网络发生拥塞。请注意:接下去不执行慢开始算法。
<2>. 由于发送方现在认为网络很可能没有发生拥塞,因此与慢开始不同之处是现在不执行慢开始算法(即拥塞窗口cwnd现在不设置为1),而是把cwnd值设置为慢开始门限ssthresh减半后的数值,然后开始执行拥塞避免算法(“加法增大”),使拥塞窗口缓慢地线性增大。
选择性应答:改变TCP的确认机制,最初的TCP只确认当前已连续收到的数据,SACK则把乱序等信息会全部告诉对方,从而减少数据发送方重传的盲目性。比如说序号1,2,3,5,7的数据收到了,那么普通的ACK只会确认序列号4,而SACK会把当前的5,7已经收到的信息在SACK选项里面告知对端,从而提高性能,当使用SACK的时候,NewReno算法可以不使用,因为SACK本身携带的信息就可以使得发送方有足够的信息来知道需要重传哪些包,而不需要重传哪些包。
另外还有Limited transmit(RFC3042)。这个算法是在拥塞窗口比较小的时候如果在一个传输窗口内有多个包丢失时比较有效率的恢复算法。之前已经讲过,TCP有一个快速恢复的机制,而快速恢复的前提是收到3个重复ACK。然而,接收方发送重复ACK却又需要乱序包的到达才可以触发,TCP在每收到一个乱序包就会立即发送一个重复的ACK给发送端。如果拥塞窗口比较小的时候会发生情况呢?发送方和接收方进入一段互相等待的状况,接收方等待再收到一个包于是发生重复ACK,而发送方却等待第3个重复ACK,如果窗口较小,例如为3,如果此时第一个包丢失了,接收方对第二个和第三个包分别发送了重复ACK,总共两个重复ACK,此时发送端由于窗口的关系不能再发送数据,此时双方进入互等,直到发送方的重传超时计时器到,才能打破该僵局,显然如果是这样的话效率就明显降低,因为重传超时的时间设置为RTT+4×RTTVar,一般该值都比较大。
Limited Transmit就是为了解决这种情况的,它的方法很简单,那就是当收到两个重复ACK时,检测两个条件:
1)接收方的通告窗口rwnd是否允许传输新的数据包,即是否满足rwnd>cwnd?
2)停留在网络中的数据包个数是否小于或等于cwnd+2?
如果这两个条件都满足的话,那么TCP再发送新的数据包,其实第二个条件换个意思理解就是说在这种情况下可以超出拥塞窗口最多再发送两个数据包。假设新的数据包和相应的ACK不被丢失的话,那么有了这两个新的数据包,从而双方可以立即从僵局中恢复出来,发送方接着进入标准的快速恢复。注意的是尽管可以发送两个新的数据包,但是cwnd的值要保持不变,而不能把它增加2。显然Limited Transmit算法比利用超时重传在包乱序时具有更好的鲁棒性
协议学习过程中遇到的一些名词:
head-of-line blocking:
输入排队最主要的缺点是存在对头阻塞(HOL Blocking)现象。这是比较容易理解的。在一条入线上输入队列中缓存的输入信元,其目的出现通常情况下各不相同。如果对头的信元因为竞争失败而暂时无法得到服务,那么对头信元的等待将使整个队列中所有信元被迫等待。例如,假定某入线I1的对头信元的目的出线为O1,恰巧另一条入线I2的对头信元的目的出线也是O1。仲裁逻辑判定入线I2首先获得服务,入线I1上的信元则必须等待。这将导致整个入线I1的输入队列中的后续信元进入等待。即使I1队列中的后续的第2个信元的目的是另外某个出线Ox,且Ox当时正处于空闲状态,该信元也不能被服务,因为该信元牵头的对头信元阻挡着它的传送
DoS/DDoS:
DoS:最常见的DoS攻击有对计算机网络的带宽攻击和连通性攻击。带宽攻击指以极大的通信量冲击网络,使得所有可用网络资源都被消耗殆尽,最后导致合法的用户请求无法通过。连通性攻击指用大量的连接请求冲击计算机,使得所有可用的操作系统资源都被消耗殆尽,最终计算机无法再处理合法用户的请求
DDoS:传统上,攻击者所面临的主要问题是网络带宽,由于较小的网络规模和较慢的网络速度的限制,攻击者无法发出过多的请求。虽然类似“the ping of death”的攻击类型只需要较少量的包就可以摧毁一个没有打过补丁的UNIX系统,但大多数的DoS攻击还是需要相当大的带宽的,而以个人为单位的黑客们很难使用高带宽的资源。为了克服这个缺点,DoS攻击者开发了分布式的攻击。攻击者简单利用工具集合许多的网络带宽来同时对同一个目标发动大量的攻击请求,这就是DDoS(Distributed Denial of Service)攻击。
SYN attack:
SYN Flood是一种广为人知的DoS(拒绝服务攻击)是DDoS(分布式拒绝服务攻击)的方式之一,这是一种利用TCP协议缺陷,发送大量伪造的TCP连接请求,从而使得被攻击方资源耗尽(CPU满负荷或内存不足)的攻击方式
half-open:
TCP的半开连接(half-open)是指TCP连接的一端崩溃,或者在未通知对端的情况下移除socket,不可以正常收发数据,否则会产生RST。
TCP的半关闭是指TCP连接的一端调用shutdown操作使数据只能往一个方向流动,只有一方发送了FIN,仍然可以正常收(或发)数据
以上是关于MPTCP协议学习的主要内容,如果未能解决你的问题,请参考以下文章