Maximum segment size
Maximum Segment Size (MSS) is a key parameter in the Transmission Control Protocol (TCP) that specifies the largest amount of data, measured in bytes, that a TCP endpoint can receive in a single unfragmented segment, excluding the lengths of the TCP and IP headers.[1] Introduced in RFC 879 (1983), an early extension to the TCP specification, the MSS is negotiated during the three-way handshake for establishing a connection, where each host advertises its maximum receive segment size via a TCP option (kind 2, length 4) included in the SYN segments. This negotiation ensures that segments do not exceed the path's capabilities, thereby preventing IP fragmentation and improving transmission efficiency across diverse network paths.[2] The effective MSS used by a sender is the minimum of the value advertised by the receiver (or the default if none is received) and the sender's own maximum transmission size, adjusted for header overheads such as the IP Maximum Transmission Unit (MTU) minus 40 bytes for standard IPv4 headers (20 bytes each for IP and TCP without options).[1] If no MSS option is exchanged, TCP implementations default to 536 bytes for IPv4 networks (derived from the minimum IP datagram size of 576 bytes minus 40 bytes of headers) or 1220 bytes for IPv6 (based on a minimum MTU of 1280 bytes minus 60 bytes of headers).[2] This default value, established early in TCP's development, balances compatibility with legacy networks while allowing modern implementations to use larger values—often up to 1460 bytes on standard Ethernet (1500-byte MTU minus 40 bytes)—when path MTU discovery is supported.[3] MSS plays a critical role in TCP's reliability and performance, particularly in environments with varying link MTUs, such as the internet, where improper sizing can lead to packet blackholing or retransmissions due to fragmentation.[1] Over time, refinements in RFCs have addressed edge cases, such as handling MSS in the presence of IP options or during Path MTU Discovery (PMTUD), emphasizing that senders must clamp their segment sizes to avoid exceeding the discovered path MTU.[3] By dynamically adapting to network constraints, MSS enables robust data transfer while minimizing overhead, making it a foundational element of TCP's end-to-end design.[2]Fundamentals
Definition and Purpose
The Maximum Segment Size (MSS) is a parameter in the Transmission Control Protocol (TCP) that specifies the largest amount of data, measured in bytes, that a TCP endpoint can receive in a single segment, excluding the sizes of the TCP and IP headers. This value is advertised via the MSS option in the TCP header during connection establishment, allowing communicating hosts to agree on an appropriate segment size for their session.[4] The MSS effectively defines the payload capacity of a TCP segment, ensuring that the total packet size remains manageable within network constraints.[5] The primary purpose of the MSS is to prevent IP-layer fragmentation by limiting the data payload so that the resulting TCP segment, when encapsulated in an IP datagram, does not exceed the path's Maximum Transmission Unit (MTU).[6] By setting the MSS to fit within the available MTU after accounting for header overhead, TCP avoids the need for intermediate routers to fragment packets, which can introduce delays and inefficiency.[7] This mechanism supports efficient data transfer in TCP's connection-oriented model, where reliable delivery relies on ordered, error-checked segments without the complications of reassembly. Key benefits of using MSS include reduced retransmissions due to lower likelihood of fragmented packet loss, as incomplete fragments are often dropped entirely in IP networks.[8] It also improves overall throughput by enabling larger, more efficient payloads tailored to the network path, particularly in heterogeneous environments with varying link MTUs.[7] The MSS is typically calculated using the formula: \text{MSS} = \text{MTU} - (\text{TCP header size} + \text{IP header size}) with standard header sizes of 20 bytes for TCP (without options) and 20 bytes for IPv4, yielding an MSS of, for example, 1460 bytes on an Ethernet MTU of 1500 bytes.[6] This approach minimizes overhead and enhances the reliability of TCP's end-to-end delivery guarantees.Historical Development
The concept of Maximum Segment Size (MSS) emerged in the early development of the Transmission Control Protocol (TCP) as a mechanism to optimize data transmission and mitigate fragmentation in packet-switched networks. In the original TCP specification outlined in RFC 793, published in September 1981, MSS was introduced as an optional field in the TCP header to indicate the largest amount of data, excluding headers, that a receiver could accept in a single segment.[9] This option was intended to be exchanged during connection establishment, specifically in SYN segments, allowing endpoints to align segment sizes with underlying network capabilities and avoid inefficient IP datagram fragmentation, which was a growing concern as the ARPANET transitioned toward a more interconnected Internet.[4] Without such negotiation, TCP implementations relied on fixed assumptions about segment sizes, often leading to failures in mixed-MTU environments where network paths included links with varying maximum transmission unit (MTU) limits, such as during the early expansions beyond the ARPANET's standardized frame sizes.[10] Subsequent clarifications refined the MSS mechanism to address implementation ambiguities and evolving network realities. RFC 879, published in November 1983, provided detailed guidance on the MSS option, defining its format, default value of 536 octets (derived from the minimum IP datagram size of 576 octets minus 40 octets for headers), and its role in preventing fragmentation by ensuring TCP segments fit within IP datagrams.[10] This document emphasized that MSS negotiation operates independently in each direction of a connection, responding to the proliferation of diverse network types in the early 1980s Internet, where fixed segment assumptions frequently caused packet drops or retransmissions. As the Internet scaled from research networks like ARPANET to broader commercial and dial-up connections, these early challenges highlighted the need for dynamic size adjustment to maintain reliability.[11] Later milestones incorporated MSS into modern protocol updates, particularly with the advent of IPv6 and revised TCP standards. In 2012, RFC 6691 updated the MSS guidelines to account for IPv6's larger headers and clarified calculations, recommending that MSS values subtract only fixed header lengths (40 octets for IPv6 plus 20 for TCP) without adjusting for variable options, thereby promoting consistency across protocol versions.[12] This addressed fragmentation issues in hybrid IPv4/IPv6 environments. Finally, RFC 9293, published in August 2022, consolidated and obsoleted prior specifications including RFC 793 and RFC 879, mandating MSS option support in all TCP implementations and updating defaults to 1220 octets for IPv6 to better suit contemporary broadband and high-speed networks, where diverse link types like tunnels and mobile connections continue to drive the need for adaptive MSS to circumvent "black hole" routers that silently discard oversized packets.[13]TCP Implementation
Segment Structure
A TCP segment is composed of a fixed header followed by a variable-length data payload, with optional fields that may extend the header. The header, as defined in the original TCP specification, has a minimum length of 20 bytes and includes essential fields such as 16-bit source and destination ports, a 32-bit sequence number to track byte order, a 32-bit acknowledgment number for confirming receipt, a 4-bit data offset indicating header length in 32-bit words, 6 reserved bits (set to zero), 6 control flags (URG for urgent data, ACK for acknowledgment, PSH to push data, RST to reset connection, SYN for synchronization, and FIN to finish), a 16-bit window size for flow control, a 16-bit checksum for integrity, and a 16-bit urgent pointer if applicable.[4] Following the fixed portion are variable-length options (multiples of 8 bits) and padding to align to a 32-bit boundary, after which the payload carries the actual application data up to the negotiated maximum segment size (MSS).[4] The MSS specifically constrains the size of this payload—the TCP data octets—to ensure the total segment (header plus payload) fits within the underlying IP datagram limits without fragmentation. It represents the maximum amount of data a receiver can accept in a single segment, calculated as the maximum transmission unit (MTU) minus the combined IP and TCP header lengths (typically 20 bytes each, totaling 40 bytes), and explicitly excludes the TCP and IP headers themselves from the countable data portion.[11] Application-layer protocol headers, such as those from HTTP or TLS, are treated as part of the TCP payload and thus consume space within the MSS limit, potentially reducing the effective space for pure application data.[14] This design promotes efficient transmission by avoiding IP fragmentation, which can degrade performance.[15] For illustration, consider a common scenario on an Ethernet link with a 1500-byte MTU: an MSS of 1460 bytes allows a TCP payload of that size, combined with a 20-byte IP header and 20-byte TCP header, to exactly fill the 1500-byte packet without exceeding the limit.| Component | Size (bytes) | Description |
|---|---|---|
| IP Header | 20 | Fixed IPv4 header without options. |
| TCP Header | 20 | Minimum TCP header without options. |
| TCP Payload | 1460 | Data up to MSS limit. |
| Total | 1500 | Fits standard Ethernet MTU. |
MSS Negotiation in Handshake
During the three-way handshake for establishing a TCP connection, endpoints communicate their Maximum Segment Size (MSS) capabilities using the TCP MSS option to ensure segments do not exceed the receiver's capacity. This option, defined with Kind 2 and Length 4 bytes, carries a 16-bit value representing the maximum number of data octets the sender can receive in a segment, excluding headers.[20] The option is included exclusively in segments with the SYN control bit set, specifically the initial SYN from the client and the SYN-ACK from the server, allowing each endpoint to announce its receive MSS unilaterally.[20] The negotiation process determines the effective MSS for each direction as the minimum of the locally computed maximum (derived from the interface MTU minus fixed IP and TCP header sizes of 20 bytes each) and the value announced by the remote peer via the MSS option.[21] If no MSS option is received, implementations must fall back to a default send MSS of 536 bytes for IPv4 (corresponding to the minimum IP datagram size of 576 bytes minus 40 bytes of headers) or 1220 bytes for IPv6 (based on the minimum MTU of 1280 bytes minus 60 bytes of headers).[21] This minimum ensures compatibility with the network layer's transmission limits, preventing fragmentation at the initial setup stage.[21] In practice, the handshake proceeds as follows: The client initiates with a SYN segment proposing its MSS, commonly 1460 bytes for an Ethernet MTU of 1500 bytes after subtracting headers.[10] The server responds with a SYN-ACK segment including its own MSS proposal, and the client sends the final ACK without an MSS option, confirming the connection with the negotiated values now in effect.[22] Once established, the MSS values are fixed for the duration of the connection, with no provision for renegotiation during data transfer.[21] For IPv6 connections, the process mirrors IPv4 but accounts for the larger minimum MTU and potential jumbograms; an announced MSS of 65,535 bytes is interpreted as effectively unlimited, relying on Path MTU Discovery for actual limits.[23] If the MSS option is malformed or exceeds protocol bounds (e.g., greater than 65,535), implementations silently ignore it and revert to the default to maintain robustness.[21]Relation to Network Limits
Connection to MTU
The Maximum Transmission Unit (MTU) represents the largest packet size, including headers, that a network link can transmit without fragmentation.[24] For instance, the standard Ethernet MTU is 1500 bytes.[24] The Maximum Segment Size (MSS) is derived from the MTU by subtracting the sizes of the fixed IP and TCP headers to determine the maximum TCP payload.[3] In IPv4, with 20-byte IP and 20-byte TCP headers, the formula is MSS = MTU - 40 bytes.[3] For IPv6, which uses a 40-byte IP header, the adjustment is MSS = MTU - 60 bytes.[25] This derivation excludes variable options in the headers, requiring senders to further reduce the data length accordingly.[3] The interplay between MSS and MTU ensures that TCP segments fit within the link's capacity, preventing IP-layer fragmentation.[3] If the MSS exceeds the effective MTU minus headers, packets may be fragmented, dropped, or require inefficient reassembly, leading to performance degradation.[24] Representative calculations illustrate this relationship. For an Ethernet link with a 1500-byte MTU under IPv4, the MSS is 1460 bytes (1500 - 40).[24] In a PPPoE scenario over DSL with a 1492-byte MTU, the MSS is 1432 bytes after accounting for protocol overhead and IPv6 headers (1492 - 60).[26]Path MTU Discovery Integration
Path MTU Discovery (PMTUD) allows a sender to dynamically determine the effective maximum transmission unit (MTU) along a network path by transmitting IP packets with the Don't Fragment (DF) flag set at an initially assumed large size (such as the sender's local interface MTU), and upon receiving an ICMP "Datagram Too Big" message from an intermediate router indicating the next-hop MTU limit, the sender reduces the packet size to that MTU and may later probe with larger sizes to refine the path MTU estimate.[27] In IPv6 networks, the process is analogous, utilizing ICMPv6 "Packet Too Big" messages to signal the need for fragmentation, with the sender updating its path MTU cache based on the reported MTU value.[28] This mechanism ensures that subsequent packets avoid fragmentation, which can degrade performance, by adapting to the smallest MTU on the end-to-end path. Integration of PMTUD with maximum segment size (MSS) occurs after initial TCP handshake negotiation, where discovered path MTU values inform MSS clamping: the sender limits segment sizes to the path MTU minus the lengths of IP and TCP headers, preventing oversized packets that would otherwise be dropped or fragmented.[29] This addresses "black hole" connections, in which PMTUD fails due to silent packet drops when ICMP responses are lost, causing TCP retransmissions and potential connection stalls; RFC 4821 formalizes this by standardizing robust probing at the packetization layer to detect and adjust for such path constraints without full reliance on ICMP feedback.[29][30] A primary challenge in PMTUD is the blocking of ICMP messages by firewalls or security devices, which prevents the sender from receiving necessary feedback and leads to persistent black hole failures, particularly in environments with strict filtering policies.[29] To counter this, Packetization Layer Path MTU Discovery (PLPMTUD) employs application-layer probing—such as sending incrementally larger TCP segments or UDP datagrams—to infer path limits through timeout detection rather than ICMP, as specified in RFC 4821.[29] An extension in RFC 8899 adapts PLPMTUD for datagram-based transports like UDP, enhancing reliability in scenarios where traditional ICMP-dependent methods falter.[31] In modern IPv6 deployments, PMTUD is strongly recommended for nodes to exploit path MTUs exceeding the minimum link MTU of 1280 bytes, as fragmentation is not supported end-to-end.[25] For instance, the IPv6 minimum path MTU of 1280 bytes constrains the effective MSS to 1220 bytes to accommodate fixed header overheads, ensuring compatibility across diverse network links while avoiding discovery failures.[25]Standards and Variations
Default Values Across Protocols
In TCP, the default Maximum Segment Size (MSS) for IPv4 is 536 bytes, derived from the minimum IP datagram size of 576 bytes minus the 20-byte IP header and 20-byte TCP header.[9] For IPv6, the default MSS is 1220 bytes, based on the minimum IPv6 MTU of 1280 bytes minus the 40-byte IPv6 header and 20-byte TCP header.[25] Other protocols incorporate analogous mechanisms for segment sizing. In the Stream Control Transmission Protocol (SCTP), there is no explicit MSS option; instead, user messages are fragmented into DATA chunks sized to fit the Path MTU (PMTU), with receivers required to support at least 1500 bytes per packet to ensure interoperability.[32] The QUIC protocol (RFC 9000) uses variable framing over UDP without a traditional MSS, but sets a minimum datagram size of 1200 bytes for initial packets and path validation, effectively aligning with the IPv6 minimum MTU minus headers (approximately path MTU minus 40 bytes for IPv6 plus UDP overhead).[33] These defaults promote interoperability across diverse network paths by preventing fragmentation on links with limited MTU, such as the 576-byte minimum for IPv4 in early Internet designs.[9] The 536-byte TCP value specifically accommodates legacy infrastructure without requiring prior path knowledge.[9] Current specifications reaffirm these values while emphasizing dynamic adjustments. RFC 9293 (2022), updating TCP standards, retains the 536-byte IPv4 and 1220-byte IPv6 defaults but recommends Path MTU Discovery (PMTUD) over static limits for optimal performance, without altering legacy defaults. Similar guidance applies to SCTP and QUIC, prioritizing PMTUD for modern deployments.[32][33]Adjustments in Modern Networks
In virtual private networks (VPNs) employing IPsec, tunneling introduces header overhead ranging from 20 to 50 bytes, depending on the mode (transport or tunnel) and options like encryption integrity checks or padding. This reduces the effective maximum transmission unit (MTU), often requiring MSS clamping to avoid fragmentation; for example, with a standard 1500-byte Ethernet MTU, the MSS may be adjusted from 1460 bytes to approximately 1360 bytes in tunnel mode to accommodate the overhead. Modern TCP implementations, including Linux kernel features via iptables TCPMSS targets and Cisco IOS with theip tcp adjust-mss command, provide auto-clamping during the TCP three-way handshake, dynamically setting the MSS based on interface MTU minus 40 bytes for IP and TCP headers.[34][24][35]
Mobile and wireless networks, governed by 3GPP specifications for LTE, adjust MSS to account for radio bearer overhead, with a common MTU of 1428 bytes that reserves space for potential backhaul encryption like IPsec while fitting within the air interface limits. This value ensures efficient transmission over variable radio conditions without excessive fragmentation. In Wi-Fi (IEEE 802.11) environments, fragmentation thresholds—typically set to 2346 bytes but configurable lower to combat interference—indirectly constrain the effective L2 MTU, influencing MSS values; thresholds below the IP MTU prompt devices to fragment larger frames, increasing overhead and necessitating TCP MSS reductions to optimize performance.[36][37]
High-speed Ethernet links supporting jumbo frames enable an MTU of 9000 bytes, allowing MSS values up to 8960 bytes after subtracting 40 bytes for IP and TCP headers, which reduces per-packet overhead and boosts throughput in data centers or LANs by minimizing segmentation. However, end-to-end symmetric support is essential; mismatched devices in the path can cause fragmentation or packet drops, as jumbo frames exceed standard Ethernet limits.[38]
Emerging trends in transport protocols decouple MSS from traditional TCP mechanisms. HTTP/3 over QUIC, built on UDP, dynamically adjusts datagram sizes up to a default maximum of 65527 bytes using Path MTU Discovery (PMTUD), with initial packets padded to at least 1200 bytes for path validation and no explicit MSS negotiation. Similarly, IPv6 transition tunnels like 6to4 clamp the MTU to 1280 bytes—the IPv6 minimum—to prevent encapsulation-induced fragmentation across IPv4 infrastructures.[33][39]