connect () возвращает «неверный аргумент» с адресом ipv6

У меня есть эта простая пара клиент-серверных приложений. Код довольно прост, я использую только новые рекомендованные методы, такие как getaddinfo и т. Д., И все отлично работает для ipv4. Даже для петли ipv6 (:: 1) это работает. Проблемы начинаются, когда дело доходит до некоторых других адресов ipv6 … У меня есть две машины в сети, все отлично работает, когда я передаю их адреса ipv4, но когда я даю свой клиентский адрес ipv6, я получаю сообщение об ошибке при соединении: неверный аргумент ,
Эй, разве я уже не знаю это? Я делаю! Когда я пытаюсь ping6 этот адрес ipv6, я получаю ту же ошибку:

connect: неверный аргумент

Но есть способ преодолеть этот блок — нужно выбрать интерфейс с ключом -I, и с тех пор все работает без сбоев. Но как я могу добиться того же в моем клиентском приложении? Что я должен делать? Мой клиентский код выглядит так:

struct addrinfo hints;
struct addrinfo *server;

memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;

int status;
if((status = getaddrinfo(argv[1], argv[2], &hints, &server) != 0))
{
perror("getaddrinfo error");
return 1;
}

int sock_fd;
struct addrinfo *ptr;
for(ptr=server;ptr!=NULL;ptr=ptr->ai_next)
{
if( (sock_fd = socket(ptr->ai_family,ptr->ai_socktype,ptr->ai_protocol)) == -1)
{
perror("socket error");
continue;
}
if( connect(sock_fd, ptr->ai_addr,ptr->ai_addrlen) == -1 )
{
perror("connect error");
continue;
}
break;
}

7

Решение

Адреса, начинающиеся с ff... многоадресные адреса. Подключение потока к многоадресному адресу не работает.

Адреса, начинающиеся с fe80... являются локальными ссылочными адресами, с которыми связан идентификатор интерфейса. Попробуйте посмотреть на sockaddr вернулся из getaddrinfo, это scope поле заполнено?

6

Другие решения

Вам необходимо указать интерфейс для проверки связи IPv6 (т.е. -I eth0):

ping6 -I eth0 fe80::208:54ff:fe34:22ae

При использовании локальных адресов канала для проверки связи IPv6 требуется определить, какое устройство должно отправлять / получать пакет — каждое устройство имеет локальный адрес канала.

Попытка без этого приведет к сообщению об ошибке, например:

--> # ping6 fe80::208:54ff:fe34:22ae
connect: Invalid argument

В этом случае вы должны указать интерфейс, как показано здесь:

--> # ping6 -I eth0 fe80::208:54ff:fe34:22ae
PING fe80::208:54ff:fe34:22ae(fe80::208:54ff:fe34:22ae) from fe80::208:54ff:fe34:22ae eth0: 56 data bytes
64 bytes from fe80::208:54ff:fe34:22ae: icmp_seq=0 ttl=64 time=0.027 ms
64 bytes from fe80::208:54ff:fe34:22ae: icmp_seq=1 ttl=64 time=0.030 ms
64 bytes from fe80::208:54ff:fe34:22ae: icmp_seq=2 ttl=64 time=0.036 ms

Один подобный подход вы должны следовать в своем клиентском приложении.

7

Я рекомендую вам включить протокол IP6 в интерфейсе / сетевом соединении, кроме того, выкиньте протокол ip4, если у вас все еще есть ошибка.

На моем Linux Box это также происходило, когда у меня был активен ip4-интерфейс, и мое приложение пыталось использовать ip4-интерфейс с настройками ip6. То же самое должно быть действительно для окон.

Если что-то не понятно спросите.

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector