curl 使用Linux虚拟以太网接口(veth)测试自定义TCP堆栈

2fjabf4q  于 2022-11-13  发布在  Linux
关注(0)|答案(1)|浏览(135)

如果设置了一对虚拟以太网设备veth 0和veth 1:

ip link add veth0 type veth peer name veth1

# Bring the interfaces up
sudo ifconfig veth0 up
sudo ifconfig veth1 up

sudo ifconfig veth0 1.1.1.1
sudo ifconfig veth1 1.1.1.2

在我的应用程序中,我使用一个原始套接字连接到veth0。传入的数据包被转发到我自己的TCP/IP栈实现。来自栈的响应被发送回套接字。
我还在堆栈上运行了一个简单的HTTP服务器,我尝试使用curl

sudo curl -vvv --interface veth1 1.1.1.1/1/2/10000
*   Trying 1.1.1.1...
* Local Interface veth1 is ip 1.1.1.2 using address family 2
* Local port: 0

现在,我的自定义堆栈接收到SYN,进入SYN-RECEIVED状态,并使用SYN-ACK回复a。
但是,curl似乎没有接收到SYN-ACK,因为它一直在重新传输原始的SYN
根据tcpdump,SYN-ACK似乎确实到达了1.1.1.2:

$ sudo tcpdump -i veth1  -vv
tcpdump: listening on veth1, link-type EN10MB (Ethernet), capture size 262144 bytes
02:43:41.680087 IP (tos 0x0, ttl 64, id 59135, offset 0, flags [DF], proto TCP (6), length 60)
    1.1.1.2.41847 > 1.1.1.1.http: Flags [S], cksum 0x0433 (incorrect -> 0x38a4), seq 446675468, win 29200, options [mss 1460,sackOK,TS val 1266013534 ecr 0,nop,wscale 7], length 0
02:43:41.680345 IP (tos 0x0, ttl 64, id 30106, offset 0, flags [DF], proto TCP (6), length 52)
    1.1.1.1.http > 1.1.1.2.41847: Flags [S.], cksum 0x0bbe (correct), seq 697874744, ack 446675469, win 65535, options [mss 1460,wscale 5,nop,sackOK,nop,nop], length 0
02:43:42.690344 IP (tos 0x0, ttl 64, id 59136, offset 0, flags [DF], proto TCP (6), length 60)
    1.1.1.2.41847 > 1.1.1.1.http: Flags [S], cksum 0x0433 (incorrect -> 0x34b2), seq 446675468, win 29200, options [mss 1460,sackOK,TS val 1266014544 ecr 0,nop,wscale 7], length 0
02:43:44.706343 IP (tos 0x0, ttl 64, id 59137, offset 0, flags [DF], proto TCP (6), length 60)
    1.1.1.2.41847 > 1.1.1.1.http: Flags [S], cksum 0x0433 (incorrect -> 0x2cd2), seq 446675468, win 29200, options [mss 1460,sackOK,TS val 1266016560 ecr 0,nop,wscale 7], length 0
02:43:46.850382 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 1.1.1.1 tell 1.1.1.2, length 28
02:43:46.850579 ARP, Ethernet (len 6), IPv4 (len 4), Reply 1.1.1.1 is-at 92:c6:e5:d6:03:2f (oui Unknown), length 46
02:43:47.680487 IP (tos 0x0, ttl 64, id 30107, offset 0, flags [DF], proto TCP (6), length 52)
    1.1.1.1.http > 1.1.1.2.41847: Flags [S.], cksum 0x0bbe (correct), seq 697874744, ack 446675469, win 65535, options [mss 1460,wscale 5,nop,sackOK,nop,nop], length 0
02:43:48.898343 IP (tos 0x0, ttl 64, id 59138, offset 0, flags [DF], proto TCP (6), length 60)
    1.1.1.2.41847 > 1.1.1.1.http: Flags [S], cksum 0x0433 (incorrect -> 0x1c72), seq 446675468, win 29200, options [mss 1460,sackOK,TS val 1266020752 ecr 0,nop,wscale 7], length 0
02:43:57.090346 IP (tos 0x0, ttl 64, id 59139, offset 0, flags [DF], proto TCP (6), length 60)
    1.1.1.2.41847 > 1.1.1.1.http: Flags [S], cksum 0x0433 (incorrect -> 0xfc71), seq 446675468, win 29200, options [mss 1460,sackOK,TS val 1266028944 ecr 0,nop,wscale 7], length 0
02:43:59.680648 IP (tos 0x0, ttl 64, id 30108, offset 0, flags [DF], proto TCP (6), length 52)
    1.1.1.1.http > 1.1.1.2.41847: Flags [S.], cksum 0x0bbe (correct), seq 697874744, ack 446675469, win 65535, options [mss 1460,wscale 5,nop,sackOK,nop,nop], length 0
^C
10 packets captured
10 packets received by filter
0 packets dropped by kernel

Wireshark screenshot.
有人知道为什么我的SYN-ACK不能到达TCP连接的另一端吗?

ruarlubt

ruarlubt1#

问题是veth接口默认使用校验和卸载,因此转发的包具有错误的校验和,被内核忽略。在veth接口(发送方和接收方)上运行'ethtool --offload IF_NAME rx off tx off',可以修复该问题。

相关问题