Я пытаюсь написать серверное приложение, которое прослушивает соединения как IPv6, так и IPv4. Кажется, правильным способом для этого является прослушивание IPv6-адреса, который также будет принимать соединения IPv4.
Соответствующий фрагмент кода:
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
getaddrinfo(NULL, MYPORT, &hints, &res);
(в значительной степени скопировано из руководства Биджа)
Проблема в том, что, по крайней мере, в моей системе getaddrinfo
возвращает запись с AF_INET
first и AF_INET6
second - тогда как getaddrinfo
клиента возвращает AF_INET6
first, согласно спецификации. При моем наивном подходе сервер выбирает IPv4, клиент выбирает IPv6, и соединение не устанавливается.
Я попытался исправить это, установив hints.ai_family = AF_INET6
, но это не работает в системах, где IPv6 недоступен.
Я вижу два очевидных решения:
а) попробуйте сначала запросить IPv6 и в случае сбоя вернитесь к IPv4, либо
б) просмотреть результаты getaddrinfo
, найти IPv6 и, если нет, выбрать первую запись
но мне не нравится ни один слишком;) Я чувствую, что должен быть способ убедить getaddrinfo
сделать правильные вещи или, возможно, другой способ достичь моей цели.