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 1/2] 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(); From b178f26e526c5f7575bc6a4a644454004e4e7134 Mon Sep 17 00:00:00 2001 From: Yihong Wu <54519668+domosekai@users.noreply.github.com> Date: Sat, 4 Dec 2021 16:16:22 +0800 Subject: [PATCH 2/2] Reduce redundant loop Co-authored-by: Davide Beatrici --- src/Mayaqua/DNS.c | 12 ++++++++++-- src/Mayaqua/Network.c | 2 ++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Mayaqua/DNS.c b/src/Mayaqua/DNS.c index 74581d6b..ab02ba19 100644 --- a/src/Mayaqua/DNS.c +++ b/src/Mayaqua/DNS.c @@ -413,7 +413,6 @@ void DnsResolver(THREAD *t, void *param) else { hints.ai_family = AF_INET; - hints.ai_flags = AI_ADDRCONFIG; } struct addrinfo *results; @@ -434,21 +433,30 @@ void DnsResolver(THREAD *t, void *param) Copy(&resolver->IPv6, &ip, sizeof(resolver->IPv6)); resolver->IPv6.ipv6_scope_id = in->sin6_scope_id; ipv6_ok = true; + if (ipv4_ok) + { + break; + } } else if (IsIP4(&ip) && ipv4_ok == false) { Copy(&resolver->IPv4, &ip, sizeof(resolver->IPv4)); ipv4_ok = true; + if (ipv6_ok) + { + break; + } } } else { const struct sockaddr_in *in = (struct sockaddr_in *)result->ai_addr; InAddrToIP(&ip, &in->sin_addr); - if (IsIP4(&ip) && ipv4_ok == false) + if (IsIP4(&ip)) { Copy(&resolver->IPv4, &ip, sizeof(resolver->IPv4)); ipv4_ok = true; + break; } } } diff --git a/src/Mayaqua/Network.c b/src/Mayaqua/Network.c index e8b81af1..5bbda204 100644 --- a/src/Mayaqua/Network.c +++ b/src/Mayaqua/Network.c @@ -9892,7 +9892,9 @@ bool HasIPv6Address() if ((type & IPV6_ADDR_GLOBAL_UNICAST) && ((type & IPV6_ADDR_ZERO) == 0) && ((type & IPV6_ADDR_LOOPBACK) == 0)) { ret = true; + break; } + } }