一、TCP连接的ISN
        之前我们说过初始建立TCP连接的时候的系列号(ISN)是随机选择的,那么这个系列号为什么不采用一个固定的值呢?主要有两方面的原因
  • 防止同一个连接的不同实例(different instantiations/incarnations of the same connection)的数据包混淆。
同一个连接的不同实例是怎么回事呢?之前我们说过(源IP、源端口号、目的地址、目的端口号)这个四元组唯一标识一个TCP连接,当一个TCP连接在经历四次挥手关闭时,假如有一个数据包延迟特别大,而这个连接在关闭后又马上以相同的四元组建立起来,那么先前这个连接的TCP数据包到达的时候,如果系列号还落在接收窗内,那么这个数据包就可能会被错误接收。因此RFC0793指出ISN应该每4μs自增1,从而防止同一个连接的不同实例的数据包混淆。另外对数据完整性要求比较高的应该同时在应用层添加校验。
  • 防止TCP系列号欺骗
TCP系列号欺骗如下图所示,假设A是服务器,B是拥有特殊权限的客户端,C是攻击者,第一条消息C冒充B来向服务器A请求建立连接,此时C发出的数据包的IP地址会填写成B的;第二条消息假设A没有其他手段来验证B,而仅仅根据IP地址判断C发过来的建立连接的请求是B发过来的,因此向B发送SYN+ACK,此时假设B被C进行了DOS攻击或者处于其他异常状态而不能响应第二条消息(如果B处于正常状态会响应一个RST包来重启TCP连接,后面我们讲解RST数据包);第三条消息假如C能正确的猜测出A在第二条消息中的ISN,就可以冒充B和A完成三次握手的过程,让A误以为和B建立了连接。接下来C就可以冒充B给A发送一些危险数据或者指令而实现攻击。

因此假如ISN仅仅是依靠时间来增长还不够安全,因此RFC1948又提出了一个ISN随机生成的算法

ISN = M + F(localhost, localport, remotehost, remoteport)

其中M是一个计时器,这个计时器每隔4毫秒加1。F是一个Hash算法,根据源IP、目的IP、源端口、目的端口生成一个随机数值。要保证hash算法不能被外部轻易推算得出,用MD5算法是一个比较好的选择。
具体到linux的实现中,F采用MD5进行Hash,另外还会在F这个函数中带入一个随机的net_secret安全码进一步安全性,linux中M计时器则是每64ns加1。
二、连接超时
        当一个TCP连接请求超时的时候,比如对应目标IP的主机挂掉的时候,会触发SYN数据包的重传,重传的时间间隔按照指数退避(exponential backoff)算法增长,还记得我们之前说过得SYN和FIN数据包是在逻辑上占有一个byte的是,也就会消耗一个系列号,消耗系列号意味着能进行重传,没有数据的ACK确认包因为不消耗系列号即使传输过程中出错也不会触发ACK数据包的重传。后续TCP重传部分我们会进一步介绍TCP的重传和指数退避。

在linux中net.ipv4.tcp_syn_retries变量表示TCP主动连接端SYN数据包的最大重传次数,net.ipv4.tcp_synack_retries表示TCP连接的被动端响应的SYN+ACK包的最大重传次数。也可以通过TCP_SYNCNT的socket选项单独设置某一个TCP连接SYN重传次数。

我们观察一下下图中SYN重传的过程,首先发出No 1的SYN包,在1s内没有收到SYN-ACK包,触发SYN重传即No 2包,后续又分别以2s/4s/8s/16s/32s的间隔进行SYN的重传,直到No 7包进行第6次重传依旧没有收到SYN-ACK回复(net.ipv4.tcp_syn_retries默认配置值为6),客户端放弃连接。

三、长连接与短连接
TCP连接类型又可以分为长连接和短连接
  • 短连接:Client方与Server每进行一次报文收发时才进行通讯连接,收发完毕后立即断开连接。此种方式常用于一点对多点通讯,比如多个Client连接一个Server.优点是管理起来比较简单,存在的连接都是有用的连接,不需要额外的控制手段
  • 长连接:Client方与Server方先建立通讯连接,连接建立后不断开,然后再进行报文发送和接收。这种方式下由于通讯连接一直存在,可以用下面命令查看连接是否建立:netstat –f inet|grep 端口号(如5678)。此种方式常用于点对点通讯。

补充说明
1、linux中计算ISN的过程可以参考相关代码tcp_v4_init_sequence

TCP系列05—连接管理—4、TCP连接的ISN、连接建立超时及TCP的长短连接的更多相关文章

  1. TCP连接的ISN、连接建立超时及TCP的长短连接

    问题现象: 一.TCP连接的ISN         之前我们说过初始建立TCP连接的时候的系列号(ISN)是随机选择的,那么这个系列号为什么不采用一个固定的值呢?主要有两方面的原因 防止同一个连接的不 ...

  2. TCP系列36—窗口管理&流控—10、linux下的异常报文系列接收

    在这篇文章中我们看一下server端在接收到异常数据系列时的处理,主要目的是通过wireshark示例对这些异常数据系列的处理有一个直观的认识,感兴趣的自行阅读相关代码和协议,这里不再进行详细介绍 在 ...

  3. TCP系列32—窗口管理&流控—6、TCP zero windows和persist timer

    一.简介 我们之前介绍过,TCP报文中的window size表示发出这个报文的一端准备多少bytes的数据,当TCP的一端一直接收数据,但是应用层没有及时读取的话,数据一直在TCP模块中缓存,最终受 ...

  4. TCP系列33—窗口管理&流控—7、Silly Window Syndrome(SWS)

    一.SWS介绍 前面我们已经通过示例看到如果接收端的应用层一直没有读取数据,那么window size就会慢慢变小最终可能变为0,此时我们假设一种场景,如果应用层读取少量数据(比如十几bytes),接 ...

  5. TCP系列31—窗口管理&流控—5、TCP流控与滑窗

    一.TCP流控 之前我们介绍过TCP是基于窗口的流量控制,在TCP的发送端会维持一个发送窗口,我们假设发送窗口的大小为N比特,网络环回时延为RTT,那么在网络状况良好没有发生拥塞的情况下,发送端每个R ...

  6. TCP系列27—窗口管理&流控—1、概述

    在前面的内容中我们依次介绍了TCP的连接建立和终止过程和TCP的各种重传方式.接着我们在这部分首先关注交互式应用TCP连接相关内容如延迟ACK.Nagle算法.Cork算法等,接着我们引入流控机制(f ...

  7. TCP系列30—窗口管理&流控—4、Cork算法

    一.Cork算法概述 Cork算法与Nagle算法类似,也有人把Cork算法称呼为super-Nagle.Nagle算法提出的背景是网络因为大量小包小包而导致利用率低下产生网络拥塞,网络发生拥塞的时候 ...

  8. TCP系列29—窗口管理&流控—3、Nagle算法

    一.Nagle算法概述 之前我们介绍过,有一些交互式应用会传递大量的小包(称呼为tinygrams),这些小包的负载可能只有几个bytes,但是TCP和IP的基本头就有40bytes,如果大量传递这种 ...

  9. TCP系列28—窗口管理&流控—2、延迟ACK(Delayed Acknowledgments)

    一.简介 之前的内容中我们多次提到延迟ACK(Delayed Ack),延迟ACK是在RFC1122协议中定义的,协议指出,一个TCP实现应该实现延迟ACK,但是ACK不能被过度延迟,协议给出延迟AC ...

随机推荐

  1. ruby 字符串加密

    str = 'This is a test.rb!' #DES加密 puts str.crypt('salt') #MD532位加密 require 'digest' puts Digest::MD5 ...

  2. STM32 USB设备描述符、配置描述符、端点描述符含义

    查了一整天的资料,自己把不懂的全部试了一遍 一下是程序以及注释 /* USB设备描述符*/ const uint8_t CustomHID_DeviceDescriptor[CUSTOMHID_SIZ ...

  3. 笔记-python-float(‘inf’)

    笔记-python-float(‘inf’) 看算法时发现了flaot(‘inf’). Python中可以用如下方式表示正负无穷: float("inf"), float(&quo ...

  4. SQL 备忘录

    都兼容 MySQL 查看表结构:DESC ${table_name} 查看建表语句:SHOW CREATE TABLE ${table_name} ​表增加列:ALTER TABLE ${table_ ...

  5. Prism for WPF 搭建一个简单的模块化开发框架 (一个节点)

    原文:Prism for WPF 搭建一个简单的模块化开发框架 (一个节点) 这里我就只贴图不贴代码了,看看这个节点之前的效果 觉得做的好的地方可以范之前的文章看看 有好的建议也可以说说   填充数据 ...

  6. day 3 list列表生成式

    1.定义一个list列表,里面元素是0-33 a = [] i = 0 while i<33: a.append(i) i+=1 print(a) [0, 1, 2, 3, 4, 5, 6, 7 ...

  7. E2E test protractor selenium

    E2E Test和传统的Unit Test不同的是:(1)不涉及代码层面,不会去测试某段代码是否正确或者某行代码是否被覆盖(2)它是从用户的角度出发,用来测试一个应用的流程是否符合预期. 一 Sele ...

  8. c++ reference can not be reassigned

    #include <iostream> using namespace std; int main () { // declare simple variables int i; int ...

  9. js 中常用到的封装方法

    /** * 获取URL参数 */ function getQueryString(name) { var reg = new RegExp("(^|&)" + name + ...

  10. 「日常训练」Alternative Thinking(Codeforces Round #334 Div.2 C)

    题意与分析 (CodeForces - 603A) 这题真的做的我头疼的不得了,各种构造样例去分析性质... 题意是这样的:给出01字符串.可以在这个字符串中选择一个起点和一个终点使得这个连续区间内所 ...