2015-11-25 3 views
3

Я пытаюсь установить выходной интерфейс сокета в системе с двумя интерфейсами. Я много гугл, и я нашел разные ответы. Некоторые люди говорят, что я могу bind сокет, прежде чем звонить connect, чтобы выбрать конкретный интерфейс (как в How does a socket know which network interface controller to use?). Но другие люди говорят, что этого недостаточно (как в http://codingrelic.geekhold.com/2009/10/code-snippet-sobindtodevice.html или How to open a socket on a specific interface and receive both IPv4 and IPv6 traffic).Выбор интерфейса выхода сокета: SO_BINDTODEVICE vs bind перед подключением

У меня есть рабочая реализация с использованием SO_BINDTODEVICE. Однако решение bind перед connect не работает. Похоже, что адрес источника не влияет на маршрутизацию, и в этом случае рассматривается только таблица маршрутизации. Кто-то сказал, что это вызвано моделью слабых конечных систем Linux. Согласно http://wiki.treck.com/Appendix_C:_Strong_End_System_Model_/_Weak_End_System_Model, адрес источника не задает выходной интерфейс.

Если возможно, я хотел бы иметь портативное решение. Я знаю, что SO_BINDTODEVICE доступен только в Linux.

+0

Я запускаю тестовое связывание с интерфейсом со связыванием. Он должен работать, вы должны показать свой код, чтобы выяснить, где проблема. – rodolk

ответ

2

Исходный адрес не влияет на маршрутизацию пакета. Интерфейс будет выбран на основе адреса назначения и таблицы маршрутизатора хоста. Вы можете изменить его с помощью команды route.

route default gw [gateway IP] 

Независимо от того, какой интерфейс подключен к сокету, пакет должен маршрутизироваться на основе таблицы маршрутов. Интерфейс, которому привязан сокет, определит исходный IP-адрес.

Теперь я запустил некоторые тесты, привязанные к интерфейсу loopback и подключив сокет к другому адресу в Интернете, и в этом случае соединение завершилось с ошибкой 22 (EINVAL). Тем не менее, в других тестах с двумя интерфейсами (ни один из них не был loopback), и подключение к серверу в Интернете, независимо от того, какой интерфейс я связал сокет, пакет был отправлен в соответствии с таблицей маршрутизации, в моем случае по умолчанию править. Адрес источника зависит от привязки.

+0

Так что я не могу выбрать конкретный интерфейс вывода, используя 'bind' перед' connect'? Я не хочу использовать iptables для решения проблемы. –

+0

Насколько я знаю, вы не можете сделать это со связью. – rodolk

+0

Можете ли вы попробовать позвонить sendto после bind? – rodolk

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