awesome-everything EN
↑ Обратно к восхождению

Сети и протоколы

TCP handshake: чтение трасс и кода

Суть Читай реальные трассы tcpdump, вывод ss и сниппет обработки соединений, предсказывай поведение TCP и выбирай фикс с наибольшим рычагом.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на senior-высоте — в орбите
◷ 14 min

Захваты пакетов и дампы сокетов — это место, где реально диагностируются проблемы TCP. Читай каждую трассу, разбирай, что делает соединение, затем выбирай фикс, к которому senior-инженер потянется первым.

Цель

Отработай цикл, который ты запускаешь в каждом инциденте TCP: прочитай трассу или строку ss, восстанови механику sequence number и состояний, и назови ту единственную правку, что решает проблему до касания sysctl.

Трасса 1 — handshake на проводе

14:02:11.001 IP 10.0.0.5.51514 > 10.0.0.9.6379: Flags [S],  seq 1000000, win 64240, length 0
14:02:11.001 IP 10.0.0.9.6379  > 10.0.0.5.51514: Flags [S.], seq 4200000, ack 1000001, win 65160, length 0
14:02:11.002 IP 10.0.0.5.51514 > 10.0.0.9.6379: Flags [.],  seq 1000001, ack 4200001, win 64240, length 0
14:02:11.002 IP 10.0.0.5.51514 > 10.0.0.9.6379: Flags [P.], seq 1000001, ack 4200001, win 64240, length 14
Викторина

Четвёртый пакет несёт 14 байт данных, начиная с seq 1000001. Почему он начинается там, а не с 1000000, и что подтверждает ack 4200001?

$ sudo tcpdump -i eth0 'tcp[tcpflags] & tcp-syn != 0' -tnn
IP 203.0.113.7.40001 > 198.51.100.10.443: Flags [S],  seq 100, win 29200, length 0
IP 198.51.100.10.443 > 203.0.113.7.40001: Flags [S.], seq 3851629874, ack 101, win 28960, length 0
IP 203.0.113.9.55000 > 198.51.100.10.443: Flags [S],  seq 200, win 29200, length 0
IP 198.51.100.10.443 > 203.0.113.9.55000: Flags [S.], seq 4025814937, ack 201, win 28960, length 0
(ещё тысячи SYN от случайных источников; почти ни один не шлёт финальный ACK)
$ nstat -az | grep -i syncookies
TcpExtSyncookiesSent            41827
TcpExtSyncookiesRecv              312
Викторина

SyncookiesSent равно 41 827, но SyncookiesRecv всего 312. Сервер не уходит в нехватку памяти. Что происходит и почему сервер в безопасности?

Трасса 3 — ss во время инцидента

$ ss -tan state established | wc -l
12384
$ ss -tan state close-wait | wc -l
9821
$ ss -s
TCP:   23552 (estab 12384, closed 8920, orphaned 2, timewait 1247)
$ ps -p 1234 -o pid,stat,rss,cmd
  PID STAT   RSS CMD
 1234 Ssl 8392000 /usr/bin/app-server   # RSS растёт каждую минуту
Викторина

9.8k сокетов сидят в CLOSE-WAIT, а RSS продолжает расти. В чём баг и куда смотреть в коде?

Трасса 4 — ss -tin на медленной передаче

$ ss -tin state established dst 203.0.113.20
ESTAB 0 0 10.0.0.5:44120 203.0.113.20:443
   cubic wscale:7,7 rtt:148.2/9.1 mss:1448 cwnd:11 ssthresh:8
   bytes_sent:9M bytes_acked:9M retrans:0/214 reordering:12 rate:780Kbps
Викторина

RTT 148 мс, cwnd застрял на 11 MSS при ssthresh 8, 214 кумулятивных ретрансмитов и CUBIC — и всё же пропускная способность лишь 780 Кбит/с на быстром канале. Какой диагноз и самая перспективная правка?

Итог

Каждый инцидент TCP читается в трассах. Арифметика sequence number вытекает из одного правила: SYN (и FIN) потребляют по одному номеру, поэтому первый байт данных — ISN+1. Высокий SyncookiesSent при низком Recv — это поглощённый флуд, а не утечка. Завал CLOSE-WAIT с растущим RSS — всегда отсутствующий close() в приложении. А cwnd, прижатый низко с ретрансмитами под CUBIC на long-RTT lossy пути, — сигнатура, говорящая: переведи этот сокет на BBR. Диагностируй с провода и таблицы сокетов, затем делай ту единственную правку, на которую указывают данные.

Продолжить восхождение ↑TCP handshake: измерь и укроти churn соединений
хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.