序号回绕问题¶
一个 tcp 流的初始序列号(ISN)并不是从 0 开始的,而是采用一定的随机算法产生的,因此 ISN 可能很大,因此同一个 tcp 流的 seq 号可能会回绕到 0。而我们 tcp 对于丢包和乱序等问题的判断都是依赖于序列号大小比较的。此时就出现了所谓的 tcp 序列号回绕(sequence wraparound)问题。
解决¶
内核中给出的解决方案:
/*
* The next routines deal with comparing 32 bit unsigned ints
* and worry about wraparound (automatic with unsigned arithmetic).
*/
static inline int before(__u32 seq1, __u32 seq2)
{
return (__s32)(seq1 - seq2) < 0;
}
#define after(seq2, seq1) before(seq1, seq2)
将序列号设为无符号整数,求差,再转为有符号数判断谁先谁后。以 uint8
为例:seq1=255
,seq2=5
,从 seq1
到 seq2
发生了回绕现象。按内核中的方法 seq2 - seq1 = 6 > 0
说明 seq2
在 seq1
之后