Linux有没有办法记录发送TCP RST数据包的原因?

Linux有没有办法记录发送TCP RST数据包的原因?,linux,tcp,linux-kernel,tcpdump,Linux,Tcp,Linux Kernel,Tcpdump,运行此版本的kernel4.11.8-1.el6.elrepo.x86_64,想知道TCP堆栈为什么发送一些RST数据包,即是否存在BSDnet.inet.TCP.log_debug=1的Linux对应项 以下是需要说明原因的案例之一。RST在握手的最终确认后立即发送。可以看出,SYN丢失了好几次,最后一次ACK没有在1s内到达。但仍不清楚发送RST的原因。禁用syn cookie没有帮助 15:27:41.166799 IP CLIENT.16537 > SERVER.80: Flags

运行此版本的kernel
4.11.8-1.el6.elrepo.x86_64
,想知道TCP堆栈为什么发送一些RST数据包,即是否存在BSD
net.inet.TCP.log_debug=1的Linux对应项

以下是需要说明原因的案例之一。RST在握手的最终确认后立即发送。可以看出,SYN丢失了好几次,最后一次ACK没有在1s内到达。但仍不清楚发送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

感谢您的帮助。

此确切功能不可用,请查看调用
tcp\u send\u active\u reset
的代码。类似:

int-tcp\u断开连接(结构sock*sk,int标志)
{
...
int old_state=sk->sk_state;
如果(旧状态!=TCP\U关闭)
tcp_设置_状态(sk、tcp_关闭);
如果。。。
}否则如果(tcp需要重置(旧状态)||
(tp->snd\u nxt!=tp->write\u seq&&

(1)调用
tcp\u disconnect()
tcp\u set\u state()
时的sk\u state,以获得旧的\u状态,以及在tcp\u send\u active\u reset中跟踪点处的探测,以确认在特定套接字上发送了重置。

不是问题的答案,但在这种特定情况下,RST可能是由于错误的“ack 1”而发送的由客户端在“15:27:46.547072”(应该是“ack 1773519352”)处发送,谢谢,但是握手后的ack编号1只是tcpdump为了便于阅读而进行的调整。您可以使用
iptables-I OUTPUT-p tcp-m tcp--tcp标志SYN、ack、FIN、RST-j LOG
跟踪它们,然后查看
/var/LOG/kern.LOG
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());