Открытие сокета

Когда браузер получает IP-адрес конечного сервера, то он берёт эту информацию и данные об используемом порте из URL (80 порт для HTTP, 443 для HTTPS) и осуществляет вызов функции socket системной библиотеки и запрашивает поток TCP сокета — AF_INET и SOCK_STREAM.

  • Этот запрос сначала проходит через транспортный уровень, где собирается TCP-сегмент. В заголовок добавляется порт назначения, исходный порт выбирается из динамического пула ядра (настройка net.ipv4.ip_local_port_range в Linux).
  • Получившийся сегмент отправляется на сетевой уровень, на котором добавляется дополнительный IP-заголовок. Также включаются IP-адрес сервера назначения и адрес текущей машины — после этого пакет сформирован. Тут же происходит выбор исходящего интерфейса, будет использоваться настройка приоритета использования интерфейсов для исходящего трафика (например, файл /etc/gai.conf).
  • Пакет передаётся на канальный уровень. Добавляется заголовок кадра, включающий MAC-адрес сетевой карты (NIC) компьютера, а также MAC-адрес шлюза (локального роутера). Как и на предыдущих этапах, если ядру ничего не известно о MAC-адресе шлюза, то для его нахождения отправляется широковещательный ARP-запрос.

На этой точке пакет готов к передаче через:

  • Ethernet
  • WiFi
  • По сотовой связи

В случае интернет-соединения большинства частных пользователей или небольших компаний пакет будет отправлен с компьютера, через локальную сеть, а затем через модем (MOdulator/DEModulator), который транслирует цифровые единицы и нули в аналоговый сигнал, подходящий для передачи по телефонной линии, кабелю или беспроводным телефонным соединениям. На другой стороне соединения расположен другой модем, который конвертирует аналоговый сигнал в цифровые данные и передаёт их следующему сетевому узлу, где происходит дальнейший анализ данных об отправителе и получателе.

В конечном итоге пакет доберётся до маршрутизатора, управляющего локальной подсетью, так же называемого шлюзом. Этот шлюз-маршрутизатор может иметь много VLAN (виртуальных локальных сетей), которые разделяет IP-подсети. В зависимости от IP и подсети, входящий фрейм данных будет приземляться на физический порт, затем заголовок Ethernet пакета (в случае Ethernet) будет удален, останется IP-адрес источника, IP-адрес назначения и информация о портах. Маршрутизаторы поддерживают свою таблицу маршрутизации пакетов от входящего интерфейса к исходящему интерфейсу, этот маршрутизатор читает заголовок IP-пакета и выполняет поиск в локальной таблице маршрутизации (которая строится с использованием статических маршрутов или с использованием динамических протоколов, таких как BGP, OSPF), чтобы найти исходящий интерфейс. Перед маршрутизацией пакета в заголовке IP из поля TTL (time to live) будет вычтена 1 (используется для предотвращения бесконечного зацикливания пакетов, пакет будет отброшен, если поле TTL достигнет нуля или если текущий маршрутизатор не имеет места в своей очереди / буферах (возможно, из-за перегрузки сети) или из-за ошибочных соединений и плохого CRC.). Помимо изменения TTL могут быть изменены другие поля, например если пакеты будут фрагментированы из-за меньшего размера MTU на исходящем интерфейсе, то маршрутизатор пошлет IP пакеты в так называемых чанках (chunks) - порции, и маршрутизатор перепишет IP-заголовки основываясь на оригинальном IP-пакете, также будут изменены контрольные суммы и т.д. Наконец, эти пакеты снова будут инкапсулированы во фрейм Ethernet или в любой другой поддерживаемый тип, который поддерживается на интерфейсе и отправлены следующему сетевому узлу для аналогичной обработки. Оттуда он продолжит движение к маршрутизаторам на пути, проходящем через различные автономные системы (ASN - это уникальный номер, назначенный поставщикам интернет-услуг для идентификации себя в Интернете и маршрутизации интернет-трафика. Протокол BGP-Border Gateway Protocol поддерживает большие таблицы маршрутизации в маршрутизаторах ISP и ретрансляции пакетов в пункт назначения), а затем, наконец, достигает сервера назначения, где он передается в стек TCP / IP на сервере для дальнейшей обработки и доставки приложениям.

Во время TCP-соединения происходит множество подобных запросов и ответов.

Жизненный цикл TCP-соединения

a. Клиент выбирает номер начальной последовательности (ISN) и отправляет пакет серверу с установленным битом SYN для открытия соединения.

b. Сервер получает пакет с битом SYN и, если готов к установлению соединения, то:

  • Выбирает собственный номер начальной последовательности;
  • Устанавливает SYN-бит, чтобы сообщить о выборе начальной последовательности;
  • Копирует ISN клиента +1 в поле ACK и добавляет ACK-флаг для обозначения подтверждения получения первого пакета.

c. Клиент подтверждает соединение путём отправки пакета:

  • Увеличивает номер своей начальной последовательности;
  • Увеличивает номер подтверждения получения;
  • Устанавливает поле ACK.

d. Данные передаются следующим образом:

  • Когда одна сторона отправляет N байтов, то увеличивает значение поля SEQ на это число.
  • Когда вторая сторона подтверждает получение этого пакета (или цепочки пакетов), она отправляет пакет ACK, в котором значение поля ACK равняется последней полученной последовательности.

e. Закрытие соединения:

  • Сторона, которая хочет закрыть соединение, отправляет пакет FIN;
  • Другая сторона подтверждает FIN (с помощью ACK) и отправляет собственный FIN-пакет;
  • Инициатор прекращения соединения подтверждает получение FIN отправкой собственного ACK.

TCP Windowing

Чтобы установить максимально возможную и надежную пропускную способность, отправитель и получатель устанавливает идеальный объем данных для отправки в каждом пакете, используя опцию / поле TCP Window. Получатель объявляет отправителю сколько данных он может получить в каждом пакете ACK, который соответствует свободное пространство буфера для сокета (SO_RCVBUF) и по умолчанию составляет 65535 байт.

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

Окно перегрузки - это управление потоком, которое динамически настраивается на пропускную способность и надежность сети. Окно перегрузки запускает окно, в два раза превышающее максимальный размер сегмента. Он увеличивается механизмом медленного запуска TCP на каждом ACKed-пакете на 1. С этим алгоритмом окно перегрузки фактически удваивается для каждого времени прохождения туда-обратно.

По достижении порога медленного старта TCP переходит от использования алгоритма медленного старта к алгоритму предотвращения скопления. Окно увеличивается на 1 сегмент за каждое путешествие туда и обратно.