tcp协议头中有seq和ack_seq两个字段分别代表序列号和确认号。tcp协议通过序列号标识发送的报文段seq的类型是__u32,当超过__u32的最大值时会回绕到0。
一个tcp流的初始序列号(ISN)并不是从0开始的而是采用一定的随机算法产生的,因此ISN可能很大(比如(2^32-10))因此同一个tcp流的seq号可能会回绕到0。而我们tcp对于丢包和乱序等问题的判断嘟是依赖于序列号大小比较的此时就出现了所谓的tcp序列号回绕(sequence wraparound)问题。
内核中给出的序列号(解决序列号回绕问题)判断解决方案十分简潔:
点击(此处)折叠或打开
由于我们将结果转化成了有符号数由于最高位是1,因此结果是一个负数负数的绝对值为
如果seq2=128的话,我们会发現:
此时结果尤为正了判断的结果是seq1>seq2。因此上述算法正确的前提是,回绕后的增量小于2^(n-1)-1
由于tcp序列号用的32位无符号数,因此可以支持嘚回绕幅度是2^31-1满足要求了。