| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 网络协议 -> 再探 TCP/IP -> 正文阅读 |
|
[网络协议]再探 TCP/IP |
文章目录概念性的东西就不再赘述了,看着也累:温故Linux后端编程(四):膜拜《TCP/IP 卷一》 TCP连接的建立与终止TCP是一个面向连接的协议。无论哪一方向另一方发送数据之前,都必须先在双方之间建立一条连接。 三次握手为了建立一条TCP连接:
其中,双方的序号(Seq)的初始值(ISN)都是根据自身主机的时钟随机生成的,这也可以在一定程度上防止通信数据被伪造。 无论是建立连接还是终止连接,都会消耗一个序号,这从SYN包中seq值及对SYN应答包中的seq值、FIN包的seq值及对FIN应答包中的seq值可以看出来。 建立连接超时注意:对于报文段2(服务端的SYN+ACK),同样会存在超时重传。 服务端在发送该报文段(报文段2)时,会启动超时重传定时器,定时器一到,就会重传。 对于建立连接时,SYN包丢失,其重传间隔2倍方递增。当重传达到最大次数后,即发生丢包。默认是5次,间隔为 1s+2s+4s+8s+16s+32s=63s。Windows(win7)上的实现,是只重传两次(即总共3次),间隔为3s,6s。即在01秒发第1包,则04秒发重传包,10秒重传包。(SYN重传时间间隔,注意该时间间隔是OS实现时自身确定的,而与网络的实际状况(如畅通、拥塞)等无关) syn攻击SYN攻击是指发送方不断发送连接请求(第一个TCP包,SYN),待服务端发送回应(第2个TCP包,SYN+ACK),发送方收到服务端的回应后,却不再发送第3个TCP包。这样会造成服务端存在大量的打开的TCP连接(处于open状态,但并不是established状态),这样会消耗服务端大量的系统资源(Socket内核资源)。这就是SYN攻击。 服务端在收到客户端发来的SYN报文段后,会回复SYN+ACK报文段,此时这条连接已处于半打开状态,会将该半打开状态的连接放入一个队列(listen监听队列)。 需要注意的是,该回复的报文段(SYN+ACK)同样存在超时重传,如果一定时间内未收到客户端发来的ACK报文段,服务端则会重传SYN+ACK报文段。达到最大重传次数后,将该条半打开连接从队列中移除。 SYN攻击就是利用这个特点,不断发起SYN报文段,但却不回复对服务端SYN+ACK报文段的确认。造成服务端维护较多的半打开连接,消耗系统资源。而正常的连接请求,却因为资源不足而无法响应或响应缓慢。 发送方的实现方式有两种(使用WinPCap可实现):
这两种方式,对服务端来说,TCP服务端在发送了第2个TCP包后,都会一直得不到应答,直到超时。服务端会维持大量的这种状态的SOCKET。 为什么需要扰乱初始化序列号?一台PC它的ISN有自己的增长规律,如果它在ASA里面,有些攻击者他会不断的去连接PC,PC这时候就会不断的回复SYN,ACK。攻击者就能得到不同节点时间段的ISN,然后用这些不同时间段的ISN来计算出PC的ISN增长规律,通过判断ISN增长规律,攻击者就有可能判断出你的操作系统。 一台PC和某个主机已经建立了TCP连接,攻击者想做一个会话劫持,它需要伪装PC的IP地址、端口号、协议号。这些伪装了还是不行,还得知道你的序列号在什么范围。所以攻击者这时候也会通过多次探测来猜测ISN的增长规律,当得到ISN的增长规律会就会把PC干掉,攻击者自己连接到相应的主机。 所以ASA就要防止这些攻击者通过多次试探来获取PC的ISN增长规律,因为一旦PC的ISN增长规律被获取后,攻击者就可以对我的操作系统进行判断,而且还有可能造成更严重的会话劫持。所以ASA会对初始化序列号进行扰乱。 当PC在T1时刻发送SYN的时候,经过ASA,ASA会把T1时刻的ISN随机加一个数发走,在T2时刻发送SYN的时候,经过ASA,ASA又会把T2时刻的ISN随机加一个会减去一个数发走。由于ASA总是会在ISN的数上随机加上一个或者减去一个数,这样的话,攻击者在看你的ISN的时候就会觉得没有规律可寻。 四次挥手CLOSE_WAITE状态:TCP的半关闭TCP提供了连接的一端在结束它的发送后还能接收来自另一端数据的能力。这就是所谓的半关闭。 如果应用程序不调用 close而调用shutdown,且第2个参数值为1,则插口的API支持半关闭。然而,大多数的应用程序通过调用close终止两个方向的连接。 2MSL等待状态注意区分跟服务端的 close_wait状态,这个是time_wait状态。之前面试就有遇到这两种状态搞混了的,巨尴尬。 为什么客户端在TIME-WAIT阶段要等2MSL? 当客户端发出最后的ACK确认报文时,并不能确定服务器端能够收到该段报文。所以客户端在发送完ACK确认报文之后,会设置一个时长为2MSL的计时器。MSL指的是Maximum Segment Lifetime:一段TCP报文在传输过程中的最大生命周期。2MSL即是服务器端发出为FIN报文和客户端发出的ACK确认报文所能保持有效的最大时长。 RFC 793 [Postel 1981c] 指出MSL为2分钟。然而,实现中的常用值是30秒, 1分钟,或2分钟。总之,MSL是一个由OS指定的值,而不是根据网络的实际情况计算出来的。 (客户的 I P地址和端口号,服务器的 I P地址和端口号)不能再被使用。这个连接只能在 2 M S L结束后才能再被使用。 服务器端在1MSL内没有收到客户端发出的ACK确认报文,就会再次向客户端发出FIN报文; 如果客户端在2MSL内,再次收到了来自服务器端的FIN报文,说明服务器端由于各种原因没有接收到客户端发出的ACK确认报文。客户端再次向服务器端发出ACK确认报文,计时器重置,重新开始2MSL的计时;否则客户端在2MSL内没有再次收到来自服务器端的FIN报文,说明服务器端正常接收了ACK确认报文,客户端可以进入CLOSED阶段,完成“四次挥手”。 所以,客户端要经历时长为2SML的TIME-WAIT阶段;这也是为什么客户端比服务器端晚进入CLOSED阶段的原因。 端口被占用这时会引发一个问题: 1.如果发起断开连接的这一方是客户端,通常客户端不需要指定本地端口号,在断开连接后,重启程序,会重新随机选择一个本地端口再去连接服务器。客户端程序正常。 2.如果发起断开连接的这一方是服务端,通常服务端使用熟知的(固定的)监听端口号,在断开连接后,重启程序,服务端监听本地端口会失败,会提示端口被使用。这是因为该端口在上次主动断开连接后,还处理2MSL的time_wait状态。解决方法是设置监听端口的SO_REUSEADDR选项。注意:即使服务端设置了SO_REUSEADDR选项,使用服务端可以重用处理time-wait状态的端口,但仍不允许存在相同的连接。什么意思呢? 例如,服务器S 3.3.3.3 监听 3000端口,客户端 4.4.4.4,端口4000连接到S。这时,S主动断开连接,然后,重启了服务(服务端SOCKET设置了SO_REUSEADDR选项)。这时,如果客户端仍使用4000去建立连接,仍会提示连接失败 TCP的超时与重传数据包的超时重传 对于数据包(ACK包不是数据包),也会超时重传,在发生超时重传时,TCP不是以固定的时间间隔来重传的,而是会再每次重传时都将下一次重传的间隔设置为上次重传间隔的2倍,因此重传间隔是倍数增加的。直到收到确认或者彻底失败。由于正常发送报文段时,重传定时器的超时值为EstimateRTT + 4 * DevRTT,因此第一重传时会将下一次的超时时间设置为2倍的该值,依次类推。 TCP数据包重传的次数也根据系统设置的不同而有区分,有些系统,一个报文只会被重传3次,如果重传三次后还未收到该报文的确认,那么就不再尝试重传,直接reset重置该TCP连接,但有些要求很高的业务应用系统,则会不断的重传被丢弃的报文,以尽最大可能保证业务数据的正常交互。 拥塞避免算法慢启动算法是在一个连接上发起数据流的方法,但有时我们会达到中间路由器的极限,此时分组将被丢弃。拥塞避免算法是一种处理丢失分组的方法。 该算法假定由于分组受到损坏引起的丢失是非常少的(远小于 1 %),因此分组丢失就意味着在源主机和目的主机之间的某处网络上发生了拥塞。有两种分组丢失的指示:发送超时和接收到重复的确认。 拥塞避免算法和慢启动算法是两个目的不同、独立的算法。但是当拥塞发生时,我们希望降低分组进入网络的传输速率,于是可以调用慢启动来作到这一点。在实际中这两个算法通常在一起实现。 拥塞避免算法和慢启动算法需要对每个连接维持两个变量:一个拥塞窗口 cwnd和一个慢启动门限ssthresh。这样得到的算法的工作过程如下:
那样,这会使窗口按指数方式增长:发送 1个报文段,然后是2个,接着是4个……。 快速重传与快速恢复算法由于我们不知道一个重复的 ACK是由一个丢失的报文段引起的,还是由于仅仅出现了几个报文段的重新排序,因此我们等待少量重复的ACK到来。假如这只是一些报文段的重新排序,则在重新排序的报文段被处理并产生一个新的 ACK之前,只可能产生1 ~ 2个重复的ACK。 接下来执行的不是慢启动算法而是拥塞避免算法。这就是快速恢复算法。 这个算法通常按如下过程进行实现:
重新分组当TCP超时并重传时,它不一定要重传同样的报文段。相反, TCP允许进行重新分组而发送一个较大的报文段,这将有助于提高性能(当然,这个较大的报文段不能够超过接收方声明的MSS)。在协议中这是允许的,因为 TCP是使用字节序号而不是报文段序号来进行识别它所要发送的数据和进行确认。 |
|
网络协议 最新文章 |
使用Easyswoole 搭建简单的Websoket服务 |
常见的数据通信方式有哪些? |
Openssl 1024bit RSA算法---公私钥获取和处 |
HTTPS协议的密钥交换流程 |
《小白WEB安全入门》03. 漏洞篇 |
HttpRunner4.x 安装与使用 |
2021-07-04 |
手写RPC学习笔记 |
K8S高可用版本部署 |
mySQL计算IP地址范围 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 | -2024/12/29 10:20:34- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |
数据统计 |