SSTP の中の TCP:再送が二度起きる理由
SSTP はトンネルを TLS 上の TCP ストリームで運ぶ。経路がパケットを落とすと、外側と内側の回復が同時に後退する。
うわさはプロトコルより先に届く。周りに聞けば、SSTP は遅いもの、何かに迫られない限り避ける選択肢だと言われる。その評判は、ある一種の経路における一つの故障モードを語っているにすぎない。
仕組みは実在する。ただし条件付きであり、評判はそこに触れない。
一つの経路上の二つの信頼できるストリーム
SSTP はトンネルを HTTPS セッションの中に包む。HTTPS は TCP 上で動き、その外側のストリームが順序どおりの配信を保証する。したがって、セグメントが一つ欠けるだけで、その後ろに並ぶすべてが止まる。別の内側の会話に属する後続のバイトも、それでも待たされる。
内側の TCP フローは独自の順序と輻輳制御を保つ。外側の回復は見えないため、観測できるのは停止だけである。その停止が、経路が輻輳していると伝える信号になる。
ここで両方の層が同時に後退する。これが相互作用のすべてであり、セグメントが一つ失われるだけで始まる。
効果が現れる場所と現れない場所
きれいな経路では、外側のストリームが何かを回復することはほとんどない。相互作用は決して発動せず、SSTP は対話的なトラフィックをまったく問題なく運ぶ。一律の主張はまさにこの点で崩れる。
効果が現れるのは、損失や並べ替えが下位の経路に達したときだ。輻輳した Wi-Fi リンクや遅延が変動するモバイル接続が条件を作る。すると、詰まった外側のキューがトンネル内の目に見える遅延に変わる。
負荷によっても拡大する。多数の並列フローがキューを埋め、先頭ブロッキングを悪化させる。同じ経路上の対話セッションが一つだけなら許容できると感じるかもしれない。
症状が通常そうではないもの
遅いセッションがすべてこの問題ではない。最初のパケットから一定して低い速度なら、容量、シェーピング、サーバー側の制限を示す。局所的な輻輳と一致する停止は、アクセスリンク上のキューイングを示す。
対処法は異なるため、診断が先に来る。バッファの調整はシェーピングされたリンクには何の効果もない。プロトコルを変えても、容量を使い切ったサーバーには何の効果もない。繰り返されるリセットはまったく別の場所を示す。
# outer path quality to the SSTP endpoint
ping -c 50 203.0.113.44 | tail -3
mtr -rwc 50 203.0.113.44
# is the local link saturated while the session stalls?
sar -n DEV 2 5
# retransmissions on the outer connection
ss -tin dst 203.0.113.44
問題が起きている間に測定を行う。健全な一分間に取ったキャプチャは、悪い一分間に走るループについて何も証明しない。
信頼する価値のある比較
別のトランスポートが本当に利用できるなら、管理された条件で比較する。同じホスト、同じネットワーク、同じ宛先、同じ作業。両方の実行は同じ十分間の中に収め、経路の条件をそろえる。
ポートを変えてもプロトコルは変わらない。無関係なプロファイルを SSTP クライアントに読み込んでも、代替のトランスポートは生まれない。比較が意味を持つのは、サーバーが第二の選択肢を提供している場合だけだ。
TLS の検証は常に有効にしておく。性能の作業は、検証されていない証明書を受け入れる理由にはならない。停止が主に上りリンクの飽和中に現れるなら、層を責める前にキューイングを確認する。