Как определить, какой сетевой интерфейс (IP-адрес) будет использоваться для отправки пакета на определенный IP-адрес?

StackOverflow https://stackoverflow.com/questions/2432493

  •  19-09-2019
  •  | 
  •  

Вопрос

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

Это было полезно?

Решение

Чтобы немного расширить комментарий Реми Лебо: GetBestInterfaceEx() лучший выбор, если вы используете Windows XP или новее.Это будет работать как для адресов IPv4, так и для IPv6.

GetBestInterface/GetBestInterfaceEx возвращает индекс (назовем его IDX) наиболее подходящего интерфейса, который будет использоваться для связи с некоторым адресом.

Затем вы можете сопоставить этот индекс с локальным IP-адресом, получив сопоставление интерфейса <-> IP-адреса с помощью ПолучитьIpAddrTable или Получить адреса адаптеров если у вас двойной стек (поддерживается как IPv6, так и IPv4).

Переберите эту таблицу и найдите интерфейс с dwIndex (или IfIndex, в случае GetAdaptersAddresses), совпадающим с IDX.

Другие советы

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

Если это невозможно, вы можете использовать подход: отправить запрос SIP на все IP-адреса, используя фиктивное значение в заголовке Via, например 0.0.0.0, и снова установить интерфейс, на который вы получаете ответ, как интерфейс по умолчанию.Преимущество этого подхода также состоит в том, что ответ SIP сообщит вам общедоступный IP-адрес, с которого был получен запрос, что может быть полезно, если ваш стек SIP находится за NAT.

Я думаю, что по TCP вы можете получить адрес локальной стороны сокета после подключения().Я не знаю, верно ли то же самое для UDP (подозреваю, что нет), но, возможно, стоит попробовать.

Сокет позволит вам привязаться к локальной конечной точке перед вызовом подключения (как UDP, так и TCP).

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top