TCP(Transmission Control Protocol)
信頼性のあるコネクション型通信
TCPとは
TCPは、信頼性のあるコネクション型のトランスポート層プロトコルです。 確認応答(ACK)、再送制御、順序保証、フロー制御、輻輳制御を提供し、 データが確実に届くことを保証します。HTTP、SSH、FTP等で使用されます。
TCPヘッダ構造
送信元ポート(16)
宛先ポート(16)
シーケンス番号(32)
確認応答番号(32)
データオフセット/フラグ
ウィンドウサイズ(16)
チェックサム(16)
緊急ポインタ(16)
シーケンス番号
送信データのバイト位置。順序保証に使用。
確認応答番号
次に期待するバイト位置。受信確認に使用。
ウィンドウサイズ
受信可能なバイト数。フロー制御に使用。
フラグ
SYN, ACK, FIN, RST, PSH, URG
3-way Handshake(接続確立)
クライアント
サーバー
SYN_SENT
SYN (seq=x) →
LISTEN
← SYN+ACK (seq=y, ack=x+1)
SYN_RCVD
ESTABLISHED
ACK (ack=y+1) →
ESTABLISHED
4-way Handshake(接続終了)
1クライアント: FIN送信 → FIN_WAIT_1
2サーバー: ACK送信 → CLOSE_WAIT、クライアント: FIN_WAIT_2
3サーバー: FIN送信 → LAST_ACK
4クライアント: ACK送信 → TIME_WAIT(2MSL後にCLOSED)
TIME_WAIT
最後のACKが失われた場合の再送に備えて2MSL(通常60秒)待機。 高負荷サーバーではTIME_WAITソケット蓄積に注意。
輻輳制御
スロースタート
初期cwnd=1MSS。ACK受信ごとに指数的に増加(1→2→4→8...)。 閾値(ssthresh)到達で輻輳回避へ。
輻輳回避
ssthresh以降は線形増加(RTTごとに+1MSS)。 パケットロス検出で減速。
高速再送
3重複ACK受信で即座に再送。タイムアウトを待たない。 高速リカバリへ移行。
輻輳制御アルゴリズム
CUBIC(Linux標準)、BBR(Google開発)、Reno等。 環境に応じて選択。
TCP状態遷移
| 状態 | 説明 | 注意点 |
|---|---|---|
| ESTABLISHED | 接続確立、データ転送中 | 正常状態 |
| TIME_WAIT | 接続終了後の待機 | 蓄積するとポート枯渇 |
| CLOSE_WAIT | 相手からFIN受信、自分のclose待ち | アプリがclose漏れ |
| SYN_RECV | SYN受信、SYN+ACK送信済み | SYN Flood攻撃で蓄積 |
Linux TCPチューニング
1 # コネクション状態確認 2 ss -tan state established 3 ss -tan state time-wait | wc -l 4 5 # カーネルパラメータ確認 6 sysctl net.ipv4.tcp_max_syn_backlog 7 sysctl net.core.somaxconn 8 9 # 主要なチューニング項目 10 # TIME_WAIT再利用(クライアント側) 11 sysctl -w net.ipv4.tcp_tw_reuse=1 12 13 # SYNバックログ増加 14 sysctl -w net.ipv4.tcp_max_syn_backlog=65536 15 sysctl -w net.core.somaxconn=65536 16 17 # ウィンドウスケーリング 18 sysctl -w net.ipv4.tcp_window_scaling=1 19 20 # 輻輳制御アルゴリズム確認/変更 21 sysctl net.ipv4.tcp_congestion_control 22 sysctl -w net.ipv4.tcp_congestion_control=bbr 23 24 # キープアライブ設定 25 sysctl -w net.ipv4.tcp_keepalive_time=600 26 sysctl -w net.ipv4.tcp_keepalive_probes=3 27 sysctl -w net.ipv4.tcp_keepalive_intvl=15
SRE/インフラ観点
監視項目
- • コネクション数: ESTABLISHED, TIME_WAIT, CLOSE_WAIT
- • 再送率: RetransSegs / OutSegs
- • RTT: 接続レイテンシ
- • ソケットバッファ: 送受信キュー
よくある問題
- • TIME_WAIT蓄積: エフェメラルポート枯渇
- • CLOSE_WAIT蓄積: アプリのclose漏れ
- • SYN Flood: DoS攻撃
- • Connection Reset: 異常終了
1 # トラブルシューティング 2 # 状態別コネクション数 3 ss -tan | awk '{print $1}' | sort | uniq -c 4 5 # 特定ポートのコネクション 6 ss -tan 'sport = :80' 7 8 # TCP統計 9 netstat -s | grep -i tcp 10 cat /proc/net/snmp | grep Tcp 11 12 # パケットキャプチャ 13 tcpdump -i eth0 'tcp port 80' -nn