0
votes

I'm learning about network protocols and socket programming in C++ (Ubuntu 20.04). I wrote simple server and client applications using socket(PF_INET, SOCK_STREAM, 0).

My network configuration is as follows:

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 it works like a charm. All messages are delivered from Bob to Chat.

As a natural next step I rewritten my server application, this time using a raw socket - socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)). The network is the same, the client application is the same. And here my problem begins. Bob sends ACK, and at first kernel was responding with RST/ACK from Chat's side. After reading some posts on forums i learnt that kernel does not have open socket on a given port at Chat's network namespace and is thinking that there is no connection and responds accordingly, which seems fine. iptables -A OUTPUT -p tcp --tcp-flags RST RST -j DROP in the Chat's network namespace resolves that. I respond to that connection myself and don't want the kernel to interfere. So back to scenario, now Bob sends ACK, Chat responds with handcrafted SYN/ACK, and receives... RST. What is the kernel doing that the Bob can't send me the proper ACK response? From the Bob's perspective frames should be correct. And kernel can't drop connection from the Chat's side, because i already blocked that.

I also did the same trick with firewall on Bob's network namespace (just for experiment as it doesn't make sense to me). From now I get FIN/ACK from the Bob.

Of course there is a probability that I can't handcraft frames properly so here is working scenario to compare with non-working one:

Working
client - 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                     ..........

server - socket(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........

Normal ACK here
--------------------

Non working
client - 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                     ".........

server - socket(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                     .]..".....

RST here

(The one concern about handcrafted SYN/ACK packet I have is the value of TSval. I fill it as very similar to the one from working scenario. Is it correct?)
--------------------

It would be amazing if someone could answer my questions and explain me what am I doing wrong.

1

1 Answers

0
votes

It looks like you're responding with incorrect ack number in your handcrafted SYN/ACK packet. It should be sequence number from SYN packet plus 1.

Compare the sequence and ack numbers from "working case":

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---/

And the "non working" case:

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---/