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.

Easily said:

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

Frame Network Layer: Packet

Packet Transport Layer TCP: Segment

Segment Transport Layer UDP: UDP Datagramm

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

for MTU reduction can occur elsewhere in the communication path

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

and in the

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) :

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 :

4.2.2.5 TCP Options: TCP MUST be able to receive a TCP option in any segment. … 4.2.2.6 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

of the at least the of The maximum size of an IP datagram is 65535 due to the length of the field.

of an is 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.

Glossary:

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 i f UDP is in use