Identifying last packet in a message sent by TCP - networking

Say we have sender A sending a message to receiver B using TCP. Say the message to be sent from A to B is split into three packets of length 500 bytes, 500 bytes and 50 bytes, to be sent in that order. How does A indicate to B that the packet of length 50 bytes is the last part of the message? I can understand that an ACK from B to A, sent every other packet received by B, indicates using the sequence number how much data has been received by B since the last ACK was sent by B. I read that FIN is used to terminate the connection between the sender and receiver. However, I can't find a description of how the the last packet, of a message split into several packets, is indicated. I'm thinking the packets have to be reassembled, in order, before the message is sent to the receiving application. I think that as one of TCPs actions is to split the message into packets, there must be some way of the sender flagging the last packet of a message has been sent.

I think that as one of TCPs actions is to split the message into
packets
No, TCP takes a stream of data and segments it into PDUs called segments. It is IP that uses the TCP segments as the payload of IP packets, which are in turn the payload of the data-link protocol, e.g. ethernet, frames.
However, I can't find a description of how the the last packet, of a
message split into several packets, is indicated.
Something like that is up to a higher protocol, e.g. HTTP. I think you are looking at TCP the wrong way. A TCP connection is like a bidirectional pipe; whatever you put in one end comes out the other end. TCP has no idea of the data structure, it just sends whatever it gets from the application or application-layer protocol. When an application or application-layer protocol is through using the connection, it tells TCP to tear it down.
The receiving TCP simply receives data and reorders it, asking for lost or missing segments. It passes properly ordered data up to the application or application-layer protocol, having no idea of the data structure because it is just a data stream to TCP.
Also, remember that both ends of a TCP connection are peers that can send and receive, and either end can send a segment with FIN that tells the other end that it is done sending, but the end sending the FIN is obligated to continue to receive until the other end also sends a FIN to say it is done sending. Either side could also kill the connection with a RST segment.
there must be some way of the sender flagging the last packet of a
message has been sent.
Probably, but that is not the job of TCP, that is up to the application or application-layer protocol. When the application-layer is done, it tells TCP to close, and that starts the FIN process. TCP has no idea what is the last part of a message is because it knows nothing about the data. It keeps the pipe open until it is told to close it.

Related

Are request and response part of two different TCP connections?

I am very new to networking, so this might sound simple. Though I have tried to look here and here and here and have got few basics of TCP, there are few questions whose answers I am not certain about.
Is a request and response part of 2 different TCP establishments. To explain that :
Is a connection established, kept alive until all packets are delivered, request sent and connection closed for each request and same happens for its response.
or
A connection is opened, request sent, connection kept alive, response arrives and connection closed.
Is the ACK number always 1 + sequence number of sent segment.
Is a request and response part of 2 different TCP establishments
You need just 3 packets to handshake and establish a bidirectional TCP connection. So no, you do not establish TCP connection for receiving and sending parts.
On the other hand, there is a sutdown() system call which allows to shutdown a part of the bidirectional connection. See man shutdown(2). So there is a possibility to establish a unidirectional connection by opening a bidirectional and then shutdown one of the sides.
Is the ACK number always 1 + sequence number of sent segment.
We usually do not send ACK for every received packet. There are also selective ACKs, retransmissions etc. So in general, the answer is no, the ACK number is not always seq + 1.
On the other hand, if you are sending a small amount of data and waiting for the confirmation, no errors or packet loss occurred, most probably there will be just one packet with that data and one ACK with seq + 1.
Hope that helps.

TCP keep-alive gets involved after TCP zero-window and closes the connection erroneously

We're seeing this pattern happen a lot between two RHEL 6 boxes that are transferring data via a TCP connection. The client issues a TCP Window Full, 0.2s later the client sends TCP Keep-Alives, to which the server responds with what look like correctly shaped responses. The client is unsatisfied by this however and continues sending TCP Keep-Alives until it finally closes the connection with an RST nearly 9s later.
This is despite the RHEL boxes having the default TCP Keep-Alive configuration:
net.ipv4.tcp_keepalive_time = 7200
net.ipv4.tcp_keepalive_probes = 9
net.ipv4.tcp_keepalive_intvl = 75
...which declares that this should only occur until 2hrs of silence. Am I reading my PCAP wrong (relevant packets available on request)?
Below is Wireshark screenshot of the pattern, with my own packet notes in the middle.
Actually, these "keep-alive" packets are not used for TCP keep-alive! They are used for window size updates detection.
Wireshark treats them as keep-alive packets just because these packets look like keep-alive packet.
A TCP keep-alive packet is simply an ACK with the sequence number set to one less than the current sequence number for the connection.
(We assume that ip 10.120.67.113 refers to host A, 10.120.67.132 refers to host B.) In packet No.249511, A acks seq 24507484. In next packet(No.249512), B send seq 24507483(24507484-1).
Why there are so many "keep-alive" packets, what are they used for?
A sends data to B, and B replies zero-window size to tell A that he temporarily can't receive data anymore. In order to assure that A knows when B can receive data again, A send "keep-alive" packet to B again and again with persistence timer, B replies to A with his window size info (In our case, B's window size has always been zero).
And the normal TCP exponential backoff is used when calculating the persist timer. So we can see that A send its first "keep-alive" packet after 0.2s, send its second packet after 0.4s, the third is sent after 0.8, the fouth is sent after 1.6s...
This phenomenon is related to TCP flow control.
The source and destination IP addresses in the packets originating from client do not match the destination and source IP addresses in the response packets, which indicates that there is some device in between the boxes doing NAT. It is also important to understand where the packets have been captured. Probably a packet capture on the client itself will help understand the issue.
Please note that the client can generate TCP keepalive if it does not receive a data packet for two hours or more. As per RFC 1122, the client retries keepalive if it does not receive a keepalive response from the peer. It eventually disconnects after continuous retry failure.
The NAT devices typically implement connection caches to maintain the state of ongoing connections. If the size of the connection reaches limit, the NAT devices drops old connections in order to service the new connections. This could also lead to such a scenario.
The given packet capture indicates that there is a high probability that packets are not reaching the client, so it will be helpful to capture packets on client machine.
I read the trace slightly differently:
Sender sends more data than receiver can handle and gets zerowindow response
Sender sends window probes (not keepalives it is way to soon for that) and the application gives up after 10 seconds with no progress and closes the connection, the reset indicates there is data pending in the TCP sendbuffer.
If the application uses a large blocksize writing to the socket it may have seen no progress for more than the 10 seconds seen in the tcpdump.
If this is a straight connection (no proxies etc.) the most likely reason is that the receiving up stop receiving (or is slower than the sender & data transmission)
It looks to me like packet number 249522 provoked the application on 10.120.67.113 to abort the connection. All the window probes get a zero window response from .132 (with no payload) and then .132 sends (unsolicited) packet 249522 with 63 bytes (and still showing 0 window). The PSH flag suggests that this 63 bytes is the entire data written by the app on .132. Then .113 in the same millisecond responds with an RST. I can't think of any reason why the TCP stack would send a RST immediately after receiving data (sequence numbers are correct). In my view it is almost certain that the app on .113 decided to give up based on the 63 byte message sent by .132.

What if a TCP handshake segment is lost?

In TCP 3-way handshake, 3 segments will be sent (SYN, SYN ACK, ACK). What if the third segment(ACK) is lost? Is the sender going to resend the segment or give up establishing the connection? And how do the two hosts know the segment is lost?
TCP has a sequence number in all packets. Hence it's easy to know if a packet was lost or not. If a host doesn't get an ACK on a packet he just resends it.
In most cases though, even if that ACK was lost, there will be no resending for a very simple reason. Directly after the ACK, the host that opened the TCP protocol is likely to start sending data. That data will, as all TCP packets, have an ACK number, so the recipient would get an ACK that way. Hence, the sender of the SYN-ACK should reasonably not care that it didn't get the ACK, because it gets an "implicit" ACK in the following package.
The re-send of the SYN-ACK is only necessary of there no data is received at all.
Update: I found the place in the RFC that specified exactly this:
If our SYN has been acknowledged (perhaps in this
incoming segment) the precedence level of the incoming segment must
match the local precedence level exactly, if it does not a reset
must be sent.
In other words, if the ACK is dropped but the next packet is not dropped, then everything is fine. Otherwise, the connection must be reset. Which makes perfect sense.
I am not an expert on this particular situation, but I suspect what will happen is the client will think it is connected but the server will not. If the client tries to send data to the server, the server will reject it and send a RST packet to the client so it can reset its "connection".

tcp: recomposing data at the end

How do TCP knows which is the last packet of a large file (that was segmented by tcp) in the scenario that the connection is kept-established. (like ftp or sending mp3 on yahoo messenger)
I mean how does it know which packet carries data of one.mp3 and which packet carries data of another.mp3 ??
Anyone ?
Thank you
There are at least 2 possible approaches.
Declare upfront how much data you're going to send. Something like a packet that declares Sending a message that's 4008 bytes long
The second approach is to use a terminating sequence (nastier to process)
So the receiver:
Tries to read the declared amount or
Scans for the terminating sequence
TCP is a stream protocol and fragmentation should be transparent to a TCP application. It operates on streams of data, never packets. A stream is assembled to its intended order using the sequence numbers. The sequence of bytes send by application is encapsulated in tcp segments. The stream is recreated on the receiver side before data is delivered to the application.
The IP protocol can do fragmentation.
Each TCP segment goes to the IP layer and may be fragmented there. Segment is reassembled by collecting all of the packets and offset field from the header is used to put it in the right place.

TCP/IP protocol and fragmentation

Using the TCP/IP protocol, given a connection between a client and a server, are the packets sent by the client to the server always received in the same order they were sent?
For example, if the client sends 3 packets of data, A, B and C, will the server always receive A first followed by B and C or is it possible for the server to receive C first, followed by A and B?
At IP level, packets may arrive in any order (if they arrive). At TCP level, the data stream is guaranteed to be ordered in the same manner on both ends.
That means yes, the server will always receive A then B then C. As long as you are using TCP.
When using TCP, data is received by the destination application in the same order as it is sent by the source application.
See the following for more details:
http://en.wikipedia.org/wiki/Transmission_Control_Protocol#Data_transfer
TCP is a transmission protocol, and it transmits data by sending the data out in IP packets over the underlying IP network. TCP is responsible for ensuring the correct transmission of the data, which includes ordering the arriving packets, re-requesting missing ones and discarding duplicates.
TCP as such does not expose any notion of "packet" to the user; the fact that the data is chunked into IP packets is a detail of the "over IP" implementation. A different implementation, e.g. TCP-over-bicycle-courier, might employ an entirely different scheme.
It cannot happen that you receive data in a different order on the application side over a TCP socket.
It may happen that packets are received in a different order by the networking layer of the OS, but TCP makes it a requirement that the upper levels get data in order. It is the OS' role to ask again for unreceived fragments etc and assemble these fragments. So, you need not worry.
UDP, on the other hand, offers no such guarantee.
The server (as the physical NIC of the machine) might receive them in any order. Your OS might receive them in any order again - that will mostly (but not allways) be the order of physical reception. Your client application is guaranteed to receive them in correct order, thats a property of TCP
In general, packets will be received in the same order they are transmitted. But the network may drop or reorder packets. For example, packets may take different routes and arrive out of order. Packets may be lost or even duplicated on the network. The TCP implementation is responsible for retransmitting packets that are lost, acknowledging packets that are received, ignoring duplicated packets, all with the objective of accurately reconstructing the transmitted byte stream at the receiver.
At the application level, you send a stream of bytes and receive a stream of bytes. TCP does whatever is needed to ensure the received stream of bytes is identical to the sent stream of bytes, regardless of what happens to the packets on the network.

Resources