核心?在手工制作的 SYN/ACK 帧后发送 RST

问题描述

我正在学习 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

... aa它就像一个魅力。所有消息都从 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 那里得到 FIN/ACK。

当然有可能我无法正确地手工制作框架,所以这里是工作场景与非工作场景进行比较:

工作
客户端 - 套接字(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,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
--------------------

不工作
客户端 - 套接字(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,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 的值。我将其填充为与工作场景中的非常相似。正确吗?)
--------------------

如果有人能回答我的问题并解释我做错了什么,那就太棒了。

解决方法

看起来您在手工制作的 SYN/ACK 数据包中使用了不正确的 ack 编号进行响应。应该是SYN包的序列号加1。

比较“工作案例”中的序列号和确认号:

SYN
0020   .. .. .. .. .. .. 59 cc e9 d7 00 00 00 00 .. ..   .....XY.........
                         \---seq---/ \---ack---/
SYN/ACK
0020   .. .. .. .. .. .. cf 89 17 79 59 cc e9 d8 .. ..   ...X.....yY.....
                         \---seq---/ \---ack---/

还有“不工作”的情况:

SYN
0020   .. .. .. .. .. .. 4d 0e 47 f3 00 00 00 00 .. ..   .....XM.G.......
                         \---seq---/ \---ack---/
SYN/ACK
0020   .. .. .. .. .. .. b6 a4 00 00 4d 0e 47 f3 .. ..   ...X......M.G...
                         \---seq---/ \---ack---/

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...