RFC 6691
TCP Options and Maximum Segment Size (MSS)
RFC 6691: TCP Options and Maximum Segment Size (MSS) π
okay bestie, this one's from the Internet Engineering Task Force (IETF) π It was written by D. Borman at Quantum Corporation, published in July 2012, and it's Informational, so it's not a Standards Track spec. It's ISSN 2070-1721. It updates RFC 879 and RFC 2385, and it doesn't obsolete anything. The whole point is figuring out what number goes in the TCP MSS option when IP and TCP options are in play β¨
Abstract π¦
This memo talks about what value to use with the TCP Maximum Segment Size (MSS) option, and it updates RFC 879 and RFC 2385.
Status of This Memo π
ngl this part is a bit formal, but here's the tea: this document is not an Internet Standards Track spec. It's published just to share info πΈ
It's a product of the IETF, so it reflects what the IETF community agreed on. It got public review and was approved by the Internet Engineering Steering Group (IESG). Not every IESG-approved document is eligible for any level of Internet Standard, though. See Section 2 of RFC 5741 for that.
For the current status, any errata, or how to send feedback, check http://www.rfc-editor.org/info/rfc6691.
Copyright Notice π
Copyright (c) 2012 IETF Trust and the persons identified as the document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) as they stand on the publication date. Please read these carefully, because they spell out your rights and restrictions for this document. Code Components pulled out of this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions, and they come with no warranty, as described in the Simplified BSD License.
1. Introduction π
okay so there's been some confusion about what value to use with the TCP MSS option when IP and TCP options are involved π RFC 879 [RFC879] says:
The MSS counts only data octets in the segment, it does not count the TCP header or the IP header.
the problem is that this line doesn't say what to do about IP and TCP options, even though they're part of the headers. RFC 1122 [RFC1122] clarified the MSS option, which is discussed in Appendix A, but people still seem a little lost π
1.1. Terminology π
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 [RFC2119].
2. The Short Statement β¨
Here's the main takeaway π When you calculate the value for the TCP MSS option, the MTU value SHOULD be decreased by only the size of the fixed IP and TCP headers, and it SHOULD NOT be decreased to account for any possible IP or TCP options. Then, the other half: the sender MUST reduce the TCP data length to account for any IP or TCP options it's actually including in the packets it sends. The rest of the document just expands on that, and the goal is to avoid IP-level fragmentation of TCP packets π§
The fixed TCP header is 20 bytes [RFC793], the fixed IPv4 header is 20 bytes [RFC791], and the fixed IPv6 header is 40 bytes [RFC2460]. Deciding which MTU value to use, especially for multi-homed hosts, is outside the scope of this document π«Ά
3. MSS in Other RFCs π¦
3.1. RFC 879 πΈ
RFC 879 [RFC879] covers the MSS option and some other stuff. In the Introduction, it says:
THE TCP MAXIMUM SEGMENT SIZE IS THE IP MAXIMUM DATAGRAM SIZE MINUS FORTY.
In Section 13, it says:
The definition of the MSS option can be stated: The maximum number of data octets that may be received by the sender of this TCP option in TCP segments with no TCP header options transmitted in IP datagrams with no IP header options.
both of those are correct π But then, in the next paragraph (Section 14), it muddies things by saying the consequence is:
When TCP is used in a situation when either the IP or TCP headers are not minimum and yet the maximum IP datagram that can be received remains 576 octets then the TCP Maximum Segment Size option must be used to reduce the limit on data octets allowed in a TCP segment. For example, if the IP Security option (11 octets) were in use and the IP maximum datagram size remained at 576 octets, then the TCP should send the MSS with a value of 525 (536-11).
and that's where it goes wrong π The simpler, more correct version would be:
When TCP is used in a situation where either the IP or TCP headers are not minimum, the sender must reduce the amount of TCP data in any given packet by the number of octets used by the IP and TCP options.
3.2. RFC 2385 π
RFC 2385 [RFC2385] incorrectly says, in Section 4.3:
As with other options that are added to every segment, the size of the MD5 option must be factored into the MSS offered to the other side during connection negotiation. Specifically, the size of the header to subtract from the MTU (whether it is the MTU of the outgoing interface or IP's minimal MTU of 576 bytes) is now at least 18 bytes larger.
this is wrong, bestie π The MSS option value only gets adjusted for the fixed IP and TCP headers.
4. Clarification from the TCP Large Windows Mailing List π
The first clarification was sent to the TCP Large Windows mailing list in 1993 [Borman93], and this section is based on that message π
The MSS value sent in an MSS option should equal the effective MTU minus the fixed IP and TCP headers. Since both IP and TCP options get ignored when calculating the MSS option, if there are any IP or TCP options going out in a packet, the sender must decrease the TCP data size to match. Here's the reason, in table form π
+--------------------+--------------------+
| MSS is adjusted | MSS isn't adjusted |
| to include options | to include options |
+--------------------+--------------------+--------------------+
| Sender adjusts | Packets are too | Packets are the |
| packet length | short | correct length |
| for options | | |
+--------------------+--------------------+--------------------+
| Sender doesn't | Packets are the | Packets are too |
| adjust packet | correct length | long |
| length for options | | |
+--------------------+--------------------+--------------------+
The goal is to avoid sending IP datagrams that have to be fragmented, and packets sent with the constraints in the lower right of this grid will cause IP fragmentation π± The sender can't know whether the received MSS option was adjusted to include options. So the only way to guarantee the packets aren't too long is for the data sender to shrink the TCP data length by the size of the IP and TCP options. Since the sender is already adjusting the TCP data length for IP and TCP options, there's no need to include those option lengths in the MSS value π
There's another reason not to bake options into the MSS value. The MSS is a fixed number, but IP and TCP option lengths vary, so the MSS can never accurately reflect every possible combination of options. The only party that knows exactly how many IP and TCP options are in any given packet is the sender. That's why the sender should be the one adjusting the TCP data length for IP and TCP options β¨
5. Additional Considerations πΈ
5.1. Path MTU Discovery π§
The TCP MSS option sets an upper bound on the size of packets that can be received. So if you set the MSS option too small, it can hurt Path MTU Discovery's ability to find a larger path MTU π For more on Path MTU Discovery, check out:
- "Path MTU Discovery" [RFC1191]
- "TCP Problems with Path MTU Discovery" [RFC2923]
- "Packetization Layer Path MTU Discovery" [RFC4821]
5.2. Interfaces with Variable MSS Values π¦
The effective MTU can sometimes change, like when variable compression is in use, e.g., RObust Header Compression (ROHC) [RFC5795]. TCP is tempted to advertise the biggest possible MSS, so it can make the most of compressed payloads π The catch is that some compression schemes occasionally have to send full headers (so payloads get smaller) to resynchronize state at their endpoint compressors/decompressors. If the largest MTU is used to calculate the MSS value to advertise, TCP retransmission may interfere with compressor resynchronization π
So when the effective MTU of an interface varies, TCP SHOULD use the smallest effective MTU of that interface to calculate the value to advertise in the MSS option π
5.3. IPv6 Jumbograms π
To support TCP over IPv6 jumbograms, implementations need to be able to send TCP segments larger than 64K π RFC 2675 [RFC2675] defines that a value of 65,535 is to be treated as infinity, and Path MTU Discovery [RFC1981] is used to determine the actual MSS.
5.4. Avoiding Fragmentation π
Packets that are too long will either get fragmented or dropped. If they're fragmented, intermediary firewalls or middle boxes may drop the fragmented packets. Either way, when packets get dropped, the connection can fail, so it's best to avoid generating fragments ππ«Ά
7.2. Informative References β¨
Okay bestie, these are the extra reads that back up the story but aren't strictly required to implement it π. Here's the full list, exactly as it's written in the spec:
[Borman93] Borman, D., "TCP MSS & Timestamps", Message to the tcplw
mailing list, January 7, 1993.
[RFC1191] Mogul, J. and S. Deering, "Path MTU discovery", RFC 1191,
November 1990.
[RFC1981] McCann, J., Deering, S., and J. Mogul, "Path MTU
Discovery for IP version 6", RFC 1981, August 1996.
[RFC2385] Heffernan, A., "Protection of BGP Sessions via the TCP
MD5 Signature Option", RFC 2385, August 1998.
[RFC2923] Lahey, K., "TCP Problems with Path MTU Discovery",
RFC 2923, September 2000.
[RFC4821] Mathis, M. and J. Heffner, "Packetization Layer Path MTU
Discovery", RFC 4821, March 2007.
[RFC5795] Sandlund, K., Pelletier, G., and L-E. Jonsson, "The
RObust Header Compression (ROHC) Framework", RFC 5795,
March 2010.
Appendix A. Details from RFC 793 and RFC 1122 π
Okay, this appendix is where the MSS details get really juicy π§. It starts with what RFC 793 [RFC793] says about the MSS option. The vibe is that the option tells the other side the biggest segment this TCP can receive, and it only shows up in the very first connection request. If the option isn't used at all, then any segment size goes π . The exact wording is:
Maximum Segment Size Option Data: 16 bits
If this option is present, then it communicates the maximum
receive segment size at the TCP which sends this segment. This
field must only be sent in the initial connection request
(i.e., in segments with the SYN control bit set). If this
option is not used, any segment size is allowed.
Next up is RFC 1122 [RFC1122], which clarifies things in Section 4.2.2.6, on pages 85-86 π«Ά. First, it changes what happens when the MSS option is missing. Here's the quote:
If an MSS option is not received at connection setup, TCP MUST
assume a default send MSS of 536 (576-40) [TCP:4].
So the default is a send MSS of 536, which is 576 minus 40. Then RFC 1122 explains how to pick the value you actually put in the MSS option. The rule is that it has to fit under a formula built from the reassembly limit:
The MSS value to be sent in an MSS option must be less than or
equal to:
MMS_R - 20
where MMS_R is the maximum size for a transport-layer message that
can be received (and reassembled). TCP obtains MMS_R and MMS_S
from the IP layer; see the generic call GET_MAXSIZES in
Section 3.4.
Here's the tea β. The spec never actually says the 20 is the size of the fixed TCP header, but that's what it's implying. Then, over in Section 3.3.2 (on page 57), MMS_R gets defined in terms of EMTU_R:
MMS_R = EMTU_R - 20
The reason for that 20 is that it's the minimum size of an IP header π¦. The page 56 bit (also Section 3.3.2) defines EMTU_R like this:
We designate the largest datagram size that can be reassembled by
EMTU_R ("Effective MTU to receive"); this is sometimes called the
"reassembly buffer size". EMTU_R MUST be greater than or equal to
576, SHOULD be either configurable or indefinite, and SHOULD be
greater than or equal to the MTU of the connected network(s).
Now here's the plot twist π. EMTU_R is the biggest datagram you can reassemble, not the biggest one you can receive without fragmentation. Those are two very different vibes. If you take it literally, since most modern TCP/IP stacks can reassemble a full 64K IP packet, you'd end up using 65535 - 20 - 20, which comes out to 65495 for the MSS option. But it's not that simple, bestie. RFC 1122 also says, on page 86:
The choice of TCP segment size has a strong effect on performance.
Larger segments increase throughput by amortizing header size and
per-datagram processing overhead over more data bytes; however, if
the packet is so large that it causes IP fragmentation, efficiency
drops sharply if any fragments are lost [IP:9].
So bigger isn't always better π. Once a packet gets big enough to fragment, losing even one fragment makes everything fall apart. The implementations ignore the "greater than or" part thing is the key bit here. Any IP datagram that's bigger than the MTU of the connected network has to get fragmented before it can be received, so implementations just skip that clause from the RFC 1122 "SHOULD" sentence quoted above. That means the MSS value you send has to be less than or equal to this formula:
EMTU_R - FixedIPhdrsize - FixedTCPhdrsize
In that formula, FixedTCPhdrsize is 20, and FixedIPhdrsize is 20 for IPv4 and 40 for IPv6 π. So the number you put in the MSS option depends on which IP version you're running, and it has to stay in that safe zone. Main character energy for the protocol, honestly β¨.
Author's Address
David Borman
Quantum Corporation
Mendota Heights, MN 55120
EMail: david.borman@quantum.com
π¦ where this page comes from
- ietf: rfc6691 2012-07
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms