ARP резолвинг в Linux или ping(8) в Linux?

sergey_m

Не могу понять такую вещь. Почему когда я пингую хост в локальной сети, которого нет, то EHOSTUNREACH вылазит пачками по 3 штуки? Вроде бы ping(8) шлёт пакеты с интервалом в одну секунду. По идее sendto(2) либо возвращает EHOSTUNREACH сразу, либо возвращает 0 и ошибку уже никак не вернуть. Почему же тогда такие "рывки" возникают?

Sebasten

Нас уже двое

Marinavo_0507

Ты ведь это спрашивал уже.
Опять процесс завершился по SIGKILL, не успев сохранить состояние?

sergey_m

Я такого не спрашивал. Могу припомнить другое:
Когда Linux 2.6.x является роутером и не может форвардить пакет из-за отсутствия записи в ARP cache, то он как и положено отсылает ICMP host unreachable. Вопрос только в том, почему он высылает его 3 раза?
Так это следствия одного и того же?

Marinavo_0507

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

sergey_m

Ну меня ломает спрашивать в рассылке. Если тут никто не знает, то и хуй с ним, так и буду жить незнаючи ответа.
P.S. А ты не мог бы мне как почётному склеротику дать ссылку на то, как ты отвечал мне на первый вопрос?

Marinavo_0507

> Ну меня ломает спрашивать в рассылке.
Ты обязан. Недавно ты заявил, что те, кто не хотят сообщать о проблеме, не должны пиздеть в форумах.
> А ты не мог бы мне как почётному склеротику дать ссылку на то, как ты отвечал мне на первый вопрос?
Странно, а куда проебался ответ?
Там дело в том, что для каждого neighbour, для которого нет записи в arp-таблице, создаётся временная очередь пакетов, ждущих ответа на arp-запрос. Запросы посылаются регулярно (в отличие от FreeBSD и когда ядро понимает, что neighbour недоступен, то очищает очередь, и на каждый пакет оттуда генерирует icmp error. Частота запросов, размер очереди, тайм-аут - это настраивается. icmp error, дойдя по процесса-источника, превращается в EHOSTUNREACH, но странно, что ошибки не склеиваются.

sergey_m

> Ты обязан. Недавно ты заявил, что те, кто не хотят сообщать о проблеме, не должны пиздеть в форумах.
Не могу себе позволить чтобы меня гугл находил в линуксовых списках рассылки
Там дело в том, что для каждого neighbour, для которого нет записи в arp-таблице, создаётся временная очередь пакетов, ждущих ответа на arp-запрос. Запросы посылаются регулярно (в отличие от FreeBSD и когда ядро понимает, что neighbour недоступен, то очищает очередь, и на каждый пакет оттуда генерирует icmp error.
Я бы не сказал, что очередь и регулярная отсылка ARP request есть бенефит. Во всяком случае это объясняет поведение роутера.
icmp error, дойдя по процесса-источника, превращается в EHOSTUNREACH, но странно, что ошибки не склеиваются.
А по-моему выходит, что локальный ping вовсе не получает EHOSTUNREACH на sendto(2). Вместо этого sendto(2) возвращается без ошибки, а потом процесс получает полноценный ICMP unreach на recvfrom(2). По-моему это объясняет почему локальный пинг получает три ошибки сразу. Ведь он никак не могу их получить через сисколл, не так ли?

Marinavo_0507

> Не могу себе позволить чтобы меня гугл находил в линуксовых списках рассылки
Я тебя за язык не тянул
> А по-моему выходит, что локальный ping вовсе не получает
> EHOSTUNREACH на sendto(2). Вместо этого sendto(2) возвращается без
> ошибки, а потом процесс получает полноценный ICMP unreach на recvfrom(2).
по поводу асинхронной доставки ошибок ты тоже уже спрашивал
> По-моему это объясняет почему локальный пинг получает три ошибки сразу.
По-моему, нет, хватило бы одного раза имхо. Но может, у авторов были причины такого поведения.

sergey_m

> по поводу асинхронной доставки ошибок ты тоже уже спрашивал
Не еби мозг. Тогда речь шла совершенно о другом. Сейчас я хочу понять механизм того, как локальный ping(8) получает ошибки пачками. Пожалуйста, прочти еще раз то, что я написал выше и выскажи своё согласие или несогласие с моим предположением.

Marinavo_0507

> Тогда речь шла совершенно о другом.
О том же самом. Входящий icmp host unreachable преобразуется в ошибку EHOSTUNREACHABLE и ставится в очередь сокета. Ближайший сисколл, будь то sendto или recvfrom, извлекает из очереди одну ошибку. Если их сразу три пришло, то нужно три сисколла, получается.

Marinavo_0507

> Я бы не сказал, что очередь и регулярная отсылка ARP request есть бенефит.
Ждать 30 секунд (или там минута? пока ядро FreeBSD переведёт ARP-запись из состояния unreachable в состояние incomplete, и снова начнёт посылать запросы, часто напрягает, если известно, что хост уже поднялся.

sergey_m

Ждать 30 секунд (или там минута? пока ядро FreeBSD переведёт ARP-запись из состояния unreachable в состояние incomplete, и снова начнёт посылать запросы, часто напрягает, если известно, что хост уже поднялся.
Ждать не надо, потому что arp request ретрансмиттится если есть еще трафик в направлении этого хоста.

sergey_m

О том же самом. Входящий icmp host unreachable преобразуется в ошибку EHOSTUNREACHABLE и ставится в очередь сокета. Ближайший сисколл, будь то sendto или recvfrom, извлекает из очереди одну ошибку. Если их сразу три пришло, то нужно три сисколла, получается.
Какой входящий icmp host unreachable, если речь о локальном пинге?

Marinavo_0507

> Ждать не надо, потому что arp request ретрансмиттится если есть еще
> трафик в направлении этого хоста.
Неправда. FreeBSD 4.11-STABLE при пинге мёртвого адреса посылает 5 запросов (ping молчит потом ждёт 20 секунд (ping выдаёт ошибку sendto: Host is down, arp-запросы не идут далее по циклу.

Marinavo_0507

> Какой входящий icmp host unreachable, если речь о локальном пинге?
Входящий через lo, конечно. Я не уверен, что там полновесный ICMP-пакет генерируется, но идея такая.

sergey_m

> Неправда. FreeBSD 4.11-STABLE при пинге мёртвого адреса посылает 5 запросов (ping молчит потом ждёт 20 секунд (ping выдаёт ошибку sendto: Host is down,
> arp-запросы не идут далее по циклу.
Правда. Эти 5 запросов ты сам сгенерировал своим пингом. Если бы ты выслал только один пакет, то не было бы пяти запросов. Через некоторое время рентрансмиты саппресятся. Время настраивается через sysctl.

Marinavo_0507

> Если бы ты выслал только один пакет, то не было бы пяти запросов.
Однако и ошибка бы тоже не пришла. То есть во FreeBSD либо arp-запрос, либо сразу ошибка, в зависимости от состояния записи.

sergey_m

> Однако и ошибка бы тоже не пришла. То есть во FreeBSD либо arp-запрос, либо сразу ошибка, в зависимости от состояния записи.
Верно.

Marinavo_0507

То есть если состояние unreachable, то надо ждать, пока оно само изменится на incomplete, до 20 секунд по умолчанию, даже если знаешь, что хост уже поднялся и должен ответить.

sergey_m

То есть если состояние unreachable, то надо ждать, пока оно само изменится на unreachable, до 20 секунд по умолчанию, даже если знаешь, что хост уже поднялся и должен ответить.
Совершенно верно. Правда если хост перезагрузился, то он пошлет gratious arp и тут же попадёт в таблицу. Конечно если хост не перегружался, а просто пропадал связь, то будет как ты сказал. В поведении Linux мне не нравится то, что на каждый пакет, пришедший к неизвестному хосту, будет вызывать ARP request, то есть broadcast пакет. С другой стороны при rate limiting это терпимо. Судя по всему rate limiting есть в наличии.

Marinavo_0507

> Конечно если хост не перегружался, а просто пропадал связь, то будет как ты сказал.
Вот это меня и напрягало, при диагностике проблем в сети, где есть роутеры на FreeBSD.
> В поведении Linux мне не нравится то, что на каждый пакет, пришедший к неизвестному хосту, будет вызывать ARP request, то есть broadcast пакет.
Не каждый, конечно. Приход нового пакета не вызывает нового запроса, если очередь к данному neighbour'у уже непуста. Называть это rate limiting не верно, так как дальнейшие запросы инициируются таймером, а не приходом пакетов: если пакеты продолжают приходить, запросы уходят равномерно, пока neighbour не ответит.

sergey_m

А сколько пакетов ставится в очередь?

Marinavo_0507

По умолчанию 3, можно настроить.

sergey_m

3 per destination или per source?

Marinavo_0507

per neighbour

sergey_m

Идея с очередью мне всё равно не нравится, а алгоритм ретрансмитов нравится. Займусь этим.

Marinavo_0507

А где FreeBSD держит самый первый пакет, пока ожидается ответ на самый первый запрос?

sergey_m

> А где FreeBSD держит самый первый пакет, пока ожидается ответ на самый первый запрос?
В struct llinfo_arp. Типа вырожденная очередь на один пакет.
Оставить комментарий
Имя или ник:
Комментарий: