TCP Retransmission там где его не должно быть. Почему?
Добрый день, товарищи.
Имеется простенькая программа, которая опрашивает сайт с каталогами автозапчастей. По ссылке carscats.ru/crc/crc.xml хранится список серверов удаленных раб.столов. Программа обращается на сайт, читает xml файл, опрашивает каждый сервер из списка и выводит доступные серверы у себя (чтобы по кнопке можно было подрубиться к RDP удаленного сервиса). Проблема в том, что на одном из компов в магазине, опрос недоступного сервера в том списке (92.242.44.134. Резолвится из epc200.carscats.ru) происходит аж 3 раза. То есть в нормальных условиях (на других компах), Wireshark видит отправку только одного TCP пакета. Ответа нет и программа работает дальше (выводит список того что доступно). На проблемном компе отправка идет один раз... и потом еще 2 раза с небольшим интервалом идет повторная отправка (TCP Retransmission). Это занимает до 15 сек и все это время программа висит, что доставляет некоторые неудобства. Есть способ разобраться "почему так"? Все компы подключены к одной сети (а некоторые тестируемые даже в один свитч с проблемным).
Может это быть из-за каких то настроек TCP стека в Windows 7?
Проблема в том, что на одном из компов в магазине, опрос недоступного сервера в том списке (92.242.44.134. Резолвится из epc200.carscats.ru) происходит аж 3 раза
Это как раз поведение по умолчанию - 15 сек таймаут и 3 попытки послать SYN пакет (например, для Linux - не суть, для винды то же самое).
В случае с другими компами, видимо, не просто нет ответа, а приходит RST
А почему тогда на другие может приходить RST, а на этот один не приходит? Куда копать?
Сервер не отвечает. Если пинговать - пинг бесконечно долго висит.
galaxy, в том то и дело что сервер не наш, а удаленный. Сторонний сервис. Как я описал - все компы (вроде как) нормально работают с этой прогой. Подвисает только один. В в перехвачено трафике на нем видно что он не один раз шлёт запрос.
galaxy, ну я там смотрел по фильтру с IP тем самым. Не было пакетов с RST. Вообще нет пакетов с того IP. Есть только НА тот IP. Просто на проблемном ПК эти пакеты 2 раза отправляются повторно.
Кстати, я туплю про этот RST, че меня на нем заклинило?...
RST шлется обычно, когда кривой пакет приходит (не соответствующий стейту или с кривым sequence).
Если порт закрыт, отлуп идет по ICMP (Destination Unreachable). Попробуйте их поискать (ну и к слову, возможно, на проблемном компе что-то с ICMP)
Давайте так: я не могу проблему диагностировать удаленно и вслепую, логи и доступ есть у вас. Я могу высказать только предположения, исходя из теории и здравого смысла.
Так вот, что происходит, когда некто пытается законнектиться к хосту, который недоступен/офлайн? Посылаются SYN пакеты и ожидается ответ. Для недоступного хоста варианта, в общем, два: либо он (или узлы на пути к нему) сообщают о его недоступности, либо не сообщают и ответа не приходит. В первом случае сообщение о недоступности - ICMP пакет (да, в ответ на TCP пакет!) с соответствующими флагами (можно, конечно, и спецом RST послать, iptables умеет). Тогда коннект просто завершается с ошибкой, быстро - как только получен ответ. Второй случай - ответа нет. В полной соответствии с парадигмой TCP клиент ждет некоторое время и пытается сделать ретрансмит, полагая, что пакет мог потеряться. А потом еще раз. До тех пор пока не сработает таймаут, который определяет либо приложение, либо ОС (в случае блокирующих сокетов это, собственно, единственный вариант, таймаут по умолчанию как раз около 15 сек).
Т.е. если приложение не задает само таймуатов, и удаленный хост не посылает ответа (потому что закрыт фаерволом, или Роскомнадзором, или комп-клиент почему-то не принимает ICMP пакеты), то это зависание - абсолютно нормальное ожидаемое поведение. Попробуйте закрыть порт наглухо iptables (-j DROP) и сделайте на него telnet: соединение подвиснет.
Если у вас одни компы быстро понимают, что хост недоступен, значит они получают ICMP уведомление. Проблемный почему-то не получает. Попробуйте понять, почему.
galaxy, теория ясна. Ладно. Но... эти ответы были бы видны в Wireshark? Просто на нормальных хостах нет ответов от того айпишника. Просто прога шлёт «вникуда» н 555 порт TCP пакет и успокаивается.
galaxy, честно в винде ничего не делал (вопрос же о компе с виндой). Одна из причин почему сюда обратился - думал есть какие то ньюансы в работе TCP стека в семерке и что-то там можно накрутить. Завтра на работе буду и проверю Настройки фаервола. Включу ICMP. Но все же не понятно почему тогда ответ от того айпишника не фиксируется в дампе пакетов (на тех же компах, где все нормально)
Я тут посидел потестил из под винды (win 7). Короче, эта зараза игнорирует ICMP сообщение о недоступности (любого типа) и продолжает ретрансмитить... Так что я не очень понимаю, как большинство ваших компов быстро детектит офлайн хосты. По идее только механизм RST остается (ну или странный механизм: принять соединение и тут же его закрыть через FIN)...
Короче, если что найдете в дампах, расскажите, интересно :)
galaxy, ну там не 15 секунд точно. первый пакет в 1сек, второй (уже повтор) - через 5 сек... и третий раз еще через секунды 3-4. То есть поведение тут не по умолчанию...
А почему не сделать прогу чуть менее "простенькой", вынеся опрос доступности сайтов в отдельные потоки (динамически создавать на каждый сайт), и менять в табличке "доступность" в момент прихода ответа?
Евгений Воробьев, Тогда написать свою, но с блекджеком и девушками с "пониженной социальной ответственностью" )
Сомнительно что это займет больше полутора часа, зато работать будет надежнее...