【发布时间】:2021-05-16 13:14:57
【问题描述】:
我正在学习 C++ (Ubuntu 20.04) 中的网络协议和套接字编程。我使用socket(PF_INET, SOCK_STREAM, 0) 编写了简单的服务器和客户端应用程序。
我的网络配置如下:
echo 1 > /proc/sys/net/ipv4/ip_forward
ip netns add Server
ip link add Chat type veth peer name Server
ip addr add 10.0.1.1/24 dev Server
ip link set Server up
ip link set Chat netns Server
ip netns exec Server ip addr add 10.0.1.2/24 dev Chat
ip netns exec Server ip link set Chat up
ip netns exec Server ip link set lo up
ip netns exec Server ip route add default via 10.0.1.1
ip netns add Client
ip link add Bob type veth peer name Client
ip addr add 10.0.2.1/24 dev Client
ip link set Client up
ip link set Bob netns Client
ip netns exec Client ip addr add 10.0.2.2/24 dev Bob
ip netns exec Client ip link set Bob up
ip netns exec Client ip link set lo up
ip netns exec Client ip route add default via 10.0.2.1
... aaand 它就像一个魅力。所有消息都从 Bob 传递到 Chat。
下一步我很自然地重写了我的服务器应用程序,这次使用的是原始套接字 - socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))。网络相同,客户端应用程序相同。我的问题从这里开始。 Bob 发送 ACK,起初内核以来自 Chat 的 RST/ACK 响应。在阅读了论坛上的一些帖子后,我了解到内核在 Chat 的网络命名空间的给定端口上没有打开的套接字,并且认为没有连接并做出相应的响应,这似乎很好。聊天的网络命名空间中的iptables -A OUTPUT -p tcp --tcp-flags RST RST -j DROP 解决了这个问题。我自己响应该连接并且不希望内核干扰。回到场景,现在 Bob 发送 ACK,Chat 用手工制作的 SYN/ACK 响应,然后接收...... RST。 Bob 无法向我发送正确的 ACK 响应的内核在做什么?从 Bob 的角度来看,框架应该是正确的。并且内核无法从聊天端断开连接,因为我已经阻止了它。
我也对 Bob 的网络命名空间上的防火墙做了同样的技巧(只是为了实验,因为它对我没有意义)。从现在开始,我会从 Bob 那里得到 FIN/ACK。
当然有可能我不能正确地手工制作框架,所以这里有一个工作场景与非工作场景进行比较:
工作
客户端-socket(PF_INET, SOCK_STREAM, 0)
SYN
0000 c6 ca 19 75 98 61 7e 4b 21 4b 4e 94 08 00 45 00 ...u.a~K!KN...E.
0010 00 3c 3e 2d 40 00 40 06 e5 8b 0a 00 02 02 0a 00 .<>-@.@.........
0020 01 02 b8 dc 1b 58 59 cc e9 d7 00 00 00 00 a0 02 .....XY.........
0030 fa f0 17 32 00 00 02 04 05 b4 04 02 08 0a da c0 ...2............
0040 dc a9 00 00 00 00 01 03 03 07 ..........
服务器 - 套接字(PF_INET, SOCK_STREAM, 0)
SYN/ACK
0000 7e 4b 21 4b 4e 94 c6 ca 19 75 98 61 08 00 45 00 ~K!KN....u.a..E.
0010 00 3c 00 00 40 00 3f 06 24 b9 0a 00 01 02 0a 00 .<..@.?.$.......
0020 02 02 1b 58 b8 dc cf 89 17 79 59 cc e9 d8 a0 12 ...X.....yY.....
0030 fe 88 17 32 00 00 02 04 05 b4 04 02 08 0a c1 fc ...2............
0040 d1 69 da c0 dc a9 01 03 03 07 .i........
这里是正常的 ACK
--------------------
不工作
客户端-socket(PF_INET, SOCK_STREAM, 0)
SYN
0000 c6 ca 19 75 98 61 7e 4b 21 4b 4e 94 08 00 45 00 ...u.a~K!KN...E.
0010 00 3c fe 78 40 00 40 06 25 40 0a 00 02 02 0a 00 .<.x@.@.%@......
0020 01 02 b8 e6 1b 58 4d 0e 47 f3 00 00 00 00 a0 02 .....XM.G.......
0030 fa f0 17 32 00 00 02 04 05 b4 04 02 08 0a da c4 ...2............
0040 22 cc 00 00 00 00 01 03 03 07 ".........
服务器 - 套接字(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))
My handcrafted SYN/ACK
0000 7e 4b 21 4b 4e 94 c6 ca 19 75 98 61 08 00 45 00 ~K!KN....u.a..E.
0010 00 3c 00 00 40 00 3f 06 24 b9 0a 00 01 02 0a 00 .<..@.?.$.......
0020 02 02 1b 58 b8 e6 b6 a4 00 00 4d 0e 47 f3 a0 12 ...X......M.G...
0030 fe 88 85 78 00 00 02 04 05 b4 04 02 08 0a 8b 18 ...x............
0040 04 5d da c4 22 cc 01 03 03 07 .]..".....
这里
(我对手工制作的 SYN/ACK 数据包的一个担忧是 TSval 的值。我将其填写为与工作场景中的非常相似。对吗?)
--------------------
如果有人能回答我的问题并解释我做错了什么,那就太棒了。
【问题讨论】:
标签: ubuntu tcp network-programming handshake