2

Есть одно клиентское приложение, которое часто устанавливает TCP (HTTP) соединения с сервером. Соединение продолжается в течение одного запроса, а затем сервер закрывает соединение, поэтому сокет на сервере переходит в состояние TIME_WAIT на несколько минут. Поскольку клиентское приложение повторяет запросы, количество соединений TIME_WAIT на сервере растет и устанавливается на ~ 150 сокетов, постоянно находящихся в TIME_WAIT.

Иногда новое соединение от клиента выбирает недавно используемый временный исходный порт, который находится в состоянии TIME_WAIT на сервере, и соединение не устанавливается. С 32-кратным эфемерным диапазоном портов и 150 разъемами в TIME_WAIT вероятность этого> 10%. Точный сценарий также описан в разделе 2.3 RFC6056.

У меня нет никакого контроля над сервером, поэтому сокращение задержки TIME_WAIT или изменение поведения не вариант. Также сложно изменить клиентское приложение, чтобы выбрать исходный порт вручную, поскольку я использую стороннюю библиотеку для выполнения HTTP-запросов.

Увеличение эфемерного диапазона портов лишь незначительно уменьшит вероятность столкновения. Есть ли способ изменить временную стратегию выбора порта на клиенте (Linux), чтобы избежать таких коллизий?

1 ответ1

1

Сокет в TIME-WAIT с радостью примет новое соединение от устройства, использующего тот же 5 кортеж (протокол, исходный IP, исходный порт, IP-адрес назначения, порт назначения), при условии, что начальный порядковый номер (ISN) нового соединения выше чем последний порядковый номер, увиденный на предыдущем соединении. Согласно RFC 1122:

Когда соединение активно закрывается, оно ДОЛЖНО задерживаться в состоянии ВРЕМЯ ОЖИДАНИЯ на время 2xMSL (максимальное время жизни сегмента). Однако он МОЖЕТ принять новый SYN от удаленного TCP, чтобы заново открыть соединение из состояния TIME-WAIT, если он:

(1) назначает свой начальный порядковый номер для нового соединения большим, чем наибольший порядковый номер, который он использовал в предыдущем воплощении соединения, и

(2) возвращается в состояние TIME-WAIT, если SYN оказывается старым дубликатом.

Вы можете проверить это на машине Linux, установив эфемерный диапазон портов в один порт echo 32769 32769 > /proc/sys/net/ipv4/ip_local_port_range , а затем сделать несколько последовательных запросы на веб - сайт с Connection: Close установить заголовок HTTP wget --no-http-keep-alive www.example.com . Несмотря на то, что 5 всех ваших подключений одинаковы, сервер будет принимать новые подключения, находясь в режиме TIME-WAIT, поскольку номер ISN каждого нового подключения должен быть выше порядкового номера, который последний раз видели в сокете. В Linux ISN нового соединения должен постоянно увеличиваться - он несколько привязан к системным часам.

Если вы уверены, что TIME-WAIT всегда заканчивается на стороне сервера, и вы не можете подключиться при повторном использовании ваших эфемерных портов, то ISN, используемый вашим клиентом, не должен увеличиваться для каждого нового соединения (возможно, оно выбирается случайно или всегда использует одно и то же значение?). Если вы можете быть уверены, что каждое новое соединение от вашего клиента использует более высокое значение ISN, чем последнее, вы сможете установить соединение без проблем.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .