У меня есть веб-сервис HTTP, где иногда установка соединения не работает странным образом:
В каких ситуациях клиентская система может решить ответить пакетом RST? Я мог представить, что это происходит, когда SYN, ACK содержит, например. неправильные порядковые номера (но, похоже, это не применимо в моем случае - порядковые номера выглядят нормально). Поэтому меня интересует исчерпывающий :-) список случаев, когда клиент отправляет пакет RST после получения пакета SYN, ACK.
В частности, возможно ли, чтобы код клиентского приложения (с использованием обычного API сокетов в стиле BSD под Linux) вызвал этот пакет RST, например. позвонив close()
пока продолжается трехстороннее рукопожатие?
В заключение: проблема была в тупой ошибке в моем коде (в клиенте).
Клиент в этом случае использует неблокирующие сокеты, поэтому connect()
вызов вернется немедленно, пока ядро продолжает ждать пакета SYN, ACK от сервера. К сожалению, код клиента был очень нетерпеливым: если соединение не было установлено через несколько сотен миллисекунд, клиент звонил close()
на розетке.
В некоторых редких случаях SYN, ACK-пакеты от сервера будут задерживаться на несколько сотен миллисекунд на своем пути по сети. Когда отложенный ответ наконец прибыл на клиентский хост, ядро увидит, что сокет уже закрыт, и будет рассматривать ответ SYN, ACK как принадлежащий недопустимому сокету. Вот почему он ответил бы на сервер пакетом RST.
Итак, да, код приложения (с использованием обычного API сокетов в стиле BSD под Linux) может вызвать этот пакет RST: используя неблокирующий сокет и закрывая соединение, пока трехстороннее рукопожатие все еще продолжается.