Шрифт:
Метод, основанный на генераторе импульсов истинного времени, решает проблему распознавания опаздывающих дубликатов сегментов и новых сегментов. Однако использовать его для установления соединения может быть проблематично. Поскольку обычно получатель не помнит порядковые номера разных соединений, он не может узнать, является ли сегмент 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 понимает, что он был обманут задержавшимся дубликатом, и прерывает соединение. В результате дубликат не причиняет вреда.
При наихудшем сценарии оба сегмента — CONNECTION REQUEST и ACK — блуждают по подсети. Этот случай показан на илл. 6.11 (в). Как и в предыдущем примере, хост 2 получает задержавшийся сегмент CONNECTION REQUEST и отвечает на него. Здесь нужно учитывать, что хост 2 предложил использовать y в качестве начального порядкового номера для трафика от хоста 2 к хосту 1, хорошо зная, что сегментов, содержащих порядковый номер y, или их подтверждений в данный момент в сети нет. Когда хост 2 получает второй задержавшийся сегмент, он понимает, что это дубликат, так как в этом модуле подтверждается не y, а z. Важно понимать, что не существует такой комбинации сегментов, которая заставила бы протокол ошибиться и случайно установить соединение, когда оно никому не нужно.
Илл. 6.11. Три сценария установления соединения с помощью «тройного рукопожатия» (CR означает CONNECTION REQUEST). (а) Нормальная работа. (б) Появление старого дубликата CR. (в) Дубликат CR и дубликат ACK
TCP всегда использует «тройное рукопожатие» для установления соединения. Внутри соединения к 32-битному порядковому номеру добавляется метка времени, чтобы он не мог использоваться повторно в течение максимального времени жизни пакета, даже если скорость соединения составляет несколько гигабитов в секунду. Этот механизм был добавлен в TCP для решения проблем, возникающих при использовании быстрых линий. Он описан в RFC 1323 и называется защитой от повторного использования порядковых номеров (Protection Against Wrapped Sequence numbers, PAWS). До появления PAWS при наличии нескольких соединений с начальными порядковыми номерами TCP применял метод генератора импульсов (см. выше). Однако этот метод оказался неэффективным с точки зрения безопасности. Злоумышленники могли легко угадать следующий начальный порядковый номер и инициировать ложное соединение, обманув схему «тройного рукопожатия». Поэтому на практике используются псевдослучайные начальные порядковые номера. Однако необходимо, чтобы эти номера, со стороны кажущиеся абсолютно случайными, не повторялись в течение определенного промежутка времени. Иначе задержавшиеся дубликаты могут вызвать серьезные неполадки в сети.
6.2.3. Разрыв соединения
Разорвать соединение проще, чем установить. Но здесь также имеются подводные камни. Как уже было сказано, существует два стиля разрыва соединения: асимметричный и симметричный. Асимметричный разрыв связи соответствует принципу работы телефонной системы: когда одна из сторон вешает трубку, связь прерывается. При симметричном разрыве соединение рассматривается в виде двух отдельных однонаправленных связей, и требуется отдельное завершение каждого соединения.
Асимметричный разрыв связи является внезапным и может привести к потере данных. Рассмотрим сценарий на илл. 6.12. После установления соединения хост 1 отправляет сегмент, который успешно достигает хоста 2. Затем хост 1 передает другой сегмент. К несчастью, хост 2 отправляет DISCONNECTION REQUEST прежде, чем приходит второй сегмент. В результате соединение разрывается, а данные теряются.
Илл. 6.12. Внезапное разъединение с потерей данных
Очевидно, требуется более сложный протокол, позволяющий избежать потери данных. Один из способов состоит в использовании симметричного варианта, при котором каждое направление разъединяется независимо. В этом случае хост может продолжать получать данные даже после того, как сам отправил запрос на разъединение.
Симметричное разъединение подходит для тех случаев, когда у каждой стороны есть фиксированное количество данных для передачи и каждая из них точно знает, когда эти данные заканчиваются. В других случаях определить, что работа окончена и соединение может быть прервано, не так просто. Можно представить себе протокол, в котором хост 1 говорит: «Я закончил передачу. А вы?». Если хост 2 отвечает: «Я тоже. До свидания», соединение можно безо всякого риска разъединять.
К сожалению, этот протокол работает не всегда. Существует знаменитая проблема «двух армий» (two-army problem). Представьте, что армия белых находится в долине (илл. 6.13). На возвышенностях по обеим сторонам долины расположились две армии синих. Белая армия больше, чем любая из синих, но вместе синие превосходят белых. Если одна из армий синих атакует белых в одиночку, она потерпит поражение, но если синие сумеют атаковать белых одновременно, они могут победить.