3

The sequence number and acknowledgement number in the TCP header is specified to contain byte counts. However, a lot of resources, including RFCs, say that "lost segments are retransmitted" instead of "lost bytes are retransmitted".

If, for example, 4 500-byte segments were sent and the 2th and 3th segment got lost, is it allowed to retransmit bytes 500-1500 (previously sent in the 2th and 3th segment) as one segment? If yes, what are the advantages and disadvantages of retransmitting it as one segment? Does any common implementation do it? Here I assume that the MTU is big enough for the combined package all the time (the reason for the 2th and 3th segment being transmitted separately could be e.g. that Nagle's algorithm is disabled).

Does it make a difference for this question whether selective acknowledgements are used or not? Selective acknowledgements are required to avoid retransmitting the 4th segment. But does it have any other effect (on the 2th and 3th segment) in this scenario?

Looking at the Linux kernel source code, it seems like it puts segments into the output queue. It can sub-divide segments that are already in the queue (in the case the MTU decreases). In the TCP implementation I didn't see any code that reassembles smaller segments into bigger ones. However I could imagine that the TCP segmentation offload (TSO) could result in bigger segments being transmitted. I don't know if it's even possible to find out the exact segmentation boundaries. Would there be any benefit from a protocol-theoretic perspective?

  • Did any answer help you? If so, you should accept the answer so that the question doesn't keep popping up forever, looking for an answer. Alternatively, you can provide and accept your own answer. – Ron Maupin Dec 25 '18 at 9:07
3

The sending TCP receives a stream of bytes from the upper layer application and chops the stream up into a series of segments. When a segment is sent a retransmission timer is started. If an ACK equivalent to the last byte in the segment is not received before the retransmission timer expires, the entire segment is resent.

The receiver cannot ACK part of a segment as without receiving the entire segment it is unable to calculate the checksum and work out whether the segment is corrupted. So the receiver is only going to ACK whole segments, if it somehow receives part of a segment it treats it as corrupted and doesn’t ACK any of the segment. Therefore the sender is only ever retransmitting full segments.

As far as combining sequential retransmitted segments, the segments are kept in a retransmission queue (or pointers to the data) and the sender TCP doesn’t expect to do any further processing of that data, it will just send them as-is if the retransmission timer expires, there will be no combining of segments.

Excerpt from the TCP RFC confirms this:

When the TCP transmits a segment containing data, it puts a copy on a retransmission queue and starts a timer; when the acknowledgment for that data is received, the segment is deleted from the queue. If the acknowledgment is not received before the timer runs out, the segment is retransmitted.

As you can see there is no mention of recombining data, only resending the original segment.

Yes, selective ACKs matter in your example, without them only the first segment could be ACK and the last three would be retransmitted.

  • You wrote that " Therefore the receiver is only ever retransmitting full segments." Did you want to write "sender" instead of "receiver" here? I edited my question to made explicit the assumption that the MTU is big enough even for the combined segment. I'm sorry that this makes the start of your third paragraph a bit obsolete. :( – Manuel Jacob Jul 21 '18 at 10:02
  • Edited to fit the edited question – Karl Billington Jul 21 '18 at 10:15
3

The sender can retransmit segments (or essentially, bytes) as it chooses. However, it'll likely choose the largest segment size possible with the path/link MTU, so being able to combine two segments previously transmitted separately is unlikely - the MTU or MSS doesn't change on the fly.

Edit: In case the sender is using a much lower bandwidth than the channel provides, it is possible that the MSS (or MTU) isn't utilized and much smaller segments are actually sent. In that case, the sender could combine both segments' data into a single segment when resending. However, I don't think this is widely implemented.

Transmitting larger segments has the benefit if saving overhead (header data space) and thus increasing efficiency and decreasing used bandwidth. So, the largest possible segment size should be used at all times.

  • When asking the question, I made the implicit assumption that the MTU is big enough for the combined package. I edited the question to make the assumption explicit. I'm sorry that this makes parts of your answer obsolete. :( – Manuel Jacob Jul 21 '18 at 9:42
  • My point was that if the MSS (or MTU) supports sending both segments' data in a single segment, the source host would have done so right away. However, this might not be the case when the sending bandwidth is lower than the channel bandwidth. In that case: the source host could combine the segments but most often it won't. – Zac67 Jul 21 '18 at 15:06
2

The unit of measure along the stream in TCP is in bytes. The obligation upon a re-transmit is to resupply the same bytes. The segmentation may be altered.

Swapping a standards-lawyering hat for an implementor's hat you can ask "but wouldn't retransmitting the same bytes lead to the same assembly of those bytes into segments as in the original transmission?" To which the answer is "why yes, it would". It's then up the to implementer if they choose to exploit that knowledge for an efficiency gain.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.