RFC: 793
Оригинал: Transmission Control Protocol
Предыдущие версии: RFC 761
Категория: Стандарт Интернета
Дата публикации:
Автор:
Перевод: Николай Малых

3.4. Организация соединения

Для организации соединений используется процедура трехэтапного согласования (three-way handshake). Эта процедура обычно инициируется одним TCP, а TCP на удаленной стороне дает отклик. Трехэтапное согласование будет работать и при одновременном инициировании соединения с обеих сторон. При одновременной попытке каждый модуль TCP получает сегмент SYN, не содержащий подтверждения для переданного этой стороной ранее сегмента SYN. Потенциально возможно прибытие старого дубликата SYN в процессе одновременной организации соединения. Для решения таких проблем можно использовать сегменты reset.

Ниже рассмотрены несколько примеров организации соединений. Хотя в этих примерах не рассматривается синхронизация с использованием сегментов данных, она полностью легитимна, пока принимающая сторона TCP не будет доставлять данные пользователю до проверки их корректности (т. е., данные должны буферизоваться на приемной стороне, пока соединение не перейдет в состояние ESTABLISHED). Трехэтапное согласование снижает вероятность организации ложных соединений. Это согласование является компромиссом между расходом памяти и передачей сообщений, обеспечивающих информацию для проверки соединения.

Простейший вариант трехэтапного согласования показан на рисунке 7. Стрелка вправо (-->) на рисунке показывает отправку сегмента от TCP A к TCP B или прибытие сегмента в B из A. Левая стрелка (<--) показывает передачу сегментов в обратном направлении. Троеточия (...) показывают сегменты, которые еще остаются в сети (задержаны). XXX обозначает потерянные или отброшенные сегменты. В скобках () приведены комментарии. Состояния TCP представлены после отправки или прибытия сегментов (содержимое сегментов показано в центральной части каждой строки). Содержимое сегментов представлено в сокращенном виде — порядковый номер, флаги управления и поле ACK. Остальные поля (размер окна, адреса, длина сегмента) для краткости и простоты опущены.

    TCP A                                                TCP B

1.  CLOSED                                               LISTEN

2.  SYN-SENT    --> <SEQ=100><CTL=SYN>               --> SYN-RECEIVED

3.  ESTABLISHED <-- <SEQ=300><ACK=101><CTL=SYN,ACK>  <-- SYN-RECEIVED

4.  ESTABLISHED --> <SEQ=101><ACK=301><CTL=ACK>       --> ESTABLISHED

5.  ESTABLISHED --> <SEQ=101><ACK=301><CTL=ACK><DATA> --> ESTABLISHED

Рисунок 7. Базовое 3-этапное согласование для синхронизации соединения

В строке 2 на рисунке 7 TCP A начинает передачу сегмента SYN, говорящего об использовании порядковых номеров, начиная со 100. В строке 3 TCP B передает SYN и подтверждение для принятого SYN в адрес TCP A. Отметим, что поле подтверждения показывает ожидание TCP B приема порядкового номера 101, подтверждающего SYN с номером 100.

В строке 4 TCP A отвечает пустым сегментом с подтверждением ACK для сегмента SYN от TCP B; в строке 5 TCP A передает некоторые данные. Отметим, что порядковый номер сегмента в строке 5 совпадает с номером в строке 4, поскольку ACK не занимает пространства порядковых номеров (если это сделать, придется подтверждать подтверждения — ACK для ACK!).

Одновременное инициирование соединения лишь незначительно сложнее (см. рисунок 8). Каждое соединение TCP проходит от состояния CLOSED через SYN-SENT и SYN-RECEIVED в состояние ESTABLISHED.

    TCP A                                            TCP B

1.  CLOSED                                           CLOSED

2.  SYN-SENT     --> <SEQ=100><CTL=SYN>              ...

3.  SYN-RECEIVED <-- <SEQ=300><CTL=SYN>              <-- SYN-SENT

4.               ... <SEQ=100><CTL=SYN>              --> SYN-RECEIVED

5.  SYN-RECEIVED --> <SEQ=100><ACK=301><CTL=SYN,ACK> ...

6.  ESTABLISHED  <-- <SEQ=300><ACK=101><CTL=SYN,ACK> <-- SYN-RECEIVED

7.               ... <SEQ=101><ACK=301><CTL=ACK>     --> ESTABLISHED

Рисунок 8. Одновременная синхронизация соединения

Принципиальная необходимость использования трехэтапного согласования обусловлена стремлением избавиться от недоразумений, связанных со старыми дубликатами инициирования соединений. Для решения таких проблем используется специальное управляющее сообщение — reset (сброс). Если принимающая сторона TCP еще находится в несинхронизированном состоянии (т. е., SYN-SENT, SYN-RECEIVED), она возвращается в состояние LISTEN при получении reset. Если TCP находится с засинхронизированном состоянии (ESTABLISHED, FIN-WAIT-1, FIN-WAIT-2, CLOSE-WAIT, CLOSING, LAST-ACK, TIMEWAIT), соединение после reset разрывается и пользователю передается уведомление об этом. Позднее мы обсудим этот вопрос при рассмотрении полуоткрытых (half-open) соединений.

    TCP A                                                TCP B

1.  CLOSED                                               LISTEN

2.  SYN-SENT    --> <SEQ=100><CTL=SYN>               ...

3.  (duplicate) ... <SEQ=90><CTL=SYN>               --> SYN-RECEIVED

4.  SYN-SENT    <-- <SEQ=300><ACK=91><CTL=SYN,ACK>  <-- SYN-RECEIVED

5.  SYN-SENT    --> <SEQ=91><CTL=RST>               --> LISTEN


6.              ... <SEQ=100><CTL=SYN>               --> SYN-RECEIVED

7.  SYN-SENT    <-- <SEQ=400><ACK=101><CTL=SYN,ACK>  <-- SYN-RECEIVED

8.  ESTABLISHED --> <SEQ=101><ACK=401><CTL=ACK>      --> ESTABLISHED

Рисунок 9. Действия при получении старого дубликата SYN

На рисунке 9 показан простой пример решения проблемы со старым дубликатом. В строке 3 старый дубликат SYN принимается TCP B, который не знает об этом и дает нормальный отклик (строка 4). TCP A детектирует некорректность поля ACK и возвращает RST (reset) с полем SEQ, делающим сегмент правдоподобным (believable). TCP B, получив RST, возвращается в состояние LISTEN. Когда оригинальный сегмент SYN наконец принимается (строка 6), происходит нормальная синхронизация. Если SYN в строке 6 приходит до RST, может потребоваться более сложный обмен сообщениями с передачей RST в обоих направлениях.

2007 - 2017 © Русские переводы RFC, IETF, ISOC.