要約

  • MSSオプションは、SYNを送る側が自分の受信可能なTCPデータ長を知らせる片方向の表明である。往路と復路の値は独立し、一つの値へ合意する手続きではない。
  • 実際の送信上限は、相手の表明、IP層が許すサイズ、当該パケットのIP/TCPオプション長を送信側が組み合わせて決める。受け取ったMSSをそのまま使うわけではない。
  • MSSは経路MTU、受信ウィンドウ、アプリケーションのレコード境界、観測されたパケット長のどれでもない。方向と時点を伴う受信上限である。

1460と1200は争っていない

RFC 793 が定めたMaximum Segment Sizeは、Kind 2、長さ4のTCPオプションだった。16ビットの値は、そのセグメントを送ったTCPが受信できる最大セグメントを示す。オプションを載せられるのはSYN付きのセグメントだけである。

この文法を向きで読む必要がある。クライアントのSYNにある1460は、サーバーがクライアントへ送るTCPデータの上限になる。サーバーのSYN-ACKにある1200は、その逆を制約する。同じ接続でも、受信バッファ、インターフェース、アドレスファミリーや実装方針が両端で同じとは限らない。値が違っても、両方とも正しい。

1983年の RFC 879 は、この動作をannouncementと呼び、「しばしば誤ってnegotiationと呼ばれる」と明記した。通常の交渉なら、提案と選択の結果として共有値が生まれる。MSSには勝者を選ぶ段階がない。各受信者が、自分の側で守れる境界だけを宣言する。

この違いは言葉遣い以上のものだ。「交渉済みMSS」を一つだけ記録すると、どちらが宣言し、どちら向きの送信を制限したのかが消える。障害時には、正しい値を誤った方向へ適用したり、非対称な制約を設定不一致と決めつけたりする。

536は受信可能性を空白にしないための値だった

初期IPv4では、ホストが受信し再構成できるべきデータグラムの基準が576オクテットだった。固定IPv4ヘッダー20、固定TCPヘッダー20を引くと、TCPデータは536になる。RFC 879はMSSがヘッダーではなくデータのオクテット数を数えると整理した。

SYNとFINはシーケンス空間を一つ消費するが、MSSのデータには含まれない。ここで「シーケンス番号を進めるもの」と「データ長として数えるもの」が分離される。TCPセグメントという語をIPデータグラム全体の長さと混同すると、この減算も方向も崩れる。

RFC 1122 はMSSオプションの送受信実装を必須にし、接続開始時に相手から値を受け取らなければIPv4では536を送信側の既定値にするよう求めた。現在の RFC 9293 はIPv6について1220も示す。IPv6の最低リンクMTU 1280から固定IPv6ヘッダー40とTCPヘッダー20を引いた値である。

オプションがないことは、相手がどんな大きさでも受け取れるという許可ではない。情報がないとき、TCPは共同最低能力に基づく保守的な上限を使う。536や1220は今日の典型的な経路を測った結果ではなく、不在の表明を埋める規則である。

相手の表明と経路の許可は別物

受信したMSSは、まだ実際に送る最大データ長ではない。RFC 1122とRFC 9293はeffective send MSSを、相手の受信上限とIP層が送れる最大サイズの小さい方から、現在のヘッダー長を考慮して求める。

相手が1460を知らせても、トンネルを含む現在の経路がそれより小さいIPパケットしか通せないなら、送信側は小さくしなければならない。逆に経路が大きなパケットを通せても、相手が1200しか受け取れないと表明したなら、それを越える権限はない。

Path MTUは途中のリンク列が課す制約であり、MSSは終端が伝える受信能力である。既存のPath MTU Discovery記事は、ルーターのエラーや端点プローブから送信者が経路サイズを学び直す過程を扱った。本稿の対象は、その計算へ入る別の証拠、すなわち相手側の方向付き上限である。

実際のセグメントが上限より小さい理由は多い。アプリケーションが十分なデータを渡していない、送受信ウィンドウが狭い、輻輳制御が制限している、再送境界がある、TCPオプションが増えた、送信スケジューラが分割した、といった場合だ。観測した小さなパケットだけからMSS書換えを断定することはできない。

可変ヘッダーを誰が数えるのか

MSSは固定値だが、IP/TCPヘッダーはパケットごとに変わり得る。ここから、タイムスタンプなど将来載るかもしれないオプション分を握手時のMSSからあらかじめ引くべきか、という長い混乱が生まれた。

RFC 6691 の結論は、広告値を計算するときは固定IP/TCPヘッダーだけをMTUから引き、可変オプション分は引かない、というものだった。その代わり、送信者は実際に組み立てるパケットに含まれるIP/TCPオプションの長さだけ、TCPデータを短くしなければならない。

未来の全パケットに何のオプションが入るかを知るのは受信者ではない。一つの固定値で全組合せを表すこともできない。送信者だけが、当該パケットの実際のヘッダーを知っている。したがって、変動分を送信時点に残す方が責任と知識を一致させる。

両者が安全側に二重計上すれば、パケットは必要以上に小さくなる。誰も計上しなければ、オプション付きパケットは過大になり、断片化または破棄を招く。RFC 6691は、RFC 879に残っていたIP Securityオプションを広告MSSから直接引く例そのものを誤りとした。古い勘定例の勘違いを現在の規則へ持ち込んではならない。

RFC 1122の式については、IPオプションが二重に引かれているというErrata 6381が提出されたが、これはRejectedである。検証注記は、IP層が予約するオプションとTCPがIPへ渡すオプションの定義を区別すれば元の計算が成立すると説明する。履歴を調べるときは、提案された訂正と採用された訂正を同じものとして扱わないことも重要である。

小さすぎる表明にも副作用がある

上限を小さくすれば常に安全、とは限らない。RFC 6691は、小さすぎるMSSがPath MTU Discoveryによる大きな経路容量の利用を妨げると警告する。接続は動いても、パケット数とヘッダー比率が増え、障害を隠したまま能力を固定的に捨てることがある。

ただし、変動MTUのインターフェースでは最良時の値を宣言するのも危険である。ヘッダー圧縮が一時的に大きな完全ヘッダーへ戻ると、再送パケットがそれまでの包絡を越えるかもしれない。RFC 6691は、そのような場合に最小の有効MTUを使って広告値を計算するよう勧告した。

IPv6 jumbogramでは、16ビットMSSの65535を無限大として扱い、実際の上限をPath MTU Discoveryに委ねる。これは経路が無限だという宣言ではない。古いフィールドの表現範囲と、別の測定機構の責任を分けるための符号化規則である。

登録番号から実装を推測しない

IANAのTCP Parameters登録簿 はKind 2、長さ4をMaximum Segment Sizeとして保持し、RFC 9293を参照する。ここから分かるのは、共通文法が現在の仕様へ連結されていることだけである。どのOSが何を広告するか、中間装置が書き換えるか、ある値のパケットが実際に通るかは分からない。

RFC 9293は2022年にRFC 793、879、6691を廃止し、RFC 1122のTCP要件を置き換えた。統合後も中心原則は同じである。受信者は自分の上限を方向付きで表明し、送信者はそれをIP層の現実と組み合わせ、可変コストはパケットを作る時点で計上する。

MSSの歴史は、ひとつの数字をどこまで信じてよいかの歴史でもある。値は重要だが、主体、方向、既定規則、計算時点を失うと意味が反転する。二つの値を一つの「交渉結果」にまとめるより、二つの責任として保存する方がTCPの実像に近い。

出典と限界

これらは仕様、改訂関係、登録状態を示す。現在の実装比率、OS既定値、MSS書換えの頻度、実経路の容量や特定障害の原因を測定する資料ではない。