iphone(iOS 11)でMultiPath TCPを使う

すでにアナウンスされているとおり、iOS11よりMultipathTCP (MPTCP)のAPIサードパーティデベロッパーに公開されます。

実はiPhoneをお使いの人はすでに、iOS7からsiriでMPTCPが使われていたので裏ではすでに使われておりましたが、実際にみんなが試せるような状況になってきました。

MultiPathTCP (MPTCP)とは

MultipathTCPは複数のインターフェースを用いてTCPコネクションをはる事のできる、TCP拡張の一つです。例えばスマートフォンであればLTEWi-Fiといった2つのインターフェースを用いてコネクションをはり、両方の経路それぞれを併用してデータ通信をします。

大きなメリットとしては、使える帯域が増えるということだけではなくアプリケーション側からは1つのTCPコネクションに見えており仮に片方のコネクションが切れたとしてもTCPコネクションは維持できる点です。

Appleの発表では上記ios7のsiriにおいて、95パーセンタイル 20%の高速化と、接続失敗を5分の1に出来たようです。

ハンドシェイクと仕様

MultiPathTCPを使用するためにはクライント・サーバ両方が対応している必要があり、その際はTCP 3ウェイハンドシェク時にオプションとしてMP_CAPABLEが指定されてます。

もちろん既存のTCPコネクション(MP_CAPABLEが有効)に、別経路の通信(subflow)を追加する場合、経路上の機器からは一見ただのTCP 3ウェイハンドシェクが行われたように見えます(MP_JOINオプションが有効になってます)。

詳しくは、RFC6824を読まれるのが良いかと思います(改訂作業中:RFC6824bis)

(もちろん帯域公平性や、悪意あるユーザによるsubflowの追加を防ぐ機能があります (参考:TCP.next // Speaker Deck))

iOS11におけるMPTCP

すでにbeta版で試せるようですが、残念ながら手元に試せる環境がないため、すでに試されている人のコードを拝借させていただきます。
MPTCP experiments on iOS 11 beta — MPTCP

let config = URLSessionConfiguration.ephemeral

config.multipathServiceType = URLSessionConfiguration.MultipathServiceType.handover
let session = URLSession(configuration: config)

let url = URL(string: "http://multipath-tcp.org/data/uml/vmlinux_64")

let task = session.dataTask(with: url!, completionHandler:{...})

task.resume()

URLSessionConfiguration.MultipathServiceTypeは4つのmodeがあり、違いは以下のとおりです

  • none: MultipathTCPを使用しない
  • handover: Wi-Fi回線を優先します。LTEなどのキャリア回線からコネクションを維持したままシームレスにWi-fiにハンドオーバーします
  • interactive: レイテンシを最小にするような経路を使用します。データ量が少ない場合のみ仕様すべきで
  • aggregate: 両方の経路を使用してスループットを向上させます(デベロッパーのみが使用できます)

大まかにデベロッパーがモードを選択できることがわかります。

しかし、ファイアウォールなどによりMP_CAPABLEやMP_JOIN付きハンドシェイクがブロックされてしまったときの挙動や、レイテンシの向きの考慮(参考:One Way Latency Considerations for MPTCPdraft-song-mptcp-owl-01 - One Way Latency Considerations for MPTCP)や、NAT64下での問題(参考pdf)など、実際に試してみないと分からない気はします。


LinuxでのMPTCP対応

実際に試す場合はサーバサイドも準備する必要がありますので、少々古い記事ではありますが参考までに
asnokaze.hatenablog.com