Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

out of order FIN packet and overwrite?

While going through an open source code-base, I was thinking of an interesting scenario. Lets say after the successful TCP connection establishment , A TCP client has to send a packet with sequence number = 101. Instead it sends a FIN with sequence number 201. Now that the TCP server thinks FIN as out of order and queues it and waits for a data packet to arrive. My question is what should be the behavior of a TCP end point according to RFC, if a server receives a data packet with sequence number = 101 and length = 150. Does it overwrite the FIN sent earlier? Or server trims the data packet till the FIN sequence number? Or it dependent on the TCP implementations?

like image 640
kumar Avatar asked Sep 27 '22 10:09

kumar


1 Answers

According to some paragraphs in RFC 793

"3. If the connection is in a synchronized state (ESTABLISHED, FIN-WAIT-1, FIN-WAIT-2, CLOSE-WAIT, CLOSING, LAST-ACK, TIME-WAIT), any unacceptable segment (out of window sequence number or unacceptable acknowledgment number) must elicit only an empty acknowledgment segment containing the current send-sequence number and an acknowledgment indicating the next sequence number expected to be received, and the connection remains in the same state."

....

"A natural way to think about processing incoming segments is to imagine that they are first tested for proper sequence number (i.e., that their contents lie in the range of the expected "receive window" in the sequence number space) and then that they are generally queued and processed in sequence number order.

When a segment overlaps other already received segments we reconstruct the segment to contain just the new data, and adjust the header fields to be consistent."

...

My Resposne: Remember that if this happen, it is because of a bad-behaving TCP at the client. Not for the out-of-order but for the wrong sequence in the segment with the FIN flag. Or maybe an attack.

When TCP, in the server side, receives the segment with SEQ=201, it will store this segment for a limited time and will send back an ACK for 101 because it is waiting for that SEQ number. Then when the segment with SEQ=101 arrives, TCP in the receiving side, after receiving the segment with SEQ=101 will have a new receive window. From the first arrived segment with SEQ=201, it should get only the data beyond Byte 251 (in my test instead of doing this it removed the overlapping Bytes from the segment with SEQ=101 - This might be implementation dependent), if any, and accept the FIN. The receiving TCP will send back an ACK. When the socket is closed in the server side, the receiving TCP will send back a [FIN, ACK] segment.

To test it I have a client that does exactly what you described (this is done with raw sockets in user space, it's not possible to simulate it with TCP sockets. The server is a simple nodejs server), a FIN segment is sent and 15 seconds later the previous segment is sent. The server reads the data received and after 10 seconds it closes the socket.

Here is the tcpdump, you can see TCP server side responses:

    [rodolk@localhost ~]$ sudo tcpdump -i p2p1 -vv tcp
tcpdump: listening on p2p1, link-type EN10MB (Ethernet), capture size 65535 bytes
19:33:03.648216 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 40)
    192.168.56.101.16345 > 192.168.56.1.webcache: Flags [S], cksum 0x5f49 (correct), seq 523645, win 500, length 0
19:33:03.649826 IP (tos 0x0, ttl 128, id 26590, offset 0, flags [DF], proto TCP (6), length 44)
    192.168.56.1.webcache > 192.168.56.101.16345: Flags [S.], cksum 0x1ac8 (correct), seq 1576251572, ack 523646, win 8192, options [mss 1460], length 0
19:33:03.651208 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 40)
    192.168.56.101.16345 > 192.168.56.1.webcache: Flags [.], cksum 0x5091 (correct), seq 1, ack 1, win 500, length 0
19:33:03.651567 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 74)
    192.168.56.101.16345 > 192.168.56.1.webcache: Flags [F.], cksum 0x8121 (correct), seq 122:156, ack 1, win 500, length 34
19:33:03.651891 IP (tos 0x0, ttl 128, id 26591, offset 0, flags [DF], proto TCP (6), length 40)
    192.168.56.1.webcache > 192.168.56.101.16345: Flags [.], cksum 0x5314 (correct), seq 1, ack 1, win 65392, length 0
19:33:18.652083 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 171)
    192.168.56.101.16345 > 192.168.56.1.webcache: Flags [P.], cksum 0xf973 (correct), seq 1:132, ack 1, win 500, length 131
19:33:18.652834 IP (tos 0x0, ttl 128, id 26593, offset 0, flags [DF], proto TCP (6), length 40)
    192.168.56.1.webcache > 192.168.56.101.16345: Flags [.], cksum 0x5313 (correct), seq 1, ack 157, win 65237, length 0
19:33:28.661041 IP (tos 0x0, ttl 128, id 26594, offset 0, flags [DF], proto TCP (6), length 40)
    192.168.56.1.webcache > 192.168.56.101.16345: Flags [F.], cksum 0x5312 (correct), seq 1, ack 157, win 65237, length 0
19:33:28.961756 IP (tos 0x0, ttl 128, id 26595, offset 0, flags [DF], proto TCP (6), length 40)
    192.168.56.1.webcache > 192.168.56.101.16345: Flags [F.], cksum 0x5312 (correct), seq 1, ack 157, win 65237, length 0
like image 94
rodolk Avatar answered Oct 18 '22 14:10

rodolk