Когда один TCP-порт может быть поделён
Вы замечали, как простые вопросы иногда приводят к сложным вопросам? Сегодня мы попытаемся подступиться к одному из таких вопросов. Категория — наша любимая: сетевые аспекты Linux.
Когда два TCP-сокета могут разделять локальный адрес?
Если я перейду по ссылке https://blog.cloudflare.com/, мой браузер подключится к удалённому TCP-адресу, в данном случае это может быть 104.16.132.229:443. Подключение пойдёт с локального IP-адреса, присвоенного моей машине с Linux, через выбранный случайным образом локальный TCP-порт, скажем, 192.0.2.42:54321. Что произойдёт, если я затем решу отправиться на другой сайт? Возможно ли установить другое TCP-соединение с того же локального IP-адреса и порта?
Чтобы найти ответ на этот вопрос, давайте выясним его опытным путём. Мы подготовили для вас восемь вопросов-задачек. Ответив на каждый из них, вы откроете для себя один из аспектов тех правил, что регулируют разделение локальных адресов между TCP-сокетами под Linux. Честно предупреждаем: от этого материала может зайти ум за разум.
Вопросы разделены на две группы в зависимости от тестового сценария:

В первом сценарии два сокета подключаются с одного и того же локального порта на одни и те же удалённые IP и порт. Однако локальный IP для обоих сокетов отличается.
В свою очередь, во втором сценарии локальный IP и порт одинаковы для всех сокетов, но отличается удалённый адрес или, в сущности, только IP-адрес.
Отвечая на поставленные вопросы, мы будем делать одно из двух:
1. Позволять ОС автоматически выбирать локальный IP и/или порт для сокета или
2. Явно присваивать локальный адрес при помощи bind (), прежде, чем подключиться (connect ()) к сокету; такой метод также называется bind-before-connect.
Поскольку мы будем исследовать пограничные случаи, связанные с логикой bind(), нам нужно каким-то способом исчерпать все локальные адреса, то есть, пары (IP, порт). Можно было бы банально создать много сокетов, но проще было бы подкрутить конфигурацию системы и предположить, что на машине есть всего один локальный эфемерный порт, который ОС может присваивать сокетам:
sysctl -w net.ipv4.ip_local_port_range='60000 60000'
В каждом вопросе-загадке вас ждёт краткий листинг на Python. Ваша задача — спрогнозировать, каков будет итог выполнения кода. Выполнится ли код успешно? Или нет? Спрашивать ChatGPT не разрешается
