1
0
mirror of https://github.com/SoftEtherVPN/SoftEtherVPN.git synced 2024-11-22 17:39:53 +03:00

Fix DNS resolution when no IPv6 address is configured

This commit is contained in:
Yihong Wu 2021-12-03 14:18:43 +08:00
parent 2d1c8765aa
commit 9692a8d961
3 changed files with 63 additions and 11 deletions

View File

@ -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;
}
}
}

View File

@ -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)
{

View File

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