メインコンテンツへスキップ

Multipath TCP(MPTCP)

NOTE
この記事は最終更新日から1年以上が経過しています。内容が古くなっている可能性があります。

Multipath TCP(MPTCP)は、複数のIPアドレス/インタフェースを同時に使用して通信することで、通信のスループットを向上させるという機能です。また、あるIPアドレス/インタフェースが使用できない状態になっても別のIPアドレス/インタフェースを使うことで、通信を継続できるという耐障害性も兼ね備えています。

そんな夢のようなMPTCPに触れる機会があったので、簡単にご紹介します。

MPTCPの仕様
#

MPTCPは、IETFによって標準化作業が進められていて、RFC 6824で仕様が定められています(現在はErrataがあるので要注意)。

RFC 6824

複数のリンクを束ねて使うリンクアグリゲーションという技術は、過去に実装した経験がありますが、この時はユーザランドでの実装でした。

コグニティブ無線評価システム開発

MPTCPのLinux実装
#

RFC 6824で定義されているMPTCPがLinux Kernelに実装され、そのソースコードがインターネット上で公開されています。 現在(2017年4月)、公開されている安定版は、v0.91です。

multipath-tcp.org Github of mptcp

MPTCPのデモ動画
#

multipath-tcp.orgのページでは、MPTCPを使ったデモ動画も公開されています。 デモ動画では、Ethernet、Wi-Fi、3Gの3つのインタフェースがある状態でEthernetやWi-FiのON/OFFを切り替えても通信が継続する様子が紹介されています。

MPTCPのシグナリング
#

MPTCPは、従来のTCPのオプション領域を使ってシグナリングの情報をやり取りします。このことで、既に世の中に存在する機器(L2 SwitchやL3 Switch, etc.)に対して機能を追加せずともMPTCPを動作させることができます。 もし、中間の経路に存在する機器によって、MPTCPのオプションが落とされたり、パケットの中身が書き換えられてしまう場合には、従来のTCPに後退して通信を継続することが可能です。

MPTCPの利便性
#

MPTCPは、クライアントとサーバの両者がMPTCP対応のLinux Kernelでありさえすれば、従来のTCPを使用するアプリケーションを変更することなく、そのまま使用することができます。 ユーザランド側のアプリケーションに見えるSocketとMPTCPを構成する複数のSocketを分離してカーネル内で処理することで、ユーザにアプリケーションの変更という手間を掛けさせずに、MPTCPを使うことが可能です。

MPTCPのBackupモード
#

MPTCPには、Backupモードという、TCPレベルで通信可能(TCP_LOSS状態でない等)な他のSocketが無い場合に、そのSocketを使用して通信を行うといったモードも検討され、実装されています。 どこぞのSiriがMPTCPのBackupモードを使っていると一時期話題にも挙がりました。

iOSの「Siri」だけが使う特別なTCP by ITPro Multipath TCP を使って iOS 用のバックアップ接続を確立する by Apple

まとめ
#

インターネット上のサーバとスマートフォンがMPTCPに対応するようになれば、日々の我々の通信は、気が付かないうちにMPTCPによって行われることになるでしょう。 そうすれば、今よりももっと高精細な映像が閲覧できたり、通信遅延によるフラストレーションが軽減されるかもしれません。

おまけ
#

参考までにMPTCPの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ヘッダのオプション領域が使われています。 以上。

関連記事

MPTCPのパケットを眺めてみる(その2)

前回は、実際に送信されるMPTCPのMP_CAPABLEのパケットを眺めてみました。 今回は、ADD_ADDR、DSS、DSS FIN、MP_JOINのフォーマットと実際のパケットを見比べてみます。 MPTCPのオプションは、前回の内容を参考にしてください。

MPTCPのパケットを眺めてみる(その1)

前回は、 RFC 6824 で定義されているMPTCPについて紹介しました。 今回は、TCPのオプション領域でやり取りされるMPTCPのシグナリングパケットを簡単に説明し、RFCで定義されているオプションのフォーマットとMPTCPのMP_CAPABLEが付いた実際のパケットを見比べてみようと思います。

アップストリーム版のMPTCPを試してみた

従来、LinuxでMPTCPを利用する場合「 Linux Kernel MultiPath TCP project」が公開しているLinuxカーネルを使う必要がありましたが、アップストリームのLinuxカーネル 5.6以降でMPTCPが利用可能になりました。 今回は、Ubuntuでアップストリーム版を使った複数サブフローでのMPTCP通信を試してみました。