要約

  • RFC 768はUDPチェックサム欄のゼロに二つの意味を割り当てた。計算結果がゼロなら0xFFFFで送信し、0x0000ならチェックサムを生成していないことを示す。
  • 1989年のホスト要件は省略を認めつつ、計算を既定で有効にした。IPv6ではチェックサムが必須となり、2013年の更新で厳しく限定したトンネル用途だけに例外が加わった。

一つの欄にある二つのゼロ

1980年8月、Jon Postelが執筆したRFC 768は、できるだけ少ない仕組みでアプリケーション間のデータグラム交換を実現するUser Datagram Protocolを定めた。UDPは順序どおりの配送、重複防止、信頼性を保証しない。ヘッダーは8オクテットで、送信元ポート、宛先ポート、長さ、チェックサムの後にデータが続く。

最後の欄には算術上の特殊な端がある。UDPはTCPと同じ16ビットの1の補数チェックサムを使う。計算対象はUDPヘッダーとデータだけではない。送信元と宛先のIPアドレス、プロトコル番号、UDP長を含む疑似ヘッダーも加わる。Postelは、この疑似ヘッダーが誤配送への保護になると説明した。

1の補数演算では、ゼロに二つのビット表現がある。全ビット0と全ビット1だ。RFC 768は、この二つをワイヤ上で別の意味に割り当てた。計算結果がゼロなら、送信側は全ビット1を送る。一方、送信された欄が全ビット0なら、チェックサムを生成しなかったことを意味する。フラグ用のビットを追加せず、計算値と状態表示を同じ欄に収めた。

この記事が扱う歴史的な論点はここに限られる。UDPの「ゼロチェックサム」は計算結果がゼロのチェックサムではない。未計算を符号化した値だ。二つの状態を混同すると、実装が有効なデータグラムを捨てたり、欠けているエラー検出を検証済みと誤解したりするおそれがある。

オプションでも既定値ではなかった

最初の仕様は、デバッグ時や上位プロトコルが気にしない場合などに、チェックサムの省略を認めていた。9年後、インターネットホスト要件を定めたRFC 1122は運用規則を明確にした。ホストはチェックサムの生成と検証を実装しなければならず、アプリケーションが生成を制御できる場合も、既定では有効にしなければならない。受信側には、チェックサムなしのデータグラムをアプリケーションへ渡すか選ぶ余地があった。

RFC 1122はよくある実装ミスも指摘した。計算結果がゼロなら65535で送信し、全ビット0は「なし」を意味する。文書は、LAN内だけで使う一部アプリケーションが効率のためにチェックサムを無効にし、多数の未検出エラーが報告されたと述べている。ただし件数、具体的な事故、母数は示していない。したがって、これは標準策定者が記録した懸念の証拠であり、普及率の測定ではない。

チェックサムは署名ではない。疑似ヘッダーは一部の誤配送を検出でき、計算は偶発的な破損の一部を検出できる。しかし送信者の認証、意図的な改変の防止、アプリケーションデータの妥当性確認はできない。「チェックサムがある」と「パケットが信頼できる」は別の主張だ。

IPv6は境界を狭めた

1998年のIPv6仕様RFC 2460はUDPチェックサムを必須にした。計算結果がゼロなら0xFFFFとし、チェックサム欄がゼロのIPv6 UDPデータグラムは受信側が破棄することになった。従来の省略マーカーは通常のIPv6 UDP通信では認められなくなった。

その後、具体的な性能上の事情が現れた。2013年のRFC 6935とRFC 6936は、限定されたUDPトンネルカプセル化に関するIPv6の処理を更新した。トンネル内のパケットには独自の完全性検査がある場合があり、外側のチェックサム計算にはコストがかかる。例外には適用条件、両端の動作、中継機器との互換性が伴う。IPv6全般でゼロチェックサムを許したわけではない。

規格の変化が示すのは、ビット列は同じでも、許容される文脈は変わったということだ。IPv4ではゼロが省略を示し、ホスト要件は計算を既定とした。IPv6では省略を当初拒み、後に外側トンネルという特定の役割に限って条件付きで認めた。数値だけでは省略の可否を判断できない。IPの版と使い方が必要だった。

出典