• Почему не отправляется TCP/IP пакет с флагом RST?

    powerman
    @powerman Автор вопроса
    Запустил nc на винде. При остановке nc по Ctrl-C на сервер уходит не FIN, а RST. И на сервере write() сразу получает EPIPE.
  • Странное ограничение скорости в ~2Mbps на одно TCP-соединение на канале 24Mbps ADSL2+?

    powerman
    @powerman Автор вопроса
    Статья любопытная, я её пропустил, спасибо, почитаю. Но, тем не менее, можно чуть конкретнее, что именно Вы имеете в виду?

    Настройки TCP-стека моей OS вроде как не при чём, т.к. проблема наблюдается только на одном из двух одновременно поднятых и практически идентично настроенных каналов. Модемы я менял (точнее, менял между ними телефонные линии), так что они и ethernet-кабели к ним ведущие тоже вроде исключил. Влияние провайдера вроде как тоже исключается либо использованием Win7 либо переключением модема в режим роутера.

    Последняя моя идея была в том, что причина в разных размерах TCP-окна в Win7 и других OS. Но в линухе вроде бы нет возможности явно изменить размер окна, только косвенно через разные настройки. Я пытался с этим экспериментировать, но ничего не получилось.
  • Почему не отправляется TCP/IP пакет с флагом RST?

    powerman
    @powerman Автор вопроса
    Стивенс у меня есть, и не только эта книга, и я его выше уже упоминал. И да, согласно Стивенсу RST должен отправляться, но на практике он не отправляется, в этом-то и суть вопроса — почему он не отправляется.
    Насчёт ARP мысль любопытная (хотя возможная причина потери ARP-записи именно в этот момент мне не ясна), я проверил — никаких ARP или других не-TCP-шных пакетов во время описанного в вопросе сценария не бегает.
  • Почему не отправляется TCP/IP пакет с флагом RST?

    powerman
    @powerman Автор вопроса
    Сервер A отправляет данные серверу B. Сервер B не подтверждает эти данные ни ACK ни RST, вообще никак. Сервер A, не получив никакого ответа, отправляет эти данные повторно. Сервер B снова никак на них не отвечает. Даже если допустить, что сервер B не отвечает на ретрансмиты потому, что уже видел эти данные, то он ведь и на первую порцию этих данных никак не ответил. Кроме того, насколько я знаю, на ретрансмиты всё-таки отвечают, т.к. сам факт ретрансмита говорит о том, что ответ потерялся, и его, следовательно, таки надо отправить повторно.

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

    Моя точка зрения заключается в том, что SO_LINGER здесь абсолютно не при чём:
    1. он никак не влияет на то, как отправляются или не отправляются ACK/RST в ответ на полученные пакеты, а проблема именно в этом
    2. при локальном запуске nc всё работает как ожидается (RST отправляется, сервис получает EPIPE), хотя для SO_LINGER не должно быть разницы клиент и сервис на одном сервере или на разных
    3. в Вашей цитате описания SO_LINGER явно написано, что сервис на второй стороне таки должен в любом случае получить EPIPE при очередном write()
    4. netcat во-первых не устанавливает SO_LINGER сам, и во-вторых делает явный close() перед exit() — я только что проверил по сорцам, раз Вам вывода strace не хватило — таким образом ни вручную ни автоматически при exit() SO_LINGER активироваться в моем сценарии не должен вообще
  • Почему не отправляется TCP/IP пакет с флагом RST?

    powerman
    @powerman Автор вопроса
    Там цитаты из того же Стивенса. И нигде не пишут, что лингер блокирует отправку ACK или RST в ответ на входящие пакеты по закрытому/закрываемому соединению. Наоборот, пишут что другая сторона должна таки получить EPIPE на очередном write() — т.е. должна получить RST-пакет либо должен сработать таймаут на перепосылку пакетов (вроде никаких других способов определить разорванное соединение для возврата EPIPE не существует).
  • Почему не отправляется TCP/IP пакет с флагом RST?

    powerman
    @powerman Автор вопроса
    При ненулевом лингере на пакеты, которые пришли в рамках соединения, даже если это ретрансмиты после FIN, RST не шлется.
    Откуда такая информация? В известных мне описаниях лингера ничего про ответы на входящие пакеты нет. В общем, если не сложно, хотелось бы увидеть пруфлинки на доку/rfc/etc.
  • Почему не отправляется TCP/IP пакет с флагом RST?

    powerman
    @powerman Автор вопроса
    shutdown нет потому, что там close. \n выводился в stderr.
  • Почему не отправляется TCP/IP пакет с флагом RST?

    powerman
    @powerman Автор вопроса
    Я уже писал, что у нас локалка — оба сервера подключены к одному неуправляемому свичу, пакеты подменять некому. Кроме того, я запускал tcpdump на обоих серверах, чтобы быть уверенным в том, что RST пакет не только не приходит, но и не отправляется. Ну и напоследок я на всякий случай проверил таблицу ARP и сравнил MAC-адреса, но это уже чистая паранойя была. :)
  • Почему не отправляется TCP/IP пакет с флагом RST?

    powerman
    @powerman Автор вопроса
    Что касается вышеупомянутого FIN_WAIT_2, то здесь тоже не всё понятно. Теоретически, после выхода nc соединение действительно должно остаться в FIN_WAIT_2, но практически netstat его не показывает вообще (хотя другие соединения в FIN_WAIT_2 в выводе netstat присутствуют), так что похоже что оно как-то уж совсем моментально закрывается. Но даже если бы оно осталось в FIN_WAIT_2, на мой взгляд ядро на клиенте всё-равно должно как-то реагировать на пакеты с данными, которые продолжает отправлять сервис — или ACK или RST, но хоть как-то реагировать. Хоть для соединений в FIN_WAIT_2 хоть для CLOSED. А оно не реагирует на эти пакеты вообще никак, как будто (отключенный) файрвол их DROP-ает.
  • Почему не отправляется TCP/IP пакет с флагом RST?

    powerman
    @powerman Автор вопроса
    Код не в паблике, но во-первых ничего интересного там нет, и во-вторых я не думаю, что код сервиса вообще как-то причастен к этой мистике с RST. Если до понедельника теоретически в вопросе разобраться не получится, то я попробую заменить клиент-nc и сервис на Limbo на тупые линейные блокирующие клиент и сервер на перле. Убежусь, что с ними наблюдается тот же эффект, и дальше буду искать проблему в районе ядра линуха. :(
  • Почему не отправляется TCP/IP пакет с флагом RST?

    powerman
    @powerman Автор вопроса
    Во-первых по Ctrl-C nc выполняет close() сокета перед выходом. Что наглядно показывает strace:
    ...
    select(16, [0 3], NULL, NULL, NULL)     = ? ERESTARTNOHAND (To be restarted)
    --- SIGINT (Interrupt) @ 0 (0) ---
    write(2, "\n", 1)                       = 1
    close(3)                                = 0
    exit_group(1)                           = ?
    Process 15291 detached
    

    Во-вторых я сегодня внимательно перечитал Стивенса (Unix network programming, глава 7.5 описывающая SO_LINGER), и снова хочу обратить Ваше внимание, что SO_LINGER контролирует то, как будут обрабатываться данные находящиеся в исходящем буфере ядра при выполнении close() — данные, которые ещё не были отправлены и/или подтверждены. RST, отправляемый в определённом случае SO_LINGER-ом, сообщает удалённой стороне о том, что отправка данных была прервана (причём отправляется этот RST вместо FIN, а у меня как раз этот FIN — от клиента к сервису — отправляется и подтверждается нормально). Я нигде не вижу упоминания о том, что SO_LINGER может как-то влиять на отправку или не отправку RST в ответ на принимаемые после close() пакеты.
  • Почему не отправляется TCP/IP пакет с флагом RST?

    powerman
    @powerman Автор вопроса
    SO_LINGER управляет тем, что произойдёт с ещё не отправленными данными, когда сокет закрывает сторона отправившая эти данные. В моём сценарии сокет закрывает nc, который ничего не отправлял. Так что SO_LINGER здесь вроде вообще не при делах.
  • Почему не отправляется TCP/IP пакет с флагом RST?

    powerman
    @powerman Автор вопроса
    SIGPIPE традиционно заблокирован (игнорируется), ибо его можно схлопотать при некоторых абсолютно обычных сценариях I/O. Но суть у SIGPIPE и EPIPE одна и та же, и возникают они по одной и той же причине — попытке записи в разорванное соединение. И, насколько я понимаю, определяется этот факт именно по RST-пакету. Нет RST — и SIGPIPE/EPIPE взяться неоткуда.
  • Почему не отправляется TCP/IP пакет с флагом RST?

    powerman
    @powerman Автор вопроса
    Наверное могу, но… а что Вы там хотите увидеть такого, чего нет на моём скриншоте (ссылка в конце вопроса)? Там как раз видны все пакеты одной полной сессии.
  • Почему не отправляется TCP/IP пакет с флагом RST?

    powerman
    @powerman Автор вопроса
    В том-то и дело. После прерывания netcat сервис успешно выполняет несколько write-ов, после следующий write блокируется. EPIPE не приходит как минимум минут 15, дольше не проверял.
  • Почему не отправляется TCP/IP пакет с флагом RST?

    powerman
    @powerman Автор вопроса
    Когда nc прерывается по Ctrl-C на сервере B netstat вообще не показывает это соединение, так что оно, надо полагать, закрыто, а не находится в FIN_WAIT_2. А на сервере A это соединение находится в CLOSE_WAIT.
  • Почему не отправляется TCP/IP пакет с флагом RST?

    powerman
    @powerman Автор вопроса
    Реализация сервера своя. Более того, она написана на Inferno/Limbo. Но это вроде бы не должно влиять на отправку или не отправку RST-пакета совершенно другим сервером. И локально-то RST отправляется. Что касается recv, то, как я уже написал в тексте вопроса, этот сервис вообще не делает read() из клиента, только write(). Так что да, сервис не считывает EOF когда отключается клиент, но вопрос-то не в том, как сервису определить что клиент отключился (тут для надёжности одного считывания EOF маловато будет, нужно таймаут на write() вешать), а почему нет EPIPE?
  • JavaScript: что делает Function.call.apply(…)?

    powerman
    @powerman Автор вопроса
    Спасибо, но я знаю как работает .call(). Я не понимаю как работает цепочка вызовов .call.apply() — чем она отличается от простого вызова .apply().
  • Файловая система для Linux и Windows?

    powerman
    @powerman
    Я довольно редко гружу винду, но, тем не менее, BSOD при доступе к ext3 не было ни разу ни под XP 32bit ни под Seven 64bit. Возможно, проблема в Вашей системе?
  • Как подмонтировать lbook V3 под линухом?

    powerman
    @powerman Автор вопроса
    Да, на Ubuntu всё работает. Выяснилось, что нужно было галочку в ядре включить. :)