Этот вопрос можно рассматривать как родственный вопрос предыдущего. опубликовано мной. Очень утомительно, когда вы хотите привязать локальный адрес ссылки к сокету IPv6, вам нужно установить поле sin6_scope_id
структуры sockaddr_in6
. Мне интересно, может ли кто-нибудь предложить решение, следуя хорошей практике.
как привязать локальный адрес ссылки к сокету ipv6
Ответы (3)
Локальный адрес канала IPv6 не уникален на узле, он уникален только для сетевой карты, поэтому вы должны указать идентификатор области. Другими словами, вполне допустимо иметь несколько адаптеров с одинаковым IPv6-адресом.
Это означает, что вы должны принять в качестве входных данных идентификатор области действия или подходящую текстовую форму (%eth0, %1), которую вы можете передать getaddrinfo()
.
Один из методов состоит в том, чтобы взять локальный адрес IPv6, перечислить интерфейсы и, если только один соответствует, использовать его, если совпадений больше одного, то выручить со списком интерфейсов и заставить пользователя указать, какой из них в полной форме.
Проблема возникает только тогда, когда вы жестко задаете локальный адрес ссылки, что на самом деле не является практичным решением для нетривиального приложения.
В противном случае вы должны получить sockaddr
для привязки от getifaddrs()
, который заполнит идентификатор области для вас (например, вы можете разрешить своему пользователю указать имя интерфейса, а затем выполнить поиск в списке, возвращенном getifaddrs()
, чтобы найти локальный адрес ссылки, связанный с этим интерфейсом) .
Для локальных адресов IPv6 (префикс fe80::/10
) член sin6_scope_id
в структуре sockaddr_in6
является номером интерфейса, и вы можете получить этот номер,
if_nametoindex(const char *ifname);