1
0
mirror of https://github.com/SoftEtherVPN/SoftEtherVPN.git synced 2024-12-26 01:59:53 +03:00

Return and cache all addresses from DNS resolver

This commit is contained in:
Yihong Wu 2021-12-06 00:45:00 +08:00
parent a9239a6aab
commit e6bf956806
3 changed files with 146 additions and 54 deletions

View File

@ -75,6 +75,8 @@ void DnsFree()
{
DNS_CACHE *entry = LIST_DATA(cache, i);
Free((void *)entry->Hostname);
FreeHostIPAddressList(entry->IPList_v6);
FreeHostIPAddressList(entry->IPList_v4);
Free(entry);
}
}
@ -153,6 +155,35 @@ DNS_CACHE *DnsCacheUpdate(const char *hostname, const IP *ipv6, const IP *ipv4)
return NULL;
}
LIST *iplist_v6 = NULL;
LIST *iplist_v4 = NULL;
if (ipv6 != NULL)
{
iplist_v6 = NewListFast(NULL);
AddHostIPAddressToList(iplist_v6, ipv6);
}
if (ipv4 != NULL)
{
iplist_v4 = NewListFast(NULL);
AddHostIPAddressToList(iplist_v4, ipv4);
}
DNS_CACHE *ret = DnsCacheUpdateEx(hostname, iplist_v6, iplist_v4);
FreeHostIPAddressList(iplist_v6);
FreeHostIPAddressList(iplist_v4);
return ret;
}
DNS_CACHE *DnsCacheUpdateEx(const char *hostname, const LIST *iplist_v6, const LIST *iplist_v4)
{
if (DnsCacheIsEnabled() == false || IsEmptyStr(hostname))
{
return NULL;
}
DNS_CACHE *entry;
LockList(cache);
@ -161,11 +192,14 @@ DNS_CACHE *DnsCacheUpdate(const char *hostname, const IP *ipv6, const IP *ipv4)
t.Hostname = hostname;
entry = Search(cache, &t);
if (ipv6 == NULL && ipv4 == NULL)
if (iplist_v6 == NULL && iplist_v4 == NULL)
{
if (entry != NULL)
{
Delete(cache, entry);
Free((void *)entry->Hostname);
FreeHostIPAddressList(entry->IPList_v6);
FreeHostIPAddressList(entry->IPList_v4);
Free(entry);
entry = NULL;
}
@ -182,19 +216,25 @@ DNS_CACHE *DnsCacheUpdate(const char *hostname, const IP *ipv6, const IP *ipv4)
entry->Expiration = Tick64();
if (ipv6 != NULL)
FreeHostIPAddressList(entry->IPList_v6);
FreeHostIPAddressList(entry->IPList_v4);
if (iplist_v6 != NULL)
{
if (CmpIpAddr(&entry->IPv6, ipv6) != 0)
{
Copy(&entry->IPv6, ipv6, sizeof(entry->IPv6));
}
entry->IPList_v6 = CloneIPAddressList(iplist_v6);
}
else
{
if (CmpIpAddr(&entry->IPv4, ipv4) != 0)
{
Copy(&entry->IPv4, ipv4, sizeof(entry->IPv4));
}
entry->IPList_v6 = NULL;
}
if (iplist_v4 != NULL)
{
entry->IPList_v4 = CloneIPAddressList(iplist_v4);
}
else
{
entry->IPList_v4 = NULL;
}
}
}
@ -225,7 +265,7 @@ DNS_CACHE_REVERSE *DnsCacheReverseFind(const IP *ip)
DNS_CACHE_REVERSE *DnsCacheReverseUpdate(const IP *ip, const char *hostname)
{
if (DnsCacheIsEnabled() == false || IsZeroIP(&ip))
if (DnsCacheIsEnabled() == false || IsZeroIP(ip))
{
return NULL;
}
@ -278,10 +318,50 @@ bool DnsResolve(IP *ipv6, IP *ipv4, const char *hostname, UINT timeout, volatile
return false;
}
LIST *iplist_v6 = NewListFast(NULL);
LIST *iplist_v4 = NewListFast(NULL);
bool ret = DnsResolveEx(iplist_v6, iplist_v4, hostname, timeout, cancel_flag);
if (ipv6 != NULL && LIST_NUM(iplist_v6) > 0)
{
IP *ip = LIST_DATA(iplist_v6, 0);
Copy(ipv6, ip, sizeof(IP));
}
else
{
Zero(ipv6, sizeof(ipv6));
}
if (ipv4 != NULL && LIST_NUM(iplist_v4) > 0)
{
IP *ip = LIST_DATA(iplist_v4, 0);
Copy(ipv4, ip, sizeof(IP));
}
else
{
ZeroIP4(ipv4);
}
FreeHostIPAddressList(iplist_v6);
FreeHostIPAddressList(iplist_v4);
return ret;
}
bool DnsResolveEx(LIST *iplist_v6, LIST *iplist_v4, const char *hostname, UINT timeout, volatile const bool *cancel_flag)
{
if (iplist_v6 == NULL || iplist_v4 == NULL || IsEmptyStr(hostname))
{
return false;
}
if (StrCmpi(hostname, "localhost") == 0)
{
GetLocalHostIP6(ipv6);
GetLocalHostIP4(ipv4);
IP ipv6, ipv4;
GetLocalHostIP6(&ipv6);
GetLocalHostIP4(&ipv4);
AddHostIPAddressToList(iplist_v6, &ipv6);
AddHostIPAddressToList(iplist_v4, &ipv4);
return true;
}
@ -290,21 +370,13 @@ bool DnsResolve(IP *ipv6, IP *ipv4, const char *hostname, UINT timeout, volatile
{
if (IsIP6(&ip))
{
if (ipv6 != NULL)
{
ZeroIP4(ipv4);
Copy(ipv6, &ip, sizeof(IP));
return true;
}
AddHostIPAddressToList(iplist_v6, &ip);
return true;
}
else
{
if (ipv4 != NULL)
{
Zero(ipv6, sizeof(IP));
Copy(ipv4, &ip, sizeof(IP));
return true;
}
AddHostIPAddressToList(iplist_v4, &ip);
return true;
}
return false;
@ -332,7 +404,8 @@ bool DnsResolve(IP *ipv6, IP *ipv4, const char *hostname, UINT timeout, volatile
DNS_RESOLVER resolver;
Zero(&resolver, sizeof(resolver));
ZeroIP4(&resolver.IPv4);
resolver.IPList_v6 = iplist_v6;
resolver.IPList_v4 = iplist_v4;
resolver.Hostname = hostname;
THREAD *worker = NewThread(DnsResolver, &resolver);
@ -368,10 +441,7 @@ bool DnsResolve(IP *ipv6, IP *ipv4, const char *hostname, UINT timeout, volatile
if (resolver.OK)
{
Copy(ipv6, &resolver.IPv6, sizeof(IP));
Copy(ipv4, &resolver.IPv4, sizeof(IP));
DnsCacheUpdate(hostname, ipv6, ipv4);
DnsCacheUpdateEx(hostname, iplist_v6, iplist_v4);
return true;
}
@ -384,8 +454,19 @@ CACHE:
return false;
}
Copy(ipv6, &cached->IPv6, sizeof(IP));
Copy(ipv4, &cached->IPv4, sizeof(IP));
UINT i;
for (i = 0; i < LIST_NUM(cached->IPList_v6); ++i)
{
IP *ip = LIST_DATA(cached->IPList_v6, i);
AddHostIPAddressToList(iplist_v6, ip);
}
for (i = 0; i < LIST_NUM(cached->IPList_v4); ++i)
{
IP *ip = LIST_DATA(cached->IPList_v4, i);
AddHostIPAddressToList(iplist_v4, ip);
}
return true;
}
@ -428,24 +509,16 @@ void DnsResolver(THREAD *t, void *param)
{
const struct sockaddr_in6 *in = (struct sockaddr_in6 *)result->ai_addr;
InAddrToIP6(&ip, &in->sin6_addr);
if (IsIP6(&ip) && ipv6_ok == false)
if (IsIP6(&ip))
{
Copy(&resolver->IPv6, &ip, sizeof(resolver->IPv6));
resolver->IPv6.ipv6_scope_id = in->sin6_scope_id;
ip.ipv6_scope_id = in->sin6_scope_id;
AddHostIPAddressToList(resolver->IPList_v6, &ip);
ipv6_ok = true;
if (ipv4_ok)
{
break;
}
}
else if (IsIP4(&ip) && ipv4_ok == false)
else if (IsIP4(&ip))
{
Copy(&resolver->IPv4, &ip, sizeof(resolver->IPv4));
AddHostIPAddressToList(resolver->IPList_v4, &ip);
ipv4_ok = true;
if (ipv6_ok)
{
break;
}
}
}
else
@ -454,9 +527,8 @@ void DnsResolver(THREAD *t, void *param)
InAddrToIP(&ip, &in->sin_addr);
if (IsIP4(&ip))
{
Copy(&resolver->IPv4, &ip, sizeof(resolver->IPv4));
AddHostIPAddressToList(resolver->IPList_v4, &ip);
ipv4_ok = true;
break;
}
}
}

View File

@ -24,8 +24,8 @@
struct DNS_CACHE
{
const char *Hostname;
IP IPv4;
IP IPv6;
LIST *IPList_v4;
LIST *IPList_v6;
UINT64 Expiration;
};
@ -39,8 +39,8 @@ struct DNS_CACHE_REVERSE
struct DNS_RESOLVER
{
const char *Hostname;
IP IPv4;
IP IPv6;
LIST *IPList_v4;
LIST *IPList_v6;
bool OK;
};
@ -63,11 +63,13 @@ void DnsCacheToggle(const bool enabled);
DNS_CACHE *DnsCacheFind(const char *hostname);
DNS_CACHE *DnsCacheUpdate(const char *hostname, const IP *ipv6, const IP *ipv4);
DNS_CACHE *DnsCacheUpdateEx(const char *hostname, const LIST *iplist_v6, const LIST *iplist_v4);
DNS_CACHE_REVERSE *DnsCacheReverseFind(const IP *ip);
DNS_CACHE_REVERSE *DnsCacheReverseUpdate(const IP *ip, const char *hostname);
bool DnsResolve(IP *ipv6, IP *ipv4, const char *hostname, UINT timeout, volatile const bool *cancel_flag);
bool DnsResolveEx(LIST *iplist_v6, LIST *iplist_v4, const char *hostname, UINT timeout, volatile const bool *cancel_flag);
void DnsResolver(THREAD *t, void *param);
bool DnsResolveReverse(char *dst, const UINT size, const IP *ip, UINT timeout, volatile const bool *cancel_flag);

View File

@ -17049,14 +17049,32 @@ bool IsMyIPAddress(IP *ip)
// Add the IP address to the list
void AddHostIPAddressToList(LIST *o, IP *ip)
{
IP *r;
IP *r = NULL;
// Validate arguments
if (o == NULL || ip == NULL)
{
return;
}
r = Search(o, ip);
if (o->cmp != NULL)
{
r = Search(o, ip);
}
else
{
UINT i;
for (i = 0; i < LIST_NUM(o); i++)
{
IP *a = LIST_DATA(o, i);
if (CmpIpAddr(ip, a) == 0)
{
r = ip;
break;
}
}
}
if (r != NULL)
{
return;
@ -17219,7 +17237,7 @@ LIST *CloneIPAddressList(LIST *o)
return NULL;
}
ret = NewListFast(CmpIpAddressList);
ret = NewListFast(o->cmp);
for (i = 0; i < LIST_NUM(o); i++)
{