IPsec トンネルを通る G.729 パケットを 1 個数える
G.729 の計算例は、ペイロード、RTP、ESP、Ethernet フレーミングがどう積み上がるか、そして同じ通話が境界ごとに違う帯域を食う理由を示す。
IPsec 上の音声はコーデックのビットレートで語られるが、その数字はコーデック自身の境界以外のどの境界でも間違っている。音声は 8 kbit/s で、それを運ぶパケットはより大きく、ESP の外殻はさらに大きく、Ethernet フレームはトンネル上のキャプチャには決して現れないフレーミングを加える。決められた形式から一つのパケットを数えることが、物理リンクが実際に何を運ぶかを知る唯一の方法である。以下の道筋は片方向だけを扱い、ここにある数字はすべて算術であって測定ではない。
コーデックの数字ではなく、パケット化の選択から始める
コーデック表が与えるのはペイロードのレートだけで、それ以外は何もない。G.729 は 8 kbit/s を出し、これは 30 ms ごとに 30 バイトの音声である。ヘッダ、保護、フレーミングについては何も語らず、結果を支配するのはこの三つである。間隔は両端が合意すべき方針の選択なので、まずこれを選んで明示する。以降の数字はすべてその一つの決定に依存する。
この例は 30 ms を使うので、パケットレートは毎秒 33.3 である。12 バイトの RTP ヘッダ、8 バイトの UDP ヘッダ、オプションなしの 20 バイトの内側 IPv4 ヘッダを前提とし、SRTP、ヘッダ圧縮、トラフィックフロー機密性のパディングはないものとする。どれかが変われば予算も動くので、前提は答えの隣に置くべきである。
内側のヘッダを加え、次に ESP の外殻を加える
アプリケーションはペイロードに RTP、UDP、IP を加えて送り、このパケット化では 70 バイトになる。この内側の流れは 18.7 kbit/s になり、すでにコーデックレートの二倍を超える。パケットの大半を占めるのは音声ではなくヘッダだからである。そのバイトはどれも声ではなく、アドレス指定と順序付けの代価である。トンネルの上で取ったキャプチャはまさにこの数字を示し、通話は小さいと言うときに人々が引くのはこの数字である。
これはケーブルに決して届かない数字でもある。ESP トンネルモードは 8 バイトの SPI とシーケンス番号、AES-GCM 用の 8 バイトの明示的 IV、2 バイトのトレーラ、16 バイトの認証タグを加える。70 バイトのペイロードにトレーラを足すと 72 になり、これは四バイト境界の整合をすでに満たすので、ここでは追加のパディングは要らない。RFC 4106 は GCM の IV とタグの大きさを定めており、どちらも脚注ではなく算術に入る:
30 payload, G.729 at 30 ms
12 RTP
8 UDP
20 inner IPv4
--
70 inner IP packet
8 ESP SPI and sequence
8 explicit IV
2 pad length and next header
16 authentication tag
--
104 ESP packetNAT 通過が必要とする外側のヘッダを加える
ESP の外殻の外側には 20 バイトの外側 IPv4 ヘッダと NAT 通過用の 8 バイトの UDP ヘッダがあり、パケットは 132 バイトになる。UDP カプセル化があるのは、パケットが二者間の変換装置を生き延びねばならないためで、保護されたペイロードに触れずに外側の形を変える。毎秒 33.3 パケットでは、132 バイトはおよそ 35.2 kbit/s であり、コーデックの公称レートのほぼ四倍にあたる。
タグも IV も、小さく見せるために見積もりから落とすことはできない。どちらもリンクが実際に運ぶものの一部だからである。それらを省いた見積もりは、受信側が拒否するパケットを記述していることになる。保護領域の内側でペイロードの境界と次のヘッダを示すために存在するトレーラも同じである。
数字を引く前に境界を名指しする
外側 IP の数字はまだ Ethernet フレーミングを含まない。タグ付きでもタグなしでも、アクセスリンクは 14 バイトの MAC ヘッダと 4 バイトのフレーム検査系列を加え、フレームを 150 バイトにする。これがスイッチポートが数える大きさである。同じパケットレートでこれは 40 kbit/s、コーデックレートの五倍であり、その差は無駄ではなく運搬の代価である。
| Boundary | Packet size | Rate at 33.3 packets/s | What it counts |
|---|---|---|---|
| Codec payload | 30 bytes | 8.0 kbit/s | The audio alone |
| Inner IP packet | 70 bytes | 18.7 kbit/s | Application headers included |
| Outer IP packet | 132 bytes | 35.2 kbit/s | ESP and NAT-T included |
| Ethernet frame | 150 bytes | 40.0 kbit/s | Link framing included |
40 kbit/s という数字は、プリアンブル、フレーム間ギャップ、VLAN タグ、事業者によるカプセル化、RTCP、シグナリング、そして逆方向に流れる音声をまだ含んでいない。これは片方向あたりの見積もりであって、リンクの予約ではない。これを予約として引くと、ある場所でリンクが確保すべき量を過大に、別の場所では過小に語ることになる。ホスト上のキャプチャはリンクが加えるフレーミングを取り逃すこともある。だからこそ 数字と並べて境界を名指しする必要があり、境界の表が一つの見出しの数字より役に立つのである。数えなかった方向については別に確保すること。
算術をインターフェースと突き合わせる
見積もりを信じる前に、既知のパケット数に対してインターフェースが報告する値と比べる。トンネルデバイスではなく物理インターフェースでキャプチャし、勘定に入れたいフレーミングが含まれるようにし、完全な一致ではなく小さな食い違いを期待する。
sudo tcpdump -ni eth0 -c 50 'udp port 4500'
ip -s link show eth0キャプチャは外側のパケットサイズを裏付け、インターフェースのカウンタはフレーミングを含めたレートを示す。両者が Ethernet の許容量ほど違えば、算術は正しく、境界の名付けだけが誤っていたことになる。フレームヘッダ一つよりはるかに大きな差は、再送やインターフェースを共有する別のフローなど、リンク上の別の何かを指している。パケット化間隔、保護スイート、境界を数字の隣に書くこと。この三つを欠いた見積もりは、次に読む人によって測定として引用される。