Zapret2 для новичков — 02: TCP (seq/ack, окно, MSS) понятным языком

Эта заметка объясняет те TCP‑механизмы, на которых “держится” большая часть логики zapret2.

1) TCP как “поток байт”

TCP для приложения выглядит как непрерывный поток байт. Но по сети ходят пакеты, каждый несёт кусок этого потока.

TCP гарантирует:

  • порядок (байты “склеятся” правильно),
  • надёжность (потерянное будет ретранслировано),
  • контроль потока (чтобы не переполнить принимающую сторону).

2) Sequence number (seq): “номер первого байта”

Упрощённо:

  • seq в TCP сегменте указывает номер первого байта payload в общем потоке.

Пример:

  • сегмент A: seq=1000, payload длиной 200 байт → несёт байты [1000..1199]
  • сегмент B: seq=1200, payload длиной 100 байт → несёт байты [1200..1299]

3) Acknowledgement (ack): “всё до N получил”

ack (обычно) означает:

  • “я получил все байты до ack-1, пришли следующий байт ack”.

Это важно для понимания:

  • почему “неправильный ack” может заставить ОС отбросить пакет,
  • почему изменение ack/seq — это сильный рычаг в “fooling”.

4) Окно (window): сколько данных можно принять

TCP окно показывает, сколько данных приёмник готов принять сейчас.

Отсюда идея техник:

  • “всунуть” часть сегмента вне окна: сервер это игнорирует, но DPI может попытаться прочитать.

В zapret2 это связано с seqovl (см. [[multisplit]] и [[multidisorder]]).

5) Retransmission (ретрансляция)

Если ACK не пришёл, TCP отправляет сегмент снова. С точки зрения наблюдателя (и DPI) это выглядит как “ещё один похожий пакет с тем же seq”.

Многие техники пытаются сделать “картинку”, похожую на ретрансляции, чтобы DPI было сложнее понять, где оригинал.

6) MSS и почему у вас “вдруг стало много пакетов”

MSS — максимальный размер TCP payload в одном сегменте (примерно MTU минус заголовки).

Если payload больше MSS:

  • он будет разбит на несколько сегментов.

В zapret2 есть автосегментация по MSS при отправке:

  • даже если вы “логически” разрезали на 2 части, каждая часть может быть ещё порезана по MSS.

Это объясняет, почему в логах иногда улетает больше сегментов, чем вы ожидали.

7) Почему порядок важен (multisplit vs multidisorder)

  • multisplit шлёт сегменты “с начала к концу”.
  • multidisorder шлёт “с конца к началу”.

Так можно получить ситуации, когда:

  • в буфере приёмника сначала лежит “хвост”, а потом приходит “голова”,
  • и разные системы/стеки по‑разному обрабатывают перекрытия (overlap) и порядок.

8) Мини‑практика (без опасных действий)

Цель упражнений — понять данные, а не “обходить”.

  • Добавь в профиль --lua-desync=posdebug и посмотри, как меняются n/d/b/s/p.
  • Добавь --lua-desync=luaexec:code="DLOG('seq '..tostring(desync.dis.tcp.th_seq)..' ack '..tostring(desync.dis.tcp.th_ack))" — и увидишь, что это обычные числа и их можно анализировать.

9) Что читать дальше

  • [[Zapret2 - 03 - Перехват пакетов и вердикты (NFQUEUE/WinDivert)]]
  • [[Zapret2 - 04 - Dissect/Reconstruct и структура desync]]