Материал просмотрен 3,349 раз(а)

Почитываю сейчас книжонку ICND, очень хорошо расписано всё. Ну в общем стал лучше разбираться в соединении по протоколу TCP. Исчезли многие вопросы, которые раньше просто не знал. Сейчас намерен поделиться так, чтобы было понятно обычному человеку.

Вообще, организация соединения по протоколу TCP начинается с так называемого трехстороннего квитирования (рукопожатия).

 

Шаг 1. Отправка SYN пакета

Отправляется пакет с выставленным флагом SYN, что означает инициализацию сессии. Разумеется, на этом этапе будет задан порт источника и порт назначения (порт источника выбирается случайно из диапазона 1024-65535), хотя на этом участке можно выделить два диапазона ещё. Порты с 1024 до 49151 используются для проприетарных приложений, контролируется IANA (те же чуваки, которые и выделяют IP адреса). Порт назначения здесь зависит от используемой службы. Стандартные порты ssh – 22, http – 80, pop3 – 110 и т.д. Все эти порты прописаны в c:\Windows\System32\drivers\etc\services ну или аналогичный файл в Linux.

SYN

SYN

 

Здесь очень интересным является поле Sequence Number, в которое заносится некоторый номер последовательности. Так же есть поле Acknowledgment Number, которое говорит о подтверждении принятого пакета с этим номером (и всех пакетов до него!).
Как же выбирается этот номер? Приведу выдержку из RFC 793:
При организации нового соединения генерируется начальный порядковый номер (initial sequence number) ISN. Генерация номера основана на текущем (возможно, фиктивном) 32-битовом значении времени, в котором младший бит инкрементируется приблизительно каждые 4 микросекунды. Таким образом, цикл номеров ISN занимает около 4.55 часа. Поскольку мы предполагаем, что сегмент сохраняется в сети в течение времени, не превышающего MSL (Maximum Segment Lifetime – максимальное время жизни
сегмента), и значение MSL < 4.55 час., можно считать значения ISN уникальными.

То есть в первом пакете с битом SYN задается некий номер последовательности. На скрине выше я привел пример, видим бит SYN и ISN 2686526190 [1].

Шаг 2. Отправка подтверждения SYN+ACK

В ответ на этот пакет, сервер, если он не против соединения, посылает пакет с битами SYN,ACK и произвольным номером последовательности Sequence Number, вычисленным по похожему принципу. А поле Acknowledgment Number будет равняться полю ISN+1.

SYN+ACK

SYN+ACK

На примере видно, что сгенерировано число Initial Receive Sequence (IRS) = 675813843 [2] и пакет послан как ответ AN: 2686526191 (предыдущий SN: 2686526190[1] + 1).

Шаг 3. Отправка подтверждения ACK

Теперь инициатору подключения не остается ничего другого, как ответить ACK и пояснить, что речь идёт об Acknowledgment number предыдущего шага IRS [2] + 1, т.е. 675813843+1 = 675813844! А Sequence nuber остаётся неизменным, AN предыдущего пакета 2686526191.

ACK

ACK

Иначе, в переводе с TCP на русский это выглядит так:

  1. Клиент: Кодовое слово “1” (Sequence number), сервер, давай мутить! (SYN);
  2. Сервер: Моё кодовое слово “5” (Sequence number), клиент, на твой запрос по кодовому слову “1” (Acknowledgment number) отвечаю (+1) ну давай мутить (SYN+ACK).
  3. Клиент: Ну хорошо! Раз ты, сервер, получай мой окончательный ответ ответ (ACK) на твое согласие (5+1) на мой запрос (1+1).

Всё. С этого момента соединение считается установленным. Дальнейшие пакеты будут передавать уже полезную нагрузку – данные протоколов вышестоящих уровней, например SSH.

При этому так же происходит взаимное увеличение Sequence Number у сервера и у клиента, но только уже не на 1, а на размер отправляемых данных.

Т.е. если в пакете передается 2686526191 (из предыдущего примера) и будет передано 100 байт полезной нагрузки, то следующий номер последовательности будет ожидаться 2686526291 – увеличенным на 100.

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

Payload

Payload

О том, что такое “окно приёма” я напишу позднее.