ARP резолвинг в Linux или ping(8) в Linux?
Нас уже двое
Опять процесс завершился по SIGKILL, не успев сохранить состояние?
Когда Linux 2.6.x является роутером и не может форвардить пакет из-за отсутствия записи в ARP cache, то он как и положено отсылает ICMP host unreachable. Вопрос только в том, почему он высылает его 3 раза?Так это следствия одного и того же?
Хотя довольно странно, что ошибка тоже по 3 раза возвращается. Не уверен, что так и было задумано, попробуй спросить в рассылке.
P.S. А ты не мог бы мне как почётному склеротику дать ссылку на то, как ты отвечал мне на первый вопрос?
Ты обязан. Недавно ты заявил, что те, кто не хотят сообщать о проблеме, не должны пиздеть в форумах.
> А ты не мог бы мне как почётному склеротику дать ссылку на то, как ты отвечал мне на первый вопрос?
Странно, а куда проебался ответ?
Там дело в том, что для каждого neighbour, для которого нет записи в arp-таблице, создаётся временная очередь пакетов, ждущих ответа на arp-запрос. Запросы посылаются регулярно (в отличие от FreeBSD и когда ядро понимает, что neighbour недоступен, то очищает очередь, и на каждый пакет оттуда генерирует icmp error. Частота запросов, размер очереди, тайм-аут - это настраивается. icmp error, дойдя по процесса-источника, превращается в EHOSTUNREACH, но странно, что ошибки не склеиваются.
Не могу себе позволить чтобы меня гугл находил в линуксовых списках рассылки
Там дело в том, что для каждого neighbour, для которого нет записи в arp-таблице, создаётся временная очередь пакетов, ждущих ответа на arp-запрос. Запросы посылаются регулярно (в отличие от FreeBSD и когда ядро понимает, что neighbour недоступен, то очищает очередь, и на каждый пакет оттуда генерирует icmp error.Я бы не сказал, что очередь и регулярная отсылка ARP request есть бенефит. Во всяком случае это объясняет поведение роутера.
icmp error, дойдя по процесса-источника, превращается в EHOSTUNREACH, но странно, что ошибки не склеиваются.А по-моему выходит, что локальный ping вовсе не получает EHOSTUNREACH на sendto(2). Вместо этого sendto(2) возвращается без ошибки, а потом процесс получает полноценный ICMP unreach на recvfrom(2). По-моему это объясняет почему локальный пинг получает три ошибки сразу. Ведь он никак не могу их получить через сисколл, не так ли?
Я тебя за язык не тянул
> А по-моему выходит, что локальный ping вовсе не получает
> EHOSTUNREACH на sendto(2). Вместо этого sendto(2) возвращается без
> ошибки, а потом процесс получает полноценный ICMP unreach на recvfrom(2).
по поводу асинхронной доставки ошибок ты тоже уже спрашивал
> По-моему это объясняет почему локальный пинг получает три ошибки сразу.
По-моему, нет, хватило бы одного раза имхо. Но может, у авторов были причины такого поведения.
Не еби мозг. Тогда речь шла совершенно о другом. Сейчас я хочу понять механизм того, как локальный ping(8) получает ошибки пачками. Пожалуйста, прочти еще раз то, что я написал выше и выскажи своё согласие или несогласие с моим предположением.
О том же самом. Входящий icmp host unreachable преобразуется в ошибку EHOSTUNREACHABLE и ставится в очередь сокета. Ближайший сисколл, будь то sendto или recvfrom, извлекает из очереди одну ошибку. Если их сразу три пришло, то нужно три сисколла, получается.
Ждать 30 секунд (или там минута? пока ядро FreeBSD переведёт ARP-запись из состояния unreachable в состояние incomplete, и снова начнёт посылать запросы, часто напрягает, если известно, что хост уже поднялся.
Ждать 30 секунд (или там минута? пока ядро FreeBSD переведёт ARP-запись из состояния unreachable в состояние incomplete, и снова начнёт посылать запросы, часто напрягает, если известно, что хост уже поднялся.Ждать не надо, потому что arp request ретрансмиттится если есть еще трафик в направлении этого хоста.
О том же самом. Входящий icmp host unreachable преобразуется в ошибку EHOSTUNREACHABLE и ставится в очередь сокета. Ближайший сисколл, будь то sendto или recvfrom, извлекает из очереди одну ошибку. Если их сразу три пришло, то нужно три сисколла, получается.Какой входящий icmp host unreachable, если речь о локальном пинге?
> трафик в направлении этого хоста.
Неправда. FreeBSD 4.11-STABLE при пинге мёртвого адреса посылает 5 запросов (ping молчит потом ждёт 20 секунд (ping выдаёт ошибку sendto: Host is down, arp-запросы не идут далее по циклу.
Входящий через lo, конечно. Я не уверен, что там полновесный ICMP-пакет генерируется, но идея такая.
> arp-запросы не идут далее по циклу.
Правда. Эти 5 запросов ты сам сгенерировал своим пингом. Если бы ты выслал только один пакет, то не было бы пяти запросов. Через некоторое время рентрансмиты саппресятся. Время настраивается через sysctl.
Однако и ошибка бы тоже не пришла. То есть во FreeBSD либо arp-запрос, либо сразу ошибка, в зависимости от состояния записи.
Верно.
То есть если состояние unreachable, то надо ждать, пока оно само изменится на incomplete, до 20 секунд по умолчанию, даже если знаешь, что хост уже поднялся и должен ответить.
То есть если состояние unreachable, то надо ждать, пока оно само изменится на unreachable, до 20 секунд по умолчанию, даже если знаешь, что хост уже поднялся и должен ответить.Совершенно верно. Правда если хост перезагрузился, то он пошлет gratious arp и тут же попадёт в таблицу. Конечно если хост не перегружался, а просто пропадал связь, то будет как ты сказал. В поведении Linux мне не нравится то, что на каждый пакет, пришедший к неизвестному хосту, будет вызывать ARP request, то есть broadcast пакет. С другой стороны при rate limiting это терпимо. Судя по всему rate limiting есть в наличии.
Вот это меня и напрягало, при диагностике проблем в сети, где есть роутеры на FreeBSD.
> В поведении Linux мне не нравится то, что на каждый пакет, пришедший к неизвестному хосту, будет вызывать ARP request, то есть broadcast пакет.
Не каждый, конечно. Приход нового пакета не вызывает нового запроса, если очередь к данному neighbour'у уже непуста. Называть это rate limiting не верно, так как дальнейшие запросы инициируются таймером, а не приходом пакетов: если пакеты продолжают приходить, запросы уходят равномерно, пока neighbour не ответит.
А сколько пакетов ставится в очередь?
По умолчанию 3, можно настроить.
3 per destination или per source?
per neighbour
Идея с очередью мне всё равно не нравится, а алгоритм ретрансмитов нравится. Займусь этим.
А где FreeBSD держит самый первый пакет, пока ожидается ответ на самый первый запрос?
В struct llinfo_arp. Типа вырожденная очередь на один пакет.
Оставить комментарий
sergey_m
Не могу понять такую вещь. Почему когда я пингую хост в локальной сети, которого нет, то EHOSTUNREACH вылазит пачками по 3 штуки? Вроде бы ping(8) шлёт пакеты с интервалом в одну секунду. По идее sendto(2) либо возвращает EHOSTUNREACH сразу, либо возвращает 0 и ошибку уже никак не вернуть. Почему же тогда такие "рывки" возникают?