Читаем Компьютерные сети. 6-е изд. полностью

Даже при известном значении SRTT выбор периода ожидания подтверждения — нетривиальная задача. В первых реализациях TCP это значение вычислялось как 2xRTT, но опыт показал, что постоянный множитель слишком негибкий и не реагирует на увеличение разброса. В частности, модели очередей случайного (то есть пуассоновского) трафика показывают, что когда нагрузка приближается к пропускной способности, задержка растет и становится крайне изменчивой. В результате может сработать таймер повторной передачи, после чего будет отправлена копия пакета, хотя оригинальный пакет все еще будет находиться в сети. Как правило, такие ситуации возникают именно при высокой нагрузке — и это не самое лучшее время для отправки в сеть лишних пакетов.

Чтобы решить эту проблему, Джейкобсон предложил сделать интервал времени ожидания чувствительным к отклонению RTT и к усредненному RTT. Для этого потребовалась еще одна сглаженная переменная — RTTVAR (RoundTrip Time Variation — изменение времени в пути туда-обратно), которая вычисляется по формуле:

Как и в предыдущем случае, это взвешенное скользящее среднее. Обычно β = 3/4. Значение интервала ожидания повторной передачи (RTO) устанавливается по формуле:

Множитель 4 выбран произвольно, однако умножение целого числа на 4 может быть выполнено одной командой сдвига, при этом менее 1 % всех пакетов придет с опозданием, превышающим четыре среднеквадратичных отклонения. Обратите внимание, что RTTVAR является не среднеквадратичным, а средним отклонением, но на практике это довольно близкие значения. В своей работе Джейкобсон приводит множество хитрых способов вычисления значений интервала ожидания с помощью только целочисленного сложения, вычитания и сдвига. Для современных хостов такая экономия не требуется, но она стала элементом культуры повсеместного применения TCP: он должен работать как на суперкомпьютерах, так и на небольших устройствах. Для RFID-чипов его пока еще не реализовали, но ведь все может быть.

Более подробные сведения о том, как вычислять этот интервал ожидания, а также начальные значения переменных, можно найти в RFC 2988. Для таймера повторной передачи минимальное значение также устанавливается равным 1 с, независимо от предварительной оценки. Это значение, выбранное с запасом (и в основном эмпирически), требуется, чтобы избежать выполнения лишних повторных передач на основании измерений (Оллман и Паксон; Allman and Paxson, 1999).

При сборе данных (R) для вычисления RTT возникает вопрос, что делать при повторной передаче сегмента. Когда для него приходит подтверждение, неясно, к какой передаче оно относится, первой или последней. Неверная догадка может серьезно нарушить работу RTO. Эта проблема была обнаружена радиолюбителем Филом Карном (Phil Karn). Его интересовал вопрос передачи TCP/IP-пакетов с помощью коротковолновой любительской радиосвязи, известной своей ненадежностью. Предложение Карна было очень простым: не обновлять оценки для сегментов, переданных повторно. Кроме того, при каждой повторной передаче время ожидания можно удваивать до тех пор, пока сегменты не пройдут с первой попытки. Это исправление получило название алгоритма Карна (Karn’s algorithm) (Карн и Партридж; Karn and Partridge, 1987) и применяется в большинстве реализаций TCP.

В протоколе TCP используется не только таймер повторной передачи, но и таймер настойчивости (persistence timer). Он предназначен для предотвращения следующей тупиковой ситуации. Получатель отправляет подтверждение, в котором указывает окно нулевого размера (это значит, что отправитель должен подождать). Через некоторое время получатель передает пакет с новым размером окна, но этот пакет теряется. Теперь обе стороны ожидают действий друг от друга. Когда срабатывает таймер настойчивости, отправитель высылает получателю пакет с вопросом, не изменилось ли текущее состояние. В ответ получатель сообщает текущий размер окна. Если он все еще равен нулю, таймер настойчивости запускается снова, и весь цикл повторяется. В случае увеличения окна отправитель может передавать данные.

В некоторых реализациях протокола используется третий таймер, называемый таймером проверки активности (keepalive timer). Он срабатывает, если соединение простаивает в течение долгого времени, заставляя одну сторону проверить, активна ли другая сторона. Если проверяющая сторона не получает ответа, соединение разрывается. Это свойство протокола довольно противоречиво, поскольку привносит дополнительные накладные расходы и может разорвать вполне жизнеспособное соединение из-за кратковременной потери связи.

И наконец, в каждом TCP-соединении используется таймер, запускаемый в состоянии TIME WAIT при закрытии соединения. Он отсчитывает двойное время жизни пакета, чтобы гарантировать, что после закрытия соединения созданные им пакеты исчезли.

6.5.10. Контроль перегрузки в TCP

Перейти на страницу:

Похожие книги