ゲームラグ白書 › TCP再送の根本原因
中間機器によるTCPオプションの除去 Middlebox strips TCP options
原因ID rt-sack-stripped · 主担当 インフラチーム・ネットワークインフラ · 副担当 インフラチーム・サーバーインフラ
図と実験のあるメインページでこのカードを開く →
一部のファイアウォール・高速化装置がTCPオプションを消したり書き換えたりすると、複数のパケットを失ったときに1往復に1つずつしか回復できなくなったり、ウィンドウ(一度に送れる量)が小さくなったりして遅くなります。
なぜ ファイアウォールの「TCP正規化」、古い高速化装置がSACK・タイムスタンプ・ウィンドウスケールのオプションを除去 → すると 失ったパケットが複数あると1往復ごとに1つずつ回復、ウィンドウは64KBに制限される → 画面では パケットロスのたびに止まる時間がずっと長くなり(SACKがないとRACK-TLPも使えない)、解消すると早送り。アップデートデータのダウンロードのような大容量の転送も遅い
症状 フリーズ , 早送り
要因 ストール, 遅延
誰に起きるか 特定の地域・ISP, サーバー全体
いつ 常に
担当 主担当 インフラチーム・ネットワークインフラ · 副担当 インフラチーム・サーバーインフラ
インフラチームの対応 ネットワーク:該当機器のTCP正規化の設定を無効にする、ファイアウォールのシーケンス番号ランダム化も確認、両端のパケットキャプチャでSYNのオプションを比較。サーバー機器・OS:ss -tiでsack・wscaleの表示がない接続が特定の経路に偏っていないか確認(tsはWindows PCが設定によって使わないため、tsだけがないのは正常な場合がある)、サーバーのnet.ipv4.tcp_sackが1になっているか確認。
グラフでは 最初から常に高い · SACKなしで開始した回復の数(TcpExtTCPRenoRecovery)
確認箇所 ss -tiで接続ごとにsack・wscaleの表示があるかを確認し、nstatのTcpExtTCPRenoRecovery(SACKなしで開始した回復)とTcpExtTCPSackRecoveryの比率、TcpExtTCPSACKDiscard(整合しないため破棄したSACKブロック数)を確認。疑わしい経路は両端でSYNをキャプチャし、オプション(Wiresharkのtcp.options.sack_permなど)を比較 該当する場合 特定の経路・機器を通る接続だけsack・wscaleがなく、TcpExtTCPRenoRecoveryの割合が高い。送信側でキャプチャしたSYNにあったSACK許可オプションが、受信側でキャプチャしたSYNにはない。シーケンス番号ランダム化が原因なら、オプションは残っているのにTcpExtTCPSACKDiscardが増える 該当しない場合 すべての接続でsackがないなら、まずサーバーのnet.ipv4.tcp_sackの値を確認。オプションがそろっていてTcpExtTCPSACKDiscardも変わらなければ、回復が遅い理由は別にある(「thin streamの遅い回復」) 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく オプションが残っていても、SACKが壊れることがあります。ファイアウォールのシーケンス番号ランダム化(sequence randomization)がヘッダーのシーケンス番号だけを書き換え、SACK内の番号をそのままにすると、送信側は整合しないSACKを破棄します。2019年のSACKの脆弱性の際にサーバーでtcp_sack=0にして無効化し、そのまま忘れている場合も結果は同じです。
出典 RFC 2018: TCP Selective Acknowledgment Options IETF SACKなしの累積ACKだけでは、1往復ごとに失ったパケットを1つしか把握できない RFC 7323: TCP Extensions for High Performance IETF ウィンドウスケールオプションがなければ、ウィンドウは最大2^16 = 64KiB RFC 8985: The RACK-TLP Loss Detection Algorithm for TCP IETF RACK-TLPにはSACKの使用が必須 net/ipv4/tcp_output.c Linux kernel LinuxのTLPは、SACKを使う接続でのみスケジュールされる IP Sysctl Linux kernel tcp_sackのデフォルトは1(有効) misc/ss.c iproute2 ss -tiは、接続が使っているオプションに応じてts、sack、wscale:送信,受信を表示 tcp: limit payload size of sacked skbs Linux kernel 2019年のSACK処理の脆弱性(CVE-2019-11477)の修正コミット Linux and FreeBSD Kernel: Multiple TCP-based remote denial of service vulnerabilities (NFLX-2019-001) Netflix 当時の暫定対策として、tcp_sack=0(SACK処理の無効化)が案内された SNMP counter Linux kernel TcpExtTCPRenoRecovery(SACKなしで回復を開始)・TcpExtTCPSackRecovery(SACKで回復を開始)、TcpExtTCPSACKDiscard(無効なSACKブロックの数) Display Filter Reference: Transmission Control Protocol Wireshark tcp.options.sack_perm(SYNのSACK許可オプション)の表示フィルター
あわせて読みたい原因
同じ層:TCP再送の根本原因
同じ症状(フリーズ)を起こすほかの層の原因
図と実験のあるメインページでこのカードを見る