你不知道的TCP协议

一. 概述

       运输层提供应用进程之间的逻辑通信,而TCP协议作为运输层最重要的两个协议之一,提供了面向连接,可靠传输的特性。本文并不介绍TCP协议的各个环节(因为无论是网络资料还是书籍都大量介绍),而是针对一些具体环节的问题,向读者解释。本文以QA的形式组织内容。

二. 主要内容

Q1:TCP在可靠运输中如何确定重传时间?

A1:采用了自适应算法,并结合Karn算法区分有效和无效的往返时间样本。

       在TCP协议中,重传的概念是简单的,但是重传时间的确认是TCP最复杂的问题之一。因为TCP下层是互联网环境(未知),而且每个IP数据报选择的路由不同。如果把超时重传时间设置过短,会导致不必要的重传,增大网络负荷;如果把超时重传时间设置过长,会增大网络的空闲时间,降低了传输效率。因此,需要有一个合理的算法来确定这个重传时间。

       在TCP协议中采用了自适应算法来进行重传时间的确定。通过记录一个报文段发出的时间以及收到确认的时间,这两个时间之差就是报文段的往返时间RTT,而RTTs是加权平均往返时间。因此,新的RTTs时间计算公式为:

新的RTTs=(1-a) x 旧的RTTs + a x 新的RTT样本

       通过上述公式,计算得出一个较为合理的RTTs。而超时计算器设置的超时时间RTO为:

RTO = RTTs + 4 x RTTd
RTTd = (1-β) x 旧的RTTd + β x |RTTs - 新的RTT样本|

       根据RFC6298文档,a,β的值分别为0.125,0.25。

       但是,这里面还有另一个问题,在超时重传后并收到了确认报文,此时并不知道收到的确认报文是对原来报文段的确认,还是对重传报文段的确认。为了解决这个问题,我们引入了Karn算法。

       Karn的主要内容为,在计算加权平均RTTs时,只要报文段重传了,就不采用其往返时间样本,这样子得出的RTTs和RTO就较为准确。后面我们又做了一次修正,修正后的Karn算法内容为,报文段每重传一次,就把超时重传时间RTO增大一些(取新的重传时间为旧的重传时间的2倍)。当不再发生报文段重传时,才重新计算超时重传时间RTO。最终,通过Karn算法区分有效和无效的往返时间样本,改进了往返时间的测量,使计算结果更加合理。

Q2:收到的报文段没有差错,只是不按序号,能否只重传缺少的数据?

A2:可以在TCP报文首部中指定"选择确认SACK"的选项。

       我们知道,在TCP协议中,收到的确认都是对这个序号之前的数据进行确认,如果中间某些数据缺少了,那么一般情况下,除了缺少的数据,后面提前收到的数据也会重传。

       那么,假设TCP接收方接收发送方的数据后,发现数据序号不连续,只要数据在接收窗口之内,接收方就收下这些数据,并把这些信息准确告诉发送方,使发送方不再重复发送这些已收到的数据,是否可以呢?答应是肯定的。

       当需要使用这种方式时,则在建立TCP连接时,就会在TCP报文首部中加上"允许SACK"的选项,使用后,需要在TCP报文段的首部中报告收到的不连续的字节块的边界,由于TCP的首部选项最多只有40字节,因此在选项中最多只能指明4个字节块的边界信息(8个边界一共32个字节,另外还需要1个SACK选项字节,以及1个长度字节(说明这个选项要占多少字节))。当发送方收到SACK后,目前大多数的实现还是重传所有未被确认的数据块。

Q3:TCP流量控制与拥塞控制的区别?

A3:它们有共同点,同时也有区别。

共同点:在控制控制中,某些拥塞控制算法是向发送端发送控制报文,这与流量控制相似。

区别:

1. 拥塞控制是一个全局性的过程(涉及所有的主机,路由器,以及其他影响因素),而流量控制主要针对点对点通信量的控制,端到端的问题(接收端控制发送端);

2. 拥塞控制目的是防止过多的数据注入到网络中,使得网络中的路由器或链路不致过载,而流量控制是通过抑制发送端发送数据的速率,使接收端来得及接收;

3. 拥塞控制的前提需要网络能够承受现有的网络负荷,而流量控制不需要;

Q4:在TCP的拥塞控制中,如何主动管理路由器的队列?

A4:通过主动队列管理AQM。

       假设一个路由器对某些分组处理时间长,这会导致这些分组很长时间才能到达终点,导致了重传,但实际上网络并没有拥塞。网络层策略对TCP拥塞控制影响最大的就是分组丢弃策略。该策略就是,由于路由器队列长度有限,当长度到达最大长度时,后面到来的分组就会丢弃(尾部丢弃策略)。而这些尾部丢弃会导致一连串分组的丢失,导致一群TCP连接进行拥塞控制的慢开始阶段,放慢发送速率,这种情况下由于影响到了多条TCP连接,这种称为全局同步。最终,全局同步导致全网通信量下降。

       因此,我们可以通过主动队列管理AQM解决。主动就是不要等到路由器的队列长度达到最大值时才丢弃后面的分组,而是达到某个值得警惕的数值时,就主动丢弃到达的分组。下面介绍曾经流行多年的随机早期检测(RED)算法:

1. 若平均队列长度小于最小门限,则把新到达的分组放入队列进行排队;

2. 若平均队列长度超过最大门限,则把新到达的分组丢弃;

3. 若平均队列长度在最小门限和最大门限之间,则按照某一丢弃概率p把新到达的分组丢弃(体现了丢弃分组的随机性);

       通过RED,我们可以在检测到网络拥塞的早期征兆时,就以概率p丢弃个别的分组,让拥塞控制只是在别的TCP连接上进行,以避免发生全局性的拥塞控制。

Q5:如何针对TCP的三次握手组织进攻,使服务器崩溃?

A5:通过SYN攻击。

       在三次握手过程中,Server发送SYN-ACK之后,收到Client的ACK之前的TCP连接称为半连接(half-open connect),此时Server处于SYN_RCVD状态,当收到ACK后,Server转入ESTABLISHED状态。

       SYN攻击就是Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server回复确认包,并等待Client的确认,由于源地址是不存在的,因此,Server需要不断重发直至超时,这些伪造的SYN包将长时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络堵塞甚至系统瘫痪。

       SYN攻击是一种典型的DDOS攻击,检测SYN攻击的方式非常简单,即当Server上有大量半连接状态且源IP地址是随机的,则可以断定遭到SYN攻击了,使用如下命令可以让之现行:netstat -nap | grep SYN_RECV

三. 总结

最后,做个简单的小结:

1. TCP可靠传输的设计非常巧妙,其中包括对超时重传时间的设计,以及如何做选择确认;

2. TCP拥塞控制和流量控制虽然实现类似,但两者在问题的出发点上不同,一个从大局出发,另一个针对的是局部甚至某一点;

3. TCP拥塞控制需要结合流量控制,才能更好发挥,其中主动队列管理AQM就是一个证明;

4. TCP三次握手存在缺陷,典型的攻击是SYN攻击,可以通过netstat命令看是否遭受SYN攻击;

发布了19 篇原创文章 · 获赞 20 · 访问量 5849

猜你喜欢

转载自blog.csdn.net/qq_15898739/article/details/102831987