mirror of
https://github.com/SoftEtherVPN/SoftEtherVPN.git
synced 2024-12-26 01:59:53 +03:00
Rewrite DNS API from scratch into dedicated file(s)
From a functional point of view, the main improvement is that GetIP() now always prioritizes IPv6 over IPv4. The previous implementation always returned an IPv4 address, unless not available: in such case it failed. This means that now connections to hostnames should be established via IPv6 if available. From a programmer point of view, getting rid of the insane wrappers is enough to justify a complete rewrite. As an extra, several unrelated unused global variables are removed.
This commit is contained in:
parent
f7e988ffc7
commit
0472f9c286
@ -21,6 +21,7 @@
|
||||
#include "UdpAccel.h"
|
||||
#include "Virtual.h"
|
||||
|
||||
#include "Mayaqua/DNS.h"
|
||||
#include "Mayaqua/Kernel.h"
|
||||
#include "Mayaqua/Mayaqua.h"
|
||||
#include "Mayaqua/Memory.h"
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "Server.h"
|
||||
|
||||
#include "Mayaqua/Cfg.h"
|
||||
#include "Mayaqua/DNS.h"
|
||||
#include "Mayaqua/FileIO.h"
|
||||
#include "Mayaqua/Internat.h"
|
||||
#include "Mayaqua/Memory.h"
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "SecureNAT.h"
|
||||
#include "Server.h"
|
||||
|
||||
#include "Mayaqua/DNS.h"
|
||||
#include "Mayaqua/Internat.h"
|
||||
#include "Mayaqua/FileIO.h"
|
||||
#include "Mayaqua/Memory.h"
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "Wpc.h"
|
||||
|
||||
#include "Mayaqua/Cfg.h"
|
||||
#include "Mayaqua/DNS.h"
|
||||
#include "Mayaqua/FileIO.h"
|
||||
#include "Mayaqua/Internat.h"
|
||||
#include "Mayaqua/Memory.h"
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "IPC.h"
|
||||
#include "Server.h"
|
||||
|
||||
#include "Mayaqua/DNS.h"
|
||||
#include "Mayaqua/Internat.h"
|
||||
#include "Mayaqua/Memory.h"
|
||||
#include "Mayaqua/Object.h"
|
||||
@ -1717,7 +1718,7 @@ bool RadiusLogin(CONNECTION *c, char *server, UINT port, UCHAR *secret, UINT sec
|
||||
{
|
||||
Add(ip_list, tmp_ip);
|
||||
}
|
||||
else if (GetIPEx(tmp_ip, token->Token[i], true))
|
||||
else if (GetIP(tmp_ip, token->Token[i]))
|
||||
{
|
||||
Add(ip_list, tmp_ip);
|
||||
}
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "WinUi.h"
|
||||
|
||||
#include "Mayaqua/Cfg.h"
|
||||
#include "Mayaqua/DNS.h"
|
||||
#include "Mayaqua/FileIO.h"
|
||||
#include "Mayaqua/Internat.h"
|
||||
#include "Mayaqua/Memory.h"
|
||||
@ -312,8 +313,8 @@ UINT SiDebugProcGetCurrentGetIPThreadCount(SERVER *s, char *in_str, char *ret_st
|
||||
return ERR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
ToStr3(tmp1, 0, GetCurrentGetIpThreadNum());
|
||||
ToStr3(tmp2, 0, GetGetIpThreadMaxNum());
|
||||
ToStr3(tmp1, 0, DnsThreadNum());
|
||||
ToStr3(tmp2, 0, DnsThreadNumMax());
|
||||
|
||||
Format(ret_str, 0,
|
||||
"Current threads = %s\n"
|
||||
@ -5629,11 +5630,11 @@ void SiLoadServerCfg(SERVER *s, FOLDER *f)
|
||||
i = CfgGetInt(f, "MaxConcurrentDnsClientThreads");
|
||||
if (i != 0)
|
||||
{
|
||||
SetGetIpThreadMaxNum(i);
|
||||
DnsThreadNumMaxSet(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetGetIpThreadMaxNum(DEFAULT_GETIP_THREAD_MAX_NUM);
|
||||
DnsThreadNumMaxSet(DNS_THREAD_DEFAULT_NUM_MAX);
|
||||
}
|
||||
|
||||
s->DontBackupConfig = CfgGetBool(f, "DontBackupConfig");
|
||||
@ -6103,7 +6104,7 @@ void SiWriteServerCfg(FOLDER *f, SERVER *s)
|
||||
return;
|
||||
}
|
||||
|
||||
CfgAddInt(f, "MaxConcurrentDnsClientThreads", GetGetIpThreadMaxNum());
|
||||
CfgAddInt(f, "MaxConcurrentDnsClientThreads", DnsThreadNumMax());
|
||||
|
||||
CfgAddInt(f, "CurrentBuild", s->Cedar->Build);
|
||||
|
||||
@ -10766,7 +10767,7 @@ SERVER *SiNewServerEx(bool bridge, bool in_client_inner_server, bool relay_serve
|
||||
LISTENER *azure;
|
||||
LISTENER *rudp;
|
||||
|
||||
SetGetIpThreadMaxNum(DEFAULT_GETIP_THREAD_MAX_NUM);
|
||||
DnsThreadNumMaxSet(DNS_THREAD_DEFAULT_NUM_MAX);
|
||||
|
||||
s = ZeroMalloc(sizeof(SERVER));
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "Connection.h"
|
||||
|
||||
#include "Mayaqua/DNS.h"
|
||||
#include "Mayaqua/Kernel.h"
|
||||
#include "Mayaqua/Memory.h"
|
||||
#include "Mayaqua/Object.h"
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "NativeStack.h"
|
||||
#include "Server.h"
|
||||
|
||||
#include "Mayaqua/DNS.h"
|
||||
#include "Mayaqua/FileIO.h"
|
||||
#include "Mayaqua/Memory.h"
|
||||
#include "Mayaqua/Object.h"
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "Command.h"
|
||||
#include "Protocol.h"
|
||||
|
||||
#include "Mayaqua/DNS.h"
|
||||
#include "Mayaqua/Memory.h"
|
||||
#include "Mayaqua/Microsoft.h"
|
||||
#include "Mayaqua/Pack.h"
|
||||
|
581
src/Mayaqua/DNS.c
Normal file
581
src/Mayaqua/DNS.c
Normal file
@ -0,0 +1,581 @@
|
||||
#include "DNS.h"
|
||||
|
||||
#include "Memory.h"
|
||||
#include "Network.h"
|
||||
#include "Object.h"
|
||||
#include "Str.h"
|
||||
#include "Tick64.h"
|
||||
|
||||
#ifdef OS_WIN32
|
||||
#include <WS2tcpip.h>
|
||||
#else
|
||||
#include <netdb.h>
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
static bool cache_enabled;
|
||||
|
||||
static LIST *cache;
|
||||
static LIST *cache_reverse;
|
||||
|
||||
static COUNTER *threads_counter;
|
||||
static UINT threads_max;
|
||||
|
||||
int DnsCacheCompare(void *p1, void *p2)
|
||||
{
|
||||
if (p1 == NULL || p2 == NULL)
|
||||
{
|
||||
return (p1 == NULL && p2 == NULL ? 0 : (p1 == NULL ? -1 : 1));
|
||||
}
|
||||
|
||||
const DNS_CACHE *c1 = *(DNS_CACHE **)p1;
|
||||
const DNS_CACHE *c2 = *(DNS_CACHE **)p2;
|
||||
|
||||
return StrCmpi(c1->Hostname, c2->Hostname);
|
||||
}
|
||||
|
||||
int DnsCacheReverseCompare(void *p1, void *p2)
|
||||
{
|
||||
if (p1 == NULL || p2 == NULL)
|
||||
{
|
||||
return (p1 == NULL && p2 == NULL ? 0 : (p1 == NULL ? -1 : 1));
|
||||
}
|
||||
|
||||
const DNS_CACHE_REVERSE *c1 = *(DNS_CACHE_REVERSE **)p1;
|
||||
const DNS_CACHE_REVERSE *c2 = *(DNS_CACHE_REVERSE **)p2;
|
||||
|
||||
return CmpIpAddr(&c1->IP, &c2->IP);
|
||||
}
|
||||
|
||||
void DnsInit()
|
||||
{
|
||||
threads_counter = NewCounter();
|
||||
DnsThreadNumMaxSet(DNS_THREAD_DEFAULT_NUM_MAX);
|
||||
|
||||
cache = NewList(DnsCacheCompare);
|
||||
cache_reverse = NewList(DnsCacheReverseCompare);
|
||||
DnsCacheToggle(true);
|
||||
}
|
||||
|
||||
void DnsFree()
|
||||
{
|
||||
DnsCacheToggle(false);
|
||||
|
||||
LockList(cache);
|
||||
{
|
||||
for (UINT i = 0; i < LIST_NUM(cache); ++i)
|
||||
{
|
||||
DNS_CACHE *entry = LIST_DATA(cache, i);
|
||||
Free((void *)entry->Hostname);
|
||||
Free(entry);
|
||||
}
|
||||
}
|
||||
UnlockList(cache);
|
||||
|
||||
ReleaseList(cache);
|
||||
cache = NULL;
|
||||
|
||||
LockList(cache_reverse);
|
||||
{
|
||||
for (UINT i = 0; i < LIST_NUM(cache_reverse); ++i)
|
||||
{
|
||||
DNS_CACHE_REVERSE *entry = LIST_DATA(cache, i);
|
||||
Free(entry->Hostname);
|
||||
Free(entry);
|
||||
}
|
||||
}
|
||||
UnlockList(cache_reverse);
|
||||
|
||||
ReleaseList(cache_reverse);
|
||||
cache_reverse = NULL;
|
||||
|
||||
DeleteCounter(threads_counter);
|
||||
threads_counter = NULL;
|
||||
}
|
||||
|
||||
UINT DnsThreadNum()
|
||||
{
|
||||
return Count(threads_counter);
|
||||
}
|
||||
|
||||
UINT DnsThreadNumMax()
|
||||
{
|
||||
return threads_max;
|
||||
}
|
||||
|
||||
void DnsThreadNumMaxSet(const UINT max)
|
||||
{
|
||||
threads_max = max;
|
||||
}
|
||||
|
||||
bool DnsCacheIsEnabled()
|
||||
{
|
||||
return cache_enabled;
|
||||
}
|
||||
|
||||
void DnsCacheToggle(const bool enabled)
|
||||
{
|
||||
cache_enabled = enabled;
|
||||
}
|
||||
|
||||
DNS_CACHE *DnsCacheFind(const char *hostname)
|
||||
{
|
||||
if (DnsCacheIsEnabled() == false || IsEmptyStr(hostname))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DNS_CACHE *entry;
|
||||
|
||||
LockList(cache);
|
||||
{
|
||||
DNS_CACHE t;
|
||||
t.Hostname = hostname;
|
||||
entry = Search(cache, &t);
|
||||
}
|
||||
UnlockList(cache);
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
DNS_CACHE *DnsCacheUpdate(const char *hostname, const IP *ipv6, const IP *ipv4)
|
||||
{
|
||||
if (DnsCacheIsEnabled() == false || IsEmptyStr(hostname))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DNS_CACHE *entry;
|
||||
|
||||
LockList(cache);
|
||||
{
|
||||
DNS_CACHE t;
|
||||
t.Hostname = hostname;
|
||||
entry = Search(cache, &t);
|
||||
|
||||
if (ipv6 == NULL && ipv4 == NULL)
|
||||
{
|
||||
if (entry != NULL)
|
||||
{
|
||||
Delete(cache, entry);
|
||||
Free(entry);
|
||||
entry = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (entry == NULL)
|
||||
{
|
||||
entry = ZeroMalloc(sizeof(DNS_CACHE));
|
||||
entry->Hostname = CopyStr(hostname);
|
||||
|
||||
Add(cache, entry);
|
||||
}
|
||||
|
||||
entry->Expiration = Tick64();
|
||||
|
||||
if (ipv6 != NULL)
|
||||
{
|
||||
if (CmpIpAddr(&entry->IPv6, ipv6) != 0)
|
||||
{
|
||||
Copy(&entry->IPv6, ipv6, sizeof(entry->IPv6));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (CmpIpAddr(&entry->IPv4, ipv4) != 0)
|
||||
{
|
||||
Copy(&entry->IPv4, ipv4, sizeof(entry->IPv4));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
UnlockList(cache);
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
DNS_CACHE_REVERSE *DnsCacheReverseFind(const IP *ip)
|
||||
{
|
||||
if (DnsCacheIsEnabled() == false || ip == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DNS_CACHE_REVERSE *entry;
|
||||
|
||||
LockList(cache_reverse);
|
||||
{
|
||||
DNS_CACHE_REVERSE t;
|
||||
Copy(&t.IP, ip, sizeof(t.IP));
|
||||
entry = Search(cache_reverse, &t);
|
||||
}
|
||||
UnlockList(cache_reverse);
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
DNS_CACHE_REVERSE *DnsCacheReverseUpdate(const IP *ip, const char *hostname)
|
||||
{
|
||||
if (DnsCacheIsEnabled() == false || IsZeroIP(&ip))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DNS_CACHE_REVERSE *entry;
|
||||
|
||||
LockList(cache_reverse);
|
||||
{
|
||||
DNS_CACHE_REVERSE t;
|
||||
Copy(&t.IP, ip, sizeof(t.IP));
|
||||
entry = Search(cache_reverse, &t);
|
||||
|
||||
if (IsEmptyStr(hostname))
|
||||
{
|
||||
if (entry != NULL)
|
||||
{
|
||||
Delete(cache, entry);
|
||||
Free(entry);
|
||||
entry = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (entry == NULL)
|
||||
{
|
||||
entry = ZeroMalloc(sizeof(DNS_CACHE_REVERSE));
|
||||
Copy(&entry->IP, ip, sizeof(entry->IP));
|
||||
|
||||
Add(cache, entry);
|
||||
}
|
||||
|
||||
entry->Expiration = Tick64();
|
||||
|
||||
if (StrCmp(entry->Hostname, hostname) != 0)
|
||||
{
|
||||
Free(entry->Hostname);
|
||||
entry->Hostname = CopyStr(hostname);
|
||||
}
|
||||
}
|
||||
}
|
||||
UnlockList(cache_reverse);
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
bool DnsResolve(IP *ipv6, IP *ipv4, const char *hostname, UINT timeout, volatile const bool *cancel_flag)
|
||||
{
|
||||
if ((ipv6 == NULL && ipv4 == NULL) || IsEmptyStr(hostname))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (StrCmpi(hostname, "localhost") == 0)
|
||||
{
|
||||
GetLocalHostIP6(ipv6);
|
||||
GetLocalHostIP4(ipv4);
|
||||
return true;
|
||||
}
|
||||
|
||||
IP ip;
|
||||
if (StrToIP(&ip, hostname))
|
||||
{
|
||||
if (IsIP6(&ip))
|
||||
{
|
||||
if (ipv6 != NULL)
|
||||
{
|
||||
ZeroIP4(ipv4);
|
||||
Copy(ipv6, &ip, sizeof(IP));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ipv4 != NULL)
|
||||
{
|
||||
Zero(ipv6, sizeof(IP));
|
||||
Copy(ipv4, &ip, sizeof(IP));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (DnsThreadNum() > DnsThreadNumMax())
|
||||
{
|
||||
Debug("DnsResolve(): Too many threads! Current: %u, Maximum: %u\n",
|
||||
DnsThreadNum(), DnsThreadNumMax());
|
||||
|
||||
goto CACHE;
|
||||
}
|
||||
|
||||
if (cancel_flag != NULL && *cancel_flag)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (timeout == 0)
|
||||
{
|
||||
timeout = DNS_RESOLVE_DEFAULT_TIMEOUT;
|
||||
}
|
||||
|
||||
Inc(threads_counter);
|
||||
|
||||
DNS_RESOLVER resolver;
|
||||
Zero(&resolver, sizeof(resolver));
|
||||
ZeroIP4(&resolver.IPv4);
|
||||
resolver.Hostname = hostname;
|
||||
|
||||
THREAD *worker = NewThread(DnsResolver, &resolver);
|
||||
WaitThreadInit(worker);
|
||||
|
||||
if (cancel_flag == NULL)
|
||||
{
|
||||
WaitThread(worker, timeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
const UINT64 end = Tick64() + timeout;
|
||||
|
||||
while (*cancel_flag == false)
|
||||
{
|
||||
const UINT64 now = Tick64();
|
||||
if (now >= end)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
BYTE next = MIN(end - now, 100);
|
||||
if (WaitThread(worker, next))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ReleaseThread(worker);
|
||||
|
||||
Dec(threads_counter);
|
||||
|
||||
if (resolver.OK)
|
||||
{
|
||||
Copy(ipv6, &resolver.IPv6, sizeof(IP));
|
||||
Copy(ipv4, &resolver.IPv4, sizeof(IP));
|
||||
|
||||
DnsCacheUpdate(hostname, ipv6, ipv4);
|
||||
|
||||
return true;
|
||||
}
|
||||
CACHE:
|
||||
Debug("DnsResolve(): Could not resolve \"%s\". Searching for it in the cache...\n", hostname);
|
||||
|
||||
const DNS_CACHE *cached = DnsCacheFind(hostname);
|
||||
if (cached == NULL || cached->Expiration <= Tick64())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Copy(ipv6, &cached->IPv6, sizeof(IP));
|
||||
Copy(ipv4, &cached->IPv4, sizeof(IP));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DnsResolver(THREAD *t, void *param)
|
||||
{
|
||||
if (t == NULL || param == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DNS_RESOLVER *resolver = param;
|
||||
|
||||
NoticeThreadInit(t);
|
||||
AddWaitThread(t);
|
||||
|
||||
struct addrinfo hints;
|
||||
Zero(&hints, sizeof(hints));
|
||||
|
||||
hints.ai_family = AF_INET6;
|
||||
hints.ai_flags = AI_ALL | AI_ADDRCONFIG | AI_V4MAPPED;
|
||||
|
||||
struct addrinfo *result;
|
||||
const int ret = getaddrinfo(resolver->Hostname, NULL, &hints, &result);
|
||||
if (ret == 0)
|
||||
{
|
||||
bool ipv6_ok = false;
|
||||
bool ipv4_ok = false;
|
||||
do
|
||||
{
|
||||
IP ip;
|
||||
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 (ipv4_ok == false)
|
||||
{
|
||||
Copy(&resolver->IPv4, &ip, sizeof(resolver->IPv4));
|
||||
ipv4_ok = true;
|
||||
}
|
||||
|
||||
result = result->ai_next;
|
||||
} while (result != NULL && (ipv6_ok == false || ipv4_ok == false));
|
||||
|
||||
resolver->OK = true;
|
||||
}
|
||||
else if (ret != EAI_NONAME)
|
||||
{
|
||||
Debug("DnsResolver(): getaddrinfo() failed with error %d!\n", ret);
|
||||
}
|
||||
|
||||
DelWaitThread(t);
|
||||
}
|
||||
|
||||
bool DnsResolveReverse(char *dst, const UINT size, const IP *ip, UINT timeout, volatile const bool *cancel_flag)
|
||||
{
|
||||
if (dst == NULL || size == 0 || IsZeroIP(ip))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (DnsThreadNum() > DnsThreadNumMax())
|
||||
{
|
||||
Debug("DnsResolveReverse(): Too many threads! Current: %u, Maximum: %u\n",
|
||||
DnsThreadNum(), DnsThreadNumMax());
|
||||
|
||||
goto CACHE;
|
||||
}
|
||||
|
||||
if (cancel_flag != NULL && *cancel_flag)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (timeout == 0)
|
||||
{
|
||||
timeout = DNS_RESOLVE_REVERSE_DEFAULT_TIMEOUT;
|
||||
}
|
||||
|
||||
Inc(threads_counter);
|
||||
|
||||
DNS_RESOLVER_REVERSE resolver;
|
||||
Zero(&resolver, sizeof(resolver));
|
||||
Copy(&resolver.IP, ip, sizeof(resolver.IP));
|
||||
|
||||
THREAD *worker = NewThread(DnsResolverReverse, &resolver);
|
||||
WaitThreadInit(worker);
|
||||
|
||||
if (cancel_flag == NULL)
|
||||
{
|
||||
WaitThread(worker, timeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
const UINT64 end = Tick64() + timeout;
|
||||
|
||||
while (*cancel_flag == false)
|
||||
{
|
||||
const UINT64 now = Tick64();
|
||||
if (now >= end)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
BYTE next = MIN(end - now, 100);
|
||||
if (WaitThread(worker, next))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ReleaseThread(worker);
|
||||
|
||||
Dec(threads_counter);
|
||||
|
||||
if (resolver.OK)
|
||||
{
|
||||
StrCpy(dst, size, resolver.Hostname);
|
||||
Free(resolver.Hostname);
|
||||
|
||||
DnsCacheReverseUpdate(ip, dst);
|
||||
|
||||
return true;
|
||||
}
|
||||
CACHE:
|
||||
Debug("DnsResolveReverse(): Could not resolve \"%r\". Searching for it in the cache...\n", ip);
|
||||
|
||||
const DNS_CACHE_REVERSE *cached = DnsCacheReverseFind(ip);
|
||||
if (cached == NULL || cached->Expiration <= Tick64())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
StrCpy(dst, size, cached->Hostname);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DnsResolverReverse(THREAD *t, void *param)
|
||||
{
|
||||
if (t == NULL || param == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DNS_RESOLVER_REVERSE *resolver = param;
|
||||
|
||||
NoticeThreadInit(t);
|
||||
AddWaitThread(t);
|
||||
|
||||
struct sockaddr_in6 in;
|
||||
Zero(&in, sizeof(in));
|
||||
in.sin6_family = AF_INET6;
|
||||
IPToInAddr6(&in.sin6_addr, &resolver->IP);
|
||||
|
||||
char tmp[NI_MAXHOST];
|
||||
const int ret = getnameinfo((struct sockaddr *)&in, sizeof(in), tmp, sizeof(tmp), NULL, 0, NI_NAMEREQD);
|
||||
if (ret == 0)
|
||||
{
|
||||
resolver->Hostname = CopyStr(tmp);
|
||||
resolver->OK = true;
|
||||
}
|
||||
else if (ret != EAI_NONAME)
|
||||
{
|
||||
Debug("DnsResolverReverse(): getnameinfo() failed with error %d!\n", ret);
|
||||
}
|
||||
|
||||
DelWaitThread(t);
|
||||
}
|
||||
|
||||
bool GetIPEx(IP *ip, const char *hostname, UINT timeout, volatile const bool *cancel_flag)
|
||||
{
|
||||
if (ip == NULL || IsEmptyStr(hostname))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
IP ipv6, ipv4;
|
||||
if (DnsResolve(&ipv6, &ipv4, hostname, timeout, cancel_flag) == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsZeroIP(&ipv6) == false)
|
||||
{
|
||||
Copy(ip, &ipv6, sizeof(IP));
|
||||
return true;
|
||||
}
|
||||
else if (IsZeroIP(&ipv4) == false)
|
||||
{
|
||||
Copy(ip, &ipv4, sizeof(IP));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
78
src/Mayaqua/DNS.h
Normal file
78
src/Mayaqua/DNS.h
Normal file
@ -0,0 +1,78 @@
|
||||
#ifndef DNS_H
|
||||
#define DNS_H
|
||||
|
||||
#include "Network.h"
|
||||
|
||||
#define DNS_CACHE_EXPIRATION (10 * 60 * 1000)
|
||||
|
||||
#ifndef USE_STRATEGY_LOW_MEMORY
|
||||
#define DNS_THREAD_DEFAULT_NUM_MAX (512)
|
||||
#else
|
||||
#define DNS_THREAD_DEFAULT_NUM_MAX (64)
|
||||
#endif
|
||||
|
||||
#define DNS_RESOLVE_DEFAULT_TIMEOUT (2300)
|
||||
#define DNS_RESOLVE_REVERSE_DEFAULT_TIMEOUT (500)
|
||||
|
||||
#define GetIP(ip, hostname) (GetIPEx(ip, hostname, 0, NULL))
|
||||
#define GetIP4(ip, hostname) (GetIP4Ex(ip, hostname, 0, NULL))
|
||||
#define GetIP6(ip, hostname) (GetIP6Ex(ip, hostname, 0, NULL))
|
||||
|
||||
#define GetIP4Ex(ip, hostname, timeout, cancel_flag) (DnsResolve(NULL, ip, hostname, timeout, cancel_flag))
|
||||
#define GetIP6Ex(ip, hostname, timeout, cancel_flag) (DnsResolve(ip, NULL, hostname, timeout, cancel_flag))
|
||||
|
||||
struct DNS_CACHE
|
||||
{
|
||||
const char *Hostname;
|
||||
IP IPv4;
|
||||
IP IPv6;
|
||||
UINT64 Expiration;
|
||||
};
|
||||
|
||||
struct DNS_CACHE_REVERSE
|
||||
{
|
||||
IP IP;
|
||||
char *Hostname;
|
||||
UINT64 Expiration;
|
||||
};
|
||||
|
||||
struct DNS_RESOLVER
|
||||
{
|
||||
const char *Hostname;
|
||||
IP IPv4;
|
||||
IP IPv6;
|
||||
bool OK;
|
||||
};
|
||||
|
||||
struct DNS_RESOLVER_REVERSE
|
||||
{
|
||||
IP IP;
|
||||
char *Hostname;
|
||||
bool OK;
|
||||
};
|
||||
|
||||
void DnsInit();
|
||||
void DnsFree();
|
||||
|
||||
UINT DnsThreadNum();
|
||||
UINT DnsThreadNumMax();
|
||||
void DnsThreadNumMaxSet(const UINT num);
|
||||
|
||||
bool DnsCacheIsEnabled();
|
||||
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_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);
|
||||
void DnsResolver(THREAD *t, void *param);
|
||||
|
||||
bool DnsResolveReverse(char *dst, const UINT size, const IP *ip, UINT timeout, volatile const bool *cancel_flag);
|
||||
void DnsResolverReverse(THREAD *t, void *param);
|
||||
|
||||
bool GetIPEx(IP *ip, const char *hostname, UINT timeout, volatile const bool *cancel_flag);
|
||||
|
||||
#endif
|
@ -352,7 +352,6 @@ typedef struct LANGLIST LANGLIST;
|
||||
|
||||
// Network.h
|
||||
typedef struct IP IP;
|
||||
typedef struct DNSCACHE DNSCACHE;
|
||||
typedef struct SOCK_EVENT SOCK_EVENT;
|
||||
typedef struct SOCK SOCK;
|
||||
typedef struct SOCKSET SOCKSET;
|
||||
@ -362,7 +361,6 @@ typedef struct ROUTE_TABLE ROUTE_TABLE;
|
||||
typedef struct IP_CLIENT IP_CLIENT;
|
||||
typedef struct ROUTE_CHANGE ROUTE_CHANGE;
|
||||
typedef struct ROUTE_CHANGE_DATA ROUTE_CHANGE_DATA;
|
||||
typedef struct GETIP_THREAD_PARAM GETIP_THREAD_PARAM;
|
||||
typedef struct WIN32_RELEASEADDRESS_THREAD_PARAM WIN32_RELEASEADDRESS_THREAD_PARAM;
|
||||
typedef struct IPV6_ADDR IPV6_ADDR;
|
||||
typedef struct TUBE TUBE;
|
||||
@ -387,8 +385,6 @@ typedef struct TCP_PAIR_HEADER TCP_PAIR_HEADER;
|
||||
typedef struct NIC_ENTRY NIC_ENTRY;
|
||||
typedef struct HTTP_VALUE HTTP_VALUE;
|
||||
typedef struct HTTP_HEADER HTTP_HEADER;
|
||||
typedef struct DNSPROXY_CLIENT DNSPROXY_CLIENT;
|
||||
typedef struct DNSPROXY_CACHE DNSPROXY_CACHE;
|
||||
typedef struct QUERYIPTHREAD QUERYIPTHREAD;
|
||||
typedef struct IPBLOCK IPBLOCK;
|
||||
typedef struct SAFE_REQUEST SAFE_REQUEST;
|
||||
@ -464,4 +460,10 @@ typedef struct HTTP_MIME_TYPE HTTP_MIME_TYPE;
|
||||
typedef struct PROXY_PARAM_IN PROXY_PARAM_IN;
|
||||
typedef struct PROXY_PARAM_OUT PROXY_PARAM_OUT;
|
||||
|
||||
// DNS.h
|
||||
typedef struct DNS_CACHE DNS_CACHE;
|
||||
typedef struct DNS_CACHE_REVERSE DNS_CACHE_REVERSE;
|
||||
typedef struct DNS_RESOLVER DNS_RESOLVER;
|
||||
typedef struct DNS_RESOLVER_REVERSE DNS_RESOLVER_REVERSE;
|
||||
|
||||
#endif // MAYATYPE_H
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -27,20 +27,14 @@ struct DYN_VALUE
|
||||
|
||||
#define MAX_HOST_NAME_LEN 255 // Maximum length of the host name
|
||||
|
||||
#define TIMEOUT_GETIP 2300
|
||||
|
||||
#define TIMEOUT_INFINITE (0x7fffffff)
|
||||
#define TIMEOUT_TCP_PORT_CHECK (10 * 1000)
|
||||
#define TIMEOUT_SSL_CONNECT (15 * 1000)
|
||||
|
||||
#define TIMEOUT_HOSTNAME (500)
|
||||
#define TIMEOUT_NETBIOS_HOSTNAME (100)
|
||||
#define EXPIRES_HOSTNAME (10 * 60 * 1000)
|
||||
|
||||
#define SOCKET_BUFFER_SIZE 0x10000000
|
||||
|
||||
#define IPV6_DUMMY_FOR_IPV4 0xFEFFFFDF
|
||||
|
||||
#define UDPLISTENER_CHECK_INTERVAL 1000ULL
|
||||
#define UDPLISTENER_WAIT_INTERVAL 1234
|
||||
|
||||
@ -48,12 +42,6 @@ struct DYN_VALUE
|
||||
|
||||
#define MAX_NUM_IGNORE_ERRORS 1024
|
||||
|
||||
#ifndef USE_STRATEGY_LOW_MEMORY
|
||||
#define DEFAULT_GETIP_THREAD_MAX_NUM 512
|
||||
#else // USE_STRATEGY_LOW_MEMORY
|
||||
#define DEFAULT_GETIP_THREAD_MAX_NUM 64
|
||||
#endif // USE_STRATEGY_LOW_MEMORY
|
||||
|
||||
#define DEFAULT_CIPHER_LIST "ECDHE+AESGCM:ECDHE+CHACHA20:DHE+AESGCM:DHE+CHACHA20:ECDHE+AES256:DHE+AES256:RSA+AES"
|
||||
|
||||
// SSL logging function
|
||||
@ -115,14 +103,6 @@ struct IPV6_ADDR
|
||||
#define IPV6_ADDR_ZERO 128 // All zeros
|
||||
#define IPV6_ADDR_LOOPBACK 256 // Loop-back
|
||||
|
||||
|
||||
// DNS cache list
|
||||
struct DNSCACHE
|
||||
{
|
||||
char *HostName;
|
||||
IP IpAddress;
|
||||
};
|
||||
|
||||
// Client list
|
||||
struct IP_CLIENT
|
||||
{
|
||||
@ -328,15 +308,6 @@ struct ICMP_RESULT
|
||||
IP IpAddress; // IP address
|
||||
};
|
||||
|
||||
|
||||
// Host name cache list
|
||||
typedef struct HOSTCACHE
|
||||
{
|
||||
UINT64 Expires; // Expiration
|
||||
IP IpAddress; // IP address
|
||||
char HostName[256]; // Host name
|
||||
} HOSTCACHE;
|
||||
|
||||
// NETBIOS name requests
|
||||
typedef struct NBTREQUEST
|
||||
{
|
||||
@ -376,17 +347,6 @@ typedef struct SOCKET_TIMEOUT_PARAM {
|
||||
bool unblocked;
|
||||
} SOCKET_TIMEOUT_PARAM;
|
||||
|
||||
// Parameters for GetIP thread
|
||||
struct GETIP_THREAD_PARAM
|
||||
{
|
||||
REF *Ref;
|
||||
char HostName[MAX_PATH];
|
||||
bool IPv6;
|
||||
UINT Timeout;
|
||||
IP Ip;
|
||||
bool Ok;
|
||||
};
|
||||
|
||||
// Parameters for the IP address release thread
|
||||
struct WIN32_RELEASEADDRESS_THREAD_PARAM
|
||||
{
|
||||
@ -900,7 +860,6 @@ bool GetSniNameFromSslPacket(UCHAR *packet_buf, UINT packet_size, char *sni, UIN
|
||||
|
||||
void SetDhParam(DH_CTX *dh);
|
||||
|
||||
bool IsUseDnsProxy();
|
||||
bool IsUseAlternativeHostname();
|
||||
|
||||
#ifdef OS_WIN32
|
||||
@ -1066,18 +1025,7 @@ void UnixSetSocketNonBlockingMode(int fd, bool nonblock);
|
||||
// Function prototype
|
||||
void InitNetwork();
|
||||
void FreeNetwork();
|
||||
void InitDnsCache();
|
||||
void FreeDnsCache();
|
||||
void LockDnsCache();
|
||||
void UnlockDnsCache();
|
||||
int CompareDnsCache(void *p1, void *p2);
|
||||
void GenDnsCacheKeyName(char *dst, UINT size, char *src, bool ipv6);
|
||||
void NewDnsCacheEx(char *hostname, IP *ip, bool ipv6);
|
||||
DNSCACHE *FindDnsCacheEx(char *hostname, bool ipv6);
|
||||
bool QueryDnsCacheEx(IP *ip, char *hostname, bool ipv6);
|
||||
void NewDnsCache(char *hostname, IP *ip);
|
||||
DNSCACHE *FindDnsCache(char *hostname);
|
||||
bool QueryDnsCache(IP *ip, char *hostname);
|
||||
|
||||
void InAddrToIP(IP *ip, struct in_addr *addr);
|
||||
void InAddrToIP6(IP *ip, struct in6_addr *addr);
|
||||
void IPToInAddr(struct in_addr *addr, IP *ip);
|
||||
@ -1090,24 +1038,7 @@ void IPToStr32(char *str, UINT size, UINT ip);
|
||||
void IPToStr4or6(char *str, UINT size, UINT ip_4_uint, UCHAR *ip_6_bytes);
|
||||
void IPToUniStr(wchar_t *str, UINT size, IP *ip);
|
||||
void IPToUniStr32(wchar_t *str, UINT size, UINT ip);
|
||||
bool GetIPEx(IP *ip, char *hostname, bool ipv6);
|
||||
bool GetIP46Ex(IP *ip4, IP *ip6, char *hostname, UINT timeout, bool *cancel);
|
||||
bool GetIP(IP *ip, char *hostname);
|
||||
bool GetIP4(IP *ip, char *hostname);
|
||||
bool GetIP6(IP *ip, char *hostname);
|
||||
bool GetIP4Ex(IP *ip, char *hostname, UINT timeout, bool *cancel);
|
||||
bool GetIP6Ex(IP *ip, char *hostname, UINT timeout, bool *cancel);
|
||||
bool GetIP4Ex6Ex(IP *ip, char *hostname, UINT timeout, bool ipv6, bool *cancel);
|
||||
bool GetIP4Ex6Ex2(IP *ip, char *hostname, UINT timeout, bool ipv6, bool *cancel, bool only_direct_dns);
|
||||
void GetIP4Ex6ExThread(THREAD *t, void *param);
|
||||
void ReleaseGetIPThreadParam(GETIP_THREAD_PARAM *p);
|
||||
void CleanupGetIPThreadParam(GETIP_THREAD_PARAM *p);
|
||||
bool GetIP4Inner(IP *ip, char *hostname);
|
||||
bool GetIP6Inner(IP *ip, char *hostname);
|
||||
bool GetHostNameInner(char *hostname, UINT size, IP *ip);
|
||||
bool GetHostNameInner6(char *hostname, UINT size, IP *ip);
|
||||
bool GetHostName(char *hostname, UINT size, IP *ip);
|
||||
void GetHostNameThread(THREAD *t, void *p);
|
||||
void GetMachineName(char *name, UINT size);
|
||||
void GetMachineNameEx(char *name, UINT size, bool no_load_hosts);
|
||||
bool GetMachineNameFromHosts(char *name, UINT size);
|
||||
@ -1212,11 +1143,6 @@ void InitWaitThread();
|
||||
void FreeWaitThread();
|
||||
void AddWaitThread(THREAD *t);
|
||||
void DelWaitThread(THREAD *t);
|
||||
void InitHostCache();
|
||||
void FreeHostCache();
|
||||
int CompareHostCache(void *p1, void *p2);
|
||||
void AddHostCache(IP *ip, char *hostname);
|
||||
bool GetHostCache(char *hostname, UINT size, IP *ip);
|
||||
bool IsSubnetMask(IP *ip);
|
||||
bool IsSubnetMask4(IP *ip);
|
||||
bool IsSubnetMask32(UINT ip);
|
||||
@ -1245,9 +1171,6 @@ IP_CLIENT *SearchIpClient(IP *ip);
|
||||
UINT GetNumIpClient(IP *ip);
|
||||
void SetLinuxArpFilter();
|
||||
int connect_timeout(SOCKET s, struct sockaddr *addr, int size, int timeout, bool *cancel_flag);
|
||||
void EnableNetworkNameCache();
|
||||
void DisableNetworkNameCache();
|
||||
bool IsNetworkNameCacheEnabled();
|
||||
ROUTE_CHANGE *NewRouteChange();
|
||||
void FreeRouteChange(ROUTE_CHANGE *r);
|
||||
bool IsRouteChanged(ROUTE_CHANGE *r);
|
||||
@ -1466,10 +1389,6 @@ QUERYIPTHREAD *NewQueryIpThread(char *hostname, UINT interval_last_ok, UINT inte
|
||||
bool GetQueryIpThreadResult(QUERYIPTHREAD *t, IP *ip);
|
||||
void FreeQueryIpThread(QUERYIPTHREAD *t);
|
||||
|
||||
void SetGetIpThreadMaxNum(UINT num);
|
||||
UINT GetGetIpThreadMaxNum();
|
||||
UINT GetCurrentGetIpThreadNum();
|
||||
|
||||
#ifdef OS_WIN32
|
||||
LIST *Win32GetNicList();
|
||||
#endif // OS_WIN32
|
||||
|
@ -3,6 +3,7 @@
|
||||
// TODO: Mayaqua should not depend on Cedar.
|
||||
#include "Cedar/WinUi.h"
|
||||
|
||||
#include "DNS.h"
|
||||
#include "Memory.h"
|
||||
#include "Str.h"
|
||||
|
||||
@ -550,8 +551,8 @@ UINT ProxySocks4Connect(PROXY_PARAM_OUT *out, PROXY_PARAM_IN *in, volatile bool
|
||||
|
||||
Zero(out, sizeof(PROXY_PARAM_OUT));
|
||||
|
||||
// Get the IP address of the destination server
|
||||
if (GetIP(&target_ip, in->TargetHostname) == false)
|
||||
// Get the IPv4 address of the destination server (SOCKS4 does not support IPv6).
|
||||
if (GetIP4(&target_ip, in->TargetHostname) == false)
|
||||
{
|
||||
return PROXY_ERROR_CONNECTION;
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "Table.h"
|
||||
|
||||
#include "Cfg.h"
|
||||
#include "DNS.h"
|
||||
#include "FileIO.h"
|
||||
#include "Internat.h"
|
||||
#include "Mayaqua.h"
|
||||
@ -1206,9 +1207,9 @@ bool LoadUnicodeCache(wchar_t *strfilename, UINT strfilesize, UCHAR *hash)
|
||||
Zero(&c, sizeof(c));
|
||||
UniToStr(c.StrFileName, sizeof(c.StrFileName), strfilename);
|
||||
c.StrFileSize = strfilesize;
|
||||
DisableNetworkNameCache();
|
||||
DnsCacheToggle(false);
|
||||
GetMachineName(c.MachineName, sizeof(c.MachineName));
|
||||
EnableNetworkNameCache();
|
||||
DnsCacheToggle(true);
|
||||
c.OsType = GetOsInfo()->OsType;
|
||||
Copy(c.hash, hash, MD5_SIZE);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user