如果我在 tcpdump 中看到传入数据包,但在套接字上却看不到,我该如何排除故障?

如果我在 tcpdump 中看到传入数据包,但在套接字上却看不到,我该如何排除故障?

例如,我看到传入的数据包在,但对于正在监听适当套接字的程序来说tcpdump却不在。strace

我如何在 Linux 上追踪这个传入数据包的“命运”?

我希望得到这样的报告:

  • ✓ 网络接口接收到数据包;
  • ✓ 数据包成功解码为 IPv4 数据包(校验和正确等);
  • ✓ 数据包通过 iptables(未被 DROP 掉);
  • ✘ 数据包路由到本地套接字(不,这不是我们的 IP 地址);
  •   数据包通过流量控制(没有因为过载而丢失);
  •   本地套接字接收到数据包

我可以在哪里获得汇总信息,而不必手动调查每个可能的停止点(也许我甚至不知道全部停止点)?

答案1

tcpdump 只是利用原始套接字复制经过网卡的数据,工作在操作系统的 TCP/IP 堆栈中。能够通过 tcpdump 捕获数据意味着数据包确实到达了网卡。

strace 只是打印每个系统调用。无法在 strace 中捕获它意味着read没有write进行系统调用。例如,read系统调用调用 NIC 驱动程序将数据从 NIC 移动到与套接字文件描述符关联的内核内存,然后将它们复制到用户空间缓冲区。strace 可以检查read调用中的参数,然后打印它们。

此外,如果是流套接字,我认为accept系统调用已经完成,文件描述符也已分配,因此客户端可以发送数据包,tcpdump 可以捕获这些数据包。我在这里有一个实例。

15:21:25.285198 IP (tos 0x0, ttl 55, id 0, offset 0, flags [DF], proto TCP (6), length 597)
    10.93.235.127.51524 > 10.225.131.26.8040: Flags [P.], cksum 0xefc8 (correct), seq 1:546, ack 1, win 2052, options [nop,nop,TS val 633828071 ecr 2357545597], length 545
POST /api/query HTTP/1.1
Content-Type: application/json
User-Agent: PostmanRuntime/7.15.2
Accept: */*
Cache-Control: no-cache
Postman-Token: e5584554-5747-4f2c-84c4-8e621b3bfeb2
Host: 10.225.131.26:8040
Accept-Encoding: gzip, deflate
Content-Length: 256
Connection: keep-alive

{"start":1567397847315,"end":1567398147315,"queries":[{"aggregator":"avg","metric":"endpoint.status.ok","rate":true,"rateOptions":{"counter":false,"diff":false},"tags":{"dc":"*","host":"n225"},"topK":""}],"allowCoprocessor":false}
15:21:25.285210 IP (tos 0x0, ttl 64, id 17260, offset 0, flags [DF], proto TCP (6), length 52)
    10.225.131.26.8040 > 10.93.235.127.51524: Flags [.], cksum 0x83fe (incorrect -> 0xb98e), ack 546, win 7513, options [nop,nop,TS val 2357545605 ecr 633828071], length 0
5 packets captured

但是 strace 显示只有accepted 而不是read,所以没有看到数据包。

2524390 accept4(9, {sa_family=AF_INET6, sin6_port=htons(51524), inet_pton(AF_INET6, "::ffff:10.93.235.127", &sin6_addr), sin6_flowinfo=htonl(0), sin6_scope_id=0}, [128->28], SOCK_CLOEXEC|SOCK_NONBLOCK) = 178687
2524390 getsockname(178687, {sa_family=AF_INET6, sin6_port=htons(8040), inet_pton(AF_INET6, "::ffff:10.225.131.26", &sin6_addr), sin6_flowinfo=htonl(0), sin6_scope_id=0}, [128->28]) = 0
2524390 setsockopt(178687, SOL_TCP, TCP_NODELAY, [1], 4) = 0
2524390 getsockopt(178687, SOL_SOCKET, SO_SNDBUF, [65536], [4]) = 0
2524390 getsockopt(178687, SOL_SOCKET, SO_SNDBUF, [65536], [4]) = 0
2524390 setsockopt(178687, SOL_SOCKET, SO_SNDBUF, [131072], 4) = 0
2524390 getsockopt(178687, SOL_SOCKET, SO_SNDBUF, [262144], [4]) = 0
2524390 getsockopt(178687, SOL_SOCKET, SO_SNDBUF, [262144], [4]) = 0
2524390 setsockopt(178687, SOL_SOCKET, SO_KEEPALIVE, [1], 4) = 0
2524390 setsockopt(178687, SOL_TCP, TCP_NODELAY, [1], 4) = 0
2524390 setsockopt(178687, SOL_SOCKET, SO_RCVBUF, [131072], 4) = 0

数据报套接字也类似。

相关内容