TCP 重发和RST探究

来源:互联网 发布:西宁c软件 编辑:程序博客网 时间:2024/06/05 16:08

先说说重发机制

超时发送的机制:

一般情况下,发送方发送一个TCP的片段,将开始计时,等待返回ACK,假如接受方收到了正确的片段,则返回ack,发送方收到后,移动窗口。如果,计时完成,依旧没有Ack,则认为丢失,重发,这个等待时间叫做(RTO,发送超时时间。RTT设置得根据当前网络情况,状态好,设的小一点,不好则要大一点,发送方会测量RTT(从发送片段,到接收到ACK的时间),每次都作为样本,然后计算mean平均值和std标准差,然后RTO = mean + 4td(这只是其中一种写法和平台有关),假如多次不行,就会发rst,表示我放弃)

快速重新发送:

首先会有这个一个情况,接收方收到12345679,10,唯独没有8,收到9的时候会返回一个ack8,收到10时则再返回一个ack8,假如发送方收到了3个ack8,则认为8丢失,不管计数器,直接重新发8。


这是重发的俩种机制,面试的时候,记不清楚了,都没有答到点子上。


接着是RST,

什么时候发送RST包

1:建立连接时,SYN达到某端口,但是该端口没有监听服务(具体的如果对客户的SYN的响应是RST,则表明该服务器主机在我们指定的端口上没有进程在等待与之连接(例如服务器进程也许没有启动),这称为硬错(hard error),客户一接收到RST,马上就返回错误ECONNREFUSED.)

2:TCP收到了一个根本不存在的连接上的分节(如果服务器主机与客户端建立连接后崩溃,如果此时,客户端向服务器发送数据,而服务器已经崩溃不能响应客户端ACK,客户TCP将持续重传数据分节,试图从服务器上接收一个ACK,如果服务器一直崩溃客户端会发现服务器已经崩溃或目的地不可达,但可能需要比较长的时间; 如果服务器在客户端发现崩溃前重启,服务器的TCP丢失了崩溃前的所有连接信息,所以服务器TCP对接收的客户数据分节以RST响应)

3:TCP想取消一个已有连接


顺便提一下RST攻击,我觉得部分情况可以解释上面的3

服务器A和服务器B之间建立了TCP连接,此时服务器C伪造了一个TCP包发给B,使B异常的断开了与A之间的TCP连接,这就是RST攻击。
那么伪造什么样的TCP包可以达成目的呢?我们至顶向下的看:
假定C伪装成A发过去的包,这个包如果是RST包的话,毫无疑问,B将会丢弃与A的缓冲区上所有数据,强制关掉连接;
如果发过去的包是SYN包,B会表示A已经发疯了(与OS的实现有关),正常连接时又来建新连接,B主动向A发个RST包,并在自己这端强制关掉连接;

(具体的攻击方法:这两种方式都能够达到复位攻击的效果。似乎挺恐怖,然而关键是C如何能伪造成A发给B的包呢?这里有两个关键因素,源端口和序列号。
一个TCP连接都是四元组,由源IP+源端口、目标IP+目标端口唯一确定一个连接。所以,如果C要伪造A发给B的包,要在上面提到的IP头和TCP头,把源IP、源端口、目标IP、目标端口都填对。这里B作为服务器,IP和端口是公开的,A是我们要下手的目标,IP当然知道,但A的源端口就不清楚了,因为这可能是A随机生成的。当然,如果能够对常见的OS如windows和linux找出生成source port规律的话,还是可以搞定的。
此外,伪造的TCP包里需要填序列号(SeqNum),如果序列号的值不在A之前向B发送时B的滑动窗口内,B是会主动丢弃的。所以我们要找到能落到当时的AB间滑动窗口的序列号。这个可以暴力解决,因为一个sequence长度是32位,取值范围0-4294967296,如果滑动窗口大小为65535的话,则最多只需要发65537(4294967296/65535=65537)个包就能有一个序列号落到滑动窗口内。RST包是很小的,IP头+TCP头也才40字节,算算我们的带宽就知道这实在只需要几秒钟就能搞定。)


看了黑皮书,感觉比较抽象,都是直接给你看现象,例子不明确。

参考的一个链接:http://www.cnblogs.com/chenny7/p/4708240.html

http://blog.sina.com.cn/s/blog_656b482a0102w6de.html

总之,人丑就要多读书,真的要多读书

原创粉丝点击