How to ensure that the server is listening on IPv6, if possible, and IPv4 otherwise?

I am trying to write a server application that listens for both IPv6 and IPv4 connections. The proper way to do this seems to be listening on an IPv6 address, which will also accept IPv4 connections.

Corresponding code snippet:

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);

(pretty much copied from the Beej manual)

The problem is that, at least on my system, it getaddrinforeturns a record with AF_INETfirst and AF_INET6second, whereas the client getaddrinfofirst returns AF_INET6according to the specification. With my naive approach, the server chooses IPv4, the client chooses IPv6, and the connection fails.

I tried to fix this by installing hints.ai_family = AF_INET6, but it fails on systems where IPv6 is not available.

:
a) IPv6 IPv4, ,
) getaddrinfo, IPv6, ,
;) , getaddrinfo , , .

+3
2

, getaddrinfo(), , . , , , " , ".

bind() listen() , getaddrinfo(). , , IPv4 IPv6, 0::0.

+3

, . , glibc, # 673708, IPv4.

, Linux-, : edit /etc/gai.conf, ( ):

label ::1/128       0
label ::/0          1
label 2002::/16     2
label ::/96         3
label ::ffff:0:0/96 4
label fec0::/10     5
label fc00::/7      6
label 2001:0::/32   7

:

label ::ffff:7f00:1/128 8

IPv6, , IPv4.

( , , ), , IPv6. . :

  • getaddrinfo().
  • , IPv6. IPV6_V6ONLY IPv6, IPv4.
  • , IPv4.
  • , , .
+1

Source: https://habr.com/ru/post/1761212/


All Articles