Uto*_*oah 5 linux tcp tcpdump linux-kernel
运行这个版本的内核4.11.8-1.el6.elrepo.x86_64并想知道为什么 TCP 堆栈发送一些 RST 数据包,即是否有 BSD 的 Linux 对应项net.inet.tcp.log_debug=1?
以下是需要原因的案例之一。在握手最终到达 ACK 后立即发送 RST。可以看到SYN丢失了好几次,并且最后一个ACK在超过1秒后才到达。但目前还不清楚为什么要发送RST。禁用 syn cookie 没有帮助。
15:27:41.166799 IP CLIENT.16537 > SERVER.80: Flags [S], seq 1397492268, win 29200, options [mss 1440,sackOK,TS val 1230199 ecr 0,nop,wscale 6], length 0
15:27:41.166820 IP SERVER.80 > CLIENT.16537: Flags [S.], seq 1773519351, ack 1397492269, win 29200, options [mss 1460,nop,nop,sackOK,nop,wscale 9], length 0
15:27:42.069572 IP CLIENT.16537 > SERVER.80: Flags [S], seq 1397492268, win 29200, options [mss 1460,sackOK,TS val 1230299 ecr 0,nop,wscale 6], length 0
15:27:42.069590 IP SERVER.80 > CLIENT.16537: Flags [S.], seq 1773519351, ack 1397492269, win 29200, options [mss 1460,nop,nop,sackOK,nop,wscale 9], length 0
15:27:43.123141 IP SERVER.80 > CLIENT.16537: Flags [S.], seq 1773519351, ack 1397492269, win 29200, options [mss 1460,nop,nop,sackOK,nop,wscale 9], length 0
15:27:44.067228 IP CLIENT.16537 > SERVER.80: Flags [S], seq 1397492268, win 29200, options [mss 1460,sackOK,TS val 1230499 ecr 0,nop,wscale
6], length 0
15:27:44.067240 IP SERVER.80 > CLIENT.16537: Flags [S.], seq 1773519351, ack 1397492269, win 29200, options [mss 1460,nop,nop,sackOK,nop,wscale 9], length 0
15:27:46.547072 IP CLIENT.16537 > SERVER.80: Flags [.], ack 1, win 457, length 0
15:27:46.547094 IP SERVER.80 > CLIENT.16537: Flags [R], seq 1773519352, win 0, length 0
15:27:46.548177 IP CLIENT.16537 > SERVER.80: Flags [.], ack 1, win 457, options [nop,nop,sack 1 {0:1}], length 0
15:27:46.548186 IP SERVER.80 > ClIENT.16537: Flags [R], seq 1773519352, win 0, length 0
Run Code Online (Sandbox Code Playgroud)
谢谢你的帮助。
这个确切的功能不可用,可以通过查看tcp_send_active_reset. 在代码中如:
int tcp_disconnect(struct sock *sk, int flags)
{
...
int old_state = sk->sk_state;
if (old_state != TCP_CLOSE)
tcp_set_state(sk, TCP_CLOSE);
if ...
} else if (tcp_need_reset(old_state) ||
(tp->snd_nxt != tp->write_seq &&
(1 << old_state) & (TCPF_CLOSING | TCPF_LAST_ACK))) {
/* The last check adjusts for discrepancy of Linux wrt. RFC
* states
*/
tcp_send_active_reset(sk, gfp_any());
Run Code Online (Sandbox Code Playgroud)
显示的多个原因中的哪一个导致 RST 未提供给任何调试宏,并且未提供给 tcp_send_active_reset。
Linux 4.15 添加了跟踪点,包括本博客条目tcp:tcp_send_reset中记录的内容。对于许多重置,可以将函数和跟踪点上的动态探针的状态汇总在一起,以与内核相同的方式检查它并推断其选择的原因。这一点很重要,因为在我的重置可能起源的示例中,套接字已经在使用探针的函数之前更改了状态,因此必须在调用时结合动态探针检查 sk->sk_state或获取 old_state在 tcp_send_active_reset 中的跟踪点处使用探针来确认重置已在特定套接字上发送。tcp:tcp_send_resettcp_disconnect()tcp_set_state()