1
0
mirror of https://github.com/SoftEtherVPN/SoftEtherVPN.git synced 2025-07-06 07:44:57 +03:00

v4.12-9514-beta

This commit is contained in:
dnobori
2014-11-18 12:05:48 +09:00
parent 2b3a4d0b75
commit 75f9836ce5
301 changed files with 1259 additions and 317 deletions

View File

@ -229,6 +229,8 @@ static LOCK *host_ip_address_list_cache_lock = NULL;
static UINT64 host_ip_address_list_cache_last = 0;
static LIST *host_ip_address_cache = NULL;
static bool disable_gethostname_by_accept = false;
static COUNTER *getip_thread_counter = NULL;
static UINT max_getip_thread = 0;
static char *cipher_list = "RC4-MD5 RC4-SHA AES128-SHA AES256-SHA DES-CBC-SHA DES-CBC3-SHA DHE-RSA-AES128-SHA DHE-RSA-AES256-SHA";
@ -2005,6 +2007,17 @@ bool RUDPIsIpInValidateList(RUDP_STACK *r, IP *ip)
return false;
}
// Always allow private IP addresses
if (IsIPPrivate(ip))
{
return true;
}
if (IsIPAddressInSameLocalNetwork(ip))
{
return true;
}
for (i = 0;i < LIST_NUM(r->NatT_SourceIpList);i++)
{
RUDP_SOURCE_IP *s = (RUDP_SOURCE_IP *)LIST_DATA(r->NatT_SourceIpList, i);
@ -4350,6 +4363,7 @@ void RUDPIpQueryThread(THREAD *thread, void *param)
void *route_change_poller = NULL;
char current_hostname[MAX_SIZE];
bool last_time_ip_changed = false;
UINT num_retry = 0;
// Validate arguments
if (thread == NULL || param == NULL)
{
@ -4429,7 +4443,9 @@ void RUDPIpQueryThread(THREAD *thread, void *param)
if (IsZeroIp(&r->NatT_IP))
{
next_getip_tick = now + (UINT64)UDP_NAT_T_GET_IP_INTERVAL;
num_retry++;
next_getip_tick = now + MIN((UINT64)UDP_NAT_T_GET_IP_INTERVAL * (UINT64)num_retry, (UINT64)UDP_NAT_T_GET_IP_INTERVAL_MAX);
}
else
{
@ -6730,6 +6746,46 @@ bool IsInSameNetwork4(IP *a1, IP *a2, IP *subnet)
return false;
}
bool IsInSameNetwork4Standard(IP *a1, IP *a2)
{
IP subnet;
SetIP(&subnet, 255, 255, 0, 0);
return IsInSameNetwork4(a1, a2, &subnet);
}
bool IsInSameLocalNetworkToMe4(IP *a)
{
IP g1, g2;
Zero(&g1, sizeof(g1));
Zero(&g2, sizeof(g2));
GetCurrentGlobalIPGuess(&g1, false);
if (IsZeroIp(&g1) == false)
{
if (IsInSameNetwork4Standard(&g1, a))
{
return true;
}
}
if (GetCurrentGlobalIP(&g2, false))
{
if (IsInSameNetwork4Standard(&g2, a))
{
return true;
}
}
if (IsIPAddressInSameLocalNetwork(a))
{
return true;
}
return false;
}
// Check whether it is a network address prefix
bool IsNetworkAddress6(IP *ip, IP *subnet)
@ -10926,6 +10982,20 @@ void InitHostCache()
HostCacheList = NewList(CompareHostCache);
}
// Get the number of wait threads
UINT GetNumWaitThread()
{
UINT ret = 0;
LockList(WaitThreadList);
{
ret = LIST_NUM(WaitThreadList);
}
UnlockList(WaitThreadList);
return ret;
}
// Add the thread to the thread waiting list
void AddWaitThread(THREAD *t)
{
@ -16631,6 +16701,8 @@ void GetIP4Ex6ExThread(THREAD *t, void *param)
ReleaseGetIPThreadParam(p);
DelWaitThread(t);
Dec(getip_thread_counter);
}
// Perform a forward DNS query (with timeout)
@ -16645,9 +16717,13 @@ bool GetIP4Ex6Ex2(IP *ip, char *hostname_arg, UINT timeout, bool ipv6, bool *can
bool ret = false;
UINT64 start_tick = 0;
UINT64 end_tick = 0;
UINT64 spent_time = 0;
UINT64 now;
UINT n;
bool use_dns_proxy = false;
char hostname[260];
UINT i;
bool timed_out;
// Validate arguments
if (ip == NULL || hostname_arg == NULL)
{
@ -16718,6 +16794,89 @@ bool GetIP4Ex6Ex2(IP *ip, char *hostname_arg, UINT timeout, bool ipv6, bool *can
}
// check the quota
start_tick = Tick64();
end_tick = start_tick + (UINT64)timeout;
n = 0;
timed_out = false;
while (true)
{
UINT64 now = Tick64();
UINT64 remain;
UINT remain32;
if (GetGetIpThreadMaxNum() > GetCurrentGetIpThreadNum())
{
// below the quota
break;
}
if (now >= end_tick)
{
// timeouted
timed_out = true;
break;
}
if (cancel != NULL && (*cancel))
{
// cancelled
timed_out = true;
break;
}
remain = end_tick - now;
remain32 = MIN((UINT)remain, 100);
SleepThread(remain32);
n++;
}
now = Tick64();
spent_time = now - start_tick;
if (n == 0)
{
spent_time = 0;
}
if ((UINT)spent_time >= timeout)
{
timed_out = true;
}
if (timed_out)
{
IP ip2;
// timed out, cancelled
if (QueryDnsCache(&ip2, hostname))
{
ret = true;
Copy(ip, &ip2, sizeof(IP));
}
Debug("GetIP4Ex6Ex2: Worker thread quota exceeded: max=%u current=%u\n",
GetGetIpThreadMaxNum(), GetCurrentGetIpThreadNum());
return ret;
}
// Increment the counter
Inc(getip_thread_counter);
if (spent_time != 0)
{
Debug("GetIP4Ex6Ex2: Waited for %u msecs to create a worker thread.\n",
spent_time);
}
timeout -= (UINT)spent_time;
p = ZeroMalloc(sizeof(GETIP_THREAD_PARAM));
p->Ref = NewRef();
StrCpy(p->HostName, sizeof(p->HostName), hostname);
@ -16774,6 +16933,7 @@ bool GetIP4Ex6Ex2(IP *ip, char *hostname_arg, UINT timeout, bool ipv6, bool *can
{
IP ip2;
#if 0
if (only_direct_dns == false)
{
if (ipv6)
@ -16802,6 +16962,7 @@ bool GetIP4Ex6Ex2(IP *ip, char *hostname_arg, UINT timeout, bool ipv6, bool *can
}
}
}
#endif
if (QueryDnsCache(&ip2, hostname))
{
@ -17457,6 +17618,27 @@ void FreeSSLCtx(struct ssl_ctx_st *ctx)
SSL_CTX_free(ctx);
}
// The number of get ip threads
void SetGetIpThreadMaxNum(UINT num)
{
max_getip_thread = num;
}
UINT GetGetIpThreadMaxNum()
{
UINT ret = max_getip_thread;
if (ret == 0)
{
ret = 0x7FFFFFFF;
}
return ret;
}
UINT GetCurrentGetIpThreadNum()
{
return Count(getip_thread_counter);
}
// Initialize the network communication module
void InitNetwork()
{
@ -17471,6 +17653,8 @@ void InitNetwork()
num_tcp_connections = NewCounter();
getip_thread_counter = NewCounter();
// Initialization of client list
InitIpClientList();
@ -17515,6 +17699,8 @@ void InitNetwork()
dh_1024 = DhNewGroup2();
Zero(rand_port_numbers, sizeof(rand_port_numbers));
SetGetIpThreadMaxNum(DEFAULT_GETIP_THREAD_MAX_NUM);
}
// Enable the network name cache
@ -17770,6 +17956,45 @@ void FreePrivateIPFile()
g_use_privateip_file = false;
}
// Check whether the specified IP address is in the same network to this computer
bool IsIPAddressInSameLocalNetwork(IP *a)
{
bool ret = false;
LIST *o;
UINT i;
// Validate arguments
if (a == NULL)
{
return false;
}
o = GetHostIPAddressList();
if (o != NULL)
{
for (i = 0;i < LIST_NUM(o);i++)
{
IP *p = LIST_DATA(o, i);
if (IsIP4(p))
{
if (IsZeroIp(p) == false && p->addr[0] != 127)
{
if (IsInSameNetwork4Standard(p, a))
{
ret = true;
break;
}
}
}
}
FreeHostIPAddressList(o);
}
return ret;
}
// Guess the IPv4, IPv6 global address from the IP address list of the current interface
void GetCurrentGlobalIPGuess(IP *ip, bool ipv6)
{
@ -17950,6 +18175,9 @@ void FreeNetwork()
FreeDynList();
DeleteCounter(getip_thread_counter);
getip_thread_counter = NULL;
}
// Add a socket to socket list
@ -19114,6 +19342,46 @@ int CmpIpAddressList(void *p1, void *p2)
return r;
}
// Get the IP address list hash of the host
UINT64 GetHostIPAddressListHash()
{
UINT i;
LIST *o;
BUF *buf = NewBuf();
UCHAR hash[SHA1_SIZE];
UINT64 ret = 0;
o = GetHostIPAddressList();
if (o != NULL)
{
for (i = 0;i < LIST_NUM(o);i++)
{
IP *ip = LIST_DATA(o, i);
char tmp[128];
Zero(tmp, sizeof(tmp));
IPToStr(tmp, sizeof(tmp), ip);
WriteBufStr(buf, tmp);
}
FreeHostIPAddressList(o);
}
WriteBufStr(buf, "test");
HashSha1(hash, buf->Buf, buf->Size);
FreeBuf(buf);
Copy(&ret, hash, sizeof(UINT64));
ret = Endian64(ret);
return ret;
}
// Get the IP address list of the host (using cache)
LIST *GetHostIPAddressList()
{

View File

@ -147,6 +147,13 @@ 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
// SSL logging function
//#define ENABLE_SSL_LOGGING
#define SSL_LOGGING_DIRNAME "@ssl_log"
@ -748,6 +755,7 @@ struct RUDP_SESSION
// Related to processing to get the IP address of the NAT-T server
#define UDP_NAT_T_GET_IP_INTERVAL DYN32(UDP_NAT_T_GET_IP_INTERVAL, (5 * 1000)) // IP address acquisition interval of NAT-T server (before success)
#define UDP_NAT_T_GET_IP_INTERVAL_MAX DYN32(UDP_NAT_T_GET_IP_INTERVAL, (150 * 1000)) // IP address acquisition interval of NAT-T server (before success)
#define UDP_NAT_T_GET_IP_INTERVAL_AFTER DYN32(UDP_NAT_T_GET_IP_INTERVAL_AFTER, (5 * 60 * 1000)) // IP address acquisition interval of NAT-T server (after success)
// Related to process to get the private IP address of itself with making a TCP connection to the NAT-T server
@ -1418,6 +1426,7 @@ void RouteToStr(char *str, UINT str_size, ROUTE_ENTRY *e);
void DebugPrintRoute(ROUTE_ENTRY *e);
void DebugPrintRouteTable(ROUTE_TABLE *r);
bool IsIPv6LocalNetworkAddress(IP *ip);
UINT GetNumWaitThread();
#ifdef ENABLE_SSL_LOGGING
void SockEnableSslLogging(SOCK *s);
@ -1484,6 +1493,8 @@ void IPNot4(IP *dst, IP *a);
void IPOr4(IP *dst, IP *a, IP *b);
void IPAnd4(IP *dst, IP *a, IP *b);
bool IsInSameNetwork4(IP *a1, IP *a2, IP *subnet);
bool IsInSameNetwork4Standard(IP *a1, IP *a2);
bool IsInSameLocalNetworkToMe4(IP *a);
bool ParseIpAndSubnetMask4(char *src, UINT *ip, UINT *mask);
bool ParseIpAndSubnetMask6(char *src, IP *ip, IP *mask);
@ -1539,6 +1550,7 @@ bool IsMyIPAddress(IP *ip);
void FreeHostIPAddressList(LIST *o);
void AddHostIPAddressToList(LIST *o, IP *ip);
int CmpIpAddressList(void *p1, void *p2);
UINT64 GetHostIPAddressListHash();
UDPLISTENER *NewUdpListener(UDPLISTENER_RECV_PROC *recv_proc, void *param);
void UdpListenerThread(THREAD *thread, void *param);
@ -1599,6 +1611,7 @@ bool SslBioSync(SSL_BIO *b, bool sync_send, bool sync_recv);
void SetCurrentGlobalIP(IP *ip, bool ipv6);
bool GetCurrentGlobalIP(IP *ip, bool ipv6);
void GetCurrentGlobalIPGuess(IP *ip, bool ipv6);
bool IsIPAddressInSameLocalNetwork(IP *a);
bool IsIPPrivate(IP *ip);
bool IsIPMyHost(IP *ip);
@ -1631,6 +1644,11 @@ 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();
bool IsIpInStrList(IP *ip, char *ip_list);
bool IsInStrByStrList(char *str, char *str_list);

View File

@ -3304,11 +3304,44 @@ BUF *BuildDhcpOptionsBuf(LIST *o)
for (i = 0;i < LIST_NUM(o);i++)
{
DHCP_OPTION *d = LIST_DATA(o, i);
UINT current_size = d->Size;
UINT current_pos = 0;
id = (UCHAR)d->Id;
sz = (UCHAR)d->Size;
if (d->Size <= 255)
{
sz = (UCHAR)d->Size;
}
else
{
sz = 0xFF;
}
WriteBuf(b, &id, 1);
WriteBuf(b, &sz, 1);
WriteBuf(b, d->Data, d->Size);
WriteBuf(b, d->Data, sz);
current_size -= sz;
current_pos += sz;
while (current_size != 0)
{
id = DHCP_ID_PRIVATE;
if (current_size <= 255)
{
sz = (UCHAR)current_size;
}
else
{
sz = 0xFF;
}
WriteBuf(b, &id, 1);
WriteBuf(b, &sz, 1);
WriteBuf(b, ((UCHAR *)d->Data) + current_pos, sz);
current_size -= sz;
current_pos += sz;
}
}
id = 0xff;
@ -3755,27 +3788,24 @@ BUF *DhcpBuildClasslessRouteData(DHCP_CLASSLESS_ROUTE_TABLE *t)
if (r->Exists && r->SubnetMaskLen <= 32)
{
if (b->Size <= (255 - 9))
{
UCHAR c;
UINT data_len;
UINT ip32;
UCHAR tmp[4];
UCHAR c;
UINT data_len;
UINT ip32;
UCHAR tmp[4];
// Width of subnet mask
c = (UCHAR)r->SubnetMaskLen;
WriteBuf(b, &c, 1);
// Width of subnet mask
c = (UCHAR)r->SubnetMaskLen;
WriteBuf(b, &c, 1);
// Number of significant octets
data_len = (r->SubnetMaskLen + 7) / 8;
Zero(tmp, sizeof(tmp));
Copy(tmp, &r->Network, data_len);
WriteBuf(b, tmp, data_len);
// Number of significant octets
data_len = (r->SubnetMaskLen + 7) / 8;
Zero(tmp, sizeof(tmp));
Copy(tmp, &r->Network, data_len);
WriteBuf(b, tmp, data_len);
// Gateway
ip32 = IPToUINT(&r->Gateway);
WriteBuf(b, &ip32, sizeof(UINT));
}
// Gateway
ip32 = IPToUINT(&r->Gateway);
WriteBuf(b, &ip32, sizeof(UINT));
}
}
@ -3965,6 +3995,7 @@ LIST *ParseDhcpOptions(void *data, UINT size)
{
BUF *b;
LIST *o;
DHCP_OPTION *last_opt;
// Validate arguments
if (data == NULL)
{
@ -3977,6 +4008,8 @@ LIST *ParseDhcpOptions(void *data, UINT size)
o = NewListFast(NULL);
last_opt = NULL;
while (true)
{
UCHAR c = 0;
@ -3995,12 +4028,27 @@ LIST *ParseDhcpOptions(void *data, UINT size)
break;
}
opt = ZeroMalloc(sizeof(DHCP_OPTION));
opt->Id = (UINT)c;
opt->Size = (UINT)sz;
opt->Data = ZeroMalloc((UINT)sz);
ReadBuf(b, opt->Data, sz);
Add(o, opt);
if (c == DHCP_ID_PRIVATE && last_opt != NULL)
{
UINT new_size = last_opt->Size + (UINT)sz;
UCHAR *new_buf = ZeroMalloc(new_size);
Copy(new_buf, last_opt->Data, last_opt->Size);
ReadBuf(b, new_buf + last_opt->Size, sz);
Free(last_opt->Data);
last_opt->Data = new_buf;
last_opt->Size = new_size;
}
else
{
opt = ZeroMalloc(sizeof(DHCP_OPTION));
opt->Id = (UINT)c;
opt->Size = (UINT)sz;
opt->Data = ZeroMalloc((UINT)sz);
ReadBuf(b, opt->Data, sz);
Add(o, opt);
last_opt = opt;
}
}
FreeBuf(b);

View File

@ -625,6 +625,7 @@ struct ICMPV6_HEADER_INFO
#define DHCP_ID_REQ_PARAM_LIST 0x37
#define DHCP_ID_CLASSLESS_ROUTE 0x79
#define DHCP_ID_MS_CLASSLESS_ROUTE 0xF9
#define DHCP_ID_PRIVATE 0xFA
// DHCP client action