Сети и протоколы
Читаем IP-заголовок
Каждый раз когда роутер форвардит пакет — он читает и модифицирует IP-заголовок. Декрементирует TTL на 1, пересчитывает checksum и принимает forwarding-решение по адресу назначения. Знание какое поле что делает позволяет диагностировать сетевые проблемы и понять почему IPv6 убрал некоторые поля совсем.
IPv4-заголовок (минимум 20 байт)
IPv4-пакеты начинаются с 20-байтного фиксированного заголовка (больше если присутствуют опции):
| Поле | Размер | Назначение |
|---|---|---|
| Version | 4 бита | Всегда 4 для IPv4. |
| IHL (длина заголовка) | 4 бита | Количество 32-битных слов в заголовке; минимум 5 (= 20 байт). |
| ToS / DSCP + ECN | 8 бит | Изначально поле приоритета; переопределено как DSCP (6 бит) для QoS + ECN (2 бита). |
| Total length | 16 бит | Заголовок + payload в байтах; максимум 65 535. |
| Identification | 16 бит | Тегирует фрагменты одного исходного пакета. |
| Flags + Fragment offset | 16 бит | Флаг «Don’t fragment», флаг «more fragments» и смещение внутри исходного пакета. |
| TTL | 8 бит | Hop limit; каждый роутер декрементирует на 1; дроп при 0. |
| Protocol | 8 бит | Протокол следующего слоя: 6 = TCP, 17 = UDP, 1 = ICMP, 58 = ICMPv6. |
| Header checksum | 16 бит | CRC только над заголовком (не payload); пересчитывается на каждом хопе потому что TTL меняется. |
| Source IP | 32 бита | Адрес отправителя. |
| Destination IP | 32 бита | Адрес получателя. |
Почему header checksum только над заголовком. Payload защищён checksum L4 (TCP/UDP). Вычислять checksum над полным пакетом на каждом роутере было бы запретительно дорого при line rate; нужен только header checksum потому что TTL меняется.
TTL — time to live
TTL — 8-битный счётчик хопов, а не измерение времени (вопреки названию). Каждый роутер декрементирует на 1. Когда достигает 0 роутер дропает пакет и шлёт ICMP «time exceeded» обратно к источнику. Это предотвращает зацикливание пакетов при проблемах маршрутизации.
traceroute эксплуатирует TTL: шлёт пробы с TTL = 1, 2, 3, … Каждый роутер который дропает пробу (TTL достигло нуля) отвечает «time exceeded», раскрывая свой адрес и RTT — путь трасируется хоп за хопом.
DSCP и ECN — рычаги качества
Первые 8 бит третьего байта несут два ортогональных сигнала качества:
- DSCP (6 бит). Differentiated Services Code Point. Роутеры используют его для приоритизации трафика в очередях. Общие значения: EF (Expedited Forwarding — голос/реальное время), AF (Assured Forwarding — видео), CS (Class Selector — legacy-совместимость). End-to-end DSCP редко выживает в публичном Интернете потому что каждый AS переписывает на ingress; на queueing влияет надёжно только внутри одной сети.
- ECN (2 бита). Explicit Congestion Notification. Перегруженный роутер маркирует пакет CE (Congestion Experienced) вместо его дропа. Принимающий хост эхоирует сигнал обратно к отправителю через TCP, который уменьшает congestion window — меньше задержка без потерь. ECN включён по умолчанию на современном Linux. L4S (RFC 9330–9332) расширяет ECN для достижения ultra-low latency через dual-queue traffic shaping.
- Минимальный размер заголовка
- 20 байт
- TTL начальное значение (Linux)
- 64
- Protocol: TCP
- 6
- Protocol: UDP
- 17
- Protocol: ICMP
- 1
- Макс. размер пакета (поле total length)
- 65 535 байт
IPv6-заголовок — упрощён намеренно
IPv6 имеет фиксированный 40-байтный заголовок без checksum и без полей фрагментации:
- Version (4 бита): Всегда 6.
- Traffic Class (8 бит): Та же семантика DSCP + ECN что и в IPv4.
- Flow Label (20 бит): Идентифицирует flow (например TCP-соединение) для consistent ECMP без перехеширования каждого пакета.
- Payload Length (16 бит): Размер только payload (не заголовка).
- Next Header (8 бит): Та же роль что Protocol в IPv4 — идентифицирует extension header или L4-протокол следующий за ним.
- Hop Limit (8 бит): Аналог TTL в IPv4.
- Source / Destination (по 128 бит): 16-байтные адреса.
Почему нет checksum. IPv6 полагается на L2 (Ethernet FCS) и L4 (checksum TCP/UDP) для целостности. Устранение per-hop пересчёта checksum уменьшает работу каждого роутера и соответствует возможностям современного оборудования.
Extension headers цепятся после фиксированного заголовка через поле Next Header — аналог IPv4 options но чище. Распространённые расширения: Hop-by-Hop Options, Routing (используется Segment Routing v6), Fragment, Destination Options.
Почему это работает
Почему IPv6-роутеры никогда не фрагментируют. IPv4 позволял роутерам разбивать oversized пакет на меньшие фрагменты — полезно, но добавляло CPU-работу на каждом хопе и создавало дыры в безопасности (некоторые firewalls инспектировали только первый фрагмент, позволяя атакующим прятать вредоносный payload). IPv6 запрещает фрагментацию роутерами. Если пакет слишком большой, роутер шлёт ICMP «Packet Too Big» обратно к отправителю, который должен уменьшить размер и переотправить. Сложность переносится на отправителя, роутер остаётся простым.
От чего защищает поле TTL?
Почему IPv6 убирает IP-level header checksum?
Расставьте поля IPv4-заголовка (после Version + IHL):
- 1 ToS / DSCP + ECN (QoS и маркировка перегрузки)
- 2 Total length (заголовок + payload)
- 3 Identification + Flags + Fragment offset
- 4 TTL (hop limit)
- 5 Protocol (TCP=6, UDP=17, ICMP=1)
- 6 Header checksum
- 7 Source IP, Destination IP
- 01Почему роутер пересчитывает IPv4 header checksum на каждом хопе?
- 02Что делает поле DSCP и почему оно редко работает end-to-end в публичном Интернете?
- 03Как traceroute раскрывает путь используя TTL?
IPv4-заголовок упаковывает 20 байт сетевого управления в каждый пакет. TTL (hop limit) предотвращает routing loops декрементируясь на каждом роутере и вызывая дроп при нуле. DSCP маркирует QoS-класс; ECN сигнализирует перегрузку без дропа. Поле Protocol направляет payload к TCP, UDP или ICMP. Header checksum покрывает только заголовок и должен пересчитываться на каждом хопе из-за изменений TTL — именно поэтому IPv6 его убрал, полагаясь на L2 и L4 для целостности. IPv6 также зафиксировал заголовок на 40 байтах, запретил фрагментацию роутерами и добавил 20-битный Flow Label для ECMP-консистентности.
встречается в47
- Federation и lookahead: батчинг за пределами DataLoadermiddle
- Senior GraphQL API: scheduling-контракт, изоляция арендаторов, наблюдаемостьsenior
- Инвалидация, dirty-биты и containmiddle
- Слои композитора: продвижение, перекрытие и память GPUmiddle
- Observability в проде: LoAF, INP и полная поверхность атакиsenior
- Hidden classes, деревья переходов и расположение в памятиmiddle
- V8 в production: Isolates, сжатие указателей и реальные аварииsenior
- Что такое воркеры и зачем они нужныjunior
- Механика web workers: dedicated, shared и OffscreenCanvasmiddle
- Structured clone и transferablesmiddle
- SharedArrayBuffer, Atomics и cross-origin isolationsenior
- Пулы воркеров, Comlink и наблюдаемость в продакшенеsenior
- Восемь слоёв трассировки: от service worker до второй навигацииmiddle
- Пять канонических поломок: где производство стабильно ломаетсяsenior
- Метод трёх треков: чтение трасс и построение системы мониторингаsenior
- Лок и single-flight: ограничение параллельных rebuildmiddle
- Stale-while-revalidate и CDN request coalescingmiddle
- Детектирование stampede и дизайн TTL для продакшенаmiddle
- Метастабильный сбой, fencing-токены и production-постмортемыsenior
- Что такое отношение: таблицы, строки, ключи и ограниченияjunior
- Ограничения, ключи и типы данных Postgresmiddle
- JSONB, массивы и когда side table побеждаетmiddle
- Целостность схемы: deferral, версионирование и сбои в продакшнеsenior
- Где происходит data fetching — и почему это решает LCPjunior
- React Server Components и Suspense streamingmiddle
- Senior internals: RSC payload, слои кэша и production паденияsenior
- Что такое OpenTelemetry: API, SDK, Collector, OTLPjunior
- Сигналы OTel, Semantic Conventions и проводной формат OTLPmiddle
- Collector OTel: receivers, processors, exporters и паттерны развёртыванияmiddle
- Vendor-нейтральность, eBPF-инструментирование, Operator и OTel в браузере и serverlesssenior
- Эксплуатация OTel Collector: надёжность, version skew, режимы отказа и управлениеsenior
- Что такое trace propagation и почему сломанная propagation хуже отсутствия трейсовjunior
- traceparent и tracestate: полный формат W3C-заголовкаmiddle
- Baggage и async-границы: перенос контекста через очереди и callback''''иmiddle
- Async context на разных языках, service mesh, миграция B3 и безопасностьsenior
- Production-сбои propagation, span links и платформенный дизайнsenior
- Debugging-воронка: SLO → RED → trace → profilejunior
- Архитектура OTel: один SDK, четыре сигнала, один wire-форматmiddle
- Петля инцидента: от пейджера до постмортема до предотвращенияmiddle
- Масштаб, безопасность и ROI наблюдаемых системsenior
- At-most-once, at-least-once, exactly-once: три контракта доставкиjunior
- Consumer-side dedup: самый дешёвый путь к exactly-once processingmiddle
- Exactly-once в production: impossibility-доказательство, гибридные паттерны и реальные инцидентыsenior
- Что такое OAuth и почему пароли — не ответjunior
- Authorization code flow с PKCEmiddle
- Sender-constrained токены: DPoP и mTLSsenior
- OAuth в production: audience атаки, observability и реальные провалыsenior