TCP内幕

状态机

  • 序列号及ACK存在的意义:序列号是为了乱序而存在,ACK是为了丢包而存在
  • TCP状态机
    • 主动连接:send sync(sync_send)->rec sync,send ack(established)
    • 被动连接:(listen)->rec sync,send sync/ack(sync_received)->rec ack(established)
    • 主动关闭:send fin(fin_wait1)->rec ack(fin_wait2)->rec fin,send ack(time_wait, 2*msl)
    • 被动关闭:rec fin->send ack(close_wait)->send fin(last_ack)->rec ack(closed)
  • ISN与MSL(4.55hour):没太搞懂
  • TIME_WAIT是主动关闭端才有的问题,“不作死就不会死”,web-server端应该开启http-keepalive尽量让client端关闭连接

超时重传机制

  • RTO计算公式
SRTT = SRTT + a(RTT-SRTT)
DevRTT = (1-b)DevRTT + b|RTT-SRTT|
RTO=uSRTT + gDevRTT
  • TCP连接与超时定时器是1:1关系,timer的运行逻辑是
    • 发送数据后,启动定时器
    • 收到所有数据ACK,关闭定时器
    • 收到ACK,但非所有数据ACK,重启定时器(收到说明大概率连续收到避免临界超时)
    • 超时后,重传最早未ACK数据包,设置min(RTO*2,60s),避免拥塞加剧;重启定时器
  • 基于SACK option通知发送方未收到的序列号范围,支持不连续的范围

流量控制

  • 接收方通过通告窗口大小来控制发送方发送速率,通过零窗口来阻止对方发送;发送方在接收到零窗口也不会一直干等,而是定时探测(零窗口探针,30-60s);
  • 发送方发送大量小包时,浪费通道,nagle算法的优化是:基于TCP_CORK选项控制的包合并发送(trigger为MTU或200s timeout),发送方也会合并ack(trigger为第二个ack或40ms超时)
  • 发送窗口=min(接收端通告窗口,拥塞窗口)

拥塞控制

  • 接收方开始以指数速度通知发送方拥塞窗口,直到一定阈值ssthresh后,为避免单连接过度占用带宽进入拥塞避免阶段,线性扩大拥塞窗口;
  • 当发生RTO超时重传时,拥塞窗口归1且减半ssthresh;
  • 当发送端接收到三个duplicate-ack时,进入快速重传及快速恢复阶段,减半拥塞窗口同时线性增大拥塞窗口,直到收到最新发送数据的ACK退出快速重传阶段

连接队列

  • backlog参数:请求sync->ack,sync(此时进入半连接队列由backlog控制)->ack(连接队列)
  • SYNC flood攻击及应对手段:主动连接方send sync后不再send ack;被动方会不断重试发送ack;

Ref

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容