【lwip】12-一文解决TCP原理( 九 )

  • IPv4网络中,MSS的典型取值为1460 ,1460Byte + 20Byte IP Header + 20Byte TCP Header = 1500Byte = 以太网典型MTU;
  • IPv6网络中,典型MSS取值为1440;另外,如果MSS=65535,表示MSS = PMTU - 60
  • 12.10.2 SACKSACK:Selective Acknowledgment (SACK) Options
    在标准的TCP实现中,使用的是累加式的ACK,例如“ACK Num = n”代表对序列号n以前的Bytes进行确认 。但是,显然,这样将无法对不连续的Segment进行确认 。此外,当出现不连续Segment时,还会导致TCP的接收队列出现一个“坑”,不将这个坑填上,坑后的数据就无法交付给应用程序 。
    为解决上述问题,TCP定义了SACK Option,可以使TCP接收者将这个“坑”的位置通告给发送者,让其对这一段数据进行重传 。
    注意:若要使用SACK特性,必须在建立连接时,在SYN Segment中附加上SACK-Permitted Option,以此告知对方自己支持SACK 。
    SACK-Permitted Option格式如下所示:
    Kind = 4Length = 2SACK Option格式如下所示:
    • SACK Option通过“Left Edge ~ Right Edge”,指定了一个或多个范围的Seq Num,称为SACK Block,指明了处于“坑”后面(或坑之间)的、已成功接收的Bytes 。
    • 由于TCP Header最长为60 Byte,因此SACK Option中最多只能包含4个SACK Block 。
    Kind(5)Length(可变)Left Edge of 1st B1ock(32bit)ight Edge of 1st B1ock(32bit)......Left Edge of nst B1ock(n≤4)ight Edge of nst Block(n≤4)例子:
    1. 终端A收到了TCP数据流中的Seq Num为0 至 1452、2905 至 4096的字节,但缺少了1453 至 2904;
    2. 终端A向B发送ACK Segment,其中ACK Num=1453、SACK Option=2905 至 4097,表明它已经收到了数据流中的Seq Num为2905 至 4096的字节,但没有还没收到1453 至 2904;
    3. 终端B收到这个SACK后,重传包含Byte 1453 至 2904的TCP Segment;
    4. 终端A向B发送ACK Segment,其中ACK Num=4097,表明它已经收到Seq Num 4097之前的所有字节;
    5. 之后,数据通信恢复正常 。
    lwip:
    • 从lwip的tcp_enqueue_flags()函数看,如果对端不支持SACK,本地也不会支持SACK 。
    12.10.3 WSOPTWSOPT:Window Scale (WSCALE or WSopt) Option
    TCP Header的Window Size字段长度为16bit,因而正常情况下,Window Advertisement最大只能是65535 Bytes 。
    Window Scale Option用于将TCP Header的Window Size字段从16bit扩展至最多30bit,格式如下所示:
    kindLengthshift.cnt(3)(3)(范围0~14)
    1. shift.cnt的取值范围为0~14,表示将Window Advertisement的值扩展至“WindowSize × 2^shift.cnt,这就是最终的窗口值 。
      1. 取值范围[0, 14]的原因:最大TCP序号限定为2^16 * 2^14= 2^30 < 2^31 。该限制用于防止字节序列号溢出 。
    2. WSopt只能出现在SYN Segment或SYN+ACK Segment中,因此shift.cnt在三次握手之后就会固定下来 。
    3. 另外,WSopt是双向独立的,因此连接的两个方向可以有不同的Shift.cnt 。但是,WSopt必须双向同时启用,也就是说,如果SYN中不带有WSopt,SYN+ACK中也不能出现WSopt;同样,如果SYN+ACK中不带有WSopt,那么发起SYN的一端就会当作自己也不曾发送过WSopt 。
    4. shift.cnt根据接收Buffer的大小,由TCP自动选取 。接收Buffer由系统或程序设定 。
    12.10.4 TSOPTTSOPT:Timestamps Option and PAWS
    • Timestamps:时间戳 。
    • PAWS:Protect Against Wrapped Sequence Numbers:防止序列号回绕 。
      • 回绕:就是序列号溢出,重新从起点计算 。
    主要两个功能:计算RTT和防止序列号回绕 。
    启用Timestamp Option后,每个TCP Segment中都会带有Timestamp Option,其中包含了两个32bit的Timestamp(TSval和TSecr) 。
    具体格式如下所示:
    Kind(8)Length(10)imestamp value(TSval)Timestamp Echo Reply(TSecr)

    经验总结扩展阅读