Выбрать главу

На практике нужно гарантировать не только то, что пакета больше нет, но и что все его подтверждения также исчезли. Поэтому вводится период T, который в несколько раз превышает максимальное время жизни пакета (для каждой сети оно является константой и выбирается с запасом; для интернета оно составляет 120 с). На какое число умножается максимальное время жизни пакета, зависит от протокола, и это влияет только на длительность T. Если подождать в течение T с момента отправки пакета, то можно быть уверенными, что все следы этого пакета уничтожены и что он не возникнет вдруг как гром среди ясного неба.

При ограниченном времени жизни пакетов можно разработать надежный и практичный способ отвергать задержавшиеся дублированные сегменты. Автор описанного ниже метода — Томлинсон (Tomlinson, 1975); позднее он был улучшен Саншайном и Далалом (Sunshine and Dalal, 1978). Варианты этого метода широко используются на практике, и одним из примеров применения является TCP.

Основная идея метода заключается в том, что отправитель присваивает сегментам последовательные номера, которые не будут повторно использоваться в течение последующих T секунд. Размер такого номера складывается из периода T и скорости пакетов в секунду. Таким образом, в любой момент времени может отправляться только один пакет с данным номером. Копии этого пакета все равно могут появиться, и получатель должен их удалить.

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

Чтобы обойти проблему потери устройством сведений о предыдущих состояниях (при сбое), можно сделать так, чтобы транспортная подсистема оставалась неактивной в течение первых T секунд после восстановления. В таком случае все старые сегменты исчезнут, и отправитель сможет начать процесс заново, используя любой последовательный номер. Недостаток этой идеи в том, что в крупных интерсетях период времени T может быть достаточно большим.

Вместо этого Томлинсон предложил снабдить каждый хост генератором импульсов истинного времени. Генераторы разных хостов синхронизировать не обязательно. Предполагается, что они представляют собой двоичные счетчики, которые увеличиваются через равные интервалы времени. Кроме того, число разрядов счетчика должно равняться числу битов в последовательных номерах (или превосходить его). Последнее и самое важное предположение состоит в том, что таймер продолжает работать, даже если хост зависает.

При установке соединения младшие k-биты генераторов импульсов используются в качестве k-битного начального порядкового номера. Таким образом, в отличие от протоколов, описанных в главе 3, каждое соединение начинает нумерацию своих сегментов с разных чисел. Диапазон этих номеров должен быть достаточно большим, чтобы к тому моменту, когда порядковые номера сделают полный круг, старые сегменты с такими же номерами уже давно исчезли. Линейная зависимость порядковых номеров от времени представлена на илл. 6.10 (а). Запретная зона показывает, в какой момент времени определенные порядковые номера сегментов являются недействительными. При отправке сегмента с порядковым номером из этой зоны он может задержаться и сыграть роль другого пакета с таким же номером, который будет отправлен позже. К примеру, если хост выходит из строя и возобновляет работу в момент времени 70 с, он будет использовать начальные порядковые номера на основе генератора импульсов; хост не начинает отсчет с наименьшего порядкового номера в запретной зоне.

Как только обе транспортные подсистемы договариваются о начальном порядковом номере, для управления потоком данных может применяться любой протокол раздвижного окна. Такой протокол безошибочно найдет и удалит дубликаты пакетов, когда они уже будут приняты. В действительности график порядковых номеров (показанный жирной линией) не прямой, а ступенчатый, так как тактовые импульсы генерируются дискретно. Впрочем, для простоты мы проигнорируем эту деталь.

Чтобы порядковые номера пакетов не попадали в запретную зону, необходимо учесть следующее. Проблемы могут возникнуть по двум причинам. Если хост отправляет слишком быстро и слишком много данных, кривая используемых в действительности порядковых номеров может оказаться круче линии зависимости начальных номеров от времени. В результате порядковый номер попадет в запретную зону. Чтобы этого не произошло, скорость передачи данных в каждом открытом соединении должна быть ограничена одним сегментом за единицу времени. Кроме того, после восстановления транспортная подсистема не должна открывать новое соединение до появления нового тактового импульса, чтобы один и тот же номер не использовался дважды. Следовательно, интервал импульсов должен быть коротким (1 мкс или меньше). При этом генератор не должен работать слишком быстро (относительно порядковых номеров). Если частота импульсов равна C, а размер пространства порядковых номеров равен S, условие S/C > T является обязательным, чтобы номера не сделали полный круг слишком быстро.

Илл. 6.10. (а) Сегменты не могут заходить в запретную зону. (б) Проблема ресинхронизации

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

Метод, основанный на генераторе импульсов истинного времени, решает проблему распознавания опаздывающих дубликатов сегментов и новых сегментов. Однако использовать его для установления соединения может быть проблематично. Поскольку обычно получатель не помнит порядковые номера разных соединений, он не может узнать, является ли сегмент CONNECTION REQUEST, содержащий какой-либо начальный порядковый номер, дубликатом одного из предыдущих соединений. Во время соединения такой проблемы не возникает, поскольку протокол раздвижного окна знает текущий порядковый номер.

Решение: «тройное рукопожатие»

Для разрешения этой специфической проблемы Томлинсон (1975) предложил «тройное рукопожатие» (three-way handshake). Этот протокол установления соединения предполагает, что одна из сторон проверяет, является ли соединение все еще действующим. Нормальная процедура установления соединения показана на илл. 6.11 (а). Хост 1 выбирает порядковый номер x и отправляет сегмент CONNECTION REQUEST, содержащий этот номер, хосту 2. Хост 2 отвечает сегментом ACK, подтверждая x и объявляя свой начальный порядковый номер y. Наконец, хост 1 подтверждает выбранный хостом 2 номер в первом отправленном им информационном сегменте.

Теперь рассмотрим работу «тройного рукопожатия» при задержке дубликата управляющего сегмента. На илл. 6.11 (б) первый сегмент представляет собой задержавшийся дубликат CONNECTION REQUEST от старого соединения. Этот сегмент приходит на хост 2; хост 1 об этом не знает. Хост 2 реагирует на это отправкой хосту 1 сегмента ACK, таким образом запрашивая подтверждение того, что хост 1 действительно пытался установить новое соединение. Когда хост 1 отказывается это сделать (REJECT), хост 2 понимает, что он был обманут задержавшимся дубликатом, и прерывает соединение. В результате дубликат не причиняет вреда.