【】tcp_v4_rcv
处于TIME_WAIT状态的socket的接收窗口大小为0,因此序号合法性检测不一样。
PAWS检查中如果新时间戳比旧时间戳大、旧时间戳已经过去了24天、记录的旧时间戳为0会通过,对RST包不推荐使用时间戳,如果携带了时间戳那么socket在做PAWS检查时会放宽条件,如果RST包的时间戳未通过检验但旧时间戳距离现在已经过去了一个MSL,那么RST包的PAWS检查仍然会放行。
challengeACK是单个连接每秒内发送不超过阈值次数的ACK。
fastopen根据监听套接字是否开启了TFO及客户端报文是否携带合法的TFOcookie,为该连接直接提前创建子套接字,而非仅创建request_sock,这样可以跳过传统三次握手的冗余校验和队列操作,实现 “发送第二次握手+数据” 的快速传输。
https://elixir.bootlin.com/linux/v3.13.11/source/net/ipv4/tcp_ipv4.c#L1936
在tcp_v4_rcv函数中,首先对sk_buff中的数据包检查目的主机、线性连续数据区长度、校验和,检查失败直接丢弃;然后查询连接哈希表和监听哈希表,找不到返回RST;
对于FIN_WAIT2超时,收到paws未通过或载荷首尾不全都在接收窗口之内的数据包会发送序号同第四次挥手相同但确认号要小1的ACK,收到RST包会直接释放连接,收到序号不比当前期望的下一个要小的SYN包会返回RST,收到无ACK标志或载荷数据已被接收或载荷数据为空的包会直接丢弃,收到无FIN标志或载荷数据结尾不是期待的下一个字节会返回RST,否则会进入TW并发送第四次挥手并且根据tcp_tw_recycle参数是否开启及是否有时间戳记录及时间戳记录是否过期设置超时时间;
处于TIME_WAIT,收到paws通过且序号等于当前期望的下一个的无载荷包会调整tw超时时间,收到paws通过且序号等于当前期望的下一个的RST包根据参数提前释放或调整tw超时时间,收到paws通过且序号比当前期望的下一个要大或时间戳更大的纯SYN包会寻找对应的监听socket回收当前sock并开启建立新连接如果找不到会回复同第四次挥手等价的ACK,收到paws未通过或带ACK标志的非RST包会重置超时时长并回复同第四次挥手等价的ACK,收到paws通过的既非ACK也非RST包会回复同第四次挥手等价的ACK,否则会直接丢弃;
处于ESTABLISHED,收到既非ACK也非RST的包直接丢弃,收到paws未通过并且也不是时间戳在重传窗口内的重传纯ACK的非RST包会发送重复ACK,收到载荷与接收窗口无交集的既非RST也非SYN包会发重复ACK,收到载荷与接收窗口无交集的RST会直接丢弃,收到序号等于当前期望的下一个的RST包会重置连接,收到载荷与接收窗口有交集但序号不等于当前期望的下一个的RST包会发challengeACK,收到SYN包会发challengeACK,收到序号等于当前期望的下一个的包且此时接收窗口大小为0会立即发送ACK,收到FIN包会进入四次挥手处理,收到已被处理过的包会立即重发ACK,收到序号超过接收窗口右侧的包会立即发送ACK;
处于LISTEN,根据四元组在半连接队列中查找相同的request_sock:
如果找到了四元组相同的request_sock,对于paws通过的重传的第一次握手SYN包会重传第二次握手并设置指数退避的重传超时时间,对于确认号不是发出的ISN+1的ACK包会发送RST,对于paws未通过或载荷首尾不全都在接收窗口之内的非RST包会发送ack,对于paws未通过或载荷首尾不全都在接收窗口之内的RST包会直接丢弃,对于RST包会重置连接,对于非ACK包会直接丢弃,否则创建新sock并分配FD,失败则根据参数是否直接丢弃或返回RST,成功则将request_sock移出半连接队列并将request_sock与新sock关联放入全连接队列;
如果没找到四元组相同的request_sock,再去连接哈希表中查找四元组相同的连接sock,如果此时找到了非TW状态的连接socket会跳转相应状态处理,如果此时找到了处于TW状态的连接socket会直接丢弃,如果此时没找到四元组相同的连接sock且本机启用了SYNcookie且收到的是ACK包且SYNcookie合法性校验通过则会创建新sock正常处理,否则直接丢弃;
处于SYN_SENT,
处于CLOSE,全部丢弃。
浙公网安备 33010602011771号