From e146f4beefd047ea5c88d77f13c52509e6266be6 Mon Sep 17 00:00:00 2001 From: Michal Privoznik Date: Wed, 15 Jul 2020 13:48:44 +0200 Subject: [PATCH] virNetSocketCheckProtocols: Separate out checking family via getaddrinfo() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The virNetSocketCheckProtocols() function is supposed to tell caller whether IPv4 and/or IPv6 is supported on the system. In the initial round, it uses getifaddrs() to see if an interface has IPv4/IPv6 address assigned and then to double check IPv6 it uses getaddrinfo() to lookup IPv6 loopback address. Separate out this latter code because it is going to be reused. Since the original code lived under an #ifdef and the new function doesn't it is marked as unused - because on some systems it may be so. Signed-off-by: Michal Privoznik Reviewed-by: Ján Tomko --- src/rpc/virnetsocket.c | 62 ++++++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 23 deletions(-) diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c index e3e935460f..1a0cf60286 100644 --- a/src/rpc/virnetsocket.c +++ b/src/rpc/virnetsocket.c @@ -141,16 +141,49 @@ static int virNetSocketForkDaemon(const char *binary) } #endif -int virNetSocketCheckProtocols(bool *hasIPv4, - bool *hasIPv6) + +static int G_GNUC_UNUSED +virNetSocketCheckProtocolByLookup(const char *address, + int family, + bool *hasFamily) { -#ifdef HAVE_IFADDRS_H - struct ifaddrs *ifaddr = NULL, *ifa; struct addrinfo hints; struct addrinfo *ai = NULL; int gaierr; memset(&hints, 0, sizeof(hints)); + hints.ai_family = family; + hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; + hints.ai_socktype = SOCK_STREAM; + + if ((gaierr = getaddrinfo(address, NULL, &hints, &ai)) != 0) { + *hasFamily = false; + + if (gaierr == EAI_FAMILY || +#ifdef EAI_ADDRFAMILY + gaierr == EAI_ADDRFAMILY || +#endif + gaierr == EAI_NONAME) { + } else { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Cannot resolve %s address: %s"), + address, + gai_strerror(gaierr)); + return -1; + } + } else { + *hasFamily = true; + } + + freeaddrinfo(ai); + return 0; +} + +int virNetSocketCheckProtocols(bool *hasIPv4, + bool *hasIPv6) +{ +#ifdef HAVE_IFADDRS_H + struct ifaddrs *ifaddr = NULL, *ifa; *hasIPv4 = *hasIPv6 = false; @@ -172,26 +205,9 @@ int virNetSocketCheckProtocols(bool *hasIPv4, freeifaddrs(ifaddr); - hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; - hints.ai_family = AF_INET6; - hints.ai_socktype = SOCK_STREAM; - if ((gaierr = getaddrinfo("::1", NULL, &hints, &ai)) != 0) { - if (gaierr == EAI_FAMILY || -# ifdef EAI_ADDRFAMILY - gaierr == EAI_ADDRFAMILY || -# endif - gaierr == EAI_NONAME) { - *hasIPv6 = false; - } else { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Cannot resolve ::1 address: %s"), - gai_strerror(gaierr)); - return -1; - } - } - - freeaddrinfo(ai); + if (virNetSocketCheckProtocolByLookup("::1", AF_INET6, hasIPv6) < 0) + return -1; VIR_DEBUG("Protocols: v4 %d v6 %d", *hasIPv4, *hasIPv6);