TCP 协议灵魂问题,巩固你的网路底层基础( 三 )


增加SYN连接 , 也就是增加半连接队列的容量 。 减少SYN+ACK重试次数 , 避免大量的超时重发 。 利用SYNCookie技术 , 在服务端接收到SYN后不立即分配连接资源 , 而是根据这个SYN计算出一个Cookie , 连同第二次握手回复给客户端 , 在客户端回复ACK的时候带上这个Cookie值 , 服务端验证Cookie合法之后才分配连接资源 。005:介绍一下TCP报文头部的字段
报文头部结构如下(单位为字节):

TCP 协议灵魂问题,巩固你的网路底层基础
文章图片
请大家牢记这张图!
源端口、目标端口
如何标识唯一标识一个连接?答案是TCP连接的四元组——源IP、源端口、目标IP和目标端口 。
那TCP报文怎么没有源IP和目标IP呢?这是因为在IP层就已经处理了IP 。 TCP只需要记录两者的端口即可 。
序列号
即Sequencenumber,指的是本报文段第一个字节的序列号 。
从图中可以看出 , 序列号是一个长为4个字节 , 也就是32位的无符号整数 , 表示范围为0~2^32-1 。 如果到达最大值了后就循环到0 。
序列号在TCP通信的过程中有两个作用:
在SYN报文中交换彼此的初始序列号 。 保证数据包按正确的顺序组装 。ISN
即InitialSequenceNumber(初始序列号),在三次握手的过程当中 , 双方会用过SYN报文来交换彼此的ISN 。
ISN并不是一个固定的值 , 而是每4ms加一 , 溢出则回到0 , 这个算法使得猜测ISN变得很困难 。 那为什么要这么做?
如果ISN被攻击者预测到 , 要知道源IP和源端口号都是很容易伪造的 , 当攻击者猜测ISN之后 , 直接伪造一个RST后 , 就可以强制连接关闭的 , 这是非常危险的 。
而动态增长的ISN大大提高了猜测ISN的难度 。
确认号
即ACK(Acknowledgmentnumber) 。 用来告知对方下一个期望接收的序列号 , 小于ACK的所有字节已经全部收到 。
标记位
常见的标记位有SYN,ACK,FIN,RST,PSH 。
SYN和ACK已经在上文说过 , 后三个解释如下:FIN:即Finish , 表示发送方准备断开连接 。
RST:即Reset , 用来强制断开连接 。
PSH:即Push,告知对方这些数据包收到后应该马上交给上层的应用 , 不能缓存 。
窗口大小
占用两个字节 , 也就是16位 , 但实际上是不够用的 。 因此TCP引入了窗口缩放的选项 , 作为窗口缩放的比例因子 , 这个比例因子的范围在0~14 , 比例因子可以将窗口的值扩大为原来的2^n次方 。
校验和
占用两个字节 , 防止传输过程中数据包有损坏 , 如果遇到校验和有差错的报文 , TCP直接丢弃之 , 等待重传 。
可选项
可选项的格式如下:

TCP 协议灵魂问题,巩固你的网路底层基础
文章图片
常用的可选项有以下几个:
TimeStamp:TCP时间戳 , 后面详细介绍 。 MSS:指的是TCP允许的从对方接收的最大报文段 。 SACK:选择确认选项 。 WindowScale:窗口缩放选项 。006:说说TCP快速打开的原理(TFO)
第一节讲了TCP三次握手 , 可能有人会说 , 每次都三次握手好麻烦呀!能不能优化一点?
可以啊 。 今天来说说这个优化后的TCP握手流程 , 也就是TCP快速打开(TCPFastOpen,即TFO)的原理 。
优化的过程是这样的 , 还记得我们说SYNFlood攻击时提到的SYNCookie吗?这个Cookie可不是浏览器的Cookie,用它同样可以实现TFO 。
TFO流程
首轮三次握手
首先客户端发送SYN给服务端 , 服务端接收到 。
注意哦!现在服务端不是立刻回复SYN+ACK , 而是通过计算得到一个SYNCookie,将这个Cookie放到TCP报文的FastOpen选项中 , 然后才给客户端返回 。
客户端拿到这个Cookie的值缓存下来 。 后面正常完成三次握手 。
首轮三次握手就是这样的流程 。 而后面的三次握手就不一样啦!
后面的三次握手
在后面的三次握手中 , 客户端会将之前缓存的Cookie、SYN和HTTP请求(是的 , 你没看错)发送给服务端 , 服务端验证了Cookie的合法性 , 如果不合法直接丢弃;如果是合法的 , 那么就正常返回SYN+ACK 。
重点来了 , 现在服务端能向客户端发HTTP响应了!这是最显著的改变 , 三次握手还没建立 , 仅仅验证了Cookie的合法性 , 就可以返回HTTP响应了 。
当然 , 客户端的ACK还得正常传过来 , 不然怎么叫三次握手嘛 。
流程如下:

TCP 协议灵魂问题,巩固你的网路底层基础
文章图片
注意:客户端最后握手的ACK不一定要等到服务端的HTTP响应到达才发送 , 两个过程没有任何关系 。
TFO的优势
TFO的优势并不在与首轮三次握手 , 而在于后面的握手 , 在拿到客户端的Cookie并验证通过以后 , 可以直接返回HTTP响应 , 充分利用了1个RTT(Round-TripTime , 往返时延)的时间提前进行数据传输 , 积累起来还是一个比较大的优势 。