#c #sockets #tcp
Вопрос:
TCP-соединение сбрасывается ПЕРВЫМ во connect()
время .
Многие клиенты подключаются к серверу и отправляют данные. Клиент отправляет [PSH,ACK] с данными перед отправкой последнего подтверждения трехстороннего рукопожатия в соответствии с пакетами, которые я захватил с помощью tcpdump.
Это приводит к отправке сначала на стороне сервера. NO_DELAY
используется опция. Судя по пакету данных, за исключением ПЕРВОГО блокирующего пакета, пакет данных выглядит очень нормально.
Вначале я подозреваю, что брандмауэр или хакеры могут получить исходный порт другими способами. ПЕРВАЯ атака возможна, но клиент сказал, что брандмауэра нет, и на этой машине запущены клиентские и серверные программы.
Кроме того, эту проблему трудно воспроизвести, и это может занять несколько недель или дольше. Он иногда получает такой пакет и вызывает сбой соединения.
Код подключения :
do
{
r1 = connect(socketfd, addr->ai_addr, addr->ai_addrlen);
} while (r1 < 0 amp;amp; errno == EINTR);
if (setsockopt(socketfd, IPPROTO_TCP, TCP_NODELAY,
amp;option_value, option_len) != 0) {}
Кто знает, каковы возможные причины? Пожалуйста, смотрите шапку ниже:
Комментарии:
1. Вы должны учитывать возможность того, что сброс «подделан» брандмауэром или другим приложением безопасности, которое недовольно подключением. Обратите внимание, что при захвате «пакета ошибок» за первым сбросом следует подтверждение данных,отправленных с кадром PSH, ACK, и далее следует кадр с полезной нагрузкой. Это несовместимо с ПЕРВЫМ отправленным локальным стеком TCP, если это фактический порядок пакетов, обрабатываемых стеком TCP. Стек TCP не сбрасывает соединение, а затем продолжает получать и отправлять данные.
2. Кроме того,ACK, завершающий 3-стороннее рукопожатие, не в порядке с пакетом PSH, ACK с полезной нагрузкой, что является интересным краевым случаем. Мне непонятно, как это может произойти при обратной связи в linux, у которой нет уровня 2; пакеты доставляются непосредственно в стек tcp. Я знаю, что у Windows действительно есть уровень 2 на обратной связи, но не знаю, могут ли пакеты поступать не по порядку.
3. Мы подтвердили, что брандмауэра нет. Это место действительно странное, стек TCP продолжает поступать и отправлять данные после сброса соединения. Однако, если трехстороннее рукопожатие не будет успешным, приведет ли пакет psh к тому, что сервер отправит его первым?
4. Как вы сказали, на этой машине нет уровня 2, и код Linux реализует обратную связь. Но при нормальных обстоятельствах пакет psh всегда находится после ack.
5. Поэтому, если вы используете linux, я предполагаю, что это ошибка, связанная с доставкой TCP-пакетов по обратной связи. Клиент отправляет SYN, сервер отправляет SYN,ACK. Тогда клиент должен согласиться. Ack должен быть доставлен в сокет в очереди SYN. Затем клиентское приложение отправляет некоторые данные. На сервер отправляется пакет с PSH,ACK. Я предполагаю,что какая-то проблема с синхронизацией какая-то ошибка означает, что пакет PSH, ACK доставляется первым, и он не может найти сокет, поэтому стек TCP отправляет сброс, потому что нет прослушивающего сокета. 1/2