前回は、RFC 6824で定義されているMPTCPについて紹介しました。
今回は、TCPのオプション領域でやり取りされるMPTCPのシグナリングパケットを簡単に説明し、RFCで定義されているオプションのフォーマットとMPTCPのMP_CAPABLEが付いた実際のパケットを見比べてみようと思います。
TCPのオプション種別
IANAによって割り当てられたTCPのオプション種別の番号は、30(0x1e)です。RFC 6824にも以下のように記載されています。
+------+--------+-----------------------+-----------+ | Kind | Length | Meaning | Reference | +------+--------+-----------------------+-----------+ | 30 | N | Multipath TCP (MPTCP) | RFC 6824 | +------+--------+-----------------------+-----------+ Table 1: TCP Option Kind Numbers
TCPヘッダに含まれるデータオフセットは4ビットの領域です。そのため、TCPヘッダの最大長は60バイト(15(0xf) * 4byte)になります。TCPヘッダのオプション領域を除く長さは20バイトなので、40バイトの領域が使用可能です。しかし、これにはMPTCP以外のオプション(例えば、SACKなど)も含まれるので、実際にはもっと少なくなります。
MPTCPのオプションフォーマット
MPTCPのオプションフォーマットは以下の通りです。
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +---------------+---------------+-------+-----------------------+ | Kind | Length |Subtype| | +---------------+---------------+-------+ | | Subtype-specific data | | (variable length) | +---------------------------------------------------------------+ Figure 3: MPTCP Option Format
1バイトの種別、1バイトの長さ、4ビットのサブタイプ、サブタイプごとの可変長のデータで構成されています。
サブタイプ
MPTCPのサブタイプは以下の通りです。
+-------+--------------+----------------------------+---------------+ | Value | Symbol | Name | Reference | +-------+--------------+----------------------------+---------------+ | 0x0 | MP_CAPABLE | Multipath Capable | Section 3.1 | | 0x1 | MP_JOIN | Join Connection | Section 3.2 | | 0x2 | DSS | Data Sequence Signal (Data | Section 3.3 | | | | ACK and data sequence | | | | | mapping) | | | 0x3 | ADD_ADDR | Add Address | Section 3.4.1 | | 0x4 | REMOVE_ADDR | Remove Address | Section 3.4.2 | | 0x5 | MP_PRIO | Change Subflow Priority | Section 3.3.8 | | 0x6 | MP_FAIL | Fallback | Section 3.6 | | 0x7 | MP_FASTCLOSE | Fast Close | Section 3.5 | +-------+--------------+----------------------------+---------------+ Table 2: MPTCP Option Subtypes
今のところ、8つのサブタイプが定義されています。
MP_CAPABLE
1本目のTCPの経路を確立する際に送受信されるSYN、SYN+ACK、ACKにはMP_CAPABLEオプションが付きます。
フォーマット
MP_CAPABLEのフォーマットは以下の通りです。
1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +---------------+---------------+-------+-------+---------------+ | Kind | Length |Subtype|Version|A|B|C|D|E|F|G|H| +---------------+---------------+-------+-------+---------------+ | Option Sender's Key (64 bits) | | | | | +---------------------------------------------------------------+ | Option Receiver's Key (64 bits) | | (if option Length == 20) | | | +---------------------------------------------------------------+ Figure 4: Multipath Capable (MP_CAPABLE) Option
SYN+MP_CAPABLEパケット
16:02:40.938112 IP (tos 0x0, ttl 64, id 23372, offset 0, flags [DF], proto TCP (6), length 72) 192.168.101.2.51080 > 192.168.109.2.5001: Flags [S], cksum 0x5390 (incorrect -> 0xbf55), seq 801567604, win 29200, options [mss 1460,sackOK,TS val 1091640 ecr 0,nop,wscale 7,mptcp capable csum {0x2bbab124627e8eb8}], length 0 0x0000: 0004 0001 0006 a036 9fa1 459f 0000 0800 0x0010: 4500 0048 5b4c 4000 4006 8c0e c0a8 6502 0x0020: c0a8 6d02 c788 1389 2fc6 f374 0000 0000 0x0030: d002 7210 5390 0000 0204 05b4 0402 080a 0x0040: 0010 a838 0000 0000 0103 0307 1e0c 0081 0x0050: 2bba b124 627e 8eb8
TCPヘッダのデータオフセットが0xdなので、オプション領域を含むTCPヘッダの長さは、52バイトです。
最後の12バイトがMP_CAPABLEの領域です。
0x1eがMPTCPオプション、0x0cが長さで12バイト、Subtypeが0、Versionが0、AフラグとHフラグがセットされています。Aフラグでチェックサムが必要、HフラグでHMAC-SHA1を使うことが示されています。
残る8バイト(“2bba b124 627e 8eb8”)が送信者の鍵です。
SYN+ACK+MP_CAPABLEパケット
16:02:40.957722 IP (tos 0x0, ttl 62, id 0, offset 0, flags [DF], proto TCP (6), length 72) 192.168.109.2.5001 > 192.168.101.2.51080: Flags [S.], cksum 0xfb5d (correct), seq 1342636158, ack 801567605, win 28560, options [mss 1460,sackOK,TS val 1094284 ecr 1091640,nop,wscale 7,mptcp capable csum {0xfea9ec93d4d9d142}], length 0 0x0000: 0000 0001 0006 a036 9fa1 4733 0000 0800 0x0010: 4500 0048 0000 4000 3e06 e95a c0a8 6d02 0x0020: c0a8 6502 1389 c788 5007 007e 2fc6 f375 0x0030: d012 6f90 fb5d 0000 0204 05b4 0402 080a 0x0040: 0010 b28c 0010 a838 0103 0307 1e0c 0081 0x0050: fea9 ec93 d4d9 d142
これもTCPヘッダのデータオフセットが0xdなので、オプション領域を含むTCPヘッダの長さは、52バイトです。
最後の12バイトがMP_CAPABLEの領域です。
先程と同様、AフラグとHフラグが設定され、最後の8バイト(“fea9 ec93 d4d9 d142”)が送信者の鍵です。
ACK+MP_CAPABLEパケット
16:02:40.957855 IP (tos 0x0, ttl 64, id 23373, offset 0, flags [DF], proto TCP (6), length 80) 192.168.101.2.51080 > 192.168.109.2.5001: Flags [.], cksum 0x5398 (incorrect -> 0xffc8), seq 1, ack 1, win 229, options [nop,nop,TS val 1091645 ecr 1094284,mptcp capable csum {0x2bbab124627e8eb8,0xfea9ec93d4d9d142},mptcp dss ack 3821824259], length 0 0x0000: 0004 0001 0006 a036 9fa1 459f 0000 0800 0x0010: 4500 0050 5b4d 4000 4006 8c05 c0a8 6502 0x0020: c0a8 6d02 c788 1389 2fc6 f375 5007 007f 0x0030: f010 00e5 5398 0000 0101 080a 0010 a83d 0x0040: 0010 b28c 1e14 0081 2bba b124 627e 8eb8 0x0050: fea9 ec93 d4d9 d142 1e08 2001 e3cc 6903
TCPヘッダのデータオフセットが0xfなので、オプション領域を含むTCPヘッダの長さは、最大の60バイトです。
最後の28バイト目からの20バイトがMP_CAPABLEの領域です。
送信者と受信者の鍵がそれぞれ入っています。
ここまでのパケットのやり取りで、MPTCPで使用される1本目のTCPのコネクションが確立されます。MPTCPがTCPのオプション領域を最大限に利用していることが見て取れます。
以後、他に使用可能なIPアドレス/インタフェースがある場合、ADD_ADDRオプションやMP_JOINオプションによって2本目以降のTCPのコネクションが確立されますが、それらの内容については、次回見比べてみようと思います。