Что такое sin6_scope_id для петлевого адреса IPv6? - PullRequest
0 голосов
/ 29 октября 2019

Я хочу создать сокет, связанный с любым портом на локальной машине, чтобы я мог имитировать socketpair() в Windows. Когда я хочу, чтобы этот сокет был IPv6, какое значение я должен установить для sin6_scope_id? Должен ли я фактически перечислять адаптеры и находить адаптер обратной связи, чтобы заполнить это поле?

Другими словами, что мне нужно делать с этим для привязки к любому локальному порту?

struct sockaddr_in6 addr;
addr.sin6_family = AF_INET6;
addr.sin6_port = htons(0);
addr.sin6_flowinfo = 0;
addr.sin6_addr = in6addr_loopback;
addr.sin6_scope_id = ????;

1 Ответ

1 голос
/ 29 октября 2019

Некоторые гуру сокетов могут знать прямой способ его установки. Но проще просто запросить систему об этом. Это правильно установит для вас «flowinfo» и «scope_id».

Общий подход таков:

Invoke getifaddrs , чтобы получить список ifaddrs экземпляров.

Перечислять список ifaddrs, возвращаемых из этого API, до тех пор, пока вы не найдете адаптер AF_INET6 с битом IFF_LOOPBACK, установленным на элементе ifa_flags. Это адаптер, с которым вы хотите связать.

Теперь, когда у вас есть указатель на экземпляр ifaddrs, приведите его член ifa_addr к (sockaddr_in6 *). Скопируйте эту структуру в свой собственный addr и установите порт.

Пример кода ниже:

struct sockaddr_in6 addr = {0};
ifaddrs* pList = NULL;
ifaddrs* pAdapterFound = NULL;
ifaddrs* pAdapter = NULL;
getifaddrs(&pList);
pAdapter = pList;
while (pAdapter)
{
    if ((pAdapter->ifa_addr != NULL) && 
        (family == pAdapter->ifa_addr->sa_family == AF_INET6) &&
        (pAdapter->ifa_flags & IFF_LOOPBACK))
    {
        pAdapterFound = pAdapter;
        break;
    }
    pAdapter = pAdapter->ifa_next;
}

if (pAdapterFound)
{    
    // C++ way to copy the sockaddr_in6 struct
    addr = *(reinterpret_cast<sockaddr_in6*>(pAdapterFound->ifa_addr));  // C++

    // If you are coding in C instead of C++
    // memcpy(&addr, pAdapterFound->ifa_addr, sizeof(addr));

    addr.sin6_port = htons(0); // or whatever port you want to bind to
}

freeifaddrs(pList);

Вы можете сослаться на вспомогательную функцию, которую я назвал GetSocketAddressForAdapter . Вы можете вызвать его следующим образом:

GetSocketAddressforAdapter(AF_INET6, "::1", 0, &address);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...