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

View File

@ -24,8 +24,8 @@
struct DNS_CACHE struct DNS_CACHE
{ {
const char *Hostname; const char *Hostname;
IP IPv4; LIST *IPList_v4;
IP IPv6; LIST *IPList_v6;
UINT64 Expiration; UINT64 Expiration;
}; };
@ -39,8 +39,8 @@ struct DNS_CACHE_REVERSE
struct DNS_RESOLVER struct DNS_RESOLVER
{ {
const char *Hostname; const char *Hostname;
IP IPv4; LIST *IPList_v4;
IP IPv6; LIST *IPList_v6;
bool OK; bool OK;
}; };
@ -63,11 +63,13 @@ void DnsCacheToggle(const bool enabled);
DNS_CACHE *DnsCacheFind(const char *hostname); DNS_CACHE *DnsCacheFind(const char *hostname);
DNS_CACHE *DnsCacheUpdate(const char *hostname, const IP *ipv6, const IP *ipv4); 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 *DnsCacheReverseFind(const IP *ip);
DNS_CACHE_REVERSE *DnsCacheReverseUpdate(const IP *ip, const char *hostname); 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 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); void DnsResolver(THREAD *t, void *param);
bool DnsResolveReverse(char *dst, const UINT size, const IP *ip, UINT timeout, volatile const bool *cancel_flag); 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 // Add the IP address to the list
void AddHostIPAddressToList(LIST *o, IP *ip) void AddHostIPAddressToList(LIST *o, IP *ip)
{ {
IP *r; IP *r = NULL;
// Validate arguments // Validate arguments
if (o == NULL || ip == NULL) if (o == NULL || ip == NULL)
{ {
return; return;
} }
if (o->cmp != NULL)
{
r = Search(o, ip); 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) if (r != NULL)
{ {
return; return;
@ -17219,7 +17237,7 @@ LIST *CloneIPAddressList(LIST *o)
return NULL; return NULL;
} }
ret = NewListFast(CmpIpAddressList); ret = NewListFast(o->cmp);
for (i = 0; i < LIST_NUM(o); i++) for (i = 0; i < LIST_NUM(o); i++)
{ {