Использование `sendto()` в сокете IPv6 для отправки на адрес IPv4

У меня есть приложение C++, которое использует тот же сокет UDP IPv6 для отправки адресатам IPv6 или IPv4.

sockfd = socket(PF_INET6, SOCK_DGRAM, 0);
dest_addr.sin6_family = AF_INET;
dest_addr.sin6_port = htons(dest_port);
inet_pton ("192.168.1.33",  &dest_addr.sin6_addr);
sendto (sockfd, message, strlen(message)+1, 0, (struct sockaddr *)&dest_addr, sizeof(struct sockaddr_in6));

В Linux это работает нормально, но во FreeBSD я получаю сообщение об ошибке Address family not supported by protocol family при отправке на адреса IPv4.

Есть ли способ настроить FreeBSD, чтобы принять это? Может быть, похоже на ipv6_ipv4mapping="YES" для прослушивания клиентов IPv4?


person Gene Vincent    schedule 10.11.2011    source источник
comment
Не лучше ли иметь сокет для ipv4 и один для ipv6?   -  person Paolo    schedule 11.11.2011
comment
@Paolo: Две причины: а) он хорошо вписывается в существующую (основанную на IPv4) структуру программы и б) приложение уже использует многие сотни сокетов, и я бы предпочел не удваивать его.   -  person Gene Vincent    schedule 11.11.2011
comment
в C++ вам нужно только (sockaddr *), а не (struct sockaddr *)   -  person phuclv    schedule 26.07.2016


Ответы (1)


Вы создаете сокет IPv6, поэтому вам нужно использовать адреса IPv6. Однако, если ваша ОС поддерживает сокеты с двойным стеком (т. е. изначально поддерживает как IPv4, так и IPv6 на одном сокете), используйте IPv4-сопоставленный IPv6-адрес для отправки на IPv4-адрес (если ОС позволяет это, некоторые нет). В противном случае вам придется использовать отдельные сокеты для IPv4 и IPv6.

person Remy Lebeau    schedule 11.11.2011
comment
Linux, похоже, не видит этого, и код работает нормально. Я надеялся, что у FreeBSD будет переключатель, чтобы быть немного более расслабленным. - person Gene Vincent; 11.11.2011
comment
@GeneVincent - я не знаком с FreeBSD, но у меня сложилось впечатление, что изменение его на inet_pton("::ffff:192.168.1.33", &dest....); должно работать на FreeBSD - person Flexo; 11.11.2011
comment
@awoodland: Конечно, это работает, но это означает преобразование каждого адреса. Общесистемное переключение на поведение Linux лучше бы удовлетворило мои потребности, но, думаю, мне придется пойти на преобразование. - person Gene Vincent; 11.11.2011
comment
@GeneVincent - я бы предложил заменить вызовы inet_pton вашей собственной функцией, которая может вставлять "::ffff:" по мере необходимости. - person Flexo; 11.11.2011