The relationship between the Maximum Transmission Unit (MTU) and the Maximum Segment Size (MSS)
Or how the Maximum Segment Size influences a TCP Session
A few days ago I have read an answer about the Maximum Segment Size (MSS) at the Wireshark Q&A site.
The answer had shacked me up a little bit, because the author wrote that the MSS is not negotiated. First I had thought that I missed something big in my understanding of the Maximum Segment Size (MSS). But after a dive into the world of the RFCs I realized that I have just misinterpreted /mistranslated the authors statement.
It is like I have thought already. The MSS is an announced limitation. And of course is this limit not negotiable and in the most cases the smallest announced MSS inside a session is the limit for both sides of this session.
With this said, everybody who just wanted to know that thing can stop reading, now.
All others who want to dive deeper should continue reading…
But it will be a little bit, like a ride in a rollercoaster, because we have to go up and down the layers of the TCP/IP stack. This article describes the relationship between the MTU and the MSS, when IPv4 is in use. With the use of IPv6 some things may vary.
We start the dive with a sharp look at some basic definitions in the world of a “TCP/IP packet”.
The TCP/IP protocol stack
First of all, we should remember us, at the four layers of the TCP/IP protocol Suite. The next drawing will show us, where the different protocols of TCP/IP stack reside compared to the OSI model. Also it will show us which protocols are used at the different layers.
This remembered, we can have a look at the names of the Procol Data Units (PDU) of each layer.
- Ethernet (Link Layer): Frame
- Network Layer: Packet
- Transport Layer TCP: Segment
- Transport Layer UDP: UDP Datagramm
- Application Layer: Data
Sometimes the PDU at the network layer is called the IP datagram instead of packet. But these definitions could not be used in an equal way. Because a packet can either be a whole IP datagram or a fragment of an IP datagram, if fragmentation has occurred (Short story about IP ID…).
The Maximum Transmission Unit (MTU)
As we have seen so far, the Transmission Unit is the data of Link Layer. So the Maximum Transmission Unit defines the limit of the number of bytes which are allowed to send at this link. (Remember: The PDU called the “IP Packet”, is the transported data at the link layer)
Typical MTUs are:
The MTU limits the amount of data at the link layer and is dependent from the individual link and we have some interesting facts around it.
- It is more or less a physical limit
- It is specified for each link separately
- MTU reduction can occur elsewhere in the communication path
- The sender and receiver doesn´t know anything about the limitation in the path
- As a mitigation Path MTU Discovery has been developed
As we can see the MTU is a strong limitation. A lot of people, at least in Germany, might know about the tuning of the MTU size to 1492 Byte to avoid fragmentation for the usage with DSL routers. The MTU of DSL is 1500 Bytes, but DSL adds an 8 Byte PPoE header somewhere at the DSL router to the packet. So that the resulting IP packet at the WAN link is 1508 Byte and needs to be fragmented. But nowadays this issue is normally mitigated by the usage of “Path MTU Discovery”. Which was not very common in these early days of DSL.
But we come back to MTU later again. Now we go on to the TCP Header and its Maximum Segment Size (MSS) option.
The Maximum Segment Size (MSS)
Mainly there are three RFCs which handle the behaviour and the definition of the Maximum Segment Size(MSS) :
- RFC 793, Transmission Control Protocol, September 1981
- RFC 879, TCP Maximum Segment Size, November 1983
- RFC 1122, Requirements for Internet Hosts — Communication Layers, October 1989
So what do they tell us about the MSS?
- First the RFC 793 tells us that the “Maximum Segment Size (MSS) is an option of the TCP header and it must be sent only when the SYN bit is set.
- Furthermore, the RFC 793 had defined the obsolete definition that any segment size is allowed if the MSS is not advertised, but it is updated by RFC 879 and all later ones.
- The RFC 879 defines that every host must be able to receive IP datagrams with the size of 576 octets.
- The RFC 879 also defines the default TCP Maximum Segment Size (MSS) with 536. And that a host is only allowed to send a larger segments, if he has received a MSS option. does not
The RFC1122 defines the following interesting behaviours :
18.104.22.168 TCP Options: TCP MUST be able to receive a TCP option in any segment. … 22.214.171.124 Maximum Segment Size Option: TCP MUST implement both sending and receiving the Maximum Segment Size option TCP SHOULD send an MSS (Maximum Segment Size) option in every SYN segment when its receive MSS differs from the default 536, and MAY send it always. If an MSS option is not received at connection setup, TCP MUST assume a default send MSS of 536 (576-40) [TCP:4]. The maximum size of a segment that TCP really sends, the "effective send MSS," MUST be the smaller of the send MSS (which reflects the available reassembly buffer size at the remote host) and the largest size permitted by the IP layer
Summarized the RFC1122 defines the following:
- TCP Options are allowed in every TCP segment
- It recommends the sending of MSS option within the SYN packet. Otherwise the default MSS of 536 octets is in use
- The MSS option MAY be send within every TCP segment
- The effective packet size is defined by the smaller value of received (MSS – 40) or own MTU
At last we have the informational RFC6691 TCP Options and Maximum Segment Size, 2012. This RFC makes suggestions how to handle the MSS if the sum of the IP and the TCP headers is greater than 40 octets. The RFC6691 suggests that the sender has to alter the received MSS transparently by himself at each time he wants to send a ip datagram, because he is the only one who knows how much longer the headers are.
This is of course a very smart way to handle this problem, but we will see if this suggestion will be implemented by the manufacturers.
So with all this said, we can reliable say how the MSS works, now:
- If no MSS is advertised the maximum allowed segment size is 536.
- A host is only allowed to send a larger segment if had received an larger MSS options in the actual session.
- Normally the MSS is send inside the SYN segments
- The maximum IP datagram size which a host is allowed to send is defined either by the received MSS limit or the own MTU limit. The smaller value of this both is the limit which counts.
- The maximum MSS is calculated at the TCP layer by adding 40 Bytes to the allowed MTU size. This could cause problems if IPsec or TCP options like Timestamps are in use
Now we can reliable say that the MSS is not negotiable.
It is like the most people would say an announced limit.
And in the most cases, it is effective for both sides. For one side of the session the MSS is the countable limit and for the other side the MTU is the countable limit, so that both sides use the same effective size of IP datagram.
The other protocols:
But what about the other protocols, which don´t have the TCP MSS option?
Let´s have a look at the RFC792 INTERNET PROTOCOL, 1981:
In the definition of the Total Length field of the IP header the following is defined:
Total Length: 16 bits Total Length is the length of the datagram, measured in octets, including internet header and data. This field allows the length of a datagram to be up to 65,535 octets. Such long datagrams are impractical for most hosts and networks. All hosts must be prepared to accept datagrams of up to 576 octets (whether they arrive whole or in fragments). It is recommended that hosts only send datagrams larger than 576 octets if they have assurance that the destination is prepared to accept the larger datagrams.
So we can see:
- Every host of the TCP/IP protocol suite MUST at least support the IP datagram size (MTU) of 576
- The maximum size of an IP datagram is 65535 due to the length of the field.
- A host should only send larger datagrams if he has assurance that the destination supports it
If we look at the different protocols especially aplications that use UDP we can see that most of them do not generate larger IP datagrams then 576 octecs. And if they do, they will mostly allow the fragmentation of the IP datagrams. So that we don´t need to be surprised any longer, if we see UDP datagrams with the “Fragmentation Allowed Bit” set wihin their IP header.
Are their any questions left, so far? Feel free to contact me.
Frame PDU of the Link Layer IP Datagram Unfragmented PDU of the Network Layer (before fragementation or after reassembly) IP IPv4 - Internet Protocol Version 4 IPv6 Internet Protocol Version 6 MTU Maximum Transmission Unit Maximum Transmission Unit Defines the limit of bytes which can be transmitted at this link Packet PDU of the Network Layer; IP datagram or a fragment of an IP datagramm PDU Protocol Data Unit Protocol Data Unit Layer specific data consist of Layer Header and Data Example Network Layer: IP Header + IP Data -> forms the PDU of the network layer called packet Segment PDU of the Transport Layer if TCP is in use Service Data Unit The PDU of the actual layer is the SDU of the layer below the actual layer PDU (n) = SDU (); n = Actual Layer Transmission Unit The Data of the Link Layer UDP Datagram PDU of the Transport Layer if UDP is in use
Great analysis, Christian. Love the way you laid it out, and it’s very informative. Thanks!
Thank you, John!
Nice article – I think it would make sense to link to the mentioned Q&A post, because some readers of your blog may want to take a look at what got you startled in the first place (I didn’t realize it was my post you talked about when reading it the first time). And you can use my name in your blog posts anytime you want, even if it is to criticize what I said or did 😉
BTW, with IPv6 minimum MTU is 1280 (I guess you know that already, but in your post you stated “Every host of the TCP/IP protocol suite MUST at least support the IP datagram size (MTU) of 576” – for IPv6, any MTU lower than 1280 is invalid)
first of all I want to thank you for the valueable comment and the permission to use your name in my posts, of course you have the same permission with my name at your blog. 😉
Indeed you pointed out two good hints:
– The link is set at this moment.
– The second point with IPv6 is a very good hint, to everybody. Yes, this post is mainly focused at IPv4. With IPv6 is some things like fragmentation or minimum allowed MTU and others can vary.
Easily said: I haven´t looked at the RFCs around IPv6 for this post.