From 9692a8d961f0f6dbcf3a6076826d8cac11a25429 Mon Sep 17 00:00:00 2001 From: Yihong Wu <54519668+domosekai@users.noreply.github.com> Date: Fri, 3 Dec 2021 14:18:43 +0800 Subject: [PATCH] Fix DNS resolution when no IPv6 address is configured --- src/Mayaqua/DNS.c | 43 ++++++++++++++++++++++++++++++++----------- src/Mayaqua/Network.c | 30 ++++++++++++++++++++++++++++++ src/Mayaqua/Network.h | 1 + 3 files changed, 63 insertions(+), 11 deletions(-) diff --git a/src/Mayaqua/DNS.c b/src/Mayaqua/DNS.c index f3a68410..74581d6b 100644 --- a/src/Mayaqua/DNS.c +++ b/src/Mayaqua/DNS.c @@ -405,8 +405,16 @@ void DnsResolver(THREAD *t, void *param) struct addrinfo hints; Zero(&hints, sizeof(hints)); - hints.ai_family = AF_INET6; - hints.ai_flags = AI_ALL | AI_ADDRCONFIG | AI_V4MAPPED; + if (HasIPv6Address()) + { + hints.ai_family = AF_INET6; + hints.ai_flags = AI_ALL | AI_ADDRCONFIG | AI_V4MAPPED; + } + else + { + hints.ai_family = AF_INET; + hints.ai_flags = AI_ADDRCONFIG; + } struct addrinfo *results; const int ret = getaddrinfo(resolver->Hostname, NULL, &hints, &results); @@ -417,18 +425,31 @@ void DnsResolver(THREAD *t, void *param) for (struct addrinfo *result = results; result != NULL; result = result->ai_next) { IP ip; - const struct sockaddr_in6 *in = (struct sockaddr_in6 *)result->ai_addr; - InAddrToIP6(&ip, &in->sin6_addr); - if (IsIP6(&ip) && ipv6_ok == false) + if (hints.ai_family == AF_INET6) { - Copy(&resolver->IPv6, &ip, sizeof(resolver->IPv6)); - resolver->IPv6.ipv6_scope_id = in->sin6_scope_id; - ipv6_ok = true; + const struct sockaddr_in6 *in = (struct sockaddr_in6 *)result->ai_addr; + InAddrToIP6(&ip, &in->sin6_addr); + if (IsIP6(&ip) && ipv6_ok == false) + { + Copy(&resolver->IPv6, &ip, sizeof(resolver->IPv6)); + resolver->IPv6.ipv6_scope_id = in->sin6_scope_id; + ipv6_ok = true; + } + else if (IsIP4(&ip) && ipv4_ok == false) + { + Copy(&resolver->IPv4, &ip, sizeof(resolver->IPv4)); + ipv4_ok = true; + } } - else if (IsIP4(&ip) && ipv4_ok == false) + else { - Copy(&resolver->IPv4, &ip, sizeof(resolver->IPv4)); - ipv4_ok = true; + const struct sockaddr_in *in = (struct sockaddr_in *)result->ai_addr; + InAddrToIP(&ip, &in->sin_addr); + if (IsIP4(&ip) && ipv4_ok == false) + { + Copy(&resolver->IPv4, &ip, sizeof(resolver->IPv4)); + ipv4_ok = true; + } } } diff --git a/src/Mayaqua/Network.c b/src/Mayaqua/Network.c index f8a72fe4..e8b81af1 100644 --- a/src/Mayaqua/Network.c +++ b/src/Mayaqua/Network.c @@ -9871,6 +9871,36 @@ bool IsIPv6Supported() #endif // NO_IPV6 } +// Check whether an IPv6 address is configured on any interface +bool HasIPv6Address() +{ + LIST *o; + UINT i; + bool ret = false; + + o = GetHostIPAddressList(); + + ret = false; + + for (i = 0; i < LIST_NUM(o); i++) + { + IP *p = LIST_DATA(o, i); + + if (IsIP6(p)) + { + UINT type = GetIPAddrType6(p); + if ((type & IPV6_ADDR_GLOBAL_UNICAST) && ((type & IPV6_ADDR_ZERO) == 0) && ((type & IPV6_ADDR_LOOPBACK) == 0)) + { + ret = true; + } + } + } + + FreeHostIPAddressList(o); + + return ret; +} + // Add the thread to the thread waiting list void AddWaitThread(THREAD *t) { diff --git a/src/Mayaqua/Network.h b/src/Mayaqua/Network.h index b7cbf9a2..d1bb30dd 100644 --- a/src/Mayaqua/Network.h +++ b/src/Mayaqua/Network.h @@ -1164,6 +1164,7 @@ SOCKLIST *NewSockList(); void StopSockList(SOCKLIST *sl); void FreeSockList(SOCKLIST *sl); bool IsIPv6Supported(); +bool HasIPv6Address(); void SetSockTos(SOCK *s, int tos); void SetSockHighPriority(SOCK *s, bool flag); void InitIpClientList();