Тайм-ауты и повторные передачи TCP

         

Быстрая повторная передача и алгоритм быстрого восстановления



Быстрая повторная передача и алгоритм быстрого восстановления

В тексте не приводится достаточно жесткого разграничения между алгоритмом быстрой повторной передачи и быстрого восстановления. Это два абсолютно независимых алгоритма. Алгоритм быстрой повторной передачи вступает в действие, когда TCP определяет потерю сегмента и номер потерянного сегмента по наличию небольшого количества последователььных дублированных подтверждений (ACK). Потерянный сегмент передается повторно. Алгоритм быстрого востановления говорит, что после быстрой повторной передачи необходимо осуществить предотвращение переполнения, а не медленный старт. Алгоритм быстрой повторной передачи впервые появился в 4.3BSD Tahoe, однако за ним неправильно следовал медленный старт. Алгоритм быстрого восстановления впервые был применен в 4.3BSD Reno.

В 1990 году [Jacobson 1990b] алгоритм предотвращения переполнения был модифицирован. Мы уже видели эти модификации в действии в примере переполнения (раздел "Пример переполнения" этой главы).

Перед тем как познакомиться с этими изменениями представьте, что TCP требует сгенерировать немедленное подтверждение (дублированный ACK), когда принят поврежденный сегмент. Этот дублированный ACK не должен быть задержан. Цель дублированного ACK заключается в том, чтобы сообщить удаленному концу о том, что сегмент был получен поврежденным, и сообщить, какой ожидается номер последовательности.

Так как мы не знаем, было ли дублирование ACK вызвано потерей сегмента или просто тем, что изменился порядок следования сегментов, мы ожидаем прихода небольшого количества дублированных ACK. Это означает, что если сегменты просто пришли в другом порядке, будет получено только один или два дублированных ACK перед тем, как перемешанные сегменты будут обработаны, после чего будет сгенерирован новый ACK. Если же последовательно пришло три или более дублированных ACK, это уже является признаком того, что сегмент был потерян (раздел "Пример переполнения"). Мы осуществляем повторную передачу отсутствующего сегмента, не ожидая истечения таймера повторной передачи. Также мы осуществляем предотвращение переполнения, но не медленный старт.

На рисунке 21.7 мы видели, что медленный старт не осуществлялся после того, как было принято три дублированных ACK. Вместо этого отправитель осуществил повторную передачу, за которой следует три сегмента новых данных (сегменты 67, 69 и 71), перед тем как были получены подтверждения на повторную передачу (сегмент 72).

Причина того, что в этом случае не был применен медленный старт, заключается в том, что получение дублированных ACK сообщило нечто большее, нежели просто о потере одного пакета. Так как получатель может только генерировать дублированные ACK, когда прибывает еще один сегмент, можно сказать, что этот сегмент вышел из сети и находится в буфере получателя. Таким образом, данные все еще двигаются между двумя концами, и мы не хотим внезапно уменьшить поток, воспользовавшись медленным cтартом.

Алгоритм функционирует следующим образом.

  1. Когда принят третий дублированный ACK, ssthresh устанавливается равным половине текущего окна переполнения, cwnd.

Передается отсутствующий сегмент.

Значение cwnd устанавливается в значение ssthresh плюс утроенное значение размера сегмента.

  • Каждый раз когда прибывает дублированный ACK, cwnd увеличивается на размер сегмента, и передается пакет (если это разрешено новым значением cwnd).
  • Когда прибывает следующий ACK, который подтверждает новые данные, устанавливается cwnd равное ssthresh (значение, установленное в шаге 1). Это должно быть ACK на повторную передачу из шага 1, пришедшее через одно время возврата после повторной передачи. Этот ACK должен также подтверждать все промежуточные сегменты, отправленные между потерянным пакетом и получением первого дублированного ACK. Этот шаг осуществляется при предотвращении переполнения, так как мы наполовину замедлили скорость, с которой производилась передача в тот момент, когда пакет был потерян.
  • Мы увидим, что произойдет с переменными cwnd и ssthresh, в следующем разделе.



    Содержание раздела