Назад | Перейти на главную страницу

Linux - повторное использование исходного порта TCP (и задержка)

У нас есть приложение, которое делает много вызовов удаленному веб-серверу / службе. Клиентское приложение - это JBoss / Java в Linux (Red Hat 5), удаленный сервер - Windows 2008. На пути есть Cisco ACE, но NAT не работает.

Мы заметили, что когда Linux / JBoss повторно использует исходный порт для выполнения HTTP-вызова, мы можем получить «Соединение отклонено». Это когда клиент повторно использует указанный исходный порт в течение пары минут.

Когда я запускаю tcpdump / wirehark с обеих сторон, я вижу что-то вроде этого:

Запрос №1: порт источника 6666, порт назначения 80

Клиент -> Сервер Syn -> Клиент Syn ACK -> Клиент ACK -> GET / Сервер -> Клиент возврата данных -> Сервер ACK -> Клиент FIN ACK -> СЕРВЕР FIN ACK -> ACK

Запрос №2: Один и тот же порт источника и назначения - успех.

Запрос №3: Один и тот же порт источника и назначения - успех.

Запрос №4: Тот же порт источника и назначения, но на этот раз сбой («Соединение отклонено»), и это выглядит так:

Клиент -> Клиент SYN -> Клиент SYN (повторная передача) -> RST, ACK

Сервер видит оба SYN, но никогда не отправляет ACK или RST (он видит RST от клиента).

После некоторого поиска я обнаружил потенциальную проблему с отметками времени TCP. Мы убедились, что ACE пропустит их, и я могу убедиться, что Windows их видит. Я также вижу соединение в состоянии TIME_WAIT на стороне сервера / Windows (но я вижу это даже после 1-го успешного GET и № 2 и № 3, и все они были успешными). Порт не открыт или находится в состоянии TIME_WAIT на стороне клиента.

Одно место, на которое я смотрел, - это уменьшить запись реестра TcpTimedWaitDelay на стороне Windows до 30 секунд. Я еще не делал этого и не тестировал это, но думаю, что это должно сработать, если наша проблема существует.

Я увеличил количество портов на стороне клиента / Linux до 15000 - 60000 (со значения по умолчанию 30000 до 60000), но безрезультатно (просто надеясь, что увеличение числа доступных портов приведет к увеличению времени задержки из-за случайности использования исходный порт)

Мне кажется странным, что сторона сервера / Windows видит, что SYN проходит, но не отвечает, что заставляет меня думать, что он думает, что SYN от предыдущего сеанса или что-то в этом роде.

Я не уверен, что мне бы это понравилось, но мне было интересно, есть ли способ запретить Linux повторно использовать исходный порт, если он недавно использовался? Как какая-то задержка в этой логике (если она есть)?

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

У всех вас есть другие мысли по этому поводу?

Спасибо!

ОБНОВИТЬ

Я установил TcpTimedWaitDelay на 30 секунд на сервере Windows. Если вызов с повторно используемым портом-источником поступает через 30 секунд, проблем нет.

Я считаю, что ACE все еще виноват в некоторых отношениях, и это может быть своего рода защита от SYN-атак (ACE - это устройство безопасности), как будто я обхожу ACE, у меня нет проблем.

Но установка 2MSL на 30 секунд кажется на данный момент достаточно хорошим решением.

Я недостаточно знаю о циклическом переключении сокетов Windows, чтобы ответить на этот вопрос, но я предполагаю, что сервер закрывает соединения, и сокеты сидят в TIME_WAIT состояние, в котором их нельзя использовать снова, пока не истечет срок их действия.

«Правильный» способ решить эту проблему - добавить больше кортежей - увеличить исходящие порты на клиенте (что вы и сделали), добавить порты прослушивания на сервере, добавить псевдонимы IP в свои интерфейсы и заставить приложения использовать эти дополнительные IP-адреса. / порты.

«Менее правильный» способ - уменьшить тайм-аут TW, который, я думаю, вы делаете с TcpTimedWaitDelay.

«Совсем не самый правильный, но все же довольно популярный» способ - включить переработку сокетов, в Linux есть варианты tw_reuse и tw_recycle, может быть в Windows есть аналог.

Последние две опции нарушают TCP RFC. Может быть, у ACE проблемы с этим?