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_RECVSYN受信、SYN+ACK送信済みSYN Flood攻撃で蓄積

Linux TCPチューニング

1# コネクション状態確認
2ss -tan state established
3ss -tan state time-wait | wc -l
4
5# カーネルパラメータ確認
6sysctl net.ipv4.tcp_max_syn_backlog
7sysctl net.core.somaxconn
8
9# 主要なチューニング項目
10# TIME_WAIT再利用(クライアント側)
11sysctl -w net.ipv4.tcp_tw_reuse=1
12
13# SYNバックログ増加
14sysctl -w net.ipv4.tcp_max_syn_backlog=65536
15sysctl -w net.core.somaxconn=65536
16
17# ウィンドウスケーリング
18sysctl -w net.ipv4.tcp_window_scaling=1
19
20# 輻輳制御アルゴリズム確認/変更
21sysctl net.ipv4.tcp_congestion_control
22sysctl -w net.ipv4.tcp_congestion_control=bbr
23
24# キープアライブ設定
25sysctl -w net.ipv4.tcp_keepalive_time=600
26sysctl -w net.ipv4.tcp_keepalive_probes=3
27sysctl -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# 状態別コネクション数
3ss -tan | awk '{print $1}' | sort | uniq -c
4
5# 特定ポートのコネクション
6ss -tan 'sport = :80'
7
8# TCP統計
9netstat -s | grep -i tcp
10cat /proc/net/snmp | grep Tcp
11
12# パケットキャプチャ
13tcpdump -i eth0 'tcp port 80' -nn