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

Сервер Linux повторно отправляет SYN ACK

Я устраняю проблему тайм-аута соединения между двумя Linux-устройствами, где кажется, что ACK для SYN-ACK был потерян в стеке сервера.

Tcpdump выполняется на стороне сервера.

Клиент получил синхронизацию, отправил ACK и пакет данных и повторно отправил данные еще 4 раза. Сервер повторно отправил syn-ack через 4 секунды после того, как он отправил syn-ack, указывая на то, что ACK от клиента потерян в стеке сервера. Клиент отвечает ACK.

Затем примерно через 3 секунды клиент повторно отправил данные и получил ACK сервера. Клиент отправил FIN на 10 с, потому что клиентское приложение установило тайм-аут 10 с.

Итак, вопрос: tcpdump показывает ACK для SYN-ACK, прибывшего на сервер. В каком случае сервер может повторно отправить SYN-ACK? Это проблема ядра или приложения на стороне сервера? А как дальше отлаживать?

Ценю вашу помощь.


20:31:01.159098 IP client.cport > server.sport: S 2848162415:2848162415(0) win 5840 
20:31:01.159103 IP server.sport > client.cport: S 901143055:901143055(0) ack 2848162416 win 5792 
20:31:01.159192 IP client.cport > server.sport: . ack 1 win 46 
20:31:01.159276 IP client.cport > server.sport: P 1:426(425) ack 1 win 46 
20:31:01.380395 IP client.cport > server.sport: P 1:426(425) ack 1 win 46 
20:31:01.824367 IP client.cport > server.sport: P 1:426(425) ack 1 win 46 
20:31:02.712362 IP client.cport > server.sport: P 1:426(425) ack 1 win 46 
20:31:04.488358 IP client.cport > server.sport: P 1:426(425) ack 1 win 46 
20:31:05.159038 IP server.sport > client.cport: S 901143055:901143055(0) ack 2848162416 win 5792 
20:31:05.159157 IP client.cport > server.sport: . ack 1 win 46 
20:31:08.040317 IP client.cport > server.sport: P 1:426(425) ack 1 win 46 
20:31:08.040326 IP server.sport > client.cport: . ack 426 win 27 
20:31:11.159618 IP client.cport > server.sport: F 426:426(0) ack 1 win 46 
20:31:11.199139 IP server.sport > client.cport: . ack 427 win 27 
20:31:14.724604 IP server.sport > client.cport: . 1:1449(1448) ack 427 win 27 
20:31:14.724612 IP server.sport > client.cport: P 1449:1756(307) ack 427 win 27 
20:31:14.724776 IP client.cport > server.sport: R 2848162842:2848162842(0) win 0
20:31:14.724779 IP client.cport > server.sport: R 2848162842:2848162842(0) win 0

Изменить: есть тонны переполнения. Может ли приложение иметь небольшое отставание от listen (), что приводит к этой проблеме?

$ netstat -s | grep -i list
    210473 times the listen queue of a socket overflowed
    210473 SYNs to LISTEN sockets ignored

Изменить 2: это мой первый пост, поэтому, пожалуйста, оставайтесь со мной. :)

Клиентское и серверное ядро: 2.6.18-92.el5

Серверное приложение: слушает только спорт. Он обрабатывает запрос клиента и отвечает обратно. Используя strace, я обнаружил, что невыполнение работы listen () составляет 5.

Существует 8 клиентских систем, в каждой из которых работает по одному экземпляру клиентского приложения. Клиентское приложение отправляет запрос на порт сервера, получает ответ от сервера. Таймер 10 секунд устанавливается после того, как клиент успешно выполняет connect (). Каждый клиентский экземпляр может отправлять несколько запросов на подключение, каждый на своем собственном клиентском порту.

Может произойти всплеск одновременных запросов от 8 клиентов.

Изменить 3: tcpdump очень похож на тот, что находится в http://forum.openvz.org/index.php?t=msg&goto=25678 , но без первопричины / решения.

Я спрашиваю себя, зачем нормальному клиенту:

  1. уменьшить ранее объявленное окно данных 5840 до 46
  2. повторно отправить тот же сегмент данных 5 раз (из них 3 раза за 1 секунду!)

Кроме того, если вам нужна помощь сообщества, вам лучше подумать, что мы давно утратили наши телепатические способности, и поэтому мы даже не знаем, какое программное обеспечение участвует в этом (начиная с версии ядра Linux) и что и как это должно работать.

Ваша очередь слишком мала, чтобы принять все ваши запросы. Задержка - это размер вашей очереди приема, когда очередь приема заполнена, ACK клиента игнорируется или соединение прерывается в соответствии с net.ipv4.tcp_abort_on_overflow. Так что увеличивайте отставание.