2009-12-09 3 views
1

У меня есть приложение, связанное с eth0, отправив пакеты UDP на порт A до 255.255.255.255. В то же время у меня есть UDP-сервер, связанный с eth0, 0.0.0.0 и портом A.Фильтрация петли UDP на Linux в C

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

Я не могу изменить полезную нагрузку UDP-пакетов и не добавлять к ней никаких заголовков.

Я уже реализовал решение, использующее RTNETLINK для извлечения всех IP-адресов машины, на которой я сижу (и фильтр, основанный на адресе из recvfrom()), но мне интересно, может ли быть более простой и чистое решение.

EDIT: Я думал о чем-то вроде пометки skb - тег исчез бы после выхода из физического интерфейса, но не был бы, если бы он просто был направлен в программное обеспечение.

Любые идеи?

+0

Похоже, в Linux все еще невозможно: http://www.mail-archive.com/[email protected]/msg196866.html – Pawel

ответ

1

Если вы можете исправить свое ядро ​​Linux, вы можете использовать опцию setsockopt() для выбора, хотите ли вы петлить передаваемые пакеты вещания или нет.

Это patch повторное использование опции IP_MULTICAST_LOOP именно для этой цели.

Кроме того, вместо «messing» с опцией IP_MULTICAST_LOOP вы можете легко добавить свой собственный вариант setsockopt(), возможно, его можно назвать IP_BROADCAST_NO_LOOP. Это гарантирует, что вы не будете изменять поведение для любого другого приложения.

+0

Ответ, который я ждал! Большое спасибо!Тем не менее, я уже нашел этот патч неделю назад - см. Мой комментарий: P – Pawel

+0

@Pawel: Ах да, вы правы, мой плохой! –

0

Вы можете вычислить контрольную сумму или CRC (лучше) над полезной нагрузкой и отфильтровать ее.

+0

Это может привести к недействительному поведению - его вполне возможно, я получаю то же самое содержимое, которое я только что отправил, но с удаленного хоста. – Pawel

+0

@Pawel: кажется, вы столкнулись с «недружественным» протоколом, если не сказать больше. Я желаю вам удачи. – jldupont

0

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

+0

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

+0

Хм, брандмауэр - это не пользовательский бизнес, а не в общем случае. Существует причина, по которой сетевой стек реализован в ядре. Эта причина - производительность. В вашей настройке каждый пакет перемещается вниз и вверх по стеку и подлежит, по меньшей мере, двум экземплярам. Вы можете вырезать «вверх» часть вместе с копией обратно в пространство пользователя с помощью простого правила брандмауэра. Похоже, ваше приложение может использовать лучший дизайн. –

+0

Дизайн, который вы предлагаете, требует соблюдения прав root и обеспечения того, чтобы правила моего брандмауэра не мешали остальной системе - что, если есть процесс, который также отправляет широковещательные сообщения и * хочет * иметь петлю? Конечно, я могу использовать передовые матчи netfilter, взломать ядро ​​и т. Д. Ради чистоты дизайна, но я предпочитаю простые и универсальные решения. Кроме того, говоря о дизайне, общесистемный брандмауэр не является местом для реализации функциональных возможностей, необходимых какой-либо программе пользовательского пространства, но это только мое скромное мнение. – Pawel

Смежные вопросы