Что вызывает отправку флага сброса TCP / IP (RST)?

123

Я пытаюсь понять, почему TCP / IP-соединение моего приложения продолжает сбиваться каждые 10 минут (точно, в течение 1-2 секунд). Я запустил Wireshark и обнаружил, что после 10 минут бездействия другой конец отправляет пакет с установленным флагом сброса (RST). Поиск в Google сообщает мне, что «флаг RESET означает, что получатель запутался и поэтому хочет прервать соединение», но это немного не хватает деталей, которые мне нужны. Что может быть причиной этого? И возможно ли, что за это отвечает какой-то маршрутизатор, или это всегда будет исходить от другой конечной точки?

Изменить: между моим компьютером и другой конечной точкой находится маршрутизатор (в частности, Linksys WRT-54G) - есть ли что-нибудь, что я должен искать в настройках маршрутизатора?

Люк
источник
13
Вот еще один: Comcast
Том Риттер
1
Хех, к счастью, у меня нет зависимости от Comcast, поскольку это происходит в локальной сети. Хотел бы я легко переложить вину;)
Люк
Вы когда-нибудь понимали это? Я не могу комментировать, потому что у меня недостаточно очков, но у меня точно такая же проблема, как и у вас, и я ищу решение.
К какой услуге относится этот конкретный случай? Может быть возможно установить поддержку активности в сокете (на уровне приложения), чтобы длительные периоды простоя не приводили к тому, что кто-то (в середине или нет) пытался принудительно сбросить соединение из-за нехватки ресурсов.
arielf 03
"Comcast" вы говорите? : D Проверьте это связанное репо: github.com/tylertreat/comcast
joonas.fi

Ответы:

89

«Маршрутизатор» может делать что угодно - особенно NAT, что может включать в себя любое количество ошибок с трафиком ...

Одна из причин, по которой устройство отправляет RST, - это ответ на получение пакета для закрытого сокета.

Трудно дать твердый, но общий ответ, потому что все возможные извращения были обнаружены в TCP с момента его появления, и самые разные люди могут вставлять RST в попытке заблокировать трафик. (Например, некоторые «национальные межсетевые экраны» работают так.)

Уилл Дин
источник
6
Либо у маршрутизатора есть 10-минутный тайм-аут для TCP-соединений, либо на маршрутизаторе включено «интеллектуальное обнаружение пакетов шлюза».
Дэвид Шварц
2
Было бы немного сложно предположить, что маршрутизатор может содержать ошибки.
Marquis of Lorne
23

Запустите сниффер пакетов (например, Wireshark) также на одноранговом узле, чтобы узнать, отправляет ли RST одноранговый узел или кто-то посередине.

Александр
источник
14

Я только что потратил некоторое время на устранение этой самой проблемы. Ни одно из предложенных решений не помогло. Оказалось, что наш системный администратор по ошибке назначил один и тот же статический IP-адрес двум несвязанным серверам, принадлежащим к разным группам, но находящимся в одной сети. Конечными результатами были периодическое отключение vnc-соединений, браузер, который приходилось обновлять несколько раз для получения веб-страницы, и другие странные вещи.

OutputLogic
источник
7

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

В наши дни вам необходимо изящно справиться (при необходимости восстановить) это состояние.

Брайан Кноблаух
источник
2
Соединение восстанавливается нормально, проблема в том, что короткий период отключения вызывает ненужное предупреждение.
Люк,
1
У меня были проблемы именно с оборудованием Cisco PIX / ASA. По умолчанию они имеют особенно короткие таймауты. Более дешевое оборудование, как правило, «лучше» в этом отношении (поскольку они не очень быстро отключаются) ...
Брайан Ноблауч
1
Я бы даже добавил, что TCP никогда не был полностью надежным с точки зрения постоянных соединений. Просто время от времени это становится заметнее. Еще один интересный пример: некоторые люди могут реализовать логику, которая помечает TCP-клиент как отключенный при обнаружении закрытия или сброса соединения. А иногда они даже не удосуживаются дать клиенту возможность восстановить связь. Это явно не совсем правильно.
Виктор Ярема,
7

RST отправляется стороной, выполняющей активное закрытие, потому что это сторона, которая отправляет последний ACK. Таким образом, если он получает FIN от стороны, выполняющей пассивное закрытие в неправильном состоянии, он отправляет пакет RST, который указывает другой стороне, что произошла ошибка.

Вишал Гупта
источник
6
Обе стороны отправляют и получают FIN при обычном закрытии. В этой ситуации нет ничего плохого, и, следовательно, нет причин для одной стороны выполнять сброс. Первое предложение даже не имеет смысла.
Marquis of Lorne
2
[RST, ACK] также может быть отправлен стороной, получающей SYN на порт, который не прослушивается. В случае, с которым я столкнулся, RST / ACK пришел примерно через 60 секунд после первого SYN. FWIW
Les,
@MarquisofLorne, само первое предложение может считаться неправильным. Но фраза «в неправильном состоянии» во втором предложении в какой-то мере делает ее верной.
Виктор Ярема,
7

Если есть маршрутизатор, выполняющий NAT, особенно маршрутизатор нижнего уровня с небольшим количеством ресурсов, он сначала будет устаревать самые старые сеансы TCP. Для этого он устанавливает RSTфлаг в пакете, который эффективно сообщает принимающей станции (очень некрасиво) закрыть соединение. это сделано для экономии ресурсов.

MKII
источник
3

Следует помнить, что многие брандмауэры Linux netfilter настроены неправильно.

Если у вас есть что-то вроде:

-A ВПЕРЕД -m состояние --state СВЯЗАН, УСТАНОВЛЕН -j ПРИНЯТЬ

-A FORWARD -p tcp -j REJECT --reject-with tcp-reset

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

Переупорядочивание особенно вероятно при использовании беспроводной сети.

Вместо этого это должно быть:

-A ВПЕРЕД -m состояние --state СВЯЗАН, УСТАНОВЛЕН -j ПРИНЯТЬ

-A FORWARD -m state --state INVALID -j DROP

-A FORWARD -p tcp -j REJECT --reject-with tcp-reset

Практически в любое время у вас есть:

... -m состояние --state СВЯЗАННО, УСТАНОВЛЕНО -j ПРИНЯТЬ

сразу за ним должны следовать:

... -m состояние --state INVALID -j DROP

Лучше отбросить пакет, чтобы сгенерировать потенциально нарушающий протокол сброс tcp. Сбросы лучше, когда они доказуемо правильны для отправки ... поскольку это устраняет таймауты. Но если есть шанс, что они недействительны, они могут причинить такую ​​боль.

Лабиринт
источник
0

Это связано с тем, что в сети есть другой процесс, отправляющий RST на ваше TCP-соединение.

Обычно RST отправляется в следующем случае

  • Процесс закрывает сокет, когда включен сокет с параметром SO_LINGER
  • ОС выполняет очистку ресурсов, когда ваш процесс завершается без закрытия сокета.

В вашем случае это похоже на то, что процесс подключает ваше соединение (IP + порт) и продолжает отправлять RST после установки соединения.

Бен
источник