Skip to content

3.8 Обработка сбойных ситуаций в транспортных протоколах. Виды сбойных ситуаций, способы их обработки. Время жизни блока данных. Таймеры. Особенности протокола TCP.

Развернутый ответ: Обработка сбойных ситуаций в транспортных протоколах

1. Введение

Транспортный уровень (OSI уровень 4) отвечает за сквозную (end-to-end) доставку данных между приложениями на разных хостах. В отличие от сетевого уровня (IP), который работает по принципу «best effort» (максимально возможное усилие) и допускает потери пакетов, транспортный уровень должен гарантировать надежность (в случае TCP) или предоставлять механизмы контроля целостности (в случае UDP).

Основная проблема заключается в том, что нижележащая сеть (каналы, маршрутизаторы) ненадежна. Пакеты могут:

  • Теряться (перегрузка, битые биты, обрыв связи).
  • Дублироваться (из-за повторных передач).
  • Приходить не в том порядке (из-за разных маршрутов).
  • Задерживаться на неопределенное время (jitter).

Для борьбы с этим в транспортных протоколах реализованы сложные механизмы обработки сбойных ситуаций.


2. Виды сбойных ситуаций

Сбойные ситуации можно классифицировать по характеру нарушения:

  1. Потеря сегмента (Data Loss):

    • Перегрузка маршрутизатора: Буфер переполнен, и пакет отбрасывается (Drop).
    • Битовые ошибки: Ошибка в контрольной сумме (Checksum) приводит к отбрасыванию пакета на приемной стороне.
    • Обрыв канала: Физический разрыв соединения или уход маршрутизатора из сети.
  2. Нарушение порядка (Out-of-Order):

    • Пакеты, отправленные последовательно (1, 2, 3), приходят вразнобой (1, 3, 2), так как IP-маршрутизация динамична и пакеты могут идти разными путями.
  3. Дублирование (Duplication):

    • Возникает, когда отправитель не получил подтверждение (ACK) вовремя и повторно отправил сегмент, а первый сегмент на самом деле дошел, просто ACK задержался. Получатель получает две копии одного и того же блока данных.
  4. Задержка (Delay / Reordering):

    • Пакет «застрял» в буфере маршрутизатора на долгое время. Он приходит с большим опозданием, когда таймер отправителя уже истек, и данные были отправлены заново.
  5. «Мертвое» соединение (Silent Failure):

    • Один из участников обмена (или промежуточный узел) перезагружается (“краш”). Оставшаяся сторона не получает никаких явных уведомлений о разрыве и продолжает ждать данные (ситуация Half-Open или Zombie Connection).

3. Способы обработки сбойных ситуаций

Для борьбы с перечисленными проблемами используются несколько базовых стратегий:

  • Нумерация последовательности (Sequence Numbers): Каждому байту или блоку данных присваивается уникальный номер. Это позволяет приемнику:
    • Собрать данные в правильном порядке (Reordering).
    • Обнаружить пропущенные блоки (по разрыву в номерах).
    • Отбросить дубликаты (если номер уже был принят).
  • Контрольные суммы (Checksums): Вычисление хэша от данных. Если хэш на приеме не совпадает с переданным, пакет уничтожается, и отправитель должен его повторить.
  • Подтверждения (Acknowledgment - ACK): Приемник явно отправляет сообщение о получении данных. Отсутствие ACK является для отправителя сигналом о сбое.
  • Повторная передача (Retransmission): Если отправитель не получил ACK за отведенное время, он отправляет те же данные повторно.
  • Механизмы «скользящего окна»: Ограничивают количество данных, которые можно отправить без подтверждения, что позволяет контролировать перегрузку и управлять потоком.

4. Время жизни блока данных (Time To Live – TTL / Lifetime)

Это критически важный параметр для предотвращения бесконечного блуждания дубликатов в сети.

  • На сетевом уровне (IP TTL): Это поле в заголовке IP, уменьшаемое на 1 каждым маршрутизатором. При достижении 0 пакет уничтожается. Это защита от петель маршрутизации.
  • На транспортном уровне (MSL - Maximum Segment Lifetime): Это максимальное время, которое сегмент может существовать в сети. Оно определяет, как долго нужно ждать, прежде чем можно будет безопасно переиспользовать номера последовательностей.
    • В TCP значение MSL обычно составляет 2 минуты (хотя часто в реализациях устанавливают 30–60 сек).
    • Смысл: Если мы отправили данные и получили ACK, старые дубликаты этих данных должны гарантированно исчезнуть из сети до того, как мы начнем использовать их порядковые номера для новых данных. Время жизни напрямую связано со временем ожидания в состоянии TIME_WAIT у TCP.

5. Таймеры (Timers)

Таймеры — это главный инструмент для работы с неопределенностью времени доставки. Транспортные протоколы используют несколько типов таймеров:

  1. Таймер повторной передачи (Retransmission Timer):

    • Запускается при отправке сегмента.
    • Если по его истечении ACK не получен, сегмент отправляется снова.
    • Ключевая сложность: Выбор значения тайм-аута (RTO — Retransmission Timeout). Если поставить мало — будут ложные срабатывания и дубли. Если много — падает производительность.
    • Алгоритм: Используется адаптивный расчет на основе RTT (Round Trip Time — время оборота). Рассчитывается средневзвешенное значение (SRTT) и вариация отклонений (RTTVAR): RTO = SRTT + 4 * RTTVAR.
  2. Таймер подтверждения (ACK Timer - Delayed ACK):

    • Используется получателем. Он не отправляет ACK мгновенно на каждый пакет, а выжидает небольшое время (обычно до 200 мс), чтобы попытаться «прицепить» ACK к встречным данным (piggybacking) или подтвердить сразу несколько сегментов одним ACK.
  3. Таймер сохранения (Persist Timer):

    • Связан с управлением потоком (окно приема). Если отправитель получил от получателя сообщение с нулевым размером окна (Window = 0), он останавливает отправку. Чтобы не ждать вечно, запускается Persist Timer. По его истечению отправитель шлет маленький зондирующий пакет (Probe), чтобы узнать, не освободилось ли окно у получателя.
  4. Таймер контроля соединения (Keepalive Timer):

    • Используется для проверки, жив ли партнер (приложение или хост) на другой стороне, при длительном простое.
    • Если в течение заданного времени (например, 2 часа по умолчанию в Linux) нет обмена данными, отправляется пустой Keepalive-пакет. Если ответа нет несколько раз (и таймеры повторной передачи срабатывают), соединение разрывается.

6. Особенности протокола TCP в обработке сбоев

Протокол TCP является самым сложным транспортным протоколом с точки зрения надежности. Его ключевые особенности:

  1. Трехэтапное установление соединения (Three-way Handshake):

    • Перед отправкой данных стороны обмениваются SYN-пакетами, согласовывая начальные номера последовательностей (ISN). Это защищает от наложения “старых” сегментов от предыдущего соединения.
    • Если SYN потерян, таймер повторной передачи на стороне клиента перезапускает попытку соединения.
  2. Выборочное подтверждение (SACK - Selective Acknowledgment):

    • Базовый TCP подтверждает только последний полученный непрерывный байт (Cumulative ACK). При потере одного пакета в середине окна, отправитель вынужден пересылать все пакеты начиная с потерянного (алгоритм Гоббса).
    • SACK позволяет приемнику сообщить отправителю точный список блоков данных, которые он получил. Отправитель пересылает только реально потерянные данные, что значительно повышает эффективность при сбоях.
  3. Управление перегрузкой (Congestion Control):

    • Сбой (потеря пакета) в TCP рассматривается не только как проблема связи, но и как индикатор перегрузки сети.
    • При срабатывании таймера повторной передачи или получении трех дублирующих ACK (указывающих на потерю), TCP включает механизмы уменьшения скорости отправки:
      • Медленный старт (Slow Start) и Избегание перегрузок (Congestion Avoidance): Снижает размер окна перегрузки (cwnd), чтобы разгрузить сеть.
    • Алгоритм Reno и CUBIC (современный стандарт в Linux): При потере (таймаут) окно обнуляется, при трех дублированных ACK (слабая потеря) окно уменьшается наполовину.
  4. Алгоритм Нейгла (Nagle’s Algorithm) и Алгоритм Кларка:

    • Хотя это больше оптимизация, они влияют на сбои при работе с интерактивными приложениями. Алгоритм Нейгла буферизирует мелкие пакеты (телеграфный режим), отправляя их пачками, что предотвращает переполнение сети большим количеством мелких сегментов (т.н. синдром глупого окна - Silly Window Syndrome).
  5. Закрытие соединения (Four-way Handshake и TIME_WAIT):

    • При разрыве соединения TCP использует таймер для состояния TIME_WAIT (длительностью 2 * MSL).
    • Особенность: Это делается для того, чтобы гарантировать, что все дубликаты последнего ACK и все старые пакеты исчезли из сети, прежде чем порт будет использован заново. Если бы не было TIME_WAIT, новый сеанс мог бы получить старые сегменты от завершенного сеанса.

7. Итоговая схема обработки потери (на примере TCP)

  1. Отправитель посылает сегмент с номером N и запускает Retransmission Timer.
  2. Сценарий А (Успех): Получатель получает сегмент, проверяет Checksum, отправляет ACK N+1. Отправитель получает ACK, сбрасывает таймер, сдвигает окно.
  3. Сценарий Б (Потеря данных/ACK): Таймер истекает.
    • Отправитель повторно отправляет сегмент N.
    • Включается экспоненциальная пауза (Exponential Backoff): тайм-аут удваивается (чтобы не усугублять перегрузку).
  4. Сценарий В (Дубль): Получатель уже получил сегмент N (но ACK потерялся) и при получении дубля просто отбрасывает его, но повторно отправляет ACK.
  5. Если сбой продолжается, таймеры срабатывают несколько раз (обычно 5–15 попыток в зависимости от ОС), после чего соединение разрывается, и приложению возвращается ошибка (ETIMEDOUT).