マルチパス
mqvpn は Multipath QUIC を使用して、複数のネットワークパスで同時にトラフィックを転送します。これにより以下が可能になります:
- シームレスなフェイルオーバー — あるパスがダウンしても、残りのパスでトラフィックが継続します。切り替え中に短い遅延が発生する場合があります。
- 帯域集約 — 複数インターフェースの帯域幅を組み合わせます(例: WiFi + LTE)。複数の同時フローがある場合に最も効果的です。単一の TCP フローで集約を行いたい場合はhybrid modeを使用してください。
マルチパスのセットアップ
CLI
--path で各ネットワークインターフェースを指定します:
sudo ./build/mqvpn --mode client --server 203.0.113.1:443 \
--auth-key <key> --path eth0 --path wlan0設定ファイル
[Multipath]
Scheduler = wlb
Path = eth0
Path = wlan0TIP
--path フラグや Path エントリを指定しない場合、mqvpn はデフォルトインターフェースを使用します(シングルパスモード)。
スケジューラ
スケジューラはパケットをパス間でどのように分配するかを決定します。mqvpn は以下のスケジューラをサポートしています:
WLB(Weighted Load Balancing)— デフォルト
WLB は、パス重み付けとフロー考慮スケジューリングを組み合わせた方式です:
- ロス率・RTT・cwnd などの実測値から各パスの推定スループットを算出し、トラフィック分配比率として使用
- deficit ベースの WRR でアクティブなパスへトラフィックを分配
- VPN トンネル内の並び替えを抑えるため、内部 TCP フロー(flow hash)をパスにピン留め
- ピン留め先が一時的に cwnd ブロックされた場合は、恒久的な再ピン留めなしで spillover
- 非 Datagram 系パケットや、有効なスケジューラ対象パスがない場合は MinRTT にフォールバック
--scheduler wlbWLB UDP Pin(wlb_udp_pin)
WLB の派生で、通常の WLB が TCP コネクションを一本のパスに固定するのに加えて、 UDP コネクションも一本のパスに固定するスケジューラです。
--scheduler wlb_udp_pinトンネル内に自前で順序付けを行う UDP フローがあって、通常の wlb では スループットが伸びない、という場面で試す価値があります。仕組みとしては、 mqvpn が遅延差のある複数パスにパケットを散らすと、順序を見ている内側の プロトコルが並び替えをロスと誤認して速度を落としてしまうことがあります。 wlb_udp_pin は同じコネクションのパケットを 1 本のパスに揃えるので、この 並び替えが起こりません。
ただし、内側が単一コネクションの場合、wlb_udp_pin でも 1 本のパス分の 帯域までしか出ません。単一のシーケンス空間で動くプロトコルでは、複数パスで 帯域を合算するには内側自体のマルチパス対応が必要だからです。それでも、 wlb で散らして並び替えで自壊するより「安定して 1 パス分が出る」方が 実用的、というのが wlb_udp_pin を選ぶ意義です。
逆に、内側 UDP が並び替えを許容するなら通常の wlb の方が向いています。 複数パスに散らした方が回線を合算した帯域を使い切れるためです。また実装上、 wlb_udp_pin で追跡できる UDP コネクション数には上限があり、毎秒大量の 短命フローを生む環境では古いフローの追跡がこぼれて固定の効果が薄くなる ので、そうしたケースも wlb の方が無難です。
順序を気にする UDP のスループットが wlb で出ないと感じたら wlb_udp_pin を試す、それ以外なら wlb のまま、という使い分けで OK です。
MinRTT(Minimum Round-Trip Time)
MinRTT は各パケットを現在の RTT が最も低いパスで送信します。よりシンプルですが、利用可能な帯域幅を効率的に活用できない場合があります。
- レイテンシを最適化(スループットより優先)
- シンプルなアルゴリズム、予測可能な動作
--scheduler minrttBackup FEC (experimental)
通常のトラフィックを AVAILABLE パスに送り、FEC リペアシンボルを STANDBY パスに送ります。プライマリリンクがロスしやすく(例: 不安定な WiFi)、 スタンバイがより信頼できる(例: LTE)構成向けに設計されています。
--scheduler backup_fec使うべき場面: ロスの多い環境での WiFi+LTE マルチパス。スタンバイパス上の リペアシンボルにより、再送 RTT を待たずにプライマリパスのロスを即座に回復 できます。
使うべきでない場面:
- シングルパス構成(スタンバイパスがない = リペアシンボルの送り先がない)
- 帯域集約を狙う高帯域シナリオ(代わりに
wlbを使用) - 両端点が mqvpn 0.4.0 以上で、FEC ビルド (
-DXQC_ENABLE_FEC=ON -DXQC_ENABLE_XOR=ON) が有効である必要があります
チューニング: デフォルトは XOR FEC でブロックあたり約 33% のオーバーヘッド (src/mqvpn_scheduler.h の MQVPN_FEC_* マクロ参照)。本実験リリースでは FEC パラメータの CLI フラグは公開されていません。
性能: ロス率 1%〜10% における WLB との実測スループット比較は 週次ベンチマークを参照。
スケジューラ選択指針
| シナリオ | 推奨 |
|---|---|
| 一般的な用途、帯域集約 | WLB + hybrid mode |
| 単一パスでの配送が必要な内部 UDP | wlb_udp_pin |
| レイテンシ重視のアプリケーション | MinRTT (帯域集約とのトレードオフだが、よりレイテンシを重視する場合はReinjection(dgram)を併用推奨。) |
| 品質の悪い回線の組み合わせ | MinRTT + hybrid mode(場合に応じて Reinjection や Reorder buffer の併用も検討) |
| ロスの多いプライマリ + 信頼できるスタンバイ(実験的) | backup_fec |
Reinjection(投機的複製)
Reinjection は、選んだパケットのコピーをもう 1 本のパスにも送る機能です。 帯域を少し余分に使う代わりに、パケットロスや回線の急な不調があっても トンネルが滑らかに動き続けるようになります。デフォルトは無効で、 スケジューラ設定とは独立に使えます。オリジナルは通常どおり送られ、 コピーは必ずオリジナルとは別のパスに送られます。
Ref: XLINK (SIGCOMM 2021)
[Multipath]
Reinjection = deadline # off | deadline | idle | dgram| モード | 何をコピーするか | 用途 |
|---|---|---|
deadline | ストリームレーン(TCP 側)のうち、届いた確認が取れないまま遅れ気味になっているデータと、不調と判定されたパスに送った全データ | TCPをQUIC Streamで転送するハイブリッドモードのトンネル向けの保険。普段は何もせずコストもほぼゼロで、回線が突然不調になった瞬間の引っかかりを最小限に抑えます |
idle | トンネルが他に何も送っていない暇な瞬間の、直近の未確認ストリームデータ(TCP 側のみ) | SSH やブラウジングなどで、たまに起きる引っかかりを低コストで減らします。チューニング不要 |
dgram | データグラムレーンを通る全パケットを常にコピー。ハイブリッドモードの TCP は対象外 | VoIP・ゲームなどリアルタイム通信専用のトンネル向け。パケットロスや回線断があっても音切れやラグが出にくくなります、注意点として常にコピーするため帯域集約とのトレードオフになります。 |
そもそもなぜ引っかかるのか: 回線が不調になっても、新しいデータは スケジューラが健全な回線へ流します。しかし不調になった回線に送信済みだった データは回復を待つ必要があり、順序どおりに届ける仕組みのため、健全な回線で 先に届いた後続データもアプリに渡せず足止めされます(マルチパスの head-of-line blocking)。無音で死んだ回線は最悪数百 ms のタイムアウトまで 検出できないため、最悪条件ではこの足止めが 1 秒近くになります。deadline は 遅れたデータをすぐ健全な回線にも送り直すことで、この足止めを削減します。
deadline モードのチューニング(デフォルト値):
ReinjectionSrttFactorPct = 110 # 最小往復時間(min_srtt)の 1.1 倍を超えて未確認ならコピー(100–1000)
ReinjectionHardDeadlineMs = 500 # 待ち時間の上限 ms(1–60000)
ReinjectionDeadlineLowerBoundMs = 20 # 待ち時間の下限 ms(1–60000。上限を超える設定は上限に切り詰め)注意:
- Reinjection は送信側の機能です。各側の設定は自分が送信するトラフィックを 保護するため、ダウンロードを保護するにはサーバ側で有効にします (アップロードはクライアント側)。
dgramは対象トラフィックの帯域を倍消費します。ダウンロードや動画も流れる 混在トンネルには非推奨です — HTTP/3 の動画を含むすべての内部 UDP を コピーするため、データグラムレーンの実効速度が回線 1 本分に落ちます。- パスごとの複製送信バイト数は control API の
get_status応答のreinject_tx_bytesで確認できます。 - 2 本以上のアクティブパスが必要です(1 本のときは自動的に何もしません)。
パスの重み付け
WLB はトランスポートの実測値からパス重みを自動更新します。手動で重みを設定する必要はありません。
仕組み:
- ロス率・RTT・cwnd から各パスの推定スループットを算出し、パス間のトラフィック分配比率(重み)として使用します
- deficit WRR が、その重みに基づいてパケット/フローの割り当てを行います
- 既存の TCP フローピンは再利用され、アイドル・高ロス・パス障害時にはエントリを破棄します
- ラウンド境界やパス復帰イベントで重み/deficit を更新します
これにより、非対称パス(例: 300 Mbps 有線 + 80 Mbps 無線)が手動チューニングなしで効率的に活用されます。
仕組み
┌─────────────────┐ ┌─────────────────┐
│ Application │ │ Internet │
├─────────────────┤ ├─────────────────┤
│ TUN (mqvpn0) │ │ TUN (mqvpn0) │
├─────────────────┤ ├─────────────────┤
│ MASQUE │ HTTP Datagrams │ MASQUE │
│ CONNECT-IP │◄──(Context ID = 0)──────►│ CONNECT-IP │
├─────────────────┤ ├─────────────────┤
│ Multipath QUIC │◄── Path A (eth0) ──────►│ Multipath QUIC │
│ │◄── Path B (wlan0) ──────►│ │
├─────────────────┤ ├─────────────────┤
│ UDP (eth0/wlan)│ │ UDP (eth0) │
└─────────────────┘ └─────────────────┘
Client Server各パスは特定のネットワークインターフェースにバインドされた個別の UDP ソケットです。Multipath QUIC が QUIC レイヤーでパスを管理し、サーバーからは複数のパスを持つ単一の QUIC 接続として認識されます。
ベンチマーク
非対称デュアルパス環境(300 Mbps + 80 Mbps、netem によるエミュレーション)でのフェイルオーバーおよび帯域集約の計測結果は、ベンチマークレポートを参照してください。
プロトコル標準
| プロトコル | 仕様 |
|---|---|
| MASQUE CONNECT-IP | RFC 9484 |
| HTTP Datagrams | RFC 9297 |
| QUIC Datagrams | RFC 9221 |
| Multipath QUIC | draft-ietf-quic-multipath |
| HTTP/3 | RFC 9114 |