1 // SoftEther VPN Source Code - Stable Edition Repository
2 // Mayaqua Kernel
3 //
4 // SoftEther VPN Server, Client and Bridge are free software under the Apache License, Version 2.0.
5 //
6 // Copyright (c) Daiyuu Nobori.
7 // Copyright (c) SoftEther VPN Project, University of Tsukuba, Japan.
8 // Copyright (c) SoftEther Corporation.
9 // Copyright (c) all contributors on SoftEther VPN project in GitHub.
10 //
11 // All Rights Reserved.
12 //
13 // http://www.softether.org/
14 //
15 // This stable branch is officially managed by Daiyuu Nobori, the owner of SoftEther VPN Project.
16 // Pull requests should be sent to the Developer Edition Master Repository on https://github.com/SoftEtherVPN/SoftEtherVPN
17 // Contributors:
18 // - nattoheaven (https://github.com/nattoheaven)
19 //
20 // License: The Apache License, Version 2.0
21 // https://www.apache.org/licenses/LICENSE-2.0
22 //
23 // DISCLAIMER
24 // ==========
25 //
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
29 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
30 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
31 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32 // SOFTWARE.
33 //
34 // THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN, UNDER
35 // JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY, MERGE, PUBLISH,
36 // DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS SOFTWARE, THAT ANY
37 // JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS SOFTWARE OR ITS CONTENTS,
38 // AGAINST US (SOFTETHER PROJECT, SOFTETHER CORPORATION, DAIYUU NOBORI OR OTHER
39 // SUPPLIERS), OR ANY JURIDICAL DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND
40 // OF USING, COPYING, MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING,
41 // AND/OR SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
42 // CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO EXCLUSIVE
43 // JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO, JAPAN. YOU MUST WAIVE
44 // ALL DEFENSES OF LACK OF PERSONAL JURISDICTION AND FORUM NON CONVENIENS.
45 // PROCESS MAY BE SERVED ON EITHER PARTY IN THE MANNER AUTHORIZED BY APPLICABLE
46 // LAW OR COURT RULE.
47 //
48 // USE ONLY IN JAPAN. DO NOT USE THIS SOFTWARE IN ANOTHER COUNTRY UNLESS YOU HAVE
49 // A CONFIRMATION THAT THIS SOFTWARE DOES NOT VIOLATE ANY CRIMINAL LAWS OR CIVIL
50 // RIGHTS IN THAT PARTICULAR COUNTRY. USING THIS SOFTWARE IN OTHER COUNTRIES IS
51 // COMPLETELY AT YOUR OWN RISK. THE SOFTETHER VPN PROJECT HAS DEVELOPED AND
52 // DISTRIBUTED THIS SOFTWARE TO COMPLY ONLY WITH THE JAPANESE LAWS AND EXISTING
53 // CIVIL RIGHTS INCLUDING PATENTS WHICH ARE SUBJECTS APPLY IN JAPAN. OTHER
54 // COUNTRIES' LAWS OR CIVIL RIGHTS ARE NONE OF OUR CONCERNS NOR RESPONSIBILITIES.
55 // WE HAVE NEVER INVESTIGATED ANY CRIMINAL REGULATIONS, CIVIL LAWS OR
56 // INTELLECTUAL PROPERTY RIGHTS INCLUDING PATENTS IN ANY OF OTHER 200+ COUNTRIES
57 // AND TERRITORIES. BY NATURE, THERE ARE 200+ REGIONS IN THE WORLD, WITH
58 // DIFFERENT LAWS. IT IS IMPOSSIBLE TO VERIFY EVERY COUNTRIES' LAWS, REGULATIONS
59 // AND CIVIL RIGHTS TO MAKE THE SOFTWARE COMPLY WITH ALL COUNTRIES' LAWS BY THE
60 // PROJECT. EVEN IF YOU WILL BE SUED BY A PRIVATE ENTITY OR BE DAMAGED BY A
61 // PUBLIC SERVANT IN YOUR COUNTRY, THE DEVELOPERS OF THIS SOFTWARE WILL NEVER BE
62 // LIABLE TO RECOVER OR COMPENSATE SUCH DAMAGES, CRIMINAL OR CIVIL
63 // RESPONSIBILITIES. NOTE THAT THIS LINE IS NOT LICENSE RESTRICTION BUT JUST A
64 // STATEMENT FOR WARNING AND DISCLAIMER.
65 //
66 // READ AND UNDERSTAND THE 'WARNING.TXT' FILE BEFORE USING THIS SOFTWARE.
67 // SOME SOFTWARE PROGRAMS FROM THIRD PARTIES ARE INCLUDED ON THIS SOFTWARE WITH
68 // LICENSE CONDITIONS WHICH ARE DESCRIBED ON THE 'THIRD_PARTY.TXT' FILE.
69 //
70 //
71 // SOURCE CODE CONTRIBUTION
72 // ------------------------
73 //
74 // Your contribution to SoftEther VPN Project is much appreciated.
75 // Please send patches to us through GitHub.
76 // Read the SoftEther VPN Patch Acceptance Policy in advance:
77 // http://www.softether.org/5-download/src/9.patch
78 //
79 //
80 // DEAR SECURITY EXPERTS
81 // ---------------------
82 //
83 // If you find a bug or a security vulnerability please kindly inform us
84 // about the problem immediately so that we can fix the security problem
85 // to protect a lot of users around the world as soon as possible.
86 //
87 // Our e-mail address for security reports is:
88 // softether-vpn-security [at] softether.org
89 //
90 // Please note that the above e-mail address is not a technical support
91 // inquiry address. If you need technical assistance, please visit
92 // http://www.softether.org/ and ask your question on the users forum.
93 //
94 // Thank you for your cooperation.
95 //
96 //
97 // NO MEMORY OR RESOURCE LEAKS
98 // ---------------------------
99 //
100 // The memory-leaks and resource-leaks verification under the stress
101 // test has been passed before release this source code.
102 
103 
104 // Network.c
105 // Network communication module
106 
107 #include <GlobalConst.h>
108 
109 #define	ENCRYPT_C
110 #define	NETWORK_C
111 
112 #define	__WINCRYPT_H__
113 
114 #ifdef	WIN32
115 // Include windows.h for Socket API
116 #define	_WIN32_WINNT		0x0502
117 #define	WINVER				0x0502
118 #include <Ws2tcpip.h>
119 #include <Wspiapi.h>
120 #include <winsock2.h>
121 #include <windows.h>
122 #include <Iphlpapi.h>
123 #include <ws2ipdef.h>
124 #include <netioapi.h>
125 #include <Icmpapi.h>
126 #endif	// WIN32
127 
128 #include <stdio.h>
129 #include <stdlib.h>
130 #include <string.h>
131 #include <wchar.h>
132 #include <stdarg.h>
133 #include <time.h>
134 #include <openssl/ssl.h>
135 #include <openssl/err.h>
136 #include <openssl/rand.h>
137 #include <openssl/engine.h>
138 #include <openssl/bio.h>
139 #include <openssl/x509.h>
140 #include <openssl/pkcs7.h>
141 #include <openssl/pkcs12.h>
142 #include <openssl/rc4.h>
143 #include <openssl/md5.h>
144 #include <openssl/sha.h>
145 #include <Mayaqua/Mayaqua.h>
146 #ifdef	UNIX_MACOS
147 #include <sys/event.h>
148 #endif	// UNIX_MACOS
149 
150 #ifdef	OS_WIN32
151 NETWORK_WIN32_FUNCTIONS *w32net;
152 struct ROUTE_CHANGE_DATA
153 {
154 	OVERLAPPED Overlapped;
155 	HANDLE Handle;
156 	UINT NumCalled;
157 };
158 #endif	// OS_WIN32
159 
160 // Whether the blocking occurs in SSL
161 #if	defined(UNIX_BSD) || defined(UNIX_MACOS)
162 #define	FIX_SSL_BLOCKING
163 #endif
164 
165 // IPV6_V6ONLY constant
166 #ifdef	UNIX_LINUX
167 #ifndef	IPV6_V6ONLY
168 #define	IPV6_V6ONLY	26
169 #endif	// IPV6_V6ONLY
170 #endif	// UNIX_LINUX
171 
172 #ifdef	UNIX_SOLARIS
173 #ifndef	IPV6_V6ONLY
174 #define	IPV6_V6ONLY	0x27
175 #endif	// IPV6_V6ONLY
176 #endif	// UNIX_SOLARIS
177 
178 
179 
180 // HTTP constant
181 static char http_404_str[] = "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n<HTML><HEAD>\r\n<TITLE>404 Not Found</TITLE>\r\n</HEAD><BODY>\r\n<H1>Not Found</H1>\r\nThe requested URL $TARGET$ was not found on this server.<P>\r\n<HR>\r\n<ADDRESS>HTTP Server at $HOST$ Port $PORT$</ADDRESS>\r\n</BODY></HTML>\r\n";
182 static char http_403_str[] = "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n<HTML><HEAD>\r\n<TITLE>403 Forbidden</TITLE>\r\n</HEAD><BODY>\r\n<H1>Forbidden</H1>\r\nYou don't have permission to access $TARGET$\r\non this server.<P>\r\n<HR>\r\n<ADDRESS>HTTP Server at $HOST$ Port $PORT$</ADDRESS>\r\n</BODY></HTML>\r\n";
183 static char http_500_str[] = "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n<HTML><HEAD>\r\n<TITLE>500 Server Error</TITLE>\r\n</HEAD><BODY>\r\n<H1>Server Error</H1>\r\nServer Error<P>\r\n<HR>\r\n<ADDRESS>HTTP Server at $HOST$ Port $PORT$</ADDRESS>\r\n</BODY></HTML>\r\n";
184 static char http_501_str[] = "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n<HTML><HEAD>\r\n<TITLE>501 Method Not Implemented</TITLE>\r\n</HEAD><BODY>\r\n<H1>Method Not Implemented</H1>\r\n$METHOD$ to $TARGET$ not supported.<P>\r\nInvalid method in request $METHOD$ $TARGET$ $VERSION$<P>\r\n<HR>\r\n<ADDRESS>HTTP Server at $HOST$ Port $PORT$</ADDRESS>\r\n</BODY></HTML>\r\n";
185 static char http_detect_server_startwith[] = "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n<HTML><HEAD>\r\n<TITLE>403 Forbidden</TITLE>\r\n</HEAD><BODY>\r\n<H1>Forbidden</H1>\r\nYou don't have permission to access ";
186 static char http_detect_server_tag_future[] = "9C37197CA7C2428388C2E6E59B829B30";
187 
188 // DNS cache list
189 static LIST *DnsCache;
190 
191 // Lock related
192 static LOCK *machine_name_lock = NULL;
193 static LOCK *disconnect_function_lock = NULL;
194 static LOCK *aho = NULL;
195 static LOCK *socket_library_lock = NULL;
196 extern LOCK *openssl_lock;
197 static LOCK *ssl_accept_lock = NULL;
198 static LOCK *ssl_connect_lock = NULL;
199 static TOKEN_LIST *cipher_list_token = NULL;
200 static COUNTER *num_tcp_connections = NULL;
201 static LOCK *dns_lock = NULL;
202 static LOCK *unix_dns_server_addr_lock = NULL;
203 static IP unix_dns_server;
204 static LIST *HostCacheList = NULL;
205 static LIST *WaitThreadList = NULL;
206 static bool disable_cache = false;
207 static bool NetworkReleaseMode = false;			// Network release mode
208 static UCHAR machine_ip_process_hash[SHA1_SIZE];
209 static LOCK *machine_ip_process_hash_lock = NULL;
210 static LOCK *current_global_ip_lock = NULL;
211 static LOCK *current_fqdn_lock = NULL;
212 static bool current_global_ip_set = false;
213 static IP current_glocal_ipv4 = {0};
214 static IP current_glocal_ipv6 = {0};
215 static char current_fqdn[MAX_SIZE];
216 static bool g_no_rudp_server = false;
217 static bool g_no_rudp_register = false;
218 static bool g_natt_low_priority = false;
219 static LOCK *host_ip_address_list_cache_lock = NULL;
220 static UINT64 host_ip_address_list_cache_last = 0;
221 static LIST *host_ip_address_cache = NULL;
222 static bool disable_gethostname_by_accept = false;
223 static COUNTER *getip_thread_counter = NULL;
224 static UINT max_getip_thread = 0;
225 
226 
227 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 AES128-GCM-SHA256 AES128-SHA256 AES256-GCM-SHA384 AES256-SHA256 DHE-RSA-AES128-GCM-SHA256 DHE-RSA-AES128-SHA256 DHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES256-SHA256 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-SHA256 ECDHE-RSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-SHA384"
228 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
229 	" DHE-RSA-CHACHA20-POLY1305 ECDHE-RSA-CHACHA20-POLY1305";
230 #endif
231 ;
232 
233 static LIST *ip_clients = NULL;
234 
235 static LIST *local_mac_list = NULL;
236 static LOCK *local_mac_list_lock = NULL;
237 
238 static UINT rand_port_numbers[256] = {0};
239 
240 
241 static bool g_use_privateip_file = false;
242 static bool g_source_ip_validation_force_disable = false;
243 
244 static DH_CTX *dh_2048 = NULL;
245 
246 typedef struct PRIVATE_IP_SUBNET
247 {
248 	UINT Ip, Mask, Ip2;
249 } PRIVATE_IP_SUBNET;
250 
251 static LIST *g_private_ip_list = NULL;
252 
253 
254 static LIST *g_dyn_value_list = NULL;
255 
256 
257 
258 //#define	RUDP_DETAIL_LOG
259 
260 
261 
262 
263 // Get a value from a dynamic value list (Returns a default value if the value is not found)
GetDynValueOrDefault(char * name,UINT64 default_value,UINT64 min_value,UINT64 max_value)264 UINT64 GetDynValueOrDefault(char *name, UINT64 default_value, UINT64 min_value, UINT64 max_value)
265 {
266 	UINT64 ret = GetDynValue(name);
267 
268 	if (ret == 0)
269 	{
270 		return default_value;
271 	}
272 
273 	if (ret < min_value)
274 	{
275 		ret = min_value;
276 	}
277 
278 	if (ret > max_value)
279 	{
280 		ret = max_value;
281 	}
282 
283 	return ret;
284 }
285 
286 // Get a value from a dynamic value list (Returns a default value if the value is not found)
287 // The value is limited to 1/5 to 50 times of the default value for safety
GetDynValueOrDefaultSafe(char * name,UINT64 default_value)288 UINT64 GetDynValueOrDefaultSafe(char *name, UINT64 default_value)
289 {
290 	return GetDynValueOrDefault(name, default_value, default_value / (UINT64)5, default_value * (UINT64)50);
291 }
292 
293 // Get a value from a dynamic value list
GetDynValue(char * name)294 UINT64 GetDynValue(char *name)
295 {
296 	UINT64 ret = 0;
297 	// Validate arguments
298 	if (name == NULL)
299 	{
300 		return 0;
301 	}
302 
303 	if (g_dyn_value_list == NULL)
304 	{
305 		return 0;
306 	}
307 
308 	LockList(g_dyn_value_list);
309 	{
310 		UINT i;
311 
312 		for (i = 0; i < LIST_NUM(g_dyn_value_list);i++)
313 		{
314 			DYN_VALUE *vv = LIST_DATA(g_dyn_value_list, i);
315 
316 			if (StrCmpi(vv->Name, name) == 0)
317 			{
318 				ret = vv->Value;
319 				break;
320 			}
321 		}
322 	}
323 	UnlockList(g_dyn_value_list);
324 
325 	return ret;
326 }
327 
328 // Set the value to the dynamic value list
SetDynListValue(char * name,UINT64 value)329 void SetDynListValue(char *name, UINT64 value)
330 {
331 	// Validate arguments
332 	if (name == NULL)
333 	{
334 		return;
335 	}
336 
337 	if (g_dyn_value_list == NULL)
338 	{
339 		return;
340 	}
341 
342 	LockList(g_dyn_value_list);
343 	{
344 		UINT i;
345 		DYN_VALUE *v = NULL;
346 
347 		for (i = 0; i < LIST_NUM(g_dyn_value_list);i++)
348 		{
349 			DYN_VALUE *vv = LIST_DATA(g_dyn_value_list, i);
350 
351 			if (StrCmpi(vv->Name, name) == 0)
352 			{
353 				v = vv;
354 				break;
355 			}
356 		}
357 
358 		if (v == NULL)
359 		{
360 			v = ZeroMalloc(sizeof(DYN_VALUE));
361 			StrCpy(v->Name, sizeof(v->Name), name);
362 
363 			Add(g_dyn_value_list, v);
364 		}
365 
366 		v->Value = value;
367 	}
368 	UnlockList(g_dyn_value_list);
369 }
370 
371 // Apply by extracting dynamic value list from the specified PACK
ExtractAndApplyDynList(PACK * p)372 void ExtractAndApplyDynList(PACK *p)
373 {
374 	BUF *b;
375 	// Validate arguments
376 	if (p == NULL)
377 	{
378 		return;
379 	}
380 
381 	b = PackGetBuf(p, "DynList");
382 	if (b == NULL)
383 	{
384 		return;
385 	}
386 
387 	AddDynList(b);
388 
389 	FreeBuf(b);
390 }
391 
392 // Insert the data to the dynamic value list
AddDynList(BUF * b)393 void AddDynList(BUF *b)
394 {
395 	PACK *p;
396 	TOKEN_LIST *t;
397 	// Validate arguments
398 	if (b == NULL)
399 	{
400 		return;
401 	}
402 
403 	SeekBufToBegin(b);
404 
405 	p = BufToPack(b);
406 	if (p == NULL)
407 	{
408 		return;
409 	}
410 
411 	t = GetPackElementNames(p);
412 	if (t != NULL)
413 	{
414 		UINT i;
415 
416 		for (i = 0;i < t->NumTokens;i++)
417 		{
418 			char *name = t->Token[i];
419 			UINT64 v = PackGetInt64(p, name);
420 
421 			SetDynListValue(name, v);
422 		}
423 
424 		FreeToken(t);
425 	}
426 
427 	FreePack(p);
428 }
429 
430 // Initialization of the dynamic value list
InitDynList()431 void InitDynList()
432 {
433 	g_dyn_value_list = NewList(NULL);
434 }
435 
436 // Solution of dynamic value list
FreeDynList()437 void FreeDynList()
438 {
439 	UINT i;
440 	if (g_dyn_value_list == NULL)
441 	{
442 		return;
443 	}
444 
445 	for (i = 0;i < LIST_NUM(g_dyn_value_list);i++)
446 	{
447 		DYN_VALUE *d = LIST_DATA(g_dyn_value_list, i);
448 
449 		Free(d);
450 	}
451 
452 	ReleaseList(g_dyn_value_list);
453 
454 	g_dyn_value_list = NULL;
455 }
456 
457 // Check whether the string in the string list appears in the specified string
IsInStrByStrList(char * str,char * str_list)458 bool IsInStrByStrList(char *str, char *str_list)
459 {
460 	TOKEN_LIST *t;
461 	bool ret = false;
462 	// Validate arguments
463 	if (str == NULL || str_list == NULL)
464 	{
465 		return false;
466 	}
467 
468 	t = ParseTokenWithoutNullStr(str_list, ", \t\r\n");
469 	if (t != NULL)
470 	{
471 		UINT i;
472 
473 		for (i = 0;i < t->NumTokens;i++)
474 		{
475 			char *s = t->Token[i];
476 
477 			if (StrLen(s) >= 1)
478 			{
479 				if (InStrEx(str, s, true))
480 				{
481 					ret = true;
482 					break;
483 				}
484 			}
485 		}
486 	}
487 
488 	FreeToken(t);
489 
490 	return ret;
491 }
492 
493 
494 // Search whether the IP address exists on the IP address list string
IsIpInStrList(IP * ip,char * ip_list)495 bool IsIpInStrList(IP *ip, char *ip_list)
496 {
497 	char ip_str[128];
498 	TOKEN_LIST *t;
499 	bool ret = false;
500 	// Validate arguments
501 	if (ip == NULL || ip_list == NULL)
502 	{
503 		return false;
504 	}
505 
506 	Zero(ip_str, sizeof(ip_str));
507 	IPToStr(ip_str, sizeof(ip_str), ip);
508 
509 	t = ParseTokenWithoutNullStr(ip_list, ", \t\r\n");
510 
511 	if (t != NULL)
512 	{
513 		UINT i;
514 
515 		for (i = 0;i < t->NumTokens;i++)
516 		{
517 			char *s = t->Token[i];
518 
519 			if (StrCmpi(s, ip_str) == 0)
520 			{
521 				ret = true;
522 				break;
523 			}
524 		}
525 	}
526 
527 	FreeToken(t);
528 
529 	return ret;
530 }
531 
532 
533 // Disable NAT-T function globally
DisableRDUPServerGlobally()534 void DisableRDUPServerGlobally()
535 {
536 	g_no_rudp_server = true;
537 }
538 
539 // Disable NAT-T registration globally
DisableRUDPRegisterGlobally()540 void DisableRUDPRegisterGlobally()
541 {
542 	g_no_rudp_register = true;
543 }
544 
545 // Lower the priority of the host at NAT-T
SetNatTLowPriority()546 void SetNatTLowPriority()
547 {
548 	g_natt_low_priority = true;
549 }
550 
551 // Extract only the host name part from FQDN
GetSimpleHostname(char * hostname,UINT hostname_size,char * fqdn)552 void GetSimpleHostname(char *hostname, UINT hostname_size, char *fqdn)
553 {
554 	UINT i;
555 	ClearStr(hostname, hostname_size);
556 	// Validate arguments
557 	if (hostname == NULL || fqdn == NULL)
558 	{
559 		return;
560 	}
561 
562 	StrCpy(hostname, hostname_size, fqdn);
563 	Trim(hostname);
564 
565 	i = SearchStrEx(hostname, ".", 0, true);
566 	if (i != INFINITE)
567 	{
568 		hostname[i] = 0;
569 	}
570 }
571 
572 // Get the current time zone
GetCurrentTimezone()573 int GetCurrentTimezone()
574 {
575 	int ret = 0;
576 
577 #ifdef	OS_WIN32
578 	ret = GetCurrentTimezoneWin32();
579 #else	// OS_WIN32
580 	{
581 #if	defined(UNIX_MACOS) || defined(UNIX_BSD)
582 		struct timeval tv;
583 		struct timezone tz;
584 
585 		Zero(&tv, sizeof(tv));
586 		Zero(&tz, sizeof(tz));
587 
588 		gettimeofday(&tv, &tz);
589 
590 		ret = tz.tz_minuteswest;
591 
592 #else	// defined(UNIX_MACOS) || defined(UNIX_BSD)
593 		tzset();
594 
595 		ret = timezone / 60;
596 #endif	// defined(UNIX_MACOS) || defined(UNIX_BSD)
597 	}
598 #endif	// OS_WIN32
599 
600 	return ret;
601 }
602 
603 // Flag of whether to use the DNS proxy
IsUseDnsProxy()604 bool IsUseDnsProxy()
605 {
606 	return false;
607 }
608 
609 // Flag of whether to use an alternate host name
IsUseAlternativeHostname()610 bool IsUseAlternativeHostname()
611 {
612 
613 	return false;
614 }
615 
616 #ifdef	OS_WIN32
617 // Get the current time zone (Win32)
GetCurrentTimezoneWin32()618 int GetCurrentTimezoneWin32()
619 {
620 	TIME_ZONE_INFORMATION info;
621 	Zero(&info, sizeof(info));
622 
623 	if (GetTimeZoneInformation(&info) == TIME_ZONE_ID_INVALID)
624 	{
625 		return 0;
626 	}
627 
628 	return info.Bias;
629 }
630 #endif	// OS_WIN32
631 
632 
633 // Set the current FQDN of the DDNS
SetCurrentDDnsFqdn(char * name)634 void SetCurrentDDnsFqdn(char *name)
635 {
636 	// Validate arguments
637 	if (name == NULL)
638 	{
639 		return;
640 	}
641 
642 	Lock(current_fqdn_lock);
643 	{
644 		StrCpy(current_fqdn, sizeof(current_fqdn), name);
645 	}
646 	Unlock(current_fqdn_lock);
647 }
648 
649 // Get the current DDNS FQDN hash
GetCurrentDDnsFqdnHash()650 UINT GetCurrentDDnsFqdnHash()
651 {
652 	UINT ret;
653 	UCHAR hash[SHA1_SIZE];
654 	char name[MAX_SIZE];
655 
656 	ClearStr(name, sizeof(name));
657 	GetCurrentDDnsFqdn(name, sizeof(name));
658 
659 	Trim(name);
660 	StrUpper(name);
661 
662 	HashSha1(hash, name, StrLen(name));
663 
664 	Copy(&ret, hash, sizeof(UINT));
665 
666 	return ret;
667 }
668 
669 // Get the current DDNS FQDN
GetCurrentDDnsFqdn(char * name,UINT size)670 void GetCurrentDDnsFqdn(char *name, UINT size)
671 {
672 	ClearStr(name, size);
673 	// Validate arguments
674 	if (name == NULL || size == 0)
675 	{
676 		return;
677 	}
678 
679 	Lock(current_fqdn_lock);
680 	{
681 		StrCpy(name, size, current_fqdn);
682 	}
683 	Unlock(current_fqdn_lock);
684 
685 	Trim(name);
686 }
687 
688 // Check whether the specified MAC address exists on the local host (high speed)
IsMacAddressLocalFast(void * addr)689 bool IsMacAddressLocalFast(void *addr)
690 {
691 	bool ret = false;
692 	// Validate arguments
693 	if (addr == NULL)
694 	{
695 		return false;
696 	}
697 
698 	Lock(local_mac_list_lock);
699 	{
700 		if (local_mac_list == NULL)
701 		{
702 			// First enumeration
703 			RefreshLocalMacAddressList();
704 		}
705 
706 		ret = IsMacAddressLocalInner(local_mac_list, addr);
707 	}
708 	Unlock(local_mac_list_lock);
709 
710 	return ret;
711 }
712 
713 // Update the local MAC address list
RefreshLocalMacAddressList()714 void RefreshLocalMacAddressList()
715 {
716 	Lock(local_mac_list_lock);
717 	{
718 		if (local_mac_list != NULL)
719 		{
720 			FreeNicList(local_mac_list);
721 		}
722 
723 		local_mac_list = GetNicList();
724 	}
725 	Unlock(local_mac_list_lock);
726 }
727 
728 // Check whether the specified MAC address exists on the local host
IsMacAddressLocal(void * addr)729 bool IsMacAddressLocal(void *addr)
730 {
731 	LIST *o;
732 	bool ret;
733 	// Validate arguments
734 	if (addr == NULL)
735 	{
736 		return false;
737 	}
738 
739 	o = GetNicList();
740 
741 	ret = IsMacAddressLocalInner(o, addr);
742 
743 	FreeNicList(o);
744 
745 	return ret;
746 }
IsMacAddressLocalInner(LIST * o,void * addr)747 bool IsMacAddressLocalInner(LIST *o, void *addr)
748 {
749 	bool ret = false;
750 	UINT i;
751 	// Validate arguments
752 	if (o == NULL || addr == NULL)
753 	{
754 		return false;
755 	}
756 
757 	for (i = 0;i < LIST_NUM(o);i++)
758 	{
759 		NIC_ENTRY *e = LIST_DATA(o, i);
760 
761 		if (Cmp(e->MacAddress, addr, 6) == 0)
762 		{
763 			ret = true;
764 			break;
765 		}
766 	}
767 
768 	return ret;
769 }
770 
771 // Get a list of the NICs on the computer
GetNicList()772 LIST *GetNicList()
773 {
774 	LIST *o = NULL;
775 
776 #ifdef	OS_WIN32
777 	o = Win32GetNicList();
778 #endif	// OS_WIN32
779 
780 #ifdef	UNIX_LINUX
781 #endif	// UNIX_LINUX
782 
783 	if (o == NULL)
784 	{
785 		return NewListFast(NULL);
786 	}
787 
788 	return o;
789 }
790 
791 #ifdef	OS_WIN32
Win32GetNicList()792 LIST *Win32GetNicList()
793 {
794 	UINT i;
795 	LIST *o = NewListFast(NULL);
796 	MS_ADAPTER_LIST *al = MsCreateAdapterList();
797 
798 	if (al == NULL)
799 	{
800 		return NULL;
801 	}
802 
803 	for (i = 0;i < al->Num;i++)
804 	{
805 		MS_ADAPTER *a = al->Adapters[i];
806 
807 		if (a->Type == 6 && a->AddressSize == 6)
808 		{
809 			NIC_ENTRY *e = ZeroMalloc(sizeof(NIC_ENTRY));
810 
811 			StrCpy(e->IfName, sizeof(e->IfName), a->Title);
812 			Copy(e->MacAddress, a->Address, 6);
813 
814 			Add(o, e);
815 		}
816 	}
817 
818 	MsFreeAdapterList(al);
819 
820 	return o;
821 }
822 #endif	// OS_WIN32
823 
824 // Release the NIC list
FreeNicList(LIST * o)825 void FreeNicList(LIST *o)
826 {
827 	UINT i;
828 	// Validate arguments
829 	if (o == NULL)
830 	{
831 		return;
832 	}
833 
834 	for (i = 0;i < LIST_NUM(o);i++)
835 	{
836 		NIC_ENTRY *e = LIST_DATA(o, i);
837 
838 		Free(e);
839 	}
840 
841 	ReleaseList(o);
842 }
843 
844 // If the computer is connected to the FLET'S line currently, detect the type of the line (obsolete)
DetectFletsType()845 UINT DetectFletsType()
846 {
847 	UINT ret = 0;
848 	//LIST *o = GetHostIPAddressList();
849 //	UINT i;
850 
851 /*
852 	for (i = 0;i < LIST_NUM(o);i++)
853 	{
854 		IP *ip = LIST_DATA(o, i);
855 
856 		if (IsIP6(ip))
857 		{
858 			char ip_str[MAX_SIZE];
859 
860 			IPToStr(ip_str, sizeof(ip_str), ip);
861 
862 			if (IsInSameNetwork6ByStr(ip_str, "2001:c90::", "/32"))
863 			{
864 				// NTT East B-FLETs
865 				ret |= FLETS_DETECT_TYPE_EAST_BFLETS_PRIVATE;
866 			}
867 
868 			if (IsInSameNetwork6ByStr(ip_str, "2408:200::", "/23"))
869 			{
870 				// Wrapping in network of NTT East NGN
871 				ret |= FLETS_DETECT_TYPE_EAST_NGN_PRIVATE;
872 			}
873 
874 			if (IsInSameNetwork6ByStr(ip_str, "2001:a200::", "/23"))
875 			{
876 				// Wrapping in network of NTT West NGN
877 				ret |= FLETS_DETECT_TYPE_WEST_NGN_PRIVATE;
878 			}
879 		}
880 	}
881 
882 	FreeHostIPAddressList(o);
883 */
884 	return ret;
885 }
886 
887 // Query for the IP address using the DNS proxy for the B FLETs
GetIPViaDnsProxyForJapanFlets(IP * ip_ret,char * hostname,bool ipv6,UINT timeout,bool * cancel,char * dns_proxy_hostname)888 bool GetIPViaDnsProxyForJapanFlets(IP *ip_ret, char *hostname, bool ipv6, UINT timeout, bool *cancel, char *dns_proxy_hostname)
889 {
890 	SOCK *s;
891 	char connect_hostname[MAX_SIZE];
892 	char connect_hostname2[MAX_SIZE];
893 	IP dns_proxy_ip;
894 	bool ret = false;
895 	bool dummy_flag = false;
896 	char request_str[512];
897 	// Validate arguments
898 	if (ip_ret == NULL || hostname == NULL)
899 	{
900 		return false;
901 	}
902 	if (timeout == 0)
903 	{
904 		timeout = BFLETS_DNS_PROXY_TIMEOUT_FOR_QUERY;
905 	}
906 	if (cancel == NULL)
907 	{
908 		cancel = &dummy_flag;
909 	}
910 
911 	// Get the IP address of the DNS proxy server
912 	if (IsEmptyStr(dns_proxy_hostname))
913 	{
914 		// B FLETs
915 		if (GetDnsProxyIPAddressForJapanBFlets(&dns_proxy_ip, BFLETS_DNS_PROXY_TIMEOUT_FOR_GET_F, cancel) == false)
916 		{
917 			return false;
918 		}
919 	}
920 	else
921 	{
922 		// FLET'S NEXT
923 		if (GetIP4Ex6Ex2(&dns_proxy_ip, dns_proxy_hostname, FLETS_NGN_DNS_QUERY_TIMEOUT, true, cancel, true) == false)
924 		{
925 			return false;
926 		}
927 	}
928 
929 	if (*cancel)
930 	{
931 		return false;
932 	}
933 
934 	IPToStr(connect_hostname, sizeof(connect_hostname), &dns_proxy_ip);
935 
936 	/*{
937 		StrCpy(connect_hostname, sizeof(connect_hostname), "2409:250:62c0:100:6a05:caff:fe09:5158");
938 	}*/
939 
940 	StrCpy(connect_hostname2, sizeof(connect_hostname2), connect_hostname);
941 	if (IsIP6(&dns_proxy_ip))
942 	{
943 		Format(connect_hostname2, sizeof(connect_hostname2), "[%s]", connect_hostname);
944 	}
945 
946 	s = ConnectEx3(connect_hostname, BFLETS_DNS_PROXY_PORT, timeout, cancel, NULL, NULL, false, false, false);
947 
948 	if (s == NULL)
949 	{
950 		return false;
951 	}
952 
953 	if (*cancel)
954 	{
955 		Disconnect(s);
956 		ReleaseSock(s);
957 
958 		return false;
959 	}
960 
961 	SetTimeout(s, timeout);
962 
963 	// Start the SSL
964 	if (StartSSLEx(s, NULL, NULL, true, 0, NULL) && (*cancel == false))
965 	{
966 		UCHAR hash[SHA1_SIZE];
967 		BUF *hash2 = StrToBin(BFLETS_DNS_PROXY_CERT_HASH);
968 
969 		Zero(hash, sizeof(hash));
970 		GetXDigest(s->RemoteX, hash, true);
971 
972 		if (Cmp(hash, hash2->Buf, SHA1_SIZE) == 0)
973 		{
974 			// Send the HTTP Request
975 			Format(request_str, sizeof(request_str),
976 				"GET " BFLETS_DNS_PROXY_PATH "?q=%s&ipv6=%u\r\n"
977 				"\r\n",
978 				hostname, ipv6, connect_hostname2);
979 
980 			if (SendAll(s, request_str, StrLen(request_str), true))
981 			{
982 				if (*cancel == false)
983 				{
984 					BUF *recv_buf = NewBuf();
985 					UINT port_ret;
986 
987 					while (true)
988 					{
989 						UCHAR tmp[MAX_SIZE];
990 						UINT r;
991 
992 						r = Recv(s, tmp, sizeof(tmp), true);
993 
994 						if (r == 0 || (recv_buf->Size > 65536))
995 						{
996 							break;
997 						}
998 						else
999 						{
1000 							WriteBuf(recv_buf, tmp, r);
1001 						}
1002 					}
1003 
1004 					ret = RUDPParseIPAndPortStr(recv_buf->Buf, recv_buf->Size, ip_ret, &port_ret);
1005 
1006 					FreeBuf(recv_buf);
1007 				}
1008 			}
1009 		}
1010 
1011 		FreeBuf(hash2);
1012 	}
1013 
1014 	Disconnect(s);
1015 	ReleaseSock(s);
1016 
1017 	if (ret)
1018 	{
1019 		NewDnsCache(hostname, ip_ret);
1020 	}
1021 
1022 	return ret;
1023 }
1024 
1025 // Get the IP address of the available DNS proxy in B-FLET'S service that is provided by NTT East of Japan
GetDnsProxyIPAddressForJapanBFlets(IP * ip_ret,UINT timeout,bool * cancel)1026 bool GetDnsProxyIPAddressForJapanBFlets(IP *ip_ret, UINT timeout, bool *cancel)
1027 {
1028 	BUF *b;
1029 	LIST *o;
1030 	bool ret = false;
1031 	// Validate arguments
1032 	if (ip_ret == NULL)
1033 	{
1034 		return false;
1035 	}
1036 	if (timeout == 0)
1037 	{
1038 		timeout = BFLETS_DNS_PROXY_TIMEOUT_FOR_GET_F;
1039 	}
1040 
1041 	b = QueryFileByUdpForJapanBFlets(timeout, cancel);
1042 
1043 	if (b == NULL)
1044 	{
1045 		return false;
1046 	}
1047 
1048 	o = ReadIni(b);
1049 
1050 	if (o != NULL)
1051 	{
1052 		INI_ENTRY *e = GetIniEntry(o, "DDnsServerForBFlets");
1053 
1054 		if (e != NULL)
1055 		{
1056 			char *s = e->Value;
1057 
1058 			if (IsEmptyStr(s) == false)
1059 			{
1060 				IP ip;
1061 
1062 				if (StrToIP(&ip, s))
1063 				{
1064 					if (IsZeroIp(&ip) == false)
1065 					{
1066 						Copy(ip_ret, &ip, sizeof(IP));
1067 						ret = true;
1068 					}
1069 				}
1070 			}
1071 		}
1072 	}
1073 
1074 	FreeIni(o);
1075 	FreeBuf(b);
1076 
1077 	return ret;
1078 }
1079 
1080 // Get a valid F.txt file in B-FLET'S service that is provided by NTT East of Japan
QueryFileByUdpForJapanBFlets(UINT timeout,bool * cancel)1081 BUF *QueryFileByUdpForJapanBFlets(UINT timeout, bool *cancel)
1082 {
1083 	bool dummy_flag = false;
1084 	BUF *txt_buf = NULL;
1085 	BUF *ret = NULL;
1086 	LIST *ip_list = NULL;
1087 	UINT i;
1088 	// Validate arguments
1089 	if (cancel == NULL)
1090 	{
1091 		cancel = &dummy_flag;
1092 	}
1093 	if (timeout == 0)
1094 	{
1095 		timeout = BFLETS_DNS_PROXY_TIMEOUT_FOR_GET_F;
1096 	}
1097 
1098 	txt_buf = ReadDump(UDP_FILE_QUERY_BFLETS_TXT_FILENAME);
1099 	if (txt_buf == NULL)
1100 	{
1101 		return NULL;
1102 	}
1103 
1104 	ip_list = NewListFast(NULL);
1105 
1106 	while (true)
1107 	{
1108 		char *line = CfgReadNextLine(txt_buf);
1109 		if (line == NULL)
1110 		{
1111 			break;
1112 		}
1113 
1114 		Trim(line);
1115 
1116 		if (IsEmptyStr(line) == false && StartWith(line, "#") == false)
1117 		{
1118 			IP ip;
1119 
1120 			if (StrToIP6(&ip, line))
1121 			{
1122 				if (IsZeroIp(&ip) == false)
1123 				{
1124 					if (IsIPv6LocalNetworkAddress(&ip) == false)
1125 					{
1126 						Add(ip_list, Clone(&ip, sizeof(IP)));
1127 					}
1128 				}
1129 			}
1130 		}
1131 
1132 		Free(line);
1133 	}
1134 
1135 	FreeBuf(txt_buf);
1136 
1137 	ret = QueryFileByIPv6Udp(ip_list, timeout, cancel);
1138 
1139 	for (i = 0;i < LIST_NUM(ip_list);i++)
1140 	{
1141 		IP *ip = LIST_DATA(ip_list, i);
1142 
1143 		Free(ip);
1144 	}
1145 
1146 	ReleaseList(ip_list);
1147 
1148 	return ret;
1149 }
1150 
1151 // Request a file by UDP (send the requests to the multiple IP addresses at the same time)
QueryFileByIPv6Udp(LIST * ip_list,UINT timeout,bool * cancel)1152 BUF *QueryFileByIPv6Udp(LIST *ip_list, UINT timeout, bool *cancel)
1153 {
1154 	bool dummy_flag = false;
1155 	UINT64 start_tick, giveup_tick;
1156 	UINT64 next_send_tick;
1157 	SOCK *s;
1158 	INTERRUPT_MANAGER *interrupt;
1159 	BUF *buf = NULL;
1160 	SOCK_EVENT *se;
1161 	UCHAR *tmp_buf;
1162 	UINT tmp_buf_size = 65535;
1163 	// Validate arguments
1164 	if (cancel == NULL)
1165 	{
1166 		cancel = &dummy_flag;
1167 	}
1168 	if (ip_list == NULL)
1169 	{
1170 		return NULL;
1171 	}
1172 
1173 	s = NewUDP6(0, NULL);
1174 	if (s == NULL)
1175 	{
1176 		return NULL;
1177 	}
1178 
1179 	tmp_buf = Malloc(tmp_buf_size);
1180 
1181 	start_tick = Tick64();
1182 	giveup_tick = start_tick + (UINT64)timeout;
1183 	next_send_tick = 0;
1184 
1185 	interrupt = NewInterruptManager();
1186 
1187 	AddInterrupt(interrupt, giveup_tick);
1188 
1189 	se = NewSockEvent();
1190 	JoinSockToSockEvent(s, se);
1191 
1192 	while (true)
1193 	{
1194 		UINT64 now = Tick64();
1195 
1196 		if (now >= giveup_tick)
1197 		{
1198 			// Time-out
1199 			break;
1200 		}
1201 
1202 		if (*cancel)
1203 		{
1204 			// User canceled
1205 			break;
1206 		}
1207 
1208 		// Receive
1209 		while (true)
1210 		{
1211 			IP src_ip;
1212 			UINT src_port;
1213 			UINT r;
1214 
1215 			r = RecvFrom(s, &src_ip, &src_port, tmp_buf, tmp_buf_size);
1216 
1217 			if (r == SOCK_LATER || r == 0)
1218 			{
1219 				break;
1220 			}
1221 
1222 			if (src_port == UDP_FILE_QUERY_DST_PORT)
1223 			{
1224 				if (r >= 40)
1225 				{
1226 					if (Cmp(tmp_buf, UDP_FILE_QUERY_MAGIC_NUMBER, StrLen(UDP_FILE_QUERY_MAGIC_NUMBER)) == 0)
1227 					{
1228 						// Successful reception
1229 						buf = NewBuf();
1230 						WriteBuf(buf, tmp_buf, r);
1231 						SeekBuf(buf, 0, 0);
1232 						break;
1233 					}
1234 				}
1235 			}
1236 		}
1237 
1238 		if (buf != NULL)
1239 		{
1240 			// Successful reception
1241 			break;
1242 		}
1243 
1244 		if (next_send_tick == 0 || (now >= next_send_tick))
1245 		{
1246 			// Transmission
1247 			UINT i;
1248 			for (i = 0;i < LIST_NUM(ip_list);i++)
1249 			{
1250 				IP *ip = LIST_DATA(ip_list, i);
1251 				UCHAR c = 'F';
1252 
1253 				SendTo(s, ip, UDP_FILE_QUERY_DST_PORT, &c, 1);
1254 			}
1255 
1256 			next_send_tick = now + (UINT64)UDP_FILE_QUERY_RETRY_INTERVAL;
1257 			AddInterrupt(interrupt, next_send_tick);
1258 		}
1259 
1260 		WaitSockEvent(se, GetNextIntervalForInterrupt(interrupt));
1261 	}
1262 
1263 	FreeInterruptManager(interrupt);
1264 
1265 	Disconnect(s);
1266 	ReleaseSock(s);
1267 
1268 	ReleaseSockEvent(se);
1269 
1270 	Free(tmp_buf);
1271 
1272 	return buf;
1273 }
1274 
1275 // Parse the user name of the NT
ParseNtUsername(char * src_username,char * dst_username,UINT dst_username_size,char * dst_domain,UINT dst_domain_size,bool do_not_parse_atmark)1276 void ParseNtUsername(char *src_username, char *dst_username, UINT dst_username_size, char *dst_domain, UINT dst_domain_size, bool do_not_parse_atmark)
1277 {
1278 	char tmp_username[MAX_SIZE];
1279 	char tmp_domain[MAX_SIZE];
1280 	TOKEN_LIST *t;
1281 
1282 	if (src_username != dst_username)
1283 	{
1284 		ClearStr(dst_username, dst_username_size);
1285 	}
1286 
1287 	ClearStr(dst_domain, dst_domain_size);
1288 	// Validate arguments
1289 	if (src_username == NULL || dst_username == NULL || dst_domain == NULL)
1290 	{
1291 		return;
1292 	}
1293 
1294 	StrCpy(tmp_username, sizeof(tmp_username), src_username);
1295 	ClearStr(tmp_domain, sizeof(tmp_domain));
1296 
1297 	// Analysis of username@domain.name format
1298 	if (do_not_parse_atmark == false)
1299 	{
1300 		t = ParseTokenWithNullStr(tmp_username, "@");
1301 		if (t->NumTokens >= 1)
1302 		{
1303 			StrCpy(tmp_username, sizeof(tmp_username), t->Token[0]);
1304 		}
1305 		if (t->NumTokens >= 2)
1306 		{
1307 			StrCpy(tmp_domain, sizeof(tmp_domain), t->Token[1]);
1308 		}
1309 		FreeToken(t);
1310 	}
1311 
1312 	// If the username part is in "domain\username" format, split it
1313 	t = ParseTokenWithNullStr(tmp_username, "\\");
1314 	if (t->NumTokens >= 2)
1315 	{
1316 		if (IsEmptyStr(tmp_domain))
1317 		{
1318 			StrCpy(tmp_domain, sizeof(tmp_domain), t->Token[0]);
1319 		}
1320 
1321 		StrCpy(tmp_username, sizeof(tmp_username), t->Token[1]);
1322 	}
1323 	FreeToken(t);
1324 
1325 	StrCpy(dst_username, dst_username_size, tmp_username);
1326 	StrCpy(dst_domain, dst_domain_size, tmp_domain);
1327 }
1328 
1329 // The calculation of the optimum MSS value for use in TCP/IP packet in the payload of bulk transfer in R-UDP session
RUDPCalcBestMssForBulk(RUDP_STACK * r,RUDP_SESSION * se)1330 UINT RUDPCalcBestMssForBulk(RUDP_STACK *r, RUDP_SESSION *se)
1331 {
1332 	UINT ret;
1333 	// Validate arguments
1334 	if (r == NULL || se == NULL)
1335 	{
1336 		return 0;
1337 	}
1338 
1339 	ret = MTU_FOR_PPPOE;
1340 
1341 	// IPv4
1342 	if (IsIP6(&se->YourIp) == false)
1343 	{
1344 		ret -= 20;
1345 	}
1346 	else
1347 	{
1348 		ret -= 40;
1349 	}
1350 
1351 	if (r->Protocol == RUDP_PROTOCOL_ICMP)
1352 	{
1353 		// ICMP
1354 		ret -= 8;
1355 
1356 		ret -= SHA1_SIZE;
1357 	}
1358 	else if (r->Protocol == RUDP_PROTOCOL_DNS)
1359 	{
1360 		// UDP
1361 		ret -= 8;
1362 
1363 		// DNS
1364 		ret -= 42;
1365 	}
1366 
1367 	// IV
1368 	ret -= SHA1_SIZE;
1369 
1370 	// Sign
1371 	ret -= SHA1_SIZE;
1372 
1373 	// SEQ_NO
1374 	ret -= sizeof(UINT64);
1375 
1376 	// Padding Max
1377 	ret -= 31;
1378 
1379 	// Ethernet header (target packets of communication)
1380 	ret -= 14;
1381 
1382 	// IPv4 Header (target packet of communication)
1383 	ret -= 20;
1384 
1385 	// TCP header (target packet of communication)
1386 	ret -= 20;
1387 
1388 	// I don't know well, but subtract 24 bytes
1389 	ret -= 24;
1390 
1391 	return ret;
1392 }
1393 
1394 // Processing of the reply packet from the NAT-T server
RUDPProcess_NatT_Recv(RUDP_STACK * r,UDPPACKET * udp)1395 void RUDPProcess_NatT_Recv(RUDP_STACK *r, UDPPACKET *udp)
1396 {
1397 	BUF *b;
1398 	PACK *p;
1399 	// Validate arguments
1400 	if (r == NULL || udp == NULL)
1401 	{
1402 		return;
1403 	}
1404 
1405 	if (udp->Size >= 8)
1406 	{
1407 		char tmp[128];
1408 
1409 		Zero(tmp, sizeof(tmp));
1410 		Copy(tmp, udp->Data, MIN(udp->Size, sizeof(tmp) - 1));
1411 
1412 		if (StartWith(tmp, "IP="))
1413 		{
1414 			IP my_ip;
1415 			UINT my_port;
1416 
1417 			// There was a response to the packet to determine the NAT state
1418 			if (IsEmptyStr(r->NatT_Registered_IPAndPort) == false)
1419 			{
1420 				if (StrCmpi(r->NatT_Registered_IPAndPort, tmp) != 0)
1421 				{
1422 					// Redo getting the token and registration because the NAT state is changed
1423 					ClearStr(r->NatT_Registered_IPAndPort, sizeof(r->NatT_Registered_IPAndPort));
1424 
1425 					r->NatT_GetTokenNextTick = 0;
1426 					r->NatT_GetTokenFailNum = 0;
1427 					r->NatT_Token_Ok = false;
1428 					Zero(r->NatT_Token, sizeof(r->NatT_Token));
1429 
1430 					r->NatT_RegisterNextTick = 0;
1431 					r->NatT_RegisterFailNum = 0;
1432 					r->NatT_Register_Ok = false;
1433 				}
1434 			}
1435 
1436 			if (RUDPParseIPAndPortStr(udp->Data, udp->Size, &my_ip, &my_port))
1437 			{
1438 				if (r->NatTGlobalUdpPort != NULL)
1439 				{
1440 					*r->NatTGlobalUdpPort = my_port;
1441 				}
1442 			}
1443 
1444 			return;
1445 		}
1446 	}
1447 
1448 	// Interpret the UDP packet
1449 	b = NewBuf();
1450 	WriteBuf(b, udp->Data, udp->Size);
1451 	SeekBuf(b, 0, 0);
1452 
1453 	p = BufToPack(b);
1454 
1455 	if (p != NULL)
1456 	{
1457 		bool is_ok = PackGetBool(p, "ok");
1458 		UINT64 tran_id = PackGetInt64(p, "tran_id");
1459 
1460 		ExtractAndApplyDynList(p);
1461 
1462 		if (r->ServerMode)
1463 		{
1464 			if (PackCmpStr(p, "opcode", "get_token"))
1465 			{
1466 				// Get the Token
1467 				if (is_ok && (tran_id == r->NatT_TranId))
1468 				{
1469 					char tmp[MAX_SIZE];
1470 
1471 					if (PackGetStr(p, "token", tmp, sizeof(tmp)) && IsEmptyStr(tmp) == false)
1472 					{
1473 						char myip[MAX_SIZE];
1474 						// Acquisition success
1475 						StrCpy(r->NatT_Token, sizeof(r->NatT_Token), tmp);
1476 						r->NatT_Token_Ok = true;
1477 						r->NatT_GetTokenNextTick = r->Now + (UINT64)GenRandInterval(UDP_NAT_T_GET_TOKEN_INTERVAL_2_MIN, UDP_NAT_T_GET_TOKEN_INTERVAL_2_MAX);
1478 						r->NatT_GetTokenFailNum = 0;
1479 
1480 						// Since success to obtain the self global IPv4 address,
1481 						// re-obtain the destination NAT-T host from this IPv4 address
1482 						if (PackGetStr(p, "your_ip", myip, sizeof(myip)))
1483 						{
1484 							IP ip;
1485 							char new_hostname[MAX_SIZE];
1486 
1487 							StrToIP(&ip, myip);
1488 
1489 							SetCurrentGlobalIP(&ip, false);
1490 
1491 							RUDPGetRegisterHostNameByIP(new_hostname,
1492 								sizeof(new_hostname), &ip);
1493 
1494 							Lock(r->Lock);
1495 							{
1496 								if (StrCmpi(r->CurrentRegisterHostname, new_hostname) != 0)
1497 								{
1498 									r->NumChangedHostname++;
1499 
1500 									if (r->NumChangedHostname <= RUDP_NATT_MAX_CONT_CHANGE_HOSTNAME)
1501 									{
1502 										if (r->NumChangedHostnameValueResetTick == 0)
1503 										{
1504 											r->NumChangedHostnameValueResetTick = r->Now + (UINT64)RUDP_NATT_CONT_CHANGE_HOSTNAME_RESET_INTERVAL;
1505 										}
1506 
1507 										// Change the host name
1508 										Debug("CurrentRegisterHostname Changed: New=%s\n", new_hostname);
1509 										StrCpy(r->CurrentRegisterHostname, sizeof(r->CurrentRegisterHostname), new_hostname);
1510 
1511 										Zero(&r->NatT_IP, sizeof(r->NatT_IP));
1512 										//Zero(&r->NatT_IP_Safe, sizeof(r->NatT_IP_Safe));
1513 
1514 										Set(r->HaltEvent);
1515 									}
1516 									else
1517 									{
1518 										if (r->NumChangedHostnameValueResetTick == 0)
1519 										{
1520 											r->NumChangedHostnameValueResetTick = r->Now + (UINT64)RUDP_NATT_CONT_CHANGE_HOSTNAME_RESET_INTERVAL;
1521 										}
1522 
1523 										if (r->Now >= r->NumChangedHostnameValueResetTick)
1524 										{
1525 											r->NumChangedHostname = 0;
1526 											r->NumChangedHostnameValueResetTick = 0;
1527 										}
1528 									}
1529 								}
1530 								else
1531 								{
1532 									r->NumChangedHostname = 0;
1533 									r->NumChangedHostnameValueResetTick = 0;
1534 								}
1535 							}
1536 							Unlock(r->Lock);
1537 						}
1538 
1539 						AddInterrupt(r->Interrupt, r->NatT_GetTokenNextTick);
1540 					}
1541 				}
1542 			}
1543 			else if (PackCmpStr(p, "opcode", "nat_t_register"))
1544 			{
1545 				// NAT-T server registration result
1546 				if (is_ok && (tran_id == r->NatT_TranId))
1547 				{
1548 					UINT my_global_port;
1549 					// Successful registration
1550 					r->NatT_Register_Ok = true;
1551 					r->NatT_RegisterNextTick = r->Now + (UINT64)GenRandInterval(UDP_NAT_T_REGISTER_INTERVAL_MIN, UDP_NAT_T_REGISTER_INTERVAL_MAX);
1552 					r->NatT_RegisterFailNum = 0;
1553 
1554 					Debug("NAT-T Registered.\n");
1555 
1556 					// Save the IP address and port number at the time of registration
1557 					PackGetStr(p, "your_ip_and_port", r->NatT_Registered_IPAndPort, sizeof(r->NatT_Registered_IPAndPort));
1558 
1559 					if (g_source_ip_validation_force_disable == false)
1560 					{
1561 						// Enable the source IP address validation mechanism
1562 						r->NatT_EnableSourceIpValidation = PackGetBool(p, "enable_source_ip_validation");
1563 
1564 					}
1565 					else
1566 					{
1567 						// Force disable the source IP address validation mechanism
1568 						r->NatT_EnableSourceIpValidation = false;
1569 					}
1570 
1571 					// Global port of itself
1572 					my_global_port = PackGetInt(p, "your_port");
1573 
1574 					if (my_global_port != 0)
1575 					{
1576 						if (r->NatTGlobalUdpPort != NULL)
1577 						{
1578 							*r->NatTGlobalUdpPort = my_global_port;
1579 						}
1580 					}
1581 
1582 					AddInterrupt(r->Interrupt, r->NatT_RegisterNextTick);
1583 				}
1584 			}
1585 			else if (PackCmpStr(p, "opcode", "nat_t_connect_relay"))
1586 			{
1587 				// Connection request from the client via the NAT-T server
1588 				if (is_ok && (PackGetInt64(p, "session_key") == r->NatT_SessionKey))
1589 				{
1590 					char client_ip_str[MAX_SIZE];
1591 					UINT client_port;
1592 					IP client_ip;
1593 
1594 					PackGetStr(p, "client_ip", client_ip_str, sizeof(client_ip_str));
1595 					client_port = PackGetInt(p, "client_port");
1596 					StrToIP(&client_ip, client_ip_str);
1597 
1598 					if (IsZeroIp(&client_ip) == false && client_port != 0)
1599 					{
1600 						UCHAR *rand_data;
1601 						UINT rand_size;
1602 
1603 						if (r->NatT_EnableSourceIpValidation)
1604 						{
1605 							RUDPAddIpToValidateList(r, &client_ip);
1606 						}
1607 
1608 						rand_size = Rand32() % 19;
1609 						rand_data = Malloc(rand_size);
1610 
1611 						Rand(rand_data, rand_size);
1612 
1613 						RUDPSendPacket(r, &client_ip, client_port, rand_data, rand_size, 0);
1614 
1615 						Free(rand_data);
1616 					}
1617 				}
1618 			}
1619 		}
1620 
1621 		FreePack(p);
1622 	}
1623 
1624 	FreeBuf(b);
1625 }
1626 
1627 // Set the flag of the source IP address validation function
RUDPSetSourceIpValidationForceDisable(bool b)1628 void RUDPSetSourceIpValidationForceDisable(bool b)
1629 {
1630 	g_source_ip_validation_force_disable = b;
1631 }
1632 
1633 // Process such as packet transmission for NAT-T server
RUDPDo_NatT_Interrupt(RUDP_STACK * r)1634 void RUDPDo_NatT_Interrupt(RUDP_STACK *r)
1635 {
1636 	// Validate arguments
1637 	if (r == NULL)
1638 	{
1639 		return;
1640 	}
1641 
1642 	if (r->ServerMode)
1643 	{
1644 
1645 		if (g_no_rudp_register == false && IsZeroIp(&r->NatT_IP_Safe) == false)
1646 		{
1647 			if (r->NatT_GetTokenNextTick == 0 || r->Now >= r->NatT_GetTokenNextTick)
1648 			{
1649 				// Try to get a token from the NAT-T server periodically
1650 				PACK *p = NewPack();
1651 				BUF *b;
1652 
1653 				PackAddStr(p, "opcode", "get_token");
1654 				PackAddInt64(p, "tran_id", r->NatT_TranId);
1655 				PackAddInt(p, "nat_traversal_version", UDP_NAT_TRAVERSAL_VERSION);
1656 
1657 				b = PackToBuf(p);
1658 				FreePack(p);
1659 
1660 				RUDPSendPacket(r, &r->NatT_IP_Safe, UDP_NAT_T_PORT, b->Buf, b->Size, 0);
1661 
1662 				FreeBuf(b);
1663 
1664 				// Determine the next acquisition time
1665 				r->NatT_GetTokenFailNum++;
1666 				r->NatT_GetTokenNextTick = r->Now + (UINT64)(UDP_NAT_T_GET_TOKEN_INTERVAL_1 * (UINT64)MIN(r->NatT_GetTokenFailNum, UDP_NAT_T_GET_TOKEN_INTERVAL_FAIL_MAX));
1667 				AddInterrupt(r->Interrupt, r->NatT_GetTokenNextTick);
1668 				r->NatT_Token_Ok = false;
1669 			}
1670 		}
1671 
1672 		{
1673 			if (IsZeroIp(&r->NatT_IP_Safe) == false)
1674 			{
1675 				// Normal servers: Send request packets to the NAT-T server
1676 				if (r->NatT_NextNatStatusCheckTick == 0 || r->Now >= r->NatT_NextNatStatusCheckTick)
1677 				{
1678 					UCHAR a = 'A';
1679 					UINT ddns_hash;
1680 					// Check of the NAT state
1681 					RUDPSendPacket(r, &r->NatT_IP_Safe, UDP_NAT_T_PORT, &a, 1, 0);
1682 
1683 					// Execution time of the next
1684 					r->NatT_NextNatStatusCheckTick = r->Now + (UINT64)GenRandInterval(UDP_NAT_T_NAT_STATUS_CHECK_INTERVAL_MIN, UDP_NAT_T_NAT_STATUS_CHECK_INTERVAL_MAX);
1685 					AddInterrupt(r->Interrupt, r->NatT_NextNatStatusCheckTick);
1686 
1687 					// Check whether the DDNS host name changing have not occurred
1688 					ddns_hash = GetCurrentDDnsFqdnHash();
1689 
1690 					if (r->LastDDnsFqdnHash != ddns_hash)
1691 					{
1692 						r->LastDDnsFqdnHash = ddns_hash;
1693 						// Do the Register immediately if there is a change in the DDNS host name
1694 						r->NatT_RegisterNextTick = 0;
1695 					}
1696 				}
1697 			}
1698 		}
1699 
1700 		if (r->NatT_Token_Ok && g_no_rudp_register == false && IsZeroIp(&r->NatT_IP_Safe) == false)
1701 		{
1702 			if (r->NatT_RegisterNextTick == 0 || r->Now >= r->NatT_RegisterNextTick)
1703 			{
1704 				// Try to register itself periodically for NAT-T server
1705 				PACK *p = NewPack();
1706 				BUF *b;
1707 				char private_ip_str[MAX_SIZE];
1708 				char machine_key[MAX_SIZE];
1709 				char machine_name[MAX_SIZE];
1710 				UCHAR hash[SHA1_SIZE];
1711 				char ddns_fqdn[MAX_SIZE];
1712 
1713 				Debug("NAT-T Registering...\n");
1714 
1715 				GetCurrentDDnsFqdn(ddns_fqdn, sizeof(ddns_fqdn));
1716 
1717 				PackAddStr(p, "opcode", "nat_t_register");
1718 				PackAddInt64(p, "tran_id", r->NatT_TranId);
1719 				PackAddStr(p, "token", r->NatT_Token);
1720 				PackAddStr(p, "svc_name", r->SvcName);
1721 				PackAddStr(p, "product_str", CEDAR_PRODUCT_STR);
1722 				PackAddInt64(p, "session_key", r->NatT_SessionKey);
1723 				PackAddInt(p, "nat_traversal_version", UDP_NAT_TRAVERSAL_VERSION);
1724 
1725 
1726 				if (g_natt_low_priority)
1727 				{
1728 					PackAddBool(p, "low_priority", g_natt_low_priority);
1729 				}
1730 
1731 				Zero(private_ip_str, sizeof(private_ip_str));
1732 				if (IsZeroIp(&r->My_Private_IP_Safe) == false)
1733 				{
1734 					IPToStr(private_ip_str, sizeof(private_ip_str), &r->My_Private_IP_Safe);
1735 					PackAddStr(p, "private_ip", private_ip_str);
1736 				}
1737 
1738 				PackAddInt(p, "private_port", r->UdpSock->LocalPort);
1739 
1740 				Zero(hash, sizeof(hash));
1741 				GetCurrentMachineIpProcessHash(hash);
1742 				BinToStr(machine_key, sizeof(machine_key), hash, sizeof(hash));
1743 				PackAddStr(p, "machine_key", machine_key);
1744 
1745 				Zero(machine_name, sizeof(machine_name));
1746 				GetMachineName(machine_name, sizeof(machine_name));
1747 				PackAddStr(p, "host_name", machine_name);
1748 				PackAddStr(p, "ddns_fqdn", ddns_fqdn);
1749 
1750 				b = PackToBuf(p);
1751 				FreePack(p);
1752 
1753 				RUDPSendPacket(r, &r->NatT_IP_Safe, UDP_NAT_T_PORT, b->Buf, b->Size, 0);
1754 				//RUDPSendPacket(r, &r->NatT_IP_Safe, UDP_NAT_T_PORT, "a", 1);
1755 
1756 				FreeBuf(b);
1757 
1758 				// Determine the next acquisition time
1759 				r->NatT_RegisterFailNum++;
1760 				r->NatT_RegisterNextTick = r->Now + (UINT64)UDP_NAT_T_REGISTER_INTERVAL_INITIAL * (UINT64)MIN(r->NatT_RegisterFailNum, UDP_NAT_T_REGISTER_INTERVAL_FAIL_MAX);
1761 				AddInterrupt(r->Interrupt, r->NatT_RegisterNextTick);
1762 				r->NatT_Register_Ok = false;
1763 			}
1764 		}
1765 	}
1766 }
1767 
1768 // R-UDP packet reception procedure
RUDPRecvProc(RUDP_STACK * r,UDPPACKET * p)1769 void RUDPRecvProc(RUDP_STACK *r, UDPPACKET *p)
1770 {
1771 	RUDP_SESSION *se = NULL;
1772 	// Validate arguments
1773 	if (r == NULL || p == NULL)
1774 	{
1775 		return;
1776 	}
1777 
1778 	if (r->ServerMode)
1779 	{
1780 		if (g_no_rudp_server)
1781 		{
1782 			return;
1783 		}
1784 	}
1785 
1786 	if (r->ServerMode && r->NoNatTRegister == false)
1787 	{
1788 
1789 		if (p->SrcPort == UDP_NAT_T_PORT && CmpIpAddr(&p->SrcIP, &r->NatT_IP_Safe) == 0)
1790 		{
1791 			// There was a response from the NAT-T server
1792 			RUDPProcess_NatT_Recv(r, p);
1793 			return;
1794 		}
1795 	}
1796 
1797 	if (r->ServerMode)
1798 	{
1799 		if (r->ProcRpcRecv != NULL)
1800 		{
1801 			if (r->ProcRpcRecv(r, p))
1802 			{
1803 				return;
1804 			}
1805 		}
1806 	}
1807 
1808 	if (r->ServerMode)
1809 	{
1810 		// Search the session by the end-point information if in the server mode
1811 		se = RUDPSearchSession(r, &p->DstIP, p->DestPort, &p->SrcIP, p->SrcPort);
1812 	}
1813 	else
1814 	{
1815 		// Session should exist only one in the case of client mode
1816 		if (LIST_NUM(r->SessionList) >= 1)
1817 		{
1818 			se = LIST_DATA(r->SessionList, 0);
1819 		}
1820 		else
1821 		{
1822 			se = NULL;
1823 		}
1824 	}
1825 
1826 	if (p->Size < 20)
1827 	{
1828 		// The received packet is too small
1829 		if (r->ServerMode == false)
1830 		{
1831 			if (se != NULL && se->Status == RUDP_SESSION_STATUS_CONNECT_SENT)
1832 			{
1833 				if (CmpIpAddr(&se->YourIp, &p->SrcIP) == 0)
1834 				{
1835 					// If the connection initialization packet which is shorter than 20 bytes
1836 					// has been received from the server side, overwrite the source port number
1837 					// of the packet to the client-side session information (for some NAT)
1838 					se->YourPort = p->SrcPort;
1839 				}
1840 			}
1841 		}
1842 		return;
1843 	}
1844 
1845 	if (se == NULL && r->ServerMode && p->Size >= 40)
1846 	{
1847 		// Corresponding to a sudden change of port number on the client side.
1848 		// The target session is a session which matches the client side IP address
1849 		// and the key and the signature is verified
1850 		UINT i;
1851 		for (i = 0; i < LIST_NUM(r->SessionList);i++)
1852 		{
1853 			RUDP_SESSION *s = LIST_DATA(r->SessionList, i);
1854 
1855 			if (CmpIpAddr(&s->YourIp, &p->SrcIP) == 0)
1856 			{
1857 				if (RUDPCheckSignOfRecvPacket(r, s, p->Data, p->Size))
1858 				{
1859 					// Signature matched
1860 					se = s;
1861 					break;
1862 				}
1863 			}
1864 		}
1865 	}
1866 
1867 	if (se == NULL)
1868 	{
1869 		// There is no session
1870 		if (r->ServerMode)
1871 		{
1872 			if (p->Size < 40)
1873 			{
1874 				bool ok = true;
1875 				UCHAR ctoken_hash[SHA1_SIZE];
1876 
1877 				Zero(ctoken_hash, sizeof(ctoken_hash));
1878 
1879 				// Examine the quota of new session creation
1880 				if (LIST_NUM(r->SessionList) >= RUDP_QUOTA_MAX_NUM_SESSIONS)
1881 				{
1882 					// Entire number of sessions exceeds the limit
1883 					ok = false;
1884 				}
1885 				else if (r->NatT_EnableSourceIpValidation && RUDPIsIpInValidateList(r, &p->SrcIP) == false)
1886 				{
1887 					// Invalid source IP address, which is not registered on the validated source IP address list
1888 					ok = false;
1889 				}
1890 				else
1891 				{
1892 					UINT i;
1893 					// Check the number of sessions per IP address
1894 					UINT num = 0;
1895 
1896 					for (i = 0;i < LIST_NUM(r->SessionList);i++)
1897 					{
1898 						RUDP_SESSION *se = LIST_DATA(r->SessionList, i);
1899 
1900 						if (CmpIpAddr(&se->YourIp, &p->SrcIP) == 0)
1901 						{
1902 							num++;
1903 						}
1904 					}
1905 
1906 					if (num >= RUDP_QUOTA_MAX_NUM_SESSIONS_PER_IP)
1907 					{
1908 						// Limit exceeded the number of sessions per IP address
1909 						ok = false;
1910 					}
1911 				}
1912 
1913 
1914 				if (ok)
1915 				{
1916 					char ip_str[64];
1917 
1918 					// Create a session since a new session creation request packet was received
1919 					se = RUDPNewSession(true, &p->DstIP, p->DestPort, &p->SrcIP, p->SrcPort, p->Data);
1920 					se->Status = RUDP_SESSION_STATUS_ESTABLISHED;
1921 					Insert(r->SessionList, se);
1922 
1923 					IPToStr(ip_str, sizeof(ip_str), &p->SrcIP);
1924 					Debug("RUDPNewSession %X %s:%u\n", se, ip_str, p->SrcPort);
1925 
1926 					if (r->Protocol == RUDP_PROTOCOL_ICMP)
1927 					{
1928 						// In case of ICMP, save the ICMP TYPE number to use
1929 						se->Icmp_Type = (p->Type == ICMP_TYPE_INFORMATION_REQUEST ? ICMP_TYPE_INFORMATION_REPLY : p->Type);
1930 					}
1931 					else if (r->Protocol == RUDP_PROTOCOL_DNS)
1932 					{
1933 						// Save the Tran ID to be used if it's a DNS
1934 						se->Dns_TranId = (USHORT)p->Type;
1935 					}
1936 				}
1937 			}
1938 		}
1939 	}
1940 	else
1941 	{
1942 		if (p->Size < 40)
1943 		{
1944 			if (r->ServerMode)
1945 			{
1946 				if (Cmp(se->Key_Init, p->Data, SHA1_SIZE) == 0)
1947 				{
1948 					// New session creation request packet have received more than once. reply an ACK immediately for second and subsequent
1949 					se->LastSentTick = 0;
1950 
1951 					// Update the endpoint information
1952 					Copy(&se->YourIp, &p->SrcIP, sizeof(IP));
1953 					se->YourPort = p->SrcPort;
1954 
1955 					if (r->Protocol == RUDP_PROTOCOL_ICMP)
1956 					{
1957 						// In case of ICMP, save the ICMP TYPE number to use
1958 						se->Icmp_Type = (p->Type == ICMP_TYPE_INFORMATION_REQUEST ? ICMP_TYPE_INFORMATION_REPLY : p->Type);
1959 					}
1960 					else if (r->Protocol == RUDP_PROTOCOL_DNS)
1961 					{
1962 						// Save the Tran ID to be used if it's a DNS
1963 						se->Dns_TranId = (USHORT)p->Type;
1964 					}
1965 				}
1966 				else
1967 				{
1968 					// Since the different session creation request packet have been received from the same end point, ignore it
1969 				}
1970 			}
1971 		}
1972 		else
1973 		{
1974 			// Process the received packet
1975 			if (RUDPProcessRecvPacket(r, se, p->Data, p->Size) || RUDPProcessBulkRecvPacket(r, se, p->Data, p->Size))
1976 			{
1977 				// Update endpoint information (only the port number)
1978 				//Copy(&se->YourIp, &p->SrcIP, sizeof(IP));
1979 				se->YourPort = p->SrcPort;
1980 
1981 				if (r->Protocol == RUDP_PROTOCOL_ICMP)
1982 				{
1983 					// In case of ICMP, save the ICMP TYPE number to use
1984 					if (r->ServerMode)
1985 					{
1986 						se->Icmp_Type = (p->Type == ICMP_TYPE_INFORMATION_REQUEST ? ICMP_TYPE_INFORMATION_REPLY : p->Type);
1987 					}
1988 					else
1989 					{
1990 						se->Icmp_Type = (p->Type == ICMP_TYPE_INFORMATION_REPLY ? ICMP_TYPE_INFORMATION_REQUEST : p->Type);
1991 					}
1992 				}
1993 				else if (r->Protocol == RUDP_PROTOCOL_DNS)
1994 				{
1995 					if (r->ServerMode)
1996 					{
1997 						// Save the Tran ID to be used if it's a DNS
1998 						se->Dns_TranId = (USHORT)p->Type;
1999 					}
2000 				}
2001 			}
2002 		}
2003 	}
2004 }
2005 
2006 // Check whether the specificed IP address is in the validated source IP address list
RUDPIsIpInValidateList(RUDP_STACK * r,IP * ip)2007 bool RUDPIsIpInValidateList(RUDP_STACK *r, IP *ip)
2008 {
2009 	UINT i;
2010 	UINT64 now = Tick64();
2011 	LIST *o = NULL;
2012 	bool ret = false;
2013 	// Validate arguments
2014 	if (r == NULL || ip == NULL)
2015 	{
2016 		return false;
2017 	}
2018 
2019 	// Always allow private IP addresses
2020 	if (IsIPPrivate(ip))
2021 	{
2022 		return true;
2023 	}
2024 
2025 	if (IsIPAddressInSameLocalNetwork(ip))
2026 	{
2027 		return true;
2028 	}
2029 
2030 	for (i = 0;i < LIST_NUM(r->NatT_SourceIpList);i++)
2031 	{
2032 		RUDP_SOURCE_IP *s = (RUDP_SOURCE_IP *)LIST_DATA(r->NatT_SourceIpList, i);
2033 
2034 		if (s->ExpiresTick <= now)
2035 		{
2036 			if (o == NULL)
2037 			{
2038 				o = NewListFast(NULL);
2039 			}
2040 
2041 			Add(o, s);
2042 		}
2043 	}
2044 
2045 	if (o != NULL)
2046 	{
2047 		for (i = 0;i < LIST_NUM(o);i++)
2048 		{
2049 			RUDP_SOURCE_IP *s = (RUDP_SOURCE_IP *)LIST_DATA(o, i);
2050 
2051 			Delete(r->NatT_SourceIpList, s);
2052 
2053 			Free(s);
2054 		}
2055 
2056 		ReleaseList(o);
2057 	}
2058 
2059 	for (i = 0;i < LIST_NUM(r->NatT_SourceIpList);i++)
2060 	{
2061 		RUDP_SOURCE_IP *s = (RUDP_SOURCE_IP *)LIST_DATA(r->NatT_SourceIpList, i);
2062 
2063 		if (CmpIpAddr(&s->ClientIP, ip) == 0)
2064 		{
2065 			ret = true;
2066 			break;
2067 		}
2068 	}
2069 
2070 	Debug("RUDP: NAT-T: Validate IP: %r, ret=%u (current list len = %u)\n", ip, ret, LIST_NUM(r->NatT_SourceIpList));
2071 
2072 	return ret;
2073 }
2074 
2075 // Add an IP address to the validated source IP address list
RUDPAddIpToValidateList(RUDP_STACK * r,IP * ip)2076 void RUDPAddIpToValidateList(RUDP_STACK *r, IP *ip)
2077 {
2078 	UINT i;
2079 	RUDP_SOURCE_IP *sip;
2080 	UINT64 now = Tick64();
2081 	LIST *o = NULL;
2082 	// Validate arguments
2083 	if (r == NULL || ip == NULL)
2084 	{
2085 		return;
2086 	}
2087 
2088 	if (LIST_NUM(r->NatT_SourceIpList) >= RUDP_MAX_VALIDATED_SOURCE_IP_ADDRESSES)
2089 	{
2090 		return;
2091 	}
2092 
2093 	for (i = 0;i < LIST_NUM(r->NatT_SourceIpList);i++)
2094 	{
2095 		RUDP_SOURCE_IP *s = (RUDP_SOURCE_IP *)LIST_DATA(r->NatT_SourceIpList, i);
2096 
2097 		if (s->ExpiresTick <= now)
2098 		{
2099 			if (o == NULL)
2100 			{
2101 				o = NewListFast(NULL);
2102 			}
2103 
2104 			Add(o, s);
2105 		}
2106 	}
2107 
2108 	if (o != NULL)
2109 	{
2110 		for (i = 0;i < LIST_NUM(o);i++)
2111 		{
2112 			RUDP_SOURCE_IP *s = (RUDP_SOURCE_IP *)LIST_DATA(o, i);
2113 
2114 			Delete(r->NatT_SourceIpList, s);
2115 
2116 			Free(s);
2117 		}
2118 
2119 		ReleaseList(o);
2120 	}
2121 
2122 	sip = NULL;
2123 
2124 	for (i = 0;i < LIST_NUM(r->NatT_SourceIpList);i++)
2125 	{
2126 		RUDP_SOURCE_IP *s = (RUDP_SOURCE_IP *)LIST_DATA(r->NatT_SourceIpList, i);
2127 
2128 		if (CmpIpAddr(&s->ClientIP, ip) == 0)
2129 		{
2130 			sip = s;
2131 			break;
2132 		}
2133 	}
2134 
2135 	if (sip == NULL)
2136 	{
2137 		sip = ZeroMalloc(sizeof(RUDP_SOURCE_IP));
2138 
2139 		Copy(&sip->ClientIP, ip, sizeof(IP));
2140 
2141 		Add(r->NatT_SourceIpList, sip);
2142 	}
2143 
2144 	sip->ExpiresTick = now + (UINT64)RUDP_VALIDATED_SOURCE_IP_ADDRESS_EXPIRES;
2145 
2146 	Debug("RUDP: NAT-T: Src IP added: %r (current list len = %u)\n", ip, LIST_NUM(r->NatT_SourceIpList));
2147 }
2148 
2149 // R-UDP interrupt processing procedure
RUDPInterruptProc(RUDP_STACK * r)2150 void RUDPInterruptProc(RUDP_STACK *r)
2151 {
2152 	UINT i;
2153 	LIST *o;
2154 	// Validate arguments
2155 	if (r == NULL)
2156 	{
2157 		return;
2158 	}
2159 
2160 	// Packet transmission and other process for NAT-T server
2161 	if (r->NoNatTRegister == false)
2162 	{
2163 		RUDPDo_NatT_Interrupt(r);
2164 	}
2165 
2166 	if (r->ServerMode == false)
2167 	{
2168 		if (r->ClientInitiated == false)
2169 		{
2170 			bool client_target_inited = false;
2171 			Lock(r->Lock);
2172 			{
2173 				client_target_inited = r->TargetIpAndPortInited;
2174 			}
2175 			Unlock(r->Lock);
2176 
2177 			if (client_target_inited)
2178 			{
2179 				// Start a connection when there is the end point information of the destination server to connect as a client
2180 				RUDP_SESSION *se;
2181 				UCHAR init_key[SHA1_SIZE];
2182 				char ip_str[128];
2183 				UINT64 ui;
2184 
2185 				Rand(init_key, SHA1_SIZE);
2186 
2187 				se = RUDPNewSession(false, &r->UdpSock->LocalIP, r->UdpSock->LocalPort,
2188 					&r->TargetIp, r->TargetPort, init_key);
2189 
2190 				IPToStr(ip_str, sizeof(ip_str), &r->TargetIp);
2191 				Debug("RUDPNewSession %X %s:%u\n", se, ip_str, r->TargetPort);
2192 
2193 				Insert(r->SessionList, se);
2194 
2195 				ui = Endian64(se->Magic_Disconnect);
2196 				WriteFifo(se->SendFifo, &ui, sizeof(UINT64));
2197 
2198 				r->ClientInitiated = true;
2199 			}
2200 		}
2201 	}
2202 
2203 	// Process for all the sessions
2204 	for (i = 0;i < LIST_NUM(r->SessionList);i++)
2205 	{
2206 		RUDP_SESSION *se = LIST_DATA(r->SessionList, i);
2207 
2208 		if (r->Halt)
2209 		{
2210 			// Disconnect all the sessions if the R-UDP stack stopped
2211 			RUDPDisconnectSession(r, se, false);
2212 		}
2213 
2214 		if (se->FlushBulkSendTube)
2215 		{
2216 			if (se->TcpSock != NULL && se->TcpSock->BulkSendTube != NULL)
2217 			{
2218 				TubeFlush(se->TcpSock->BulkSendTube);
2219 			}
2220 
2221 			se->FlushBulkSendTube = false;
2222 		}
2223 
2224 		if (se->Status == RUDP_SESSION_STATUS_ESTABLISHED)
2225 		{
2226 			// Process for all of the sessions which is established a connection
2227 			UINT j;
2228 
2229 			if (r->Now >= (se->LatestRecvMyTick + (UINT64)RUDP_TIMEOUT))
2230 			{
2231 				// Disconnect the session because the fully communication failure is detected for a while
2232 				Debug("R-UDP Session %X Timed Out.\n", se);
2233 
2234 				RUDPDisconnectSession(r, se, false);
2235 			}
2236 
2237 			// If there are received segments, read to the part that has arrived in succession
2238 			if (FifoSize(se->RecvFifo) <= RUDP_MAX_FIFO_SIZE)
2239 			{
2240 				LIST *o;
2241 				UINT64 current_seq_no;
2242 
2243 				o = NULL;
2244 				current_seq_no = se->LastRecvCompleteSeqNo;
2245 				for (j = 0;j < LIST_NUM(se->RecvSegmentList);j++)
2246 				{
2247 					RUDP_SEGMENT *s;
2248 
2249 					current_seq_no++;
2250 
2251 					s = LIST_DATA(se->RecvSegmentList, j);
2252 
2253 					if (s->SeqNo == current_seq_no)
2254 					{
2255 #ifdef	RUDP_DETAIL_LOG
2256 						Debug("%X s->SeqNo = %I64u, current_seq_no = %I64u\n", se, s->SeqNo, current_seq_no);
2257 #endif	// RUDP_DETAIL_LOG
2258 
2259 						if (s->Size == sizeof(se->Magic_KeepAliveRequest) && Cmp(s->Data, se->Magic_KeepAliveRequest, sizeof(se->Magic_KeepAliveRequest)) == 0)
2260 						{
2261 							// Receive the KeepAlive Request
2262 #ifdef	RUDP_DETAIL_LOG
2263 							Debug("Recv KeepAlive Request\n");
2264 #endif	// RUDP_DETAIL_LOG
2265 
2266 							// Send a KeepAlive Response if the transmisson queue is empty
2267 							if (LIST_NUM(se->SendSegmentList) == 0)
2268 							{
2269 #ifdef	RUDP_DETAIL_LOG
2270 								Debug("Send KeepAlive Response\n");
2271 #endif	// RUDP_DETAIL_LOG
2272 
2273 								RUDPSendSegment(r, se, se->Magic_KeepAliveResponse, sizeof(se->Magic_KeepAliveResponse));
2274 							}
2275 						}
2276 						else if (s->Size == sizeof(se->Magic_KeepAliveResponse) && Cmp(s->Data, se->Magic_KeepAliveResponse, sizeof(se->Magic_KeepAliveResponse)) == 0)
2277 						{
2278 							// Receive the KeepAlive Response
2279 #ifdef	RUDP_DETAIL_LOG
2280 							Debug("Recv KeepAlive Response\n");
2281 #endif	// RUDP_DETAIL_LOG
2282 						}
2283 						else
2284 						{
2285 							// Write to the receive FIFO
2286 							WriteFifo(se->RecvFifo, s->Data, s->Size);
2287 						}
2288 						r->TotalLogicalReceived += s->Size;
2289 
2290 						// Advance the SEQ NO which has been received completely
2291 						se->LastRecvCompleteSeqNo = s->SeqNo;
2292 
2293 						// Add to the Delete list
2294 						if (o == NULL)
2295 						{
2296 							o = NewListFast(NULL);
2297 						}
2298 						Add(o, s);
2299 					}
2300 					else
2301 					{
2302 						// Continuous reading is interrupted
2303 #ifdef	RUDP_DETAIL_LOG
2304 						Debug("%X s->SeqNo = %I64u, current_seq_no = %I64u\n", se, s->SeqNo, current_seq_no);
2305 						WHERE;
2306 #endif	// RUDP_DETAIL_LOG
2307 						break;
2308 					}
2309 				}
2310 
2311 				// Delete the segment which has been received completely
2312 				if (o != NULL)
2313 				{
2314 					for (j = 0;j < LIST_NUM(o);j++)
2315 					{
2316 						RUDP_SEGMENT *s = LIST_DATA(o, j);
2317 
2318 						Delete(se->RecvSegmentList, s);
2319 						Free(s);
2320 					}
2321 					ReleaseList(o);
2322 				}
2323 			}
2324 
2325 			if (r->ServerMode && se->Magic_Disconnect == 0)
2326 			{
2327 				if (FifoSize(se->RecvFifo) >= sizeof(UINT64))
2328 				{
2329 					UINT64 ui;
2330 
2331 					if (ReadFifo(se->RecvFifo, &ui, sizeof(UINT64)) == sizeof(UINT64))
2332 					{
2333 						ui = Endian64(ui);
2334 
2335 						if ((ui & 0xffffffff00000000ULL) != 0ULL)
2336 						{
2337 							se->Magic_Disconnect = ui;
2338 						}
2339 					}
2340 				}
2341 			}
2342 
2343 			// If the data remains in FIFO, write it to the TCP socket as possible
2344 			if (r->ServerMode == false || se->Magic_Disconnect != 0)
2345 			{
2346 				while (FifoSize(se->RecvFifo) >= 1)
2347 				{
2348 					UINT ret;
2349 
2350 					RUDPInitSock(r, se);
2351 
2352 					ret = Send(se->TcpSock, FifoPtr(se->RecvFifo), FifoSize(se->RecvFifo), false);
2353 
2354 					if (ret == SOCK_LATER)
2355 					{
2356 						// Can not write any more
2357 						break;
2358 					}
2359 					else if (ret == 0)
2360 					{
2361 						// Disconnected
2362 						Disconnect(se->TcpSock);
2363 						RUDPDisconnectSession(r, se, false);
2364 						break;
2365 					}
2366 					else
2367 					{
2368 						// Writing success
2369 						ReadFifo(se->RecvFifo, NULL, ret);
2370 					}
2371 				}
2372 			}
2373 
2374 			// Read the data as much as possible from the TCP socket and store it to FIFO
2375 			if (se->TcpSock != NULL)
2376 			{
2377 				SetNoNeedToRead(se->TcpSock);
2378 
2379 				while (FifoSize(se->SendFifo) <= RUDP_MAX_FIFO_SIZE)
2380 				{
2381 					UINT ret = Recv(se->TcpSock, r->TmpBuf, sizeof(r->TmpBuf), false);
2382 
2383 					if (ret == SOCK_LATER)
2384 					{
2385 						// Can not read any more
2386 						break;
2387 					}
2388 					else if (ret == 0)
2389 					{
2390 						// Disconnected
2391 						Disconnect(se->TcpSock);
2392 						RUDPDisconnectSession(r, se, false);
2393 						break;
2394 					}
2395 					else
2396 					{
2397 						// Reading success
2398 						WriteFifo(se->SendFifo, r->TmpBuf, ret);
2399 					}
2400 				}
2401 			}
2402 
2403 			// Attempt to send a divided segment
2404 			while (true)
2405 			{
2406 				UINT64 seq_no_min, seq_no_max;
2407 
2408 				seq_no_min = RUDPGetCurrentSendingMinSeqNo(se);
2409 				seq_no_max = RUDPGetCurrentSendingMaxSeqNo(se);
2410 
2411 #ifdef	RUDP_DETAIL_LOG
2412 				Debug("min=%I64u max=%I64u\n", seq_no_min, seq_no_max);
2413 #endif	// RUDP_DETAIL_LOG
2414 
2415 				if (seq_no_min == 0 || ((seq_no_min + RUDP_MAX_NUM_ACK - 1) >= se->NextSendSeqNo))
2416 				{
2417 					// Because there is a room to send a new segment, send a segment
2418 					UINT size = MIN(FifoSize(se->SendFifo), RUDP_MAX_SEGMENT_SIZE);
2419 
2420 					if (size == 0)
2421 					{
2422 						// There is no more data to send in FIFO
2423 						break;
2424 					}
2425 
2426 					// Transmission
2427 					RUDPSendSegment(r, se, FifoPtr(se->SendFifo), size);
2428 
2429 					r->TotalLogicalSent += size;
2430 
2431 					// Advance the FIFO
2432 					ReadFifo(se->SendFifo, NULL, size);
2433 				}
2434 				else
2435 				{
2436 					// There is no room to send a new segment further
2437 					break;
2438 				}
2439 			}
2440 
2441 			if (se->DisconnectFlag == false)
2442 			{
2443 				UINT64 seq_no_min;
2444 
2445 				if (se->LastSentTick == 0 || (r->Now >= (se->LastSentTick + (UINT64)se->NextKeepAliveInterval)))
2446 				{
2447 					if (LIST_NUM(se->SendSegmentList) == 0)
2448 					{
2449 						// Send a Keep-Alive if no data was sent for a while and the transmission queue is empty
2450 						RUDPSendSegment(r, se, se->Magic_KeepAliveRequest, sizeof(se->Magic_KeepAliveRequest));
2451 
2452 #ifdef	RUDP_DETAIL_LOG
2453 						Debug("Sent KeepAlive Request\n");
2454 #endif	// RUDP_DETAIL_LOG
2455 					}
2456 
2457 					se->NextKeepAliveInterval = RUDP_KEEPALIVE_INTERVAL_MIN + (Rand32() % (RUDP_KEEPALIVE_INTERVAL_MAX - RUDP_KEEPALIVE_INTERVAL_MIN));
2458 
2459 					AddInterrupt(r->Interrupt, r->Now + se->NextKeepAliveInterval);
2460 				}
2461 
2462 				seq_no_min = RUDPGetCurrentSendingMinSeqNo(se);
2463 				for (j = 0;j < LIST_NUM(se->SendSegmentList);j++)
2464 				{
2465 					RUDP_SEGMENT *s = LIST_DATA(se->SendSegmentList, j);
2466 
2467 					if (s->SeqNo <= (seq_no_min + RUDP_MAX_NUM_ACK - 1))
2468 					{
2469 						if (s->NextSendTick == 0 || r->Now >= s->NextSendTick)
2470 						{
2471 							UINT next_interval;
2472 							// Transmits a segment which has not been sent even once yet, or whose retransmission time has arrived
2473 							RUDPSendSegmentNow(r, se, s->SeqNo, s->Data, s->Size);
2474 
2475 							if (se->CurrentRtt != 0)
2476 							{
2477 								next_interval = (se->CurrentRtt * 120 / 100) * Power(2, MIN(s->NumSent, 10));
2478 							}
2479 							else
2480 							{
2481 								next_interval = RUDP_RESEND_TIMER * Power(2, MIN(s->NumSent, 10));
2482 							}
2483 
2484 							next_interval = MIN(next_interval, RUDP_RESEND_TIMER_MAX);
2485 
2486 							s->NumSent++;
2487 
2488 							s->NextSendTick = r->Now + next_interval;
2489 
2490 							AddInterrupt(r->Interrupt, s->NextSendTick);
2491 						}
2492 					}
2493 				}
2494 
2495 				while (LIST_NUM(se->ReplyAckList) >= 1)
2496 				{
2497 					// If there are ACKs which is not responded yet in the list, send all of them
2498 					RUDPSendSegmentNow(r, se, se->NextSendSeqNo, NULL, 0);
2499 				}
2500 
2501 				// Send all if there are bulk transfer data
2502 				if (se->TcpSock != NULL)
2503 				{
2504 					SOCK *s = se->TcpSock;
2505 
2506 					if (s->BulkRecvTube != NULL)
2507 					{
2508 						TUBE *t = s->BulkRecvTube;
2509 
2510 						while (true)
2511 						{
2512 							TUBEDATA *d = TubeRecvAsync(t);
2513 
2514 							if (d == NULL)
2515 							{
2516 								break;
2517 							}
2518 
2519 							if (d->Header != NULL && d->HeaderSize == sizeof(TCP_PAIR_HEADER))
2520 							{
2521 								TCP_PAIR_HEADER *h = d->Header;
2522 
2523 								if (h->EnableHMac)
2524 								{
2525 									se->UseHMac = true;
2526 								}
2527 							}
2528 
2529 							RUDPBulkSend(r, se, d->Data, d->DataSize);
2530 
2531 							FreeTubeData(d);
2532 						}
2533 					}
2534 				}
2535 			}
2536 		}
2537 
2538 		if (r->ServerMode == false)
2539 		{
2540 			if (se->Status == RUDP_SESSION_STATUS_CONNECT_SENT)
2541 			{
2542 				// Send a connection request periodically from the client side
2543 				if (se->LastSentTick == 0 || ((se->LastSentTick + (UINT64)RUDP_RESEND_TIMER) <= r->Now))
2544 				{
2545 					UCHAR tmp[40];
2546 					UINT size_of_padding = 19;
2547 					UINT size = size_of_padding + SHA1_SIZE;
2548 
2549 					se->LastSentTick = r->Now;
2550 
2551 					Copy(tmp, se->Key_Init, SHA1_SIZE);
2552 					Rand(tmp + SHA1_SIZE, size_of_padding);
2553 
2554 					if (r->Protocol == RUDP_PROTOCOL_ICMP)
2555 					{
2556 						// ICMP packet
2557 						UCHAR *rand_data;
2558 						UINT rand_size;
2559 
2560 						rand_size = Rand32() % 64 + 64;
2561 						rand_data = Malloc(rand_size);
2562 						Rand(rand_data, rand_size);
2563 
2564 						RUDPSendPacket(r, &se->YourIp, se->YourPort, rand_data, rand_size, ICMP_TYPE_ECHO_REQUEST);
2565 						Free(rand_data);
2566 
2567 						se->Client_Icmp_NextSendEchoRequest = r->Now + GenRandInterval(RUDP_CLIENT_ECHO_REQUEST_SEND_INTERVAL_MIN, RUDP_CLIENT_ECHO_REQUEST_SEND_INTERVAL_MAX);
2568 						AddInterrupt(r->Interrupt, se->Client_Icmp_NextSendEchoRequest);
2569 
2570 						// Try in both INFORMATION_REQUEST and ECHO_RESPONSE from the client side first
2571 						RUDPSendPacket(r, &se->YourIp, se->YourPort, tmp, size, ICMP_TYPE_ECHO_RESPONSE);
2572 						RUDPSendPacket(r, &se->YourIp, se->YourPort, tmp, size, ICMP_TYPE_INFORMATION_REQUEST);
2573 					}
2574 					else if (r->Protocol == RUDP_PROTOCOL_DNS)
2575 					{
2576 						// DNS
2577 						RUDPSendPacket(r, &se->YourIp, se->YourPort, tmp, size, se->Dns_TranId);
2578 					}
2579 					else
2580 					{
2581 						// Normal UDP
2582 						RUDPSendPacket(r, &se->YourIp, se->YourPort, tmp, size, 0);
2583 					}
2584 
2585 					AddInterrupt(r->Interrupt, r->Now + (UINT64)RUDP_RESEND_TIMER);
2586 				}
2587 			}
2588 
2589 			if (r->Protocol == RUDP_PROTOCOL_ICMP)
2590 			{
2591 				if (se->Client_Icmp_NextSendEchoRequest == 0 || (r->Now >= se->Client_Icmp_NextSendEchoRequest))
2592 				{
2593 					// Periodic ICMP Echo transmission from the client side when R-UDP used in ICMP mode
2594 					// (To maintain the mapping table of the NAT)
2595 					UCHAR *rand_data;
2596 					UINT rand_size;
2597 
2598 					rand_size = Rand32() % 64 + 64;
2599 					rand_data = Malloc(rand_size);
2600 					Rand(rand_data, rand_size);
2601 
2602 					RUDPSendPacket(r, &se->YourIp, se->YourPort, rand_data, rand_size, ICMP_TYPE_ECHO_REQUEST);
2603 					Free(rand_data);
2604 
2605 					se->Client_Icmp_NextSendEchoRequest = r->Now + GenRandInterval(RUDP_CLIENT_ECHO_REQUEST_SEND_INTERVAL_MIN, RUDP_CLIENT_ECHO_REQUEST_SEND_INTERVAL_MAX);
2606 					AddInterrupt(r->Interrupt, se->Client_Icmp_NextSendEchoRequest);
2607 				}
2608 			}
2609 		}
2610 	}
2611 
2612 	// Release the disconnected sessions
2613 	o = NULL;
2614 	for (i = 0;i < LIST_NUM(r->SessionList);i++)
2615 	{
2616 		RUDP_SESSION *se = LIST_DATA(r->SessionList, i);
2617 
2618 		if (se->DisconnectFlag)
2619 		{
2620 			if (o == NULL)
2621 			{
2622 				o = NewListFast(NULL);
2623 			}
2624 
2625 			Add(o, se);
2626 		}
2627 	}
2628 	if (o != NULL)
2629 	{
2630 		for (i = 0;i < LIST_NUM(o);i++)
2631 		{
2632 			RUDP_SESSION *se = LIST_DATA(o, i);
2633 
2634 			Delete(r->SessionList, se);
2635 
2636 			RUDPFreeSession(se);
2637 		}
2638 
2639 		ReleaseList(o);
2640 	}
2641 }
2642 
2643 // Do the bulk send
RUDPBulkSend(RUDP_STACK * r,RUDP_SESSION * se,void * data,UINT data_size)2644 void RUDPBulkSend(RUDP_STACK *r, RUDP_SESSION *se, void *data, UINT data_size)
2645 {
2646 	UCHAR *buf;
2647 	UINT buf_size;
2648 	UINT padding_size;
2649 	UINT i;
2650 	CRYPT *c;
2651 	UCHAR crypt_key_src[SHA1_SIZE * 2];
2652 	UCHAR crypt_key[SHA1_SIZE];
2653 	UINT icmp_type;
2654 	// Validate arguments
2655 	if (r == NULL || se == NULL || (data == NULL && data_size != 0))
2656 	{
2657 		return;
2658 	}
2659 
2660 	if (se->BulkSendKey->Size == RUDP_BULK_KEY_SIZE_V2)
2661 	{
2662 		// Ver 2
2663 		UCHAR iv[RUDP_BULK_IV_SIZE_V2];
2664 
2665 		padding_size = Rand32() % 31 + 1;
2666 
2667 		// Packet: IV + Encrypted(SEQ_NO + Data + padding) + MAC
2668 		buf_size = RUDP_BULK_IV_SIZE_V2 + sizeof(UINT64) + data_size + padding_size + RUDP_BULK_MAC_SIZE_V2;
2669 		buf = Malloc(buf_size);
2670 
2671 		// IV
2672 		Copy(iv, se->BulkNextIv_V2, RUDP_BULK_IV_SIZE_V2);
2673 		Copy(buf, iv, RUDP_BULK_IV_SIZE_V2);
2674 
2675 		// SEQ NO
2676 		WRITE_UINT64(buf + RUDP_BULK_IV_SIZE_V2, se->BulkNextSeqNo);
2677 		se->BulkNextSeqNo++;
2678 
2679 		// Data
2680 		Copy(buf + RUDP_BULK_IV_SIZE_V2 + sizeof(UINT64), data, data_size);
2681 
2682 		// Padding
2683 		for (i = 0;i < padding_size;i++)
2684 		{
2685 			buf[RUDP_BULK_IV_SIZE_V2 + sizeof(UINT64) + data_size + i] = (UCHAR)padding_size;
2686 		}
2687 
2688 		// Encryption
2689 		Aead_ChaCha20Poly1305_Ietf_Encrypt(buf + RUDP_BULK_IV_SIZE_V2,
2690 			buf + RUDP_BULK_IV_SIZE_V2,
2691 			sizeof(UINT64) + data_size + padding_size,
2692 			se->BulkSendKey->Data,
2693 			iv,
2694 			NULL,
2695 			0);
2696 
2697 		// Next IV
2698 		Copy(se->BulkNextIv_V2, buf + RUDP_BULK_IV_SIZE_V2 + sizeof(UINT64) + data_size + padding_size - RUDP_BULK_IV_SIZE_V2,
2699 			RUDP_BULK_IV_SIZE_V2);
2700 
2701 		if (r->Protocol == RUDP_PROTOCOL_ICMP)
2702 		{
2703 			icmp_type = se->Icmp_Type;
2704 		}
2705 		else if (r->Protocol == RUDP_PROTOCOL_DNS)
2706 		{
2707 			icmp_type = se->Dns_TranId;
2708 		}
2709 		RUDPSendPacket(r, &se->YourIp, se->YourPort, buf, buf_size, icmp_type);
2710 
2711 		Free(buf);
2712 	}
2713 	else
2714 	{
2715 		UCHAR sign[SHA1_SIZE];
2716 		UCHAR iv[SHA1_SIZE];
2717 
2718 		// Ver 1
2719 		padding_size = Rand32() % 31 + 1;
2720 
2721 		buf_size = SHA1_SIZE + SHA1_SIZE + sizeof(UINT64) + data_size + padding_size;
2722 		buf = Malloc(buf_size);
2723 
2724 		// SEQ NO
2725 		WRITE_UINT64(buf + SHA1_SIZE + SHA1_SIZE, se->BulkNextSeqNo);
2726 		se->BulkNextSeqNo++;
2727 
2728 		// Data
2729 		Copy(buf + SHA1_SIZE + SHA1_SIZE + sizeof(UINT64), data, data_size);
2730 
2731 		// Padding
2732 		for (i = 0;i < padding_size;i++)
2733 		{
2734 			buf[SHA1_SIZE + SHA1_SIZE + sizeof(UINT64) + data_size + i] = (UCHAR)padding_size;
2735 		}
2736 
2737 		// Encryption
2738 		Copy(iv, se->BulkNextIv, SHA1_SIZE);
2739 		Copy(crypt_key_src + 0, se->BulkSendKey->Data, SHA1_SIZE);
2740 		Copy(crypt_key_src + SHA1_SIZE, iv, SHA1_SIZE);
2741 		HashSha1(crypt_key, crypt_key_src, SHA1_SIZE * 2);
2742 		c = NewCrypt(crypt_key, sizeof(crypt_key));
2743 		Encrypt(c, buf + SHA1_SIZE + SHA1_SIZE, buf + SHA1_SIZE + SHA1_SIZE, sizeof(UINT64) + data_size + padding_size);
2744 		FreeCrypt(c);
2745 
2746 		// IV
2747 		Copy(buf + SHA1_SIZE, iv, SHA1_SIZE);
2748 
2749 		// Sign
2750 		if (se->UseHMac == false)
2751 		{
2752 			Copy(buf + 0, se->BulkSendKey->Data, SHA1_SIZE);
2753 			HashSha1(sign, buf, SHA1_SIZE + SHA1_SIZE + sizeof(UINT64) + data_size + padding_size);
2754 			Copy(buf + 0, sign, SHA1_SIZE);
2755 		}
2756 		else
2757 		{
2758 			HMacSha1(buf + 0, se->BulkSendKey->Data, SHA1_SIZE, buf + SHA1_SIZE, SHA1_SIZE + sizeof(UINT64) + data_size + padding_size);
2759 		}
2760 
2761 		// Next IV
2762 		Copy(se->BulkNextIv, buf + buf_size - SHA1_SIZE, SHA1_SIZE);
2763 
2764 		if (r->Protocol == RUDP_PROTOCOL_ICMP)
2765 		{
2766 			icmp_type = se->Icmp_Type;
2767 		}
2768 		else if (r->Protocol == RUDP_PROTOCOL_DNS)
2769 		{
2770 			icmp_type = se->Dns_TranId;
2771 		}
2772 		RUDPSendPacket(r, &se->YourIp, se->YourPort, buf, buf_size, icmp_type);
2773 
2774 		Free(buf);
2775 	}
2776 }
2777 
2778 // Start a socket for R-UDP Listening
ListenRUDP(char * svc_name,RUDP_STACK_INTERRUPTS_PROC * proc_interrupts,RUDP_STACK_RPC_RECV_PROC * proc_rpc_recv,void * param,UINT port,bool no_natt_register,bool over_dns_mode)2779 SOCK *ListenRUDP(char *svc_name, RUDP_STACK_INTERRUPTS_PROC *proc_interrupts, RUDP_STACK_RPC_RECV_PROC *proc_rpc_recv, void *param, UINT port, bool no_natt_register, bool over_dns_mode)
2780 {
2781 	return ListenRUDPEx(svc_name, proc_interrupts, proc_rpc_recv, param, port, no_natt_register, over_dns_mode, NULL, 0);
2782 }
ListenRUDPEx(char * svc_name,RUDP_STACK_INTERRUPTS_PROC * proc_interrupts,RUDP_STACK_RPC_RECV_PROC * proc_rpc_recv,void * param,UINT port,bool no_natt_register,bool over_dns_mode,volatile UINT * natt_global_udp_port,UCHAR rand_port_id)2783 SOCK *ListenRUDPEx(char *svc_name, RUDP_STACK_INTERRUPTS_PROC *proc_interrupts, RUDP_STACK_RPC_RECV_PROC *proc_rpc_recv, void *param, UINT port, bool no_natt_register, bool over_dns_mode,
2784 				   volatile UINT *natt_global_udp_port, UCHAR rand_port_id)
2785 {
2786 	SOCK *s;
2787 	RUDP_STACK *r;
2788 
2789 	// Creating a R-UDP stack
2790 	r = NewRUDPServer(svc_name, proc_interrupts, proc_rpc_recv, param, port, no_natt_register, over_dns_mode, natt_global_udp_port, rand_port_id);
2791 	if (r == NULL)
2792 	{
2793 		return NULL;
2794 	}
2795 
2796 	s = NewSock();
2797 
2798 	s->Type = SOCK_RUDP_LISTEN;
2799 	s->ListenMode = true;
2800 	s->Connected = true;
2801 
2802 	s->LocalPort = r->UdpSock->LocalPort;
2803 
2804 	s->R_UDP_Stack = r;
2805 
2806 	return s;
2807 }
2808 
2809 // Accept on the R-UDP socket
AcceptRUDP(SOCK * s)2810 SOCK *AcceptRUDP(SOCK *s)
2811 {
2812 	// Validate arguments
2813 	if (s == NULL || s->Type != SOCK_RUDP_LISTEN || s->ListenMode == false)
2814 	{
2815 		return NULL;
2816 	}
2817 
2818 	while (true)
2819 	{
2820 		RUDP_STACK *r = s->R_UDP_Stack;
2821 		SOCK *ret;
2822 
2823 		if (s->Disconnecting || s->CancelAccept)
2824 		{
2825 			return NULL;
2826 		}
2827 
2828 		ret = GetNextWithLock(r->NewSockQueue);
2829 
2830 		if (ret != NULL)
2831 		{
2832 			switch (r->Protocol)
2833 			{
2834 			case RUDP_PROTOCOL_UDP:
2835 				StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_NAT_T);
2836 				AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails),
2837 					"RUDP/UDP");
2838 				break;
2839 
2840 			case RUDP_PROTOCOL_DNS:
2841 				StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_DNS);
2842 				AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails),
2843 					"RUDP/DNS");
2844 				break;
2845 
2846 			case RUDP_PROTOCOL_ICMP:
2847 				StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_ICMP);
2848 				AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails),
2849 					"RUDP/ICMP");
2850 				break;
2851 			}
2852 
2853 			return ret;
2854 		}
2855 
2856 		Wait(r->NewSockConnectEvent, INFINITE);
2857 	}
2858 }
2859 
2860 // Verify the signature of the received packet
RUDPCheckSignOfRecvPacket(RUDP_STACK * r,RUDP_SESSION * se,void * recv_data,UINT recv_size)2861 bool RUDPCheckSignOfRecvPacket(RUDP_STACK *r, RUDP_SESSION *se, void *recv_data, UINT recv_size)
2862 {
2863 	UCHAR sign[SHA1_SIZE];
2864 	UCHAR sign2[SHA1_SIZE];
2865 	UCHAR *p;
2866 	UINT size;
2867 	// Validate arguments
2868 	if (r == NULL || se == NULL || recv_data == NULL || recv_size == 0)
2869 	{
2870 		return false;
2871 	}
2872 
2873 	p = (UCHAR *)recv_data;
2874 	size = recv_size;
2875 	if (size < SHA1_SIZE)
2876 	{
2877 		return false;
2878 	}
2879 
2880 	// Verification the signature (segment packet)
2881 	Copy(sign, p, SHA1_SIZE);
2882 	Copy(p, se->Key_Recv, SHA1_SIZE);
2883 	HashSha1(sign2, p, recv_size);
2884 
2885 	if (r->Protocol == RUDP_PROTOCOL_DNS || r->Protocol == RUDP_PROTOCOL_ICMP)
2886 	{
2887 		XorData(sign2, sign2, r->SvcNameHash, SHA1_SIZE);
2888 	}
2889 
2890 	Copy(p, sign, SHA1_SIZE);
2891 	if (Cmp(sign, sign2, SHA1_SIZE) == 0)
2892 	{
2893 		return true;
2894 	}
2895 
2896 	if (se->BulkRecvKey == NULL)
2897 	{
2898 		return false;
2899 	}
2900 
2901 	// Verification signature (bulk packet)
2902 	if (se->BulkRecvKey->Size == RUDP_BULK_KEY_SIZE_V2)
2903 	{
2904 		// Ver 2
2905 		UCHAR *iv = p;
2906 		// Packet: IV + Encrypted(SEQ_NO + Data + padding) + MAC
2907 		// IV
2908 		if (size < RUDP_BULK_IV_SIZE_V2)
2909 		{
2910 			return false;
2911 		}
2912 		iv = p;
2913 		p += RUDP_BULK_IV_SIZE_V2;
2914 		size -= RUDP_BULK_IV_SIZE_V2;
2915 
2916 		// Decrypt
2917 		if (size < (RUDP_BULK_MAC_SIZE_V2 + 1))
2918 		{
2919 			return false;
2920 		}
2921 		if (Aead_ChaCha20Poly1305_Ietf_Decrypt(r->TmpBuf, p, size, se->BulkRecvKey->Data, iv, NULL, 0) == false)
2922 		{
2923 			return false;
2924 		}
2925 		return true;
2926 	}
2927 	else
2928 	{
2929 		// Ver 1
2930 		if (se->UseHMac == false)
2931 		{
2932 			Copy(sign, p, SHA1_SIZE);
2933 			Copy(p, se->BulkRecvKey->Data, SHA1_SIZE);
2934 			HashSha1(sign2, p, recv_size);
2935 			Copy(p, sign, SHA1_SIZE);
2936 
2937 			if (Cmp(sign, sign2, SHA1_SIZE) == 0)
2938 			{
2939 				return true;
2940 			}
2941 		}
2942 
2943 		HMacSha1(sign2, se->BulkRecvKey->Data, SHA1_SIZE, p + SHA1_SIZE, size - SHA1_SIZE);
2944 		if (Cmp(p, sign2, SHA1_SIZE) == 0)
2945 		{
2946 			se->UseHMac = true;
2947 			return true;
2948 		}
2949 	}
2950 
2951 	return false;
2952 }
2953 
2954 // Process the received packet (bulk)
RUDPProcessBulkRecvPacket(RUDP_STACK * r,RUDP_SESSION * se,void * recv_data,UINT recv_size)2955 bool RUDPProcessBulkRecvPacket(RUDP_STACK *r, RUDP_SESSION *se, void *recv_data, UINT recv_size)
2956 {
2957 	UCHAR sign[SHA1_SIZE];
2958 	UCHAR sign2[SHA1_SIZE];
2959 	UCHAR *p;
2960 	UCHAR *iv;
2961 	UINT size;
2962 	UCHAR keygen[SHA1_SIZE * 2];
2963 	UCHAR key[SHA1_SIZE];
2964 	CRYPT *c;
2965 	UCHAR padlen;
2966 	UINT64 seq_no;
2967 	UCHAR *payload;
2968 	UINT payload_size;
2969 	// Validate arguments
2970 	if (r == NULL || se == NULL || recv_data == NULL || recv_size == 0 || se->BulkRecvKey == NULL)
2971 	{
2972 		return false;
2973 	}
2974 
2975 	p = (UCHAR *)recv_data;
2976 	size = recv_size;
2977 	if (size < SHA1_SIZE)
2978 	{
2979 		return false;
2980 	}
2981 
2982 	if (se->BulkRecvKey->Size == RUDP_BULK_KEY_SIZE_V2)
2983 	{
2984 		// Ver 2
2985 		// Packet: IV + Encrypted(SEQ_NO + Data + padding) + MAC
2986 		// IV
2987 		if (size < RUDP_BULK_IV_SIZE_V2)
2988 		{
2989 			WHERE;
2990 			return false;
2991 		}
2992 		iv = p;
2993 		p += RUDP_BULK_IV_SIZE_V2;
2994 		size -= RUDP_BULK_IV_SIZE_V2;
2995 
2996 		// Decrypt
2997 		if (size < (RUDP_BULK_MAC_SIZE_V2 + 1))
2998 		{
2999 			WHERE;
3000 			return false;
3001 		}
3002 		if (Aead_ChaCha20Poly1305_Ietf_Decrypt(p, p, size, se->BulkRecvKey->Data, iv, NULL, 0) == false)
3003 		{
3004 			WHERE;
3005 			return false;
3006 		}
3007 
3008 		size -= RUDP_BULK_MAC_SIZE_V2;
3009 
3010 		// padlen
3011 		padlen = p[size - 1];
3012 		if (padlen == 0)
3013 		{
3014 			WHERE;
3015 			return false;
3016 		}
3017 		if (size < padlen)
3018 		{
3019 			WHERE;
3020 			return false;
3021 		}
3022 		size -= padlen;
3023 	}
3024 	else
3025 	{
3026 		// Validate the signature
3027 		if (se->UseHMac == false)
3028 		{
3029 			Copy(sign, p, SHA1_SIZE);
3030 			Copy(p, se->BulkRecvKey->Data, SHA1_SIZE);
3031 			HashSha1(sign2, p, recv_size);
3032 			Copy(p, sign, SHA1_SIZE);
3033 
3034 			if (Cmp(sign, sign2, SHA1_SIZE) != 0)
3035 			{
3036 				HMacSha1(sign2, se->BulkRecvKey->Data, SHA1_SIZE, p + SHA1_SIZE, recv_size - SHA1_SIZE);
3037 
3038 				if (Cmp(p, sign2, SHA1_SIZE) != 0)
3039 				{
3040 					return false;
3041 				}
3042 				else
3043 				{
3044 					se->UseHMac = true;
3045 				}
3046 			}
3047 			else
3048 			{
3049 			}
3050 		}
3051 		else
3052 		{
3053 			HMacSha1(sign2, se->BulkRecvKey->Data, SHA1_SIZE, p + SHA1_SIZE, recv_size - SHA1_SIZE);
3054 
3055 			if (Cmp(p, sign2, SHA1_SIZE) != 0)
3056 			{
3057 				return false;
3058 			}
3059 		}
3060 
3061 		p += SHA1_SIZE;
3062 		size -= SHA1_SIZE;
3063 
3064 		// IV
3065 		if (size < SHA1_SIZE)
3066 		{
3067 			return false;
3068 		}
3069 		iv = p;
3070 		p += SHA1_SIZE;
3071 		size -= SHA1_SIZE;
3072 
3073 		// Decrypt
3074 		if (size < 1)
3075 		{
3076 			return false;
3077 		}
3078 		Copy(keygen + 0, se->BulkRecvKey->Data, SHA1_SIZE);
3079 		Copy(keygen + SHA1_SIZE, iv, SHA1_SIZE);
3080 		HashSha1(key, keygen, sizeof(keygen));
3081 
3082 		c = NewCrypt(key, sizeof(key));
3083 		Encrypt(c, p, p, size);
3084 		FreeCrypt(c);
3085 
3086 		// padlen
3087 		padlen = p[size - 1];
3088 		if (padlen == 0)
3089 		{
3090 			return false;
3091 		}
3092 		if (size < padlen)
3093 		{
3094 			return false;
3095 		}
3096 		size -= padlen;
3097 	}
3098 
3099 	// SEQ NO
3100 	seq_no = READ_UINT64(p);
3101 	p += sizeof(UINT64);
3102 	size -= sizeof(UINT64);
3103 
3104 	if (seq_no == 0 || seq_no >= (0xF000000000000000ULL))
3105 	{
3106 		// Sequence number is invalid
3107 		return false;
3108 	}
3109 
3110 	if ((seq_no + RUDP_BULK_SEQ_NO_RANGE) < se->BulkRecvSeqNoMax)
3111 	{
3112 		// Sequence number is too small
3113 		return false;
3114 	}
3115 
3116 	se->LastRecvTick = r->Now;
3117 
3118 	payload = p;
3119 	payload_size = size;
3120 
3121 	se->BulkRecvSeqNoMax = MAX(seq_no, se->BulkRecvSeqNoMax);
3122 
3123 	// Send the received bulk packet to the Tube of the socket
3124 	RUDPInitSock(r, se);
3125 
3126 	if (se->TcpSock != NULL)
3127 	{
3128 		SOCK *s = se->TcpSock;
3129 		TUBE *t = s->BulkSendTube;
3130 
3131 		if (t != NULL)
3132 		{
3133 			TubeSendEx2(t, payload, payload_size, NULL, true, RUDP_BULK_MAX_RECV_PKTS_IN_QUEUE);
3134 
3135 			se->FlushBulkSendTube = true;
3136 		}
3137 	}
3138 
3139 	return true;
3140 }
3141 
3142 // Process the received packet (segment)
RUDPProcessRecvPacket(RUDP_STACK * r,RUDP_SESSION * se,void * recv_data,UINT recv_size)3143 bool RUDPProcessRecvPacket(RUDP_STACK *r, RUDP_SESSION *se, void *recv_data, UINT recv_size)
3144 {
3145 	UCHAR sign[SHA1_SIZE];
3146 	UCHAR sign2[SHA1_SIZE];
3147 	UCHAR *p;
3148 	UCHAR *iv;
3149 	UINT size;
3150 	UCHAR keygen[SHA1_SIZE * 2];
3151 	UCHAR key[SHA1_SIZE];
3152 	CRYPT *c;
3153 	UCHAR padlen;
3154 	UINT num_ack;
3155 	UINT i;
3156 	UINT64 seq_no;
3157 	UCHAR *payload;
3158 	UINT payload_size;
3159 	UINT64 max_ack;
3160 	UINT64 my_tick, your_tick;
3161 	// Validate arguments
3162 	if (r == NULL || se == NULL || recv_data == NULL || recv_size == 0)
3163 	{
3164 		return false;
3165 	}
3166 
3167 	p = (UCHAR *)recv_data;
3168 	size = recv_size;
3169 	if (size < SHA1_SIZE)
3170 	{
3171 		return false;
3172 	}
3173 
3174 	// Validate the signature
3175 	Copy(sign, p, SHA1_SIZE);
3176 	Copy(p, se->Key_Recv, SHA1_SIZE);
3177 	HashSha1(sign2, p, recv_size);
3178 	Copy(p, sign, SHA1_SIZE);
3179 
3180 	if (r->Protocol == RUDP_PROTOCOL_DNS || r->Protocol == RUDP_PROTOCOL_ICMP)
3181 	{
3182 		XorData(sign2, sign2, r->SvcNameHash, SHA1_SIZE);
3183 	}
3184 
3185 	if (Cmp(sign, sign2, SHA1_SIZE) != 0)
3186 	{
3187 		//WHERE;
3188 		return false;
3189 	}
3190 	p += SHA1_SIZE;
3191 	size -= SHA1_SIZE;
3192 
3193 	// IV
3194 	if (size < SHA1_SIZE)
3195 	{
3196 		return false;
3197 	}
3198 	iv = p;
3199 	p += SHA1_SIZE;
3200 	size -= SHA1_SIZE;
3201 
3202 	// Decrypt
3203 	if (size < 1)
3204 	{
3205 		return false;
3206 	}
3207 	Copy(keygen + 0, iv, SHA1_SIZE);
3208 	Copy(keygen + SHA1_SIZE, se->Key_Recv, SHA1_SIZE);
3209 	HashSha1(key, keygen, sizeof(keygen));
3210 
3211 	c = NewCrypt(key, sizeof(key));
3212 	Encrypt(c, p, p, size);
3213 	FreeCrypt(c);
3214 
3215 	// padlen
3216 	padlen = p[size - 1];
3217 	if (padlen == 0)
3218 	{
3219 		return false;
3220 	}
3221 	if (size < padlen)
3222 	{
3223 		return false;
3224 	}
3225 	size -= padlen;
3226 
3227 	// MyTick
3228 	if (size < sizeof(UINT64))
3229 	{
3230 		return false;
3231 	}
3232 	my_tick = READ_UINT64(p);
3233 	p += sizeof(UINT64);
3234 	size -= sizeof(UINT64);
3235 
3236 	// YourTick
3237 	if (size < sizeof(UINT64))
3238 	{
3239 		return false;
3240 	}
3241 	your_tick = READ_UINT64(p);
3242 	p += sizeof(UINT64);
3243 	size -= sizeof(UINT64);
3244 
3245 	if (your_tick > r->Now)
3246 	{
3247 		return false;
3248 	}
3249 
3250 	// MAX_ACK
3251 	if (size < sizeof(UINT64))
3252 	{
3253 		return false;
3254 	}
3255 	max_ack = READ_UINT64(p);
3256 	p += sizeof(UINT64);
3257 	size -= sizeof(UINT64);
3258 
3259 	// num_ack
3260 	if (size < sizeof(UINT))
3261 	{
3262 		return false;
3263 	}
3264 
3265 	num_ack = READ_UINT(p);
3266 	if (num_ack > RUDP_MAX_NUM_ACK)
3267 	{
3268 		return false;
3269 	}
3270 	p += sizeof(UINT);
3271 	size -= sizeof(UINT);
3272 
3273 	// ACKs
3274 	if (size < (sizeof(UINT64) * num_ack + sizeof(UINT64)))
3275 	{
3276 		return false;
3277 	}
3278 
3279 	if (max_ack >= 1)
3280 	{
3281 		RUDPProcessAck2(r, se, max_ack);
3282 	}
3283 
3284 	for (i = 0;i < num_ack;i++)
3285 	{
3286 		UINT64 seq = READ_UINT64(p);
3287 
3288 		RUDPProcessAck(r, se, seq);
3289 
3290 		p += sizeof(UINT64);
3291 		size -= sizeof(UINT64);
3292 	}
3293 
3294 	// Processing of the Tick (Calculation of RTT)
3295 	if (my_tick >= 2)
3296 	{
3297 		my_tick--;
3298 	}
3299 	se->YourTick = MAX(se->YourTick, my_tick);
3300 
3301 	se->LatestRecvMyTick = MAX(se->LatestRecvMyTick, your_tick);
3302 
3303 	if (se->LatestRecvMyTick2 != se->LatestRecvMyTick)
3304 	{
3305 		se->LatestRecvMyTick2 = se->LatestRecvMyTick;
3306 		se->CurrentRtt = (UINT)(r->Now - se->LatestRecvMyTick);
3307 
3308 #ifdef	RUDP_DETAIL_LOG
3309 		Debug("CurrentRTT = %u\n", se->CurrentRtt);
3310 #endif	// RUDP_DETAIL_LOG
3311 	}
3312 
3313 	// SEQ NO
3314 	seq_no = READ_UINT64(p);
3315 	p += sizeof(UINT64);
3316 	size -= sizeof(UINT64);
3317 
3318 	if (seq_no == 0)
3319 	{
3320 		// Sequence number of 0 is a invalid packet
3321 		return true;
3322 	}
3323 
3324 	if (seq_no == se->Magic_Disconnect)
3325 	{
3326 		// Disconnected from opponent
3327 		RUDPDisconnectSession(r, se, true);
3328 		return true;
3329 	}
3330 
3331 	// Update the last reception date and time
3332 	se->LastRecvTick = r->Now;
3333 
3334 	payload = p;
3335 	payload_size = size;
3336 
3337 #ifdef	RUDP_DETAIL_LOG
3338 	Debug("RUDP %X Segment Recv: %I64u (num_ack=%u, size=%u)\n", se, seq_no, num_ack, size);
3339 #endif	// RUDP_DETAIL_LOG
3340 
3341 	if (payload_size >= 1 && payload_size <= RUDP_MAX_SEGMENT_SIZE)
3342 	{
3343 		// Received one or more bytes of data
3344 
3345 #ifdef	RUDP_DETAIL_LOG
3346 		Debug("Recv Size: %X %I64u %u %u\n", se, seq_no, payload_size, recv_size);
3347 #endif	// RUDP_DETAIL_LOG
3348 
3349 		RUDPProcessRecvPayload(r, se, seq_no, payload, payload_size);
3350 	}
3351 
3352 	if (r->ServerMode == false)
3353 	{
3354 		if (se->Status == RUDP_SESSION_STATUS_CONNECT_SENT)
3355 		{
3356 			// Shift to the established state if the connection is not yet in established state
3357 			se->Status = RUDP_SESSION_STATUS_ESTABLISHED;
3358 
3359 			RUDPInitSock(r, se);
3360 		}
3361 	}
3362 
3363 	return true;
3364 }
3365 
3366 // Disconnect the session
RUDPDisconnectSession(RUDP_STACK * r,RUDP_SESSION * se,bool disconnected_by_you)3367 void RUDPDisconnectSession(RUDP_STACK *r, RUDP_SESSION *se, bool disconnected_by_you)
3368 {
3369 	// Validate arguments
3370 	if (r == NULL || se == NULL)
3371 	{
3372 		return;
3373 	}
3374 
3375 	if (se->DisconnectFlag == false)
3376 	{
3377 		UINT i;
3378 
3379 		se->DisconnectFlag = true;
3380 		se->DisconnectedByYou = disconnected_by_you;
3381 
3382 		Debug("R-UDP Session %X Disconnected. by you flag: %u\n", se, disconnected_by_you);
3383 
3384 		if (se->TcpSock != NULL)
3385 		{
3386 			// Disconnect a TCP socket
3387 			Disconnect(se->TcpSock);
3388 			ReleaseSock(se->TcpSock);
3389 
3390 			se->TcpSock = NULL;
3391 		}
3392 
3393 		// Send 5 disconnect signals serially if to disconnect from here
3394 		if (disconnected_by_you == false)
3395 		{
3396 			for (i = 0;i < 5;i++)
3397 			{
3398 				RUDPSendSegmentNow(r, se, se->Magic_Disconnect, NULL, 0);
3399 			}
3400 		}
3401 	}
3402 }
3403 
3404 // Initialize the TCP socket for the session
RUDPInitSock(RUDP_STACK * r,RUDP_SESSION * se)3405 void RUDPInitSock(RUDP_STACK *r, RUDP_SESSION *se)
3406 {
3407 	SOCK *s1, *s2;
3408 	UINT mss;
3409 	// Validate arguments
3410 	if (r == NULL || se == NULL || se->DisconnectFlag)
3411 	{
3412 		return;
3413 	}
3414 
3415 	if (se->TcpSock != NULL)
3416 	{
3417 		// It has already been created
3418 		return;
3419 	}
3420 
3421 	// Creating a TCP socket pair
3422 	if (NewTcpPair(&s1, &s2) == false)
3423 	{
3424 		// Failed to create. Disconnect the session
3425 		RUDPDisconnectSession(r, se, false);
3426 		return;
3427 	}
3428 
3429 	// Calculate the optimal MSS
3430 	mss = RUDPCalcBestMssForBulk(r, se);
3431 
3432 	if (r->ServerMode)
3433 	{
3434 		// Server mode
3435 		se->TcpSock = s2;
3436 
3437 		JoinSockToSockEvent(s2, r->SockEvent);
3438 
3439 		// Update the end point information of the socket s1
3440 		ZeroIP4(&s1->LocalIP);
3441 		s1->LocalPort = se->MyPort;
3442 		Copy(&s1->RemoteIP, &se->YourIp, sizeof(IP));
3443 		s1->RemotePort = se->YourPort;
3444 		if (IsLocalHostIP(&s1->RemoteIP) == false)
3445 		{
3446 			AddIpClient(&s1->RemoteIP);
3447 			s1->IpClientAdded = true;
3448 		}
3449 		s1->IsRUDPSocket = true;
3450 
3451 		s1->BulkSendKey = se->BulkSendKey;
3452 		s1->BulkRecvKey = se->BulkRecvKey;
3453 
3454 		AddRef(s1->BulkSendKey->Ref);
3455 		AddRef(s1->BulkRecvKey->Ref);
3456 
3457 		s1->RUDP_OptimizedMss = mss;
3458 
3459 		// Enqueue the newly created socket, and set the event
3460 		InsertQueueWithLock(r->NewSockQueue, s1);
3461 		Set(r->NewSockConnectEvent);
3462 	}
3463 	else
3464 	{
3465 		// Client mode
3466 		Lock(r->Lock);
3467 		{
3468 			if (r->TargetConnectedSock == NULL && r->DoNotSetTargetConnectedSock == false)
3469 			{
3470 				// Update the end point information of the socket s2
3471 				Copy(&s2->LocalIP, &r->UdpSock->LocalIP, sizeof(IP));
3472 				s2->LocalPort = se->MyPort;
3473 				Copy(&s2->RemoteIP, &se->YourIp, sizeof(IP));
3474 				s2->RemotePort = se->YourPort;
3475 				if (IsLocalHostIP(&s2->RemoteIP) == false)
3476 				{
3477 					AddIpClient(&s2->RemoteIP);
3478 					s2->IpClientAdded = true;
3479 				}
3480 				s2->IsRUDPSocket = true;
3481 
3482 				s2->BulkSendKey = se->BulkSendKey;
3483 				s2->BulkRecvKey = se->BulkRecvKey;
3484 
3485 				AddRef(s2->BulkSendKey->Ref);
3486 				AddRef(s2->BulkRecvKey->Ref);
3487 
3488 				s2->RUDP_OptimizedMss = mss;
3489 
3490 				// Register the socket to the RUDP stack
3491 				r->TargetConnectedSock = s2;
3492 				s2->R_UDP_Stack = r;
3493 				se->TcpSock = s1;
3494 
3495 				JoinSockToSockEvent(s1, r->SockEvent);
3496 
3497 				// Set the event to be set when the connection is successful
3498 				Set(r->TargetConnectedEvent);
3499 			}
3500 			else
3501 			{
3502 				Disconnect(s1);
3503 				Disconnect(s2);
3504 				ReleaseSock(s1);
3505 				ReleaseSock(s2);
3506 			}
3507 		}
3508 		Unlock(r->Lock);
3509 	}
3510 }
3511 
3512 // Process the received payload
RUDPProcessRecvPayload(RUDP_STACK * r,RUDP_SESSION * se,UINT64 seq,void * payload_data,UINT payload_size)3513 void RUDPProcessRecvPayload(RUDP_STACK *r, RUDP_SESSION *se, UINT64 seq, void *payload_data, UINT payload_size)
3514 {
3515 	RUDP_SEGMENT t;
3516 	RUDP_SEGMENT *s;
3517 	// Validate arguments
3518 	if (r == NULL || se == NULL || seq == 0 || payload_data == NULL || payload_size == 0 || payload_size > RUDP_MAX_SEGMENT_SIZE)
3519 	{
3520 		return;
3521 	}
3522 
3523 	if (seq > (se->LastRecvCompleteSeqNo + RUDP_MAX_NUM_ACK))
3524 	{
3525 		// Ignore the segment which have sequence number beyond the window size, and also not to reply an ACK
3526 		return;
3527 	}
3528 
3529 	if (seq <= se->LastRecvCompleteSeqNo)
3530 	{
3531 		// Do not receive the segment which have the sequence number that has been already received. However, reply an ACK for it
3532 		AddInt64Distinct(se->ReplyAckList, seq);
3533 		return;
3534 	}
3535 
3536 	Zero(&t, sizeof(t));
3537 	t.SeqNo = seq;
3538 
3539 	s = Search(se->RecvSegmentList, &t);
3540 	if (s != NULL)
3541 	{
3542 		// Do not receive the segment which have the sequence number that has been already received. However, reply an ACK for it
3543 		AddInt64Distinct(se->ReplyAckList, seq);
3544 		return;
3545 	}
3546 
3547 	// Received a segment of the new sequence number
3548 	s = ZeroMalloc(sizeof(RUDP_SEGMENT));
3549 	s->SeqNo = seq;
3550 	Copy(s->Data, payload_data, payload_size);
3551 	s->Size = payload_size;
3552 	Insert(se->RecvSegmentList, s);
3553 
3554 	// Reply an ACK
3555 	AddInt64Distinct(se->ReplyAckList, seq);
3556 
3557 	// Create a socket for session if it have not been created yet
3558 	//RUDPInitSock(r, se);
3559 }
3560 
3561 // Process the incoming ACK
RUDPProcessAck(RUDP_STACK * r,RUDP_SESSION * se,UINT64 seq)3562 void RUDPProcessAck(RUDP_STACK *r, RUDP_SESSION *se, UINT64 seq)
3563 {
3564 	RUDP_SEGMENT t;
3565 	RUDP_SEGMENT *s;
3566 	// Validate arguments
3567 	if (r == NULL || se == NULL || seq == 0)
3568 	{
3569 		return;
3570 	}
3571 
3572 	Zero(&t, sizeof(t));
3573 	t.SeqNo = seq;
3574 
3575 	s = Search(se->SendSegmentList, &t);
3576 	if (s == NULL)
3577 	{
3578 		return;
3579 	}
3580 
3581 	Delete(se->SendSegmentList, s);
3582 	Free(s);
3583 }
3584 
3585 // Remove all segments which are preceding max_seq as already delivered
RUDPProcessAck2(RUDP_STACK * r,RUDP_SESSION * se,UINT64 max_seq)3586 void RUDPProcessAck2(RUDP_STACK *r, RUDP_SESSION *se, UINT64 max_seq)
3587 {
3588 	LIST *o;
3589 	UINT i;
3590 	// Validate arguments
3591 	if (r == NULL || se == NULL || max_seq == 0)
3592 	{
3593 		return;
3594 	}
3595 
3596 	o = NULL;
3597 
3598 	for (i = 0;i < LIST_NUM(se->SendSegmentList);i++)
3599 	{
3600 		RUDP_SEGMENT *s = LIST_DATA(se->SendSegmentList, i);
3601 
3602 		if (s->SeqNo <= max_seq)
3603 		{
3604 			if (o == NULL)
3605 			{
3606 				o = NewListFast(NULL);
3607 			}
3608 
3609 			Add(o, s);
3610 		}
3611 	}
3612 
3613 	if (o != NULL)
3614 	{
3615 		for (i = 0;i < LIST_NUM(o);i++)
3616 		{
3617 			RUDP_SEGMENT *s = LIST_DATA(o, i);
3618 
3619 			Delete(se->SendSegmentList, s);
3620 
3621 			Free(s);
3622 		}
3623 
3624 		ReleaseList(o);
3625 	}
3626 }
3627 
3628 // Get the minimum sequence number which is trying to send
RUDPGetCurrentSendingMinSeqNo(RUDP_SESSION * se)3629 UINT64 RUDPGetCurrentSendingMinSeqNo(RUDP_SESSION *se)
3630 {
3631 	RUDP_SEGMENT *s;
3632 	// Validate arguments
3633 	if (se == NULL)
3634 	{
3635 		return 0;
3636 	}
3637 
3638 	if (LIST_NUM(se->SendSegmentList) == 0)
3639 	{
3640 		return 0;
3641 	}
3642 
3643 	s = LIST_DATA(se->SendSegmentList, 0);
3644 
3645 	return s->SeqNo;
3646 }
3647 
3648 // Get the maximum sequence number which is trying to send
RUDPGetCurrentSendingMaxSeqNo(RUDP_SESSION * se)3649 UINT64 RUDPGetCurrentSendingMaxSeqNo(RUDP_SESSION *se)
3650 {
3651 	RUDP_SEGMENT *s;
3652 	// Validate arguments
3653 	if (se == NULL)
3654 	{
3655 		return 0;
3656 	}
3657 
3658 	if (LIST_NUM(se->SendSegmentList) == 0)
3659 	{
3660 		return 0;
3661 	}
3662 
3663 	s = LIST_DATA(se->SendSegmentList, (LIST_NUM(se->SendSegmentList) - 1));
3664 
3665 	return s->SeqNo;
3666 }
3667 
3668 // R-UDP segment transmission
RUDPSendSegmentNow(RUDP_STACK * r,RUDP_SESSION * se,UINT64 seq_no,void * data,UINT size)3669 void RUDPSendSegmentNow(RUDP_STACK *r, RUDP_SESSION *se, UINT64 seq_no, void *data, UINT size)
3670 {
3671 	UCHAR dst[RUDP_MAX_PACKET_SIZE];
3672 	UCHAR *p;
3673 	UCHAR *iv;
3674 	LIST *o = NULL;
3675 	UINT i;
3676 	UCHAR padlen;
3677 	UINT current_size;
3678 	UCHAR sign[SHA1_SIZE];
3679 	UCHAR key[SHA1_SIZE];
3680 	UCHAR keygen[SHA1_SIZE * 2];
3681 	CRYPT *c;
3682 	UINT next_iv_pos;
3683 	UINT num_ack;
3684 	UINT icmp_type = 0;
3685 	// Validate arguments
3686 	if (r == NULL || se == NULL || (size != 0 && data == NULL) || (size > RUDP_MAX_SEGMENT_SIZE))
3687 	{
3688 		return;
3689 	}
3690 
3691 	Zero(dst, sizeof(dst));
3692 	p = dst;
3693 
3694 	// SIGN
3695 	Copy(p, se->Key_Send, SHA1_SIZE);
3696 	p += SHA1_SIZE;
3697 
3698 	// IV
3699 	iv = p;
3700 	Copy(iv, se->NextIv, SHA1_SIZE);
3701 	p += SHA1_SIZE;
3702 
3703 	for (i = 0;i < MIN(LIST_NUM(se->ReplyAckList), RUDP_MAX_NUM_ACK);i++)
3704 	{
3705 		UINT64 *seq = LIST_DATA(se->ReplyAckList, i);
3706 
3707 		if (o == NULL)
3708 		{
3709 			o = NewListFast(NULL);
3710 		}
3711 
3712 		Add(o, seq);
3713 	}
3714 
3715 	// MyTick
3716 	WRITE_UINT64(p, r->Now);
3717 	p += sizeof(UINT64);
3718 
3719 	// YourTick
3720 	WRITE_UINT64(p, se->YourTick);
3721 	p += sizeof(UINT64);
3722 
3723 	// MAX_ACK
3724 	WRITE_UINT64(p, se->LastRecvCompleteSeqNo);
3725 	p += sizeof(UINT64);
3726 
3727 	// NUM_ACK
3728 	num_ack = LIST_NUM(o);
3729 	WRITE_UINT(p, num_ack);
3730 	p += sizeof(UINT);
3731 
3732 	if (o != NULL)
3733 	{
3734 		// ACK body
3735 		for (i = 0;i < LIST_NUM(o);i++)
3736 		{
3737 			UINT64 *seq = LIST_DATA(o, i);
3738 
3739 			WRITE_UINT64(p, *seq);
3740 			p += sizeof(UINT64);
3741 
3742 			Delete(se->ReplyAckList, seq);
3743 
3744 			Free(seq);
3745 		}
3746 		ReleaseList(o);
3747 	}
3748 
3749 	// SEQ
3750 	WRITE_UINT64(p, seq_no);
3751 	p += sizeof(UINT64);
3752 
3753 	// data
3754 	Copy(p, data, size);
3755 	p += size;
3756 
3757 	// padding
3758 	padlen = Rand8();
3759 	padlen = MAX(padlen, 1);
3760 
3761 	for (i = 0;i < padlen;i++)
3762 	{
3763 		*p = padlen;
3764 		p++;
3765 	}
3766 
3767 	current_size = (UINT)(p - dst);
3768 
3769 	// Encrypt
3770 	Copy(keygen + 0, iv, SHA1_SIZE);
3771 	Copy(keygen + SHA1_SIZE, se->Key_Send, SHA1_SIZE);
3772 	HashSha1(key, keygen, sizeof(keygen));
3773 	c = NewCrypt(key, sizeof(key));
3774 	Encrypt(c, dst + SHA1_SIZE * 2, dst + SHA1_SIZE * 2, current_size - (SHA1_SIZE * 2));
3775 	FreeCrypt(c);
3776 
3777 	// Sign
3778 	HashSha1(sign, dst, current_size);
3779 	if (r->Protocol == RUDP_PROTOCOL_DNS || r->Protocol == RUDP_PROTOCOL_ICMP)
3780 	{
3781 		XorData(sign, sign, r->SvcNameHash, SHA1_SIZE);
3782 	}
3783 	Copy(dst, sign, SHA1_SIZE);
3784 
3785 	if (r->Protocol == RUDP_PROTOCOL_ICMP)
3786 	{
3787 		icmp_type = se->Icmp_Type;
3788 	}
3789 	else if (r->Protocol == RUDP_PROTOCOL_DNS)
3790 	{
3791 		icmp_type = se->Dns_TranId;
3792 	}
3793 	RUDPSendPacket(r, &se->YourIp, se->YourPort, dst, current_size, icmp_type);
3794 
3795 	if (size >= 1)
3796 	{
3797 		se->LastSentTick = r->Now;
3798 	}
3799 
3800 	// Next IV
3801 	next_iv_pos = Rand32() % (current_size - SHA1_SIZE);
3802 	Copy(se->NextIv, dst + next_iv_pos, SHA1_SIZE);
3803 
3804 #ifdef	RUDP_DETAIL_LOG
3805 	Debug("RUDP %X Segment Sent: %I64u (num_ack=%u, size=%u)\n", se, seq_no, num_ack, size);
3806 #endif	// RUDP_DETAIL_LOG
3807 
3808 	if (size >= 1)
3809 	{
3810 #ifdef	RUDP_DETAIL_LOG
3811 		Debug("Send Size: %X %I64u %u %u\n", se, seq_no, size, current_size);
3812 #endif	// RUDP_DETAIL_LOG
3813 	}
3814 }
3815 
3816 // R-UDP segment transmission (only put into the queue)
RUDPSendSegment(RUDP_STACK * r,RUDP_SESSION * se,void * data,UINT size)3817 void RUDPSendSegment(RUDP_STACK *r, RUDP_SESSION *se, void *data, UINT size)
3818 {
3819 	RUDP_SEGMENT *s;
3820 	// Validate arguments
3821 	if (r == NULL || se == NULL || (size != 0 && data == NULL) || (size > RUDP_MAX_SEGMENT_SIZE))
3822 	{
3823 		return;
3824 	}
3825 
3826 	s = ZeroMalloc(sizeof(RUDP_SEGMENT));
3827 
3828 	Copy(s->Data, data, size);
3829 	s->Size = size;
3830 
3831 	s->SeqNo = se->NextSendSeqNo++;
3832 
3833 	Insert(se->SendSegmentList, s);
3834 }
3835 
3836 // Search for a session
RUDPSearchSession(RUDP_STACK * r,IP * my_ip,UINT my_port,IP * your_ip,UINT your_port)3837 RUDP_SESSION *RUDPSearchSession(RUDP_STACK *r, IP *my_ip, UINT my_port, IP *your_ip, UINT your_port)
3838 {
3839 	RUDP_SESSION t;
3840 	RUDP_SESSION *se;
3841 	// Validate arguments
3842 	if (r == NULL || my_ip == NULL || your_ip == NULL)
3843 	{
3844 		return NULL;
3845 	}
3846 
3847 	Copy(&t.MyIp, my_ip, sizeof(IP));
3848 	t.MyPort = my_port;
3849 	Copy(&t.YourIp, your_ip, sizeof(IP));
3850 	t.YourPort = your_port;
3851 
3852 	se = Search(r->SessionList, &t);
3853 
3854 	return se;
3855 }
3856 
3857 // Release of the session
RUDPFreeSession(RUDP_SESSION * se)3858 void RUDPFreeSession(RUDP_SESSION *se)
3859 {
3860 	UINT i;
3861 	// Validate arguments
3862 	if (se == NULL)
3863 	{
3864 		return;
3865 	}
3866 
3867 	Debug("RUDPFreeSession %X\n", se);
3868 
3869 	for (i = 0;i < LIST_NUM(se->SendSegmentList);i++)
3870 	{
3871 		RUDP_SEGMENT *s = LIST_DATA(se->SendSegmentList, i);
3872 
3873 		Free(s);
3874 	}
3875 
3876 	ReleaseList(se->SendSegmentList);
3877 
3878 	for (i = 0;i < LIST_NUM(se->RecvSegmentList);i++)
3879 	{
3880 		RUDP_SEGMENT *s = LIST_DATA(se->RecvSegmentList, i);
3881 
3882 		Free(s);
3883 	}
3884 
3885 	ReleaseList(se->RecvSegmentList);
3886 
3887 	if (se->TcpSock != NULL)
3888 	{
3889 		Disconnect(se->TcpSock);
3890 		ReleaseSock(se->TcpSock);
3891 	}
3892 
3893 	ReleaseInt64List(se->ReplyAckList);
3894 
3895 	ReleaseFifo(se->RecvFifo);
3896 	ReleaseFifo(se->SendFifo);
3897 
3898 	ReleaseSharedBuffer(se->BulkSendKey);
3899 	ReleaseSharedBuffer(se->BulkRecvKey);
3900 
3901 	Free(se);
3902 }
3903 
3904 // Create a new session
RUDPNewSession(bool server_mode,IP * my_ip,UINT my_port,IP * your_ip,UINT your_port,UCHAR * init_key)3905 RUDP_SESSION *RUDPNewSession(bool server_mode, IP *my_ip, UINT my_port, IP *your_ip, UINT your_port, UCHAR *init_key)
3906 {
3907 	RUDP_SESSION *se;
3908 	UCHAR key1[SHA1_SIZE];
3909 	UCHAR key2[SHA1_SIZE];
3910 	UCHAR bulk_send_key[RUDP_BULK_KEY_SIZE_MAX];
3911 	UCHAR bulk_recv_key[RUDP_BULK_KEY_SIZE_MAX];
3912 	BUF *b;
3913 
3914 	se = ZeroMalloc(sizeof(RUDP_SESSION));
3915 
3916 	Copy(&se->MyIp, my_ip, sizeof(IP));
3917 	se->MyPort = my_port;
3918 
3919 	Copy(&se->YourIp, your_ip, sizeof(IP));
3920 	se->YourPort = your_port;
3921 
3922 	Copy(se->Key_Init, init_key, SHA1_SIZE);
3923 	se->LastSentTick = 0;
3924 	se->LastRecvTick = Tick64();
3925 	se->LatestRecvMyTick = Tick64();
3926 
3927 	se->NextSendSeqNo = 1;
3928 
3929 	se->ServerMode = server_mode;
3930 
3931 	se->SendSegmentList = NewList(RUDPCompareSegmentList);
3932 	se->RecvSegmentList = NewList(RUDPCompareSegmentList);
3933 
3934 	// Generate the two keys
3935 	b = NewBuf();
3936 	WriteBuf(b, init_key, SHA1_SIZE);
3937 	WriteBufStr(b, "zurukko");
3938 	HashSha1(key1, b->Buf, b->Size);
3939 	FreeBuf(b);
3940 
3941 	b = NewBuf();
3942 	WriteBuf(b, init_key, SHA1_SIZE);
3943 	WriteBuf(b, key1, SHA1_SIZE);
3944 	WriteBufStr(b, "yasushineko");
3945 	HashSha1(key2, b->Buf, b->Size);
3946 	FreeBuf(b);
3947 
3948 	// Generate the magic number for the KeepAlive
3949 	b = NewBuf();
3950 	WriteBuf(b, init_key, SHA1_SIZE);
3951 	WriteBufStr(b, "Magic_KeepAliveRequest");
3952 	HashSha1(se->Magic_KeepAliveRequest, b->Buf, b->Size);
3953 	FreeBuf(b);
3954 	b = NewBuf();
3955 	WriteBuf(b, init_key, SHA1_SIZE);
3956 	WriteBufStr(b, "Magic_KeepAliveResponse");
3957 	HashSha1(se->Magic_KeepAliveResponse, b->Buf, b->Size);
3958 	FreeBuf(b);
3959 
3960 	if (server_mode == false)
3961 	{
3962 		se->Magic_Disconnect = 0xffffffff00000000ULL | (UINT64)(Rand32());
3963 	}
3964 
3965 	Copy(se->Key_Init, init_key, SHA1_SIZE);
3966 
3967 	if (se->ServerMode)
3968 	{
3969 		Copy(se->Key_Send, key1, SHA1_SIZE);
3970 		Copy(se->Key_Recv, key2, SHA1_SIZE);
3971 	}
3972 	else
3973 	{
3974 		Copy(se->Key_Send, key2, SHA1_SIZE);
3975 		Copy(se->Key_Recv, key1, SHA1_SIZE);
3976 	}
3977 
3978 	Rand(se->NextIv, sizeof(se->NextIv));
3979 
3980 	se->ReplyAckList = NewInt64List(true);
3981 
3982 	se->NextKeepAliveInterval = RUDP_KEEPALIVE_INTERVAL_MIN + (Rand32() % (RUDP_KEEPALIVE_INTERVAL_MAX - RUDP_KEEPALIVE_INTERVAL_MIN));
3983 
3984 	se->RecvFifo = NewFifo();
3985 	se->SendFifo = NewFifo();
3986 
3987 	se->Dns_TranId = Rand16() % 65535 + 1;
3988 
3989 	// Generate the bulk transfer key
3990 	Rand(bulk_send_key, sizeof(bulk_send_key));
3991 	Rand(bulk_recv_key, sizeof(bulk_recv_key));
3992 
3993 	se->BulkSendKey = NewSharedBuffer(bulk_send_key, sizeof(bulk_send_key));
3994 	se->BulkRecvKey = NewSharedBuffer(bulk_recv_key, sizeof(bulk_recv_key));
3995 
3996 	Rand(se->BulkNextIv, sizeof(se->BulkNextIv));
3997 	Rand(se->BulkNextIv_V2, sizeof(se->BulkNextIv_V2));
3998 
3999 	se->BulkNextSeqNo = 1;
4000 
4001 	return se;
4002 }
4003 
4004 // Comparison function of the segment list items
RUDPCompareSegmentList(void * p1,void * p2)4005 int RUDPCompareSegmentList(void *p1, void *p2)
4006 {
4007 	RUDP_SEGMENT *s1, *s2;
4008 	UINT r;
4009 	// Validate arguments
4010 	if (p1 == NULL || p2 == NULL)
4011 	{
4012 		return 0;
4013 	}
4014 	s1 = *((RUDP_SEGMENT **)p1);
4015 	s2 = *((RUDP_SEGMENT **)p2);
4016 	if (s1 == NULL || s2 == NULL)
4017 	{
4018 		return 0;
4019 	}
4020 
4021 	r = COMPARE_RET(s1->SeqNo, s2->SeqNo);
4022 
4023 	return r;
4024 }
4025 
4026 // Send a UDP packet
RUDPSendPacket(RUDP_STACK * r,IP * dest_ip,UINT dest_port,void * data,UINT size,UINT icmp_type)4027 void RUDPSendPacket(RUDP_STACK *r, IP *dest_ip, UINT dest_port, void *data, UINT size, UINT icmp_type)
4028 {
4029 	UDPPACKET *p;
4030 	// Validate arguments
4031 	if (r == NULL || dest_ip == NULL || dest_port == 0 || data == NULL || size == 0)
4032 	{
4033 		return;
4034 	}
4035 
4036 	p = NewUdpPacket(&r->UdpSock->LocalIP, r->UdpSock->LocalPort,
4037 		dest_ip, dest_port,
4038 		Clone(data, size), size);
4039 
4040 	if (r->Protocol == RUDP_PROTOCOL_ICMP || r->Protocol == RUDP_PROTOCOL_DNS)
4041 	{
4042 		// ICMP Type / DNS Tran ID
4043 		p->Type = icmp_type;
4044 	}
4045 
4046 	Add(r->SendPacketList, p);
4047 }
4048 
4049 // R-UDP main thread
RUDPMainThread(THREAD * thread,void * param)4050 void RUDPMainThread(THREAD *thread, void *param)
4051 {
4052 	RUDP_STACK *r;
4053 	bool halt_flag = false;
4054 	// Validate arguments
4055 	if (thread == NULL || param == NULL)
4056 	{
4057 		return;
4058 	}
4059 
4060 	r = (RUDP_STACK *)param;
4061 
4062 	AddWaitThread(thread);
4063 	NoticeThreadInit(thread);
4064 
4065 	while (true)
4066 	{
4067 		UINT wait_interval;
4068 		UINT i;
4069 		UINT min_wait_interval;
4070 		UINT num_ignore_errors = 0;
4071 
4072 		r->Now = Tick64();
4073 
4074 		Lock(r->Lock);
4075 		{
4076 			Copy(&r->NatT_IP_Safe, &r->NatT_IP, sizeof(IP));
4077 			Copy(&r->My_Private_IP_Safe, &r->My_Private_IP, sizeof(IP));
4078 		}
4079 		Unlock(r->Lock);
4080 
4081 		// Receive the data from the UDP socket
4082 		while (true)
4083 		{
4084 			UINT ret;
4085 			IP ip_src;
4086 			UINT port_src;
4087 
4088 			ret = RecvFrom(r->UdpSock, &ip_src, &port_src, r->TmpBuf, sizeof(r->TmpBuf));
4089 
4090 			if (ret == SOCK_LATER)
4091 			{
4092 				// There is no packet more
4093 				break;
4094 			}
4095 			else if (ret != 0)
4096 			{
4097 				// Receive a Packet
4098 				bool ok = false;
4099 				UDPPACKET *p = NewUdpPacket(&ip_src, port_src,
4100 					&r->UdpSock->LocalIP, r->UdpSock->LocalPort,
4101 					Clone(r->TmpBuf, ret), ret);
4102 
4103 				if (r->Protocol == RUDP_PROTOCOL_ICMP)
4104 				{
4105 					// Analyse the incoming ICMP packet
4106 					UINT ip_header_size = GetIpHeaderSize(p->Data, p->Size);
4107 
4108 					if (ip_header_size >= sizeof(IPV4_HEADER))
4109 					{
4110 						if (p->Size >= (ip_header_size + sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO) + SHA1_SIZE))
4111 						{
4112 							IPV4_HEADER *ip_header = (IPV4_HEADER *)(((UCHAR *)p->Data) + 0);
4113 							ICMP_HEADER *icmp_header = (ICMP_HEADER *)(((UCHAR *)p->Data) + ip_header_size);
4114 							ICMP_ECHO *echo_header = (ICMP_ECHO *)(((UCHAR *)p->Data) + ip_header_size + sizeof(ICMP_HEADER));
4115 
4116 							if (icmp_header->Type == ICMP_TYPE_ECHO_RESPONSE ||
4117 								icmp_header->Type == (r->ServerMode ? ICMP_TYPE_INFORMATION_REQUEST : ICMP_TYPE_INFORMATION_REPLY))
4118 							{
4119 								UCHAR hash[SHA1_SIZE];
4120 
4121 								HashSha1(hash, ((UCHAR *)p->Data) + ip_header_size + sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO) + SHA1_SIZE,
4122 									p->Size - (ip_header_size + sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO) + SHA1_SIZE));
4123 
4124 								if (Cmp(hash, ((UCHAR *)p->Data) + ip_header_size + sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO), SHA1_SIZE) == 0)
4125 								{
4126 									UCHAR *new_data;
4127 									UINT new_data_size;
4128 									if (r->ServerMode)
4129 									{
4130 										// On the server side, the ICMP ID and the SEQ NO of received messages are treated as a source port number
4131 										Copy(&p->SrcPort, echo_header, sizeof(UINT));
4132 									}
4133 
4134 									// Record the Type
4135 									p->Type = icmp_header->Type;
4136 
4137 									// Erase the header part
4138 									new_data_size = p->Size - (ip_header_size + sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO) + SHA1_SIZE);
4139 									new_data = Clone(((UCHAR *)p->Data) + ip_header_size + sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO) + SHA1_SIZE, new_data_size);
4140 									Free(p->Data);
4141 									p->Data = new_data;
4142 									p->Size = new_data_size;
4143 
4144 									ok = true;
4145 								}
4146 							}
4147 						}
4148 					}
4149 				}
4150 				else if (r->Protocol == RUDP_PROTOCOL_DNS)
4151 				{
4152 					// Analyse the incoming DNS packet
4153 					UINT offset;
4154 
4155 					if (r->ServerMode == false)
4156 					{
4157 						offset = 42;
4158 					}
4159 					else
4160 					{
4161 						offset = 37;
4162 					}
4163 
4164 					if (p->Size > offset)
4165 					{
4166 						UCHAR *new_data;
4167 						UINT new_size = p->Size - offset;
4168 
4169 						p->Type = *((USHORT *)p->Data);
4170 
4171 						new_data = Clone(((UCHAR *)p->Data) + offset, new_size);
4172 
4173 						Free(p->Data);
4174 						p->Data = new_data;
4175 						p->Size = new_size;
4176 
4177 						ok = true;
4178 					}
4179 				}
4180 				else
4181 				{
4182 					// Don't do anything for ordinary UDP packet
4183 					ok = true;
4184 				}
4185 
4186 				if (ok)
4187 				{
4188 					// Process the received packet
4189 					RUDPRecvProc(r, p);
4190 
4191 					r->TotalPhysicalReceived += ret;
4192 				}
4193 
4194 				FreeUdpPacket(p);
4195 			}
4196 			else
4197 			{
4198 				if (r->UdpSock->IgnoreRecvErr)
4199 				{
4200 					// An ignorable reception error occurs
4201 					if ((num_ignore_errors++) >= MAX_NUM_IGNORE_ERRORS)
4202 					{
4203 						break;
4204 					}
4205 				}
4206 				else
4207 				{
4208 					// A non-ignorable reception error occurs
4209 					break;
4210 				}
4211 			}
4212 		}
4213 
4214 		// Call the interrupt notification callback function
4215 		if (r->ProcInterrupts != NULL)
4216 		{
4217 			r->ProcInterrupts(r);
4218 		}
4219 
4220 		RUDPInterruptProc(r);
4221 
4222 		// Send all packets in the transmission packet list
4223 		for (i = 0;i < LIST_NUM(r->SendPacketList);i++)
4224 		{
4225 			UDPPACKET *p = LIST_DATA(r->SendPacketList, i);
4226 
4227 			if (r->Protocol == RUDP_PROTOCOL_ICMP)
4228 			{
4229 				// In case of the ICMP protocol, assemble an ICMP header
4230 				UINT dst_size = sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO) + SHA1_SIZE + p->Size;
4231 				UCHAR *dst_data = ZeroMalloc(dst_size);
4232 
4233 				ICMP_HEADER *icmp_header = (ICMP_HEADER *)dst_data;
4234 				ICMP_ECHO *icmp_echo = (ICMP_ECHO *)(dst_data + sizeof(ICMP_HEADER));
4235 				UCHAR *hash = dst_data + sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO);
4236 				UCHAR *icmp_data = dst_data + sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO) + SHA1_SIZE;
4237 
4238 				// Header
4239 				icmp_header->Type = (UCHAR)p->Type;
4240 				icmp_header->Code = 0;
4241 				icmp_header->Checksum = 0;
4242 
4243 				if (r->ServerMode)
4244 				{
4245 					// On the server side, use the port number in the opponent internal data as ICMP ID and SEQ NO
4246 					Copy(icmp_echo, &p->DestPort, 4);
4247 				}
4248 				else
4249 				{
4250 					// Use the fixed ICMP ID and SEQ NO on the client side
4251 					icmp_echo->Identifier = Endian16(r->Client_IcmpId);
4252 					icmp_echo->SeqNo = Endian16(r->Client_IcmpSeqNo);
4253 				}
4254 
4255 				// Data body
4256 				Copy(icmp_data, p->Data, p->Size);
4257 
4258 				// Hash
4259 				HashSha1(hash, icmp_data, p->Size);
4260 
4261 				// Checksum calculation
4262 				icmp_header->Checksum = IpChecksum(dst_data, dst_size);
4263 
4264 				// Replacement
4265 				Free(p->Data);
4266 				p->Data = dst_data;
4267 				p->Size = dst_size;
4268 			}
4269 			else if (r->Protocol == RUDP_PROTOCOL_DNS)
4270 			{
4271 				BUF *b = NewBuf();
4272 				// In case of over DNS protocol, assemble a header that conforms to the DNS protocol
4273 				if (r->ServerMode == false)
4274 				{
4275 					// DNS query header
4276 					USHORT us = Rand16() % 65535 + 1;
4277 					static UCHAR dns_query_header_1[] =
4278 					{
4279 						0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08,
4280 					};
4281 					static UCHAR dns_query_header_2[] =
4282 					{
4283 						0x00, 0x00, 0x30, 0x00, 0x01, 0x00, 0x00, 0x29, 0x10,
4284 						0x00, 0x00, 0x00, 0x80, 0x00,
4285 					};
4286 					UCHAR rand_data[4];
4287 					char rand_str[MAX_SIZE];
4288 
4289 					Rand(rand_data, sizeof(rand_data));
4290 					BinToStr(rand_str, sizeof(rand_str), rand_data, sizeof(rand_data));
4291 					StrLower(rand_str);
4292 
4293 					WriteBuf(b, &us, sizeof(USHORT));
4294 					WriteBuf(b, dns_query_header_1, sizeof(dns_query_header_1));
4295 					WriteBuf(b, rand_str, 8);
4296 					WriteBuf(b, dns_query_header_2, sizeof(dns_query_header_2));
4297 					us = Endian16((USHORT)p->Size);
4298 					WriteBuf(b, &us, sizeof(USHORT));
4299 					WriteBuf(b, p->Data, p->Size);
4300 				}
4301 				else
4302 				{
4303 					// DNS response header
4304 					USHORT us = p->Type;
4305 					UINT ui;
4306 					static UCHAR dns_response_header_1[] =
4307 					{
4308 						0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00,
4309 						0x00, 0x00, 0x08,
4310 					};
4311 					static UCHAR dns_response_header_2[] =
4312 					{
4313 						0x00, 0x00, 0x30, 0x00, 0x01,
4314 						0xc0, 0x0c, 0x00, 0x30, 0x00, 0x01, 0x00, 0x00, 0xa4, 0x5b,
4315 					};
4316 					static UCHAR dns_response_header_3[] =
4317 					{
4318 						0x01, 0x00, 0x03, 0x08,
4319 					};
4320 					UCHAR rand_data[4];
4321 					char rand_str[MAX_SIZE];
4322 
4323 					Rand(rand_data, sizeof(rand_data));
4324 					BinToStr(rand_str, sizeof(rand_str), rand_data, sizeof(rand_data));
4325 					StrLower(rand_str);
4326 
4327 					WriteBuf(b, &us, sizeof(USHORT));
4328 					WriteBuf(b, dns_response_header_1, sizeof(dns_response_header_1));
4329 					WriteBuf(b, rand_str, 8);
4330 					WriteBuf(b, dns_response_header_2, sizeof(dns_response_header_2));
4331 					us = Endian16((USHORT)(p->Size + 4));
4332 					WriteBuf(b, &us, sizeof(USHORT));
4333 					WriteBuf(b, dns_response_header_3, sizeof(dns_response_header_3));
4334 					WriteBuf(b, p->Data, p->Size);
4335 
4336 					ui = Rand16() % (60 * 60 * 12) + (60 * 60 * 12);
4337 					WRITE_UINT(((UCHAR *)b->Buf) + 0x20, ui);
4338 				}
4339 				Free(p->Data);
4340 				p->Data = b->Buf;
4341 				p->Size = b->Size;
4342 				Free(b);
4343 			}
4344 
4345 			SendTo(r->UdpSock, &p->DstIP, p->DestPort, p->Data, p->Size);
4346 
4347 			r->TotalPhysicalSent += p->Size;
4348 
4349 			FreeUdpPacket(p);
4350 		}
4351 		DeleteAll(r->SendPacketList);
4352 
4353 		if (r->Halt)
4354 		{
4355 			// If it is necessary to stop, stop it after cycling through a loop
4356 			if (halt_flag == false)
4357 			{
4358 				halt_flag = true;
4359 				continue;
4360 			}
4361 			else
4362 			{
4363 				break;
4364 			}
4365 		}
4366 
4367 		// Rest the CPU until the next event
4368 		wait_interval = GetNextIntervalForInterrupt(r->Interrupt);
4369 		if (r->ServerMode)
4370 		{
4371 			min_wait_interval = RUDP_LOOP_WAIT_INTERVAL_S;
4372 		}
4373 		else
4374 		{
4375 			min_wait_interval = RUDP_LOOP_WAIT_INTERVAL_C;
4376 		}
4377 
4378 		if (wait_interval == INFINITE)
4379 		{
4380 			wait_interval = min_wait_interval;
4381 		}
4382 		else
4383 		{
4384 			wait_interval = MIN(min_wait_interval, wait_interval);
4385 		}
4386 
4387 #ifdef	RUDP_DETAIL_LOG
4388 		Debug("wait_interval = %u\n", wait_interval);
4389 #endif	// RUDP_DETAIL_LOG
4390 
4391 		if (wait_interval >= 1)
4392 		{
4393 			WaitSockEvent(r->SockEvent, wait_interval);
4394 		}
4395 
4396 #ifdef	RUDP_DETAIL_LOG
4397 		if (r->ServerMode)
4398 		{
4399 			char str1[MAX_SIZE];
4400 			char str2[MAX_SIZE];
4401 			double rate = 0.0;
4402 
4403 			ToStr64(str1, r->TotalPhysicalReceived);
4404 			ToStr64(str2, r->TotalLogicalReceived);
4405 
4406 			if (r->TotalPhysicalReceived >= 1)
4407 			{
4408 				rate = (double)r->TotalLogicalReceived / (double)r->TotalPhysicalReceived;
4409 			}
4410 
4411 			Debug("%s / %s %.4f\n", str1, str2, rate);
4412 		}
4413 #endif	// RUDP_DETAIL_LOG
4414 	}
4415 
4416 	Disconnect(r->UdpSock);
4417 
4418 	DelWaitThread(thread);
4419 }
4420 
4421 // Generate a appropriate register host name from the IP address
RUDPGetRegisterHostNameByIP(char * dst,UINT size,IP * ip)4422 void RUDPGetRegisterHostNameByIP(char *dst, UINT size, IP *ip)
4423 {
4424 	char tmp[16];
4425 	// Validate arguments
4426 	if (dst == NULL)
4427 	{
4428 		return;
4429 	}
4430 
4431 	if (ip != NULL && IsIP4(ip))
4432 	{
4433 		UCHAR hash[SHA1_SIZE];
4434 
4435 		HashSha1(hash, ip->addr, 4);
4436 		BinToStr(tmp, sizeof(tmp), hash, 2);
4437 	}
4438 	else
4439 	{
4440 		UCHAR rand[2];
4441 		Rand(rand, 2);
4442 		BinToStr(tmp, sizeof(tmp), rand, 2);
4443 	}
4444 
4445 	StrLower(tmp);
4446 	Format(dst, size,
4447 		(IsUseAlternativeHostname() ? UDP_NAT_T_SERVER_TAG_ALT : UDP_NAT_T_SERVER_TAG),
4448 		tmp[2], tmp[3]);
4449 
4450 
4451 	if (false)
4452 	{
4453 		Debug("Hash Src IP: %r\n"
4454 			  "Hash Dst HN: %s\n",
4455 			  ip,
4456 			  dst);
4457 	}
4458 }
4459 
4460 // Analyze the IP address and port number from the string
RUDPParseIPAndPortStr(void * data,UINT data_size,IP * ip,UINT * port)4461 bool RUDPParseIPAndPortStr(void *data, UINT data_size, IP *ip, UINT *port)
4462 {
4463 	char tmp[MAX_SIZE];
4464 	UINT i;
4465 	char ipstr[MAX_SIZE];
4466 	char *portstr;
4467 	// Validate arguments
4468 	if (data == NULL || ip == NULL || port == NULL)
4469 	{
4470 		return false;
4471 	}
4472 
4473 	Zero(tmp, sizeof(tmp));
4474 
4475 	Copy(tmp, data, MIN(data_size, sizeof(tmp) - 1));
4476 
4477 	if (StartWith(tmp, "IP=") == false)
4478 	{
4479 		return false;
4480 	}
4481 
4482 	i = SearchStrEx(tmp, "#", 0, true);
4483 	if (i != INFINITE)
4484 	{
4485 		tmp[i] = 0;
4486 	}
4487 
4488 	StrCpy(ipstr, sizeof(ipstr), tmp + 3);
4489 
4490 	i = SearchStrEx(ipstr, ",PORT=", 0, true);
4491 	if (i == INFINITE)
4492 	{
4493 		return false;
4494 	}
4495 
4496 	ipstr[i] = 0;
4497 	portstr = ipstr + i + 6;
4498 
4499 	StrToIP(ip, ipstr);
4500 	*port = ToInt(portstr);
4501 
4502 	return true;
4503 }
4504 
4505 // R-UDP NAT-T IP address acquisition thread
RUDPIpQueryThread(THREAD * thread,void * param)4506 void RUDPIpQueryThread(THREAD *thread, void *param)
4507 {
4508 	RUDP_STACK *r;
4509 	UINT64 next_getip_tick = 0;
4510 	UINT64 next_getprivate_ip_tick = 0;
4511 	UINT last_ip_hash = 0;
4512 	void *route_change_poller = NULL;
4513 	char current_hostname[MAX_SIZE];
4514 	bool last_time_ip_changed = false;
4515 	UINT num_retry = 0;
4516 	// Validate arguments
4517 	if (thread == NULL || param == NULL)
4518 	{
4519 		return;
4520 	}
4521 
4522 	r = (RUDP_STACK *)param;
4523 
4524 	last_ip_hash = GetHostIPAddressHash32();
4525 
4526 	route_change_poller = NewRouteChange();
4527 	IsRouteChanged(route_change_poller);
4528 
4529 	Zero(current_hostname, sizeof(current_hostname));
4530 
4531 	while (r->Halt == false)
4532 	{
4533 		UINT ip_hash = GetHostIPAddressHash32();
4534 		UINT64 now = Tick64();
4535 		bool ip_changed = false;
4536 
4537 		if (ip_hash != last_ip_hash)
4538 		{
4539 			last_time_ip_changed = false;
4540 		}
4541 
4542 		if ((ip_hash != last_ip_hash) || (IsRouteChanged(route_change_poller)))
4543 		{
4544 			if (last_time_ip_changed == false)
4545 			{
4546 				// Call all getting functions from the beginning
4547 				// if the routing table or the IP address of this host has changed
4548 				next_getip_tick = 0;
4549 				next_getprivate_ip_tick = 0;
4550 				ip_changed = true;
4551 
4552 				last_ip_hash = ip_hash;
4553 
4554 				last_time_ip_changed = true;
4555 			}
4556 		}
4557 		else
4558 		{
4559 			last_time_ip_changed = false;
4560 		}
4561 
4562 		Lock(r->Lock);
4563 		{
4564 			if (StrCmpi(current_hostname, r->CurrentRegisterHostname) != 0)
4565 			{
4566 				// The target host name has changed
4567 				next_getip_tick = 0;
4568 				StrCpy(current_hostname, sizeof(current_hostname), r->CurrentRegisterHostname);
4569 			}
4570 		}
4571 		Unlock(r->Lock);
4572 
4573 		// Get the IP address of the NAT-T server with DNS
4574 		if (next_getip_tick == 0 || now >= next_getip_tick)
4575 		{
4576 			IP ip;
4577 
4578 			if (GetIP4(&ip, current_hostname) && IsZeroIp(&ip) == false)
4579 			{
4580 				Lock(r->Lock);
4581 				{
4582 //					Debug("%r  %r\n",&r->NatT_IP, &ip);
4583 					if (CmpIpAddr(&r->NatT_IP, &ip) != 0)
4584 					{
4585 //						WHERE;
4586 						ip_changed = true;
4587 						Copy(&r->NatT_IP, &ip, sizeof(IP));
4588 					}
4589 				}
4590 				Unlock(r->Lock);
4591 			}
4592 
4593 			if (IsZeroIp(&r->NatT_IP))
4594 			{
4595 				num_retry++;
4596 
4597 				next_getip_tick = now + MIN((UINT64)UDP_NAT_T_GET_IP_INTERVAL * (UINT64)num_retry, (UINT64)UDP_NAT_T_GET_IP_INTERVAL_MAX);
4598 			}
4599 			else
4600 			{
4601 				next_getip_tick = now + (UINT64)UDP_NAT_T_GET_IP_INTERVAL_AFTER;
4602 			}
4603 
4604 			if (ip_changed)
4605 			{
4606 				Debug("NAT-T: NAT-T Server IP (%s): %r\n", current_hostname, &r->NatT_IP);
4607 
4608 				r->NatT_GetTokenNextTick = 0;
4609 				r->NatT_RegisterNextTick = 0;
4610 				r->NatT_GetTokenFailNum = 0;
4611 				r->NatT_RegisterFailNum = 0;
4612 
4613 				r->NatT_TranId = Rand64();
4614 
4615 				SetSockEvent(r->SockEvent);
4616 			}
4617 		}
4618 
4619 		// Get a private IP address of this host using TCP
4620 		if (next_getprivate_ip_tick == 0 || now >= next_getprivate_ip_tick)
4621 		{
4622 			IP ip;
4623 
4624 			if (GetMyPrivateIP(&ip, false))
4625 			{
4626 				Lock(r->Lock);
4627 				{
4628 					Copy(&r->My_Private_IP, &ip, sizeof(IP));
4629 				}
4630 				Unlock(r->Lock);
4631 			}
4632 
4633 			if (IsZeroIp(&r->My_Private_IP))
4634 			{
4635 				next_getprivate_ip_tick = now + (UINT64)UDP_NAT_T_GET_PRIVATE_IP_INTERVAL;
4636 			}
4637 			else
4638 			{
4639 				next_getprivate_ip_tick = now + (UINT64)GenRandInterval(UDP_NAT_T_GET_PRIVATE_IP_INTERVAL_AFTER_MIN, UDP_NAT_T_GET_PRIVATE_IP_INTERVAL_AFTER_MAX);
4640 			}
4641 
4642 			Debug("NAT-T: My Private IP: %r\n", &r->My_Private_IP);
4643 		}
4644 
4645 		if (r->Halt)
4646 		{
4647 			break;
4648 		}
4649 
4650 		Wait(r->HaltEvent, RUDP_LOOP_WAIT_INTERVAL_S);
4651 	}
4652 
4653 	FreeRouteChange(route_change_poller);
4654 }
4655 
4656 // Generate a random intervals
GenRandInterval(UINT min,UINT max)4657 UINT GenRandInterval(UINT min, UINT max)
4658 {
4659 	UINT a, b;
4660 
4661 	a = MIN(min, max);
4662 	b = MAX(min, max);
4663 
4664 	if (a == b)
4665 	{
4666 		return a;
4667 	}
4668 
4669 	return (Rand32() % (b - a)) + a;
4670 }
4671 
4672 // Identify the private IP of the interface which is used to connect to the Internet currently
GetMyPrivateIP(IP * ip,bool from_vg)4673 bool GetMyPrivateIP(IP *ip, bool from_vg)
4674 {
4675 	SOCK *s;
4676 	IP t;
4677 	char *hostname = UDP_NAT_T_GET_PRIVATE_IP_TCP_SERVER;
4678 	// Validate arguments
4679 	if (ip == NULL)
4680 	{
4681 		return false;
4682 	}
4683 
4684 	s = ConnectEx(hostname, UDP_NAT_T_PORT_FOR_TCP_1, UDP_NAT_T_GET_PRIVATE_IP_CONNECT_TIMEOUT);
4685 
4686 	if (s == NULL)
4687 	{
4688 		s = ConnectEx(hostname, UDP_NAT_T_PORT_FOR_TCP_2, UDP_NAT_T_GET_PRIVATE_IP_CONNECT_TIMEOUT);
4689 
4690 		if (s == NULL)
4691 		{
4692 			s = ConnectEx(GetRandHostNameForGetMyPrivateIP(), UDP_NAT_T_PORT_FOR_TCP_1, UDP_NAT_T_GET_PRIVATE_IP_CONNECT_TIMEOUT);
4693 
4694 			if (s == NULL)
4695 			{
4696 				return false;
4697 			}
4698 		}
4699 	}
4700 
4701 	Copy(&t, &s->LocalIP, sizeof(IP));
4702 
4703 	Disconnect(s);
4704 	ReleaseSock(s);
4705 
4706 	if (IsZeroIp(&t))
4707 	{
4708 		return false;
4709 	}
4710 
4711 	Copy(ip, &t, sizeof(IP));
4712 
4713 	return true;
4714 }
GetRandHostNameForGetMyPrivateIP()4715 char *GetRandHostNameForGetMyPrivateIP()
4716 {
4717 	char *hosts[] =
4718 	{
4719 		"www.microsoft.com",
4720 		"www.yahoo.com",
4721 		"www.bing.com",
4722 	};
4723 	UINT num_hosts = 3;
4724 
4725 	return hosts[Rand32() % num_hosts];
4726 }
4727 
4728 // Function to wait until changing any IP address of the host or expiring the specified time or waking the event
WaitUntilHostIPAddressChanged(void * p,EVENT * event,UINT timeout,UINT ip_check_interval)4729 void WaitUntilHostIPAddressChanged(void *p, EVENT *event, UINT timeout, UINT ip_check_interval)
4730 {
4731 	UINT64 start, end;
4732 	UINT last_hash;
4733 	// Validate arguments
4734 	if (timeout == 0x7FFFFFFF)
4735 	{
4736 		timeout = 0xFFFFFFFF;
4737 	}
4738 	if (ip_check_interval == 0)
4739 	{
4740 		ip_check_interval = 0xFFFFFFFF;
4741 	}
4742 	if (event == NULL || timeout == 0)
4743 	{
4744 		return;
4745 	}
4746 
4747 	start = Tick64();
4748 	end = start + (UINT64)timeout;
4749 	last_hash = GetHostIPAddressHash32();
4750 
4751 	while (true)
4752 	{
4753 		UINT64 now = Tick64();
4754 		UINT next_interval;
4755 
4756 		if (now >= end)
4757 		{
4758 			break;
4759 		}
4760 
4761 		if (p != NULL)
4762 		{
4763 			if (IsRouteChanged(p))
4764 			{
4765 				break;
4766 			}
4767 		}
4768 
4769 		if (last_hash != GetHostIPAddressHash32())
4770 		{
4771 			break;
4772 		}
4773 
4774 		next_interval = (UINT)(end - now);
4775 		next_interval = MIN(next_interval, ip_check_interval);
4776 
4777 		if (Wait(event, next_interval))
4778 		{
4779 			break;
4780 		}
4781 	}
4782 }
InitWaitUntilHostIPAddressChanged()4783 void *InitWaitUntilHostIPAddressChanged()
4784 {
4785 	void *p = NewRouteChange();
4786 
4787 	if (p != NULL)
4788 	{
4789 		IsRouteChanged(p);
4790 	}
4791 
4792 	return p;
4793 }
FreeWaitUntilHostIPAddressChanged(void * p)4794 void FreeWaitUntilHostIPAddressChanged(void *p)
4795 {
4796 	FreeRouteChange(p);
4797 }
4798 
4799 // Get whether the specified IPv6 address is on the local network
IsIPv6LocalNetworkAddress(IP * ip)4800 bool IsIPv6LocalNetworkAddress(IP *ip)
4801 {
4802 	UINT type;
4803 	LIST *o;
4804 	UINT i;
4805 	bool ret = false;
4806 	IP mask64;
4807 	// Validate arguments
4808 	if (ip == NULL)
4809 	{
4810 		return false;
4811 	}
4812 	if (IsIP6(ip) == false)
4813 	{
4814 		return false;
4815 	}
4816 	if (IsZeroIp(ip))
4817 	{
4818 		return false;
4819 	}
4820 
4821 	type = GetIPAddrType6(ip);
4822 
4823 	if (type & IPV6_ADDR_LOCAL_UNICAST)
4824 	{
4825 		return true;
4826 	}
4827 
4828 	if ((type & IPV6_ADDR_GLOBAL_UNICAST) == 0)
4829 	{
4830 		return false;
4831 	}
4832 
4833 	IntToSubnetMask6(&mask64, 64);
4834 
4835 	o = GetHostIPAddressList();
4836 
4837 	ret = false;
4838 
4839 	for (i = 0;i < LIST_NUM(o);i++)
4840 	{
4841 		IP *p = LIST_DATA(o, i);
4842 
4843 		if (IsIP6(p))
4844 		{
4845 			if (IsZeroIp(p) == false)
4846 			{
4847 				if (IsLocalHostIP6(p) == false)
4848 				{
4849 					if (IsInSameNetwork6(p, ip, &mask64))
4850 					{
4851 						ret = true;
4852 					}
4853 				}
4854 			}
4855 		}
4856 	}
4857 
4858 	FreeHostIPAddressList(o);
4859 
4860 	return ret;
4861 }
4862 
4863 // Check whether the specified IP address is localhost or the IP address of the local interface of itself
IsIPLocalHostOrMySelf(IP * ip)4864 bool IsIPLocalHostOrMySelf(IP *ip)
4865 {
4866 	LIST *o;
4867 	bool ret = false;
4868 	UINT i;
4869 	// Validate arguments
4870 	if (ip == NULL)
4871 	{
4872 		return false;
4873 	}
4874 
4875 	o = GetHostIPAddressList();
4876 	if (o == NULL)
4877 	{
4878 		return false;
4879 	}
4880 
4881 	for (i = 0;i < LIST_NUM(o);i++)
4882 	{
4883 		IP *p = LIST_DATA(o, i);
4884 
4885 		if (CmpIpAddr(p, ip) == 0)
4886 		{
4887 			ret = true;
4888 
4889 			break;
4890 		}
4891 	}
4892 
4893 	FreeHostIPAddressList(o);
4894 
4895 	if (IsLocalHostIP4(ip) || IsLocalHostIP6(ip))
4896 	{
4897 		ret = true;
4898 	}
4899 
4900 	return ret;
4901 }
4902 
4903 // Get the results of the port number that is determined at random
RUDPGetRandPortNumber(UCHAR rand_port_id)4904 UINT RUDPGetRandPortNumber(UCHAR rand_port_id)
4905 {
4906 	UINT ret;
4907 	// Validate arguments
4908 	if (rand_port_id == 0)
4909 	{
4910 		return 0;
4911 	}
4912 
4913 	ret = rand_port_numbers[rand_port_id];
4914 
4915 	Debug("rand_port_id[%u] = %u\n", rand_port_id, ret);
4916 	return ret;
4917 }
4918 
4919 // Obtain the hash value of combining all of the IP address assigned to the host
GetHostIPAddressHash32()4920 UINT GetHostIPAddressHash32()
4921 {
4922 	BUF *b;
4923 	UINT i;
4924 	UCHAR hash[SHA1_SIZE];
4925 	UINT ret;
4926 	LIST *o = GetHostIPAddressList();
4927 
4928 	if (o == NULL)
4929 	{
4930 		return 0;
4931 	}
4932 
4933 	b = NewBuf();
4934 	for (i = 0;i < LIST_NUM(o);i++)
4935 	{
4936 		IP *ip = LIST_DATA(o, i);
4937 
4938 		WriteBuf(b, ip, sizeof(IP));
4939 
4940 		WriteBufStr(b, ":-) yas (-:");
4941 	}
4942 	FreeHostIPAddressList(o);
4943 
4944 	WriteBuf(b, rand_port_numbers, sizeof(rand_port_numbers));
4945 
4946 	HashSha1(hash, b->Buf, b->Size);
4947 
4948 	FreeBuf(b);
4949 
4950 	Copy(&ret, hash, sizeof(UINT));
4951 
4952 	return ret;
4953 }
4954 
4955 // Create an IPv4 UDP socket destined for a particular target
NewUDP4ForSpecificIp(IP * target_ip,UINT port)4956 SOCK *NewUDP4ForSpecificIp(IP *target_ip, UINT port)
4957 {
4958 	SOCK *s;
4959 	IP local_ip;
4960 	// Validate arguments
4961 	if (target_ip == NULL || IsZeroIP(target_ip) || IsIP4(target_ip) == false)
4962 	{
4963 		target_ip = NULL;
4964 	}
4965 
4966 	Zero(&local_ip, sizeof(local_ip));
4967 	GetBestLocalIpForTarget(&local_ip, target_ip);
4968 
4969 	s = NewUDP4(port, &local_ip);
4970 
4971 	if (s == NULL)
4972 	{
4973 		s = NewUDP4(port, NULL);
4974 	}
4975 
4976 	return s;
4977 }
4978 
4979 // Get the best self IPv4 address to connect to the target IPv4 address
GetBestLocalIpForTarget(IP * local_ip,IP * target_ip)4980 bool GetBestLocalIpForTarget(IP *local_ip, IP *target_ip)
4981 {
4982 	bool ret = false;
4983 	ROUTE_ENTRY *e;
4984 	IP ip2;
4985 	UINT n = 0;
4986 	IP zero_ip;
4987 	// Validate arguments
4988 	Zero(local_ip, sizeof(IP));
4989 	ZeroIP4(&zero_ip);
4990 	if (target_ip == NULL)
4991 	{
4992 		target_ip = &zero_ip;
4993 	}
4994 	if (local_ip == NULL || IsIP4(target_ip) == false)
4995 	{
4996 		return false;
4997 	}
4998 
4999 	Copy(&ip2, target_ip, sizeof(IP));
5000 
5001 	while (true)
5002 	{
5003 		n++;
5004 		if (n >= 64)
5005 		{
5006 			break;
5007 		}
5008 
5009 		e = GetBestRouteEntry(&ip2);
5010 		if (e != NULL)
5011 		{
5012 			if (IsZeroIp(&e->GatewayIP))
5013 			{
5014 				Free(e);
5015 				break;
5016 			}
5017 
5018 			if (e->LocalRouting)
5019 			{
5020 				ret = true;
5021 				Copy(local_ip, &e->GatewayIP, sizeof(IP));
5022 				Free(e);
5023 				break;
5024 			}
5025 			else
5026 			{
5027 				Copy(&ip2, &e->GatewayIP, sizeof(IP));
5028 			}
5029 
5030 			Free(e);
5031 		}
5032 	}
5033 
5034 	if (ret == false)
5035 	{
5036 		if (IsLocalHostIP4(target_ip))
5037 		{
5038 			GetLocalHostIP4(local_ip);
5039 			ret = true;
5040 		}
5041 	}
5042 
5043 	return ret;
5044 }
5045 
5046 // Create a R-UDP client (Connection via NAT-T gateway)
NewRUDPClientNatT(char * svc_name,IP * ip,UINT * error_code,UINT timeout,bool * cancel,char * hint_str,char * target_hostname)5047 SOCK *NewRUDPClientNatT(char *svc_name, IP *ip, UINT *error_code, UINT timeout, bool *cancel, char *hint_str, char *target_hostname)
5048 {
5049 	IP nat_t_ip;
5050 	UINT dummy_int = 0;
5051 	UINT64 giveup_tick;
5052 	bool dummy_bool = false;
5053 	SOCK_EVENT *sock_event;
5054 	SOCK *sock;
5055 	bool same_lan = false;
5056 	char hostname[MAX_SIZE];
5057 
5058 
5059 
5060 	if (timeout == 0)
5061 	{
5062 		timeout = RUDP_TIMEOUT;
5063 	}
5064 	if (error_code == NULL)
5065 	{
5066 		error_code = &dummy_int;
5067 	}
5068 	if (cancel == NULL)
5069 	{
5070 		cancel = &dummy_bool;
5071 	}
5072 	*error_code = RUDP_ERROR_UNKNOWN;
5073 	if (svc_name == NULL || ip == NULL)
5074 	{
5075 		return NULL;
5076 	}
5077 
5078 	ListenTcpForPopupFirewallDialog();
5079 
5080 	giveup_tick = Tick64() + (UINT64)timeout;
5081 
5082 	// Get the IP address of the NAT-T server
5083 	RUDPGetRegisterHostNameByIP(hostname, sizeof(hostname), ip);
5084 	if (GetIP4Ex(&nat_t_ip, hostname, 0, cancel) == false)
5085 	{
5086 		*error_code = RUDP_ERROR_NAT_T_NO_RESPONSE;
5087 		return NULL;
5088 	}
5089 
5090 	if (Tick64() >= giveup_tick)
5091 	{
5092 		*error_code = RUDP_ERROR_TIMEOUT;
5093 		return NULL;
5094 	}
5095 	if (*cancel)
5096 	{
5097 		*error_code = RUDP_ERROR_USER_CANCELED;
5098 		return NULL;
5099 	}
5100 
5101 	sock = NewUDP4ForSpecificIp(&nat_t_ip, 0);
5102 	if (sock == NULL)
5103 	{
5104 		*error_code = RUDP_ERROR_UNKNOWN;
5105 		return NULL;
5106 	}
5107 	else
5108 	{
5109 		UINT64 next_send_request_tick = 0;
5110 		INTERRUPT_MANAGER *interrupt = NewInterruptManager();
5111 		UINT64 tran_id = Rand64();
5112 		UINT tmp_size = 65536;
5113 		UCHAR *tmp = Malloc(tmp_size);
5114 		char result_ip_str[MAX_SIZE];
5115 		IP result_ip;
5116 		UINT result_port;
5117 		SOCK *ret = NULL;
5118 		UINT num_tries = 0;
5119 		UINT64 current_cookie = 0;
5120 
5121 		AddInterrupt(interrupt, giveup_tick);
5122 
5123 		sock_event = NewSockEvent();
5124 		JoinSockToSockEvent(sock, sock_event);
5125 
5126 		// Communication with the NAT-T server
5127 		while (true)
5128 		{
5129 			UINT64 now = Tick64();
5130 			UINT interval;
5131 			UINT r;
5132 			IP src_ip;
5133 			UINT src_port;
5134 			UINT err;
5135 			UINT num_ignore_errors = 0;
5136 
5137 			if (now >= giveup_tick)
5138 			{
5139 				// Time-out
5140 LABEL_TIMEOUT:
5141 				*error_code = RUDP_ERROR_NAT_T_NO_RESPONSE;
5142 				break;
5143 			}
5144 
5145 			if (*cancel)
5146 			{
5147 				// User canceled
5148 				*error_code = RUDP_ERROR_USER_CANCELED;
5149 				break;
5150 			}
5151 
5152 			err = INFINITE;
5153 
5154 			// Receive a response packet from the NAT-T server
5155 			while (err == INFINITE)
5156 			{
5157 				r = RecvFrom(sock, &src_ip, &src_port, tmp, tmp_size);
5158 				if (r == SOCK_LATER)
5159 				{
5160 					// No packet
5161 					break;
5162 				}
5163 				else if (r == 0)
5164 				{
5165 					if (sock->IgnoreRecvErr == false)
5166 					{
5167 						// Communication error
5168 						goto LABEL_TIMEOUT;
5169 					}
5170 					else
5171 					{
5172 						if ((num_ignore_errors++) >= MAX_NUM_IGNORE_ERRORS)
5173 						{
5174 							goto LABEL_TIMEOUT;
5175 						}
5176 					}
5177 				}
5178 				else
5179 				{
5180 					// Check the source IP address and the port number
5181 					if (CmpIpAddr(&src_ip, &nat_t_ip) == 0 && src_port == UDP_NAT_T_PORT)
5182 					{
5183 						BUF *b = NewBuf();
5184 						PACK *p;
5185 
5186 						WriteBuf(b, tmp, r);
5187 						SeekBuf(b, 0, 0);
5188 
5189 
5190 						p = BufToPack(b);
5191 
5192 						if (p != NULL)
5193 						{
5194 							UINT64 cookie = PackGetInt64(p, "cookie");
5195 							if (cookie != 0)
5196 							{
5197 								current_cookie = cookie;
5198 							}
5199 
5200 							// Compare tran_id
5201 							if (PackGetInt64(p, "tran_id") == tran_id)
5202 							{
5203 								// Compare opcode
5204 								if (PackCmpStr(p, "opcode", "nat_t_connect_request"))
5205 								{
5206 									bool ok = PackGetBool(p, "ok");
5207 									bool multi_candidate = PackGetBool(p, "multi_candidates");
5208 
5209 									if (ok)
5210 									{
5211 										// Success
5212 										PackGetStr(p, "result_ip", result_ip_str, sizeof(result_ip_str));
5213 										StrToIP(&result_ip, result_ip_str);
5214 
5215 										result_port = PackGetInt(p, "result_port");
5216 
5217 										same_lan = PackGetBool(p, "same_lan");
5218 
5219 										if (result_port != 0)
5220 										{
5221 											if (IsZeroIp(&result_ip) == false)
5222 											{
5223 												if ((sock->IPv6 == false && IsIP4(&result_ip)) ||
5224 													(sock->IPv6 && IsIP6(&result_ip)))
5225 												{
5226 													err = RUDP_ERROR_OK;
5227 												}
5228 											}
5229 										}
5230 									}
5231 									else if (multi_candidate)
5232 									{
5233 										// There are two or more computers behind the specified IP address
5234 										err = RUDP_ERROR_NAT_T_TWO_OR_MORE;
5235 									}
5236 									else
5237 									{
5238 										// Failure
5239 										err = RUDP_ERROR_NAT_T_NOT_FOUND;
5240 									}
5241 								}
5242 							}
5243 
5244 							FreePack(p);
5245 						}
5246 
5247 						FreeBuf(b);
5248 					}
5249 				}
5250 			}
5251 
5252 			if (err != INFINITE)
5253 			{
5254 				*error_code = err;
5255 				break;
5256 			}
5257 
5258 			if (next_send_request_tick == 0 || now >= next_send_request_tick)
5259 			{
5260 				// Send a connection request to the NAT-T server
5261 				BUF *b;
5262 				char ip_str[MAX_SIZE];
5263 				PACK *p = NewPack();
5264 
5265 				PackAddStr(p, "opcode", "nat_t_connect_request");
5266 				PackAddInt64(p, "tran_id", tran_id);
5267 				IPToStr(ip_str, sizeof(ip_str), ip);
5268 				PackAddStr(p, "dest_ip", ip_str);
5269 				PackAddInt64(p, "cookie", current_cookie);
5270 				if (IsEmptyStr(hint_str) == false)
5271 				{
5272 					PackAddStr(p, "hint", hint_str);
5273 				}
5274 				if (IsEmptyStr(target_hostname) == false)
5275 				{
5276 					PackAddStr(p, "target_hostname", target_hostname);
5277 				}
5278 				PackAddStr(p, "svc_name", svc_name);
5279 
5280 				PackAddInt(p, "nat_traversal_version", UDP_NAT_TRAVERSAL_VERSION);
5281 
5282 				b = PackToBuf(p);
5283 				FreePack(p);
5284 
5285 				SendTo(sock, &nat_t_ip, UDP_NAT_T_PORT, b->Buf, b->Size);
5286 				FreeBuf(b);
5287 
5288 				// Determine the next transmission time
5289 				next_send_request_tick = now + (UINT64)UDP_NAT_T_CONNECT_INTERVAL * (UINT64)(Power(2, MAX(num_tries, 6)));
5290 				num_tries++;
5291 				AddInterrupt(interrupt, next_send_request_tick);
5292 			}
5293 
5294 			interval = GetNextIntervalForInterrupt(interrupt);
5295 			interval = MIN(interval, 50);
5296 
5297 			WaitSockEvent(sock_event, interval);
5298 		}
5299 
5300 		Free(tmp);
5301 		FreeInterruptManager(interrupt);
5302 
5303 		if (*error_code == RUDP_ERROR_OK)
5304 		{
5305 			UINT remain_timeout;
5306 			UINT64 now = Tick64();
5307 			// Success to get the IP address and the port number of the target
5308 
5309 			// Get the rest timeout tolerance
5310 			if (now <= giveup_tick)
5311 			{
5312 				remain_timeout = (UINT)(giveup_tick - now);
5313 			}
5314 			else
5315 			{
5316 				remain_timeout = 0;
5317 			}
5318 
5319 			remain_timeout = MAX(remain_timeout, 2000);
5320 
5321 			if (same_lan)
5322 			{
5323 				// Discard current UDP socket and create a new UDP socket in NewRUDPClientDirect().
5324 				// Because using a UDP socket which used for communication with the NAT-T server
5325 				// can cause trouble when the client and the server exists in the same LAN.
5326 				ReleaseSockEvent(sock_event);
5327 				ReleaseSock(sock);
5328 
5329 				sock = NULL;
5330 				sock_event = NULL;
5331 			}
5332 
5333 			ret = NewRUDPClientDirect(svc_name, &result_ip, result_port, error_code, remain_timeout, cancel,
5334 				sock, sock_event, 0, false);
5335 		}
5336 
5337 		if (sock_event != NULL)
5338 		{
5339 			ReleaseSockEvent(sock_event);
5340 		}
5341 
5342 		if (sock != NULL)
5343 		{
5344 			if (ret == NULL)
5345 			{
5346 				Disconnect(sock);
5347 			}
5348 
5349 			ReleaseSock(sock);
5350 		}
5351 
5352 		return ret;
5353 	}
5354 }
5355 
5356 // Listen to the TCP for a moment to show the firewall dialog
ListenTcpForPopupFirewallDialog()5357 void ListenTcpForPopupFirewallDialog()
5358 {
5359 #ifdef	OS_WIN32
5360 	static bool tried = false;
5361 
5362 	if (tried == false)
5363 	{
5364 		SOCK *s;
5365 		tried = true;
5366 		s = ListenAnyPortEx2(false, true);
5367 
5368 		if (s != NULL)
5369 		{
5370 			Disconnect(s);
5371 			ReleaseSock(s);
5372 		}
5373 	}
5374 #endif	// OS_WIN32
5375 }
5376 
5377 // Create a R-UDP client (direct connection)
NewRUDPClientDirect(char * svc_name,IP * ip,UINT port,UINT * error_code,UINT timeout,bool * cancel,SOCK * sock,SOCK_EVENT * sock_event,UINT local_port,bool over_dns_mode)5378 SOCK *NewRUDPClientDirect(char *svc_name, IP *ip, UINT port, UINT *error_code, UINT timeout, bool *cancel, SOCK *sock, SOCK_EVENT *sock_event, UINT local_port, bool over_dns_mode)
5379 {
5380 	RUDP_STACK *r;
5381 	UINT dummy_int = 0;
5382 	SOCK *ret = NULL;
5383 	// Validate arguments
5384 	if (error_code == NULL)
5385 	{
5386 		error_code = &dummy_int;
5387 	}
5388 	if (timeout == 0)
5389 	{
5390 		timeout = RUDP_TIMEOUT;
5391 	}
5392 	*error_code = RUDP_ERROR_UNKNOWN;
5393 	if (svc_name == NULL || ip == NULL || port == 0)
5394 	{
5395 		return NULL;
5396 	}
5397 
5398 	r = NewRUDP(false, svc_name, NULL, NULL, NULL, local_port, sock, sock_event, false, over_dns_mode, ip, NULL, 0);
5399 	if (r == NULL)
5400 	{
5401 		*error_code = RUDP_ERROR_UNKNOWN;
5402 		return NULL;
5403 	}
5404 
5405 	// Set the port number and the target IP address
5406 	Lock(r->Lock);
5407 	{
5408 		Copy(&r->TargetIp, ip, sizeof(IP));
5409 		r->TargetPort = port;
5410 		r->TargetIpAndPortInited = true;
5411 	}
5412 	Unlock(r->Lock);
5413 	SetSockEvent(r->SockEvent);
5414 
5415 	// Wait for a connection success/failure to the target IP address
5416 	WaitEx(r->TargetConnectedEvent, timeout, cancel);
5417 	Lock(r->Lock);
5418 	{
5419 		if (r->TargetConnectedSock != NULL)
5420 		{
5421 			// The connection succeeded
5422 			ret = r->TargetConnectedSock;
5423 			r->TargetConnectedSock = NULL;
5424 		}
5425 		else
5426 		{
5427 			r->DoNotSetTargetConnectedSock = true;
5428 		}
5429 	}
5430 	Unlock(r->Lock);
5431 
5432 	if (ret == NULL)
5433 	{
5434 		// Stop the R-UDP stack if the connection has failed
5435 		*error_code = RUDP_ERROR_TIMEOUT;
5436 		FreeRUDP(r);
5437 	}
5438 	else if (cancel != NULL && (*cancel))
5439 	{
5440 		// User canceled
5441 		*error_code = RUDP_ERROR_USER_CANCELED;
5442 
5443 		Disconnect(ret);
5444 		ReleaseSock(ret);
5445 
5446 		ret = NULL;
5447 	}
5448 	else
5449 	{
5450 		*error_code = RUDP_ERROR_OK;
5451 	}
5452 
5453 	return ret;
5454 }
5455 
5456 // Creating a R-UDP server
NewRUDPServer(char * svc_name,RUDP_STACK_INTERRUPTS_PROC * proc_interrupts,RUDP_STACK_RPC_RECV_PROC * proc_rpc_recv,void * param,UINT port,bool no_natt_register,bool over_dns_mode,volatile UINT * natt_global_udp_port,UCHAR rand_port_id)5457 RUDP_STACK *NewRUDPServer(char *svc_name, RUDP_STACK_INTERRUPTS_PROC *proc_interrupts, RUDP_STACK_RPC_RECV_PROC *proc_rpc_recv, void *param, UINT port, bool no_natt_register, bool over_dns_mode, volatile UINT *natt_global_udp_port, UCHAR rand_port_id)
5458 {
5459 	RUDP_STACK *r;
5460 	// Validate arguments
5461 	if (IsEmptyStr(svc_name))
5462 	{
5463 		return NULL;
5464 	}
5465 
5466 	if (g_no_rudp_server)
5467 	{
5468 		return NULL;
5469 	}
5470 
5471 	ListenTcpForPopupFirewallDialog();
5472 
5473 	r = NewRUDP(true, svc_name, proc_interrupts, proc_rpc_recv, param, port, NULL, NULL, no_natt_register, over_dns_mode, NULL, natt_global_udp_port, rand_port_id);
5474 
5475 	if (r == NULL)
5476 	{
5477 		return NULL;
5478 	}
5479 
5480 	return r;
5481 }
5482 
5483 // Creating a R-UDP
NewRUDP(bool server_mode,char * svc_name,RUDP_STACK_INTERRUPTS_PROC * proc_interrupts,RUDP_STACK_RPC_RECV_PROC * proc_rpc_recv,void * param,UINT port,SOCK * sock,SOCK_EVENT * sock_event,bool server_no_natt_register,bool over_dns_mode,IP * client_target_ip,volatile UINT * natt_global_udp_port,UCHAR rand_port_id)5484 RUDP_STACK *NewRUDP(bool server_mode, char *svc_name, RUDP_STACK_INTERRUPTS_PROC *proc_interrupts, RUDP_STACK_RPC_RECV_PROC *proc_rpc_recv, void *param, UINT port, SOCK *sock, SOCK_EVENT *sock_event, bool server_no_natt_register, bool over_dns_mode, IP *client_target_ip, volatile UINT *natt_global_udp_port, UCHAR rand_port_id)
5485 {
5486 	RUDP_STACK *r;
5487 	char tmp[MAX_SIZE];
5488 	UCHAR pid_hash[SHA1_SIZE];
5489 	UINT pid;
5490 	USHORT pid_us;
5491 
5492 	// Validate arguments
5493 	if (IsEmptyStr(svc_name))
5494 	{
5495 		return NULL;
5496 	}
5497 
5498 	ListenTcpForPopupFirewallDialog();
5499 
5500 	if (sock == NULL)
5501 	{
5502 		if (server_mode == false && client_target_ip != NULL)
5503 		{
5504 			sock = NewUDP4ForSpecificIp(client_target_ip, port);
5505 		}
5506 		else
5507 		{
5508 			if (rand_port_id == 0)
5509 			{
5510 				sock = NewUDP(port);
5511 			}
5512 			else
5513 			{
5514 				sock = NewUDPEx2RandMachineAndExePath(false, NULL, 0, rand_port_id);
5515 			}
5516 		}
5517 
5518 		if (sock == NULL)
5519 		{
5520 			return NULL;
5521 		}
5522 	}
5523 	else
5524 	{
5525 		AddRef(sock->ref);
5526 	}
5527 
5528 	if (port == 0)
5529 	{
5530 		port = sock->LocalPort;
5531 	}
5532 
5533 	if (rand_port_id != 0)
5534 	{
5535 		rand_port_numbers[rand_port_id] = port;
5536 	}
5537 
5538 	if (sock_event == NULL)
5539 	{
5540 		sock_event = NewSockEvent();
5541 	}
5542 	else
5543 	{
5544 		AddRef(sock_event->ref);
5545 	}
5546 
5547 	r = ZeroMalloc(sizeof(RUDP_STACK));
5548 
5549 	r->NatT_SessionKey = Rand64();
5550 
5551 	StrCpy(r->SvcName, sizeof(r->SvcName), svc_name);
5552 	r->RandPortId = rand_port_id;
5553 	r->NatTGlobalUdpPort = natt_global_udp_port;
5554 	r->ServerMode = server_mode;
5555 	r->Interrupt = NewInterruptManager();
5556 	r->SessionList = NewList(RUDPCompareSessionList);
5557 	r->UdpSock = sock;
5558 	r->Port = port;
5559 	r->SockEvent = sock_event;
5560 	r->HaltEvent = NewEvent();
5561 	r->Now = Tick64();
5562 	r->Lock = NewLock();
5563 	r->Param = param;
5564 	r->TargetConnectedEvent = NewEvent();
5565 	r->SendPacketList = NewList(NULL);
5566 	r->NewSockConnectEvent = NewEvent();
5567 	r->NewSockQueue = NewQueue();
5568 	r->NatT_TranId = Rand64();
5569 
5570 	r->NatT_SourceIpList = NewListFast(NULL);
5571 
5572 	StrCpy(tmp, sizeof(tmp), r->SvcName);
5573 	Trim(tmp);
5574 	StrLower(tmp);
5575 
5576 	HashSha1(r->SvcNameHash, tmp, StrLen(tmp));
5577 
5578 	r->Client_IcmpId = (USHORT)(Rand32() % 65534 + 1);
5579 	r->Client_IcmpSeqNo = (USHORT)(Rand32() % 65534 + 1);
5580 
5581 	// Determination of the type of the protocol
5582 	r->Protocol = RUDP_PROTOCOL_UDP;
5583 	if (r->Port == MAKE_SPECIAL_PORT(IP_PROTO_ICMPV4))
5584 	{
5585 		r->Protocol = RUDP_PROTOCOL_ICMP;
5586 
5587 		// Generate the ICMP ID based on the process ID
5588 #ifdef	OS_WIN32
5589 		pid = (UINT)MsGetProcessId();
5590 #else	// OS_WIN32
5591 		pid = (UINT)getpid();
5592 #endif	// OS_WIN32
5593 
5594 		pid = Endian32(pid);
5595 		HashSha1(pid_hash, &pid, sizeof(UINT));
5596 
5597 		pid_us = READ_USHORT(pid_hash);
5598 		if (pid_us == 0 || pid_us == 0xFFFF)
5599 		{
5600 			pid_us = 1;
5601 		}
5602 
5603 		r->Client_IcmpId = pid_us;
5604 	}
5605 	else if (over_dns_mode)
5606 	{
5607 		r->Protocol = RUDP_PROTOCOL_DNS;
5608 	}
5609 
5610 	if (r->ServerMode)
5611 	{
5612 		r->NoNatTRegister = server_no_natt_register;
5613 
5614 		if (r->Protocol == RUDP_PROTOCOL_ICMP || r->Protocol == RUDP_PROTOCOL_DNS)
5615 		{
5616 			// Never register to the NAT-T server in case of using the DNS or the ICMP
5617 			r->NoNatTRegister = true;
5618 		}
5619 	}
5620 
5621 	if (true
5622 		)
5623 	{
5624 		RUDPGetRegisterHostNameByIP(r->CurrentRegisterHostname, sizeof(r->CurrentRegisterHostname), NULL);
5625 	}
5626 
5627 	if (r->ServerMode)
5628 	{
5629 		r->ProcInterrupts = proc_interrupts;
5630 		r->ProcRpcRecv = proc_rpc_recv;
5631 	}
5632 
5633 	if (r->ServerMode && r->NoNatTRegister == false
5634 		)
5635 	{
5636 		r->IpQueryThread = NewThread(RUDPIpQueryThread, r);
5637 	}
5638 
5639 	JoinSockToSockEvent(r->UdpSock, r->SockEvent);
5640 
5641 	r->Thread = NewThread(RUDPMainThread, r);
5642 	WaitThreadInit(r->Thread);
5643 
5644 	return r;
5645 }
5646 
5647 // R-UDP session comparison function
RUDPCompareSessionList(void * p1,void * p2)5648 int RUDPCompareSessionList(void *p1, void *p2)
5649 {
5650 	RUDP_SESSION *s1, *s2;
5651 	UINT r;
5652 	// Validate arguments
5653 	if (p1 == NULL || p2 == NULL)
5654 	{
5655 		return 0;
5656 	}
5657 	s1 = *((RUDP_SESSION **)p1);
5658 	s2 = *((RUDP_SESSION **)p2);
5659 	if (s1 == NULL || s2 == NULL)
5660 	{
5661 		return 0;
5662 	}
5663 
5664 	r = CmpIpAddr(&s1->YourIp, &s2->YourIp);
5665 	if (r != 0)
5666 	{
5667 		return r;
5668 	}
5669 
5670 	r = COMPARE_RET(s1->YourPort, s2->YourPort);
5671 	if (r != 0)
5672 	{
5673 		return r;
5674 	}
5675 
5676 	r = CmpIpAddr(&s1->MyIp, &s2->MyIp);
5677 	if (r != 0)
5678 	{
5679 		return r;
5680 	}
5681 
5682 	r = COMPARE_RET(s1->MyPort, s2->MyPort);
5683 	if (r != 0)
5684 	{
5685 		return r;
5686 	}
5687 
5688 	return 0;
5689 }
5690 
5691 // Release of the R-UDP
FreeRUDP(RUDP_STACK * r)5692 void FreeRUDP(RUDP_STACK *r)
5693 {
5694 	UINT i;
5695 	// Validate arguments
5696 	if (r == NULL)
5697 	{
5698 		return;
5699 	}
5700 
5701 	r->Halt = true;
5702 	Set(r->HaltEvent);
5703 	SetSockEvent(r->SockEvent);
5704 
5705 	if (r->ServerMode && r->NoNatTRegister == false)
5706 	{
5707 		if (r->IpQueryThread != NULL)
5708 		{
5709 			WaitThread(r->IpQueryThread, INFINITE);
5710 			ReleaseThread(r->IpQueryThread);
5711 		}
5712 	}
5713 
5714 	WaitThread(r->Thread, INFINITE);
5715 	ReleaseThread(r->Thread);
5716 
5717 	for (i = 0;i < LIST_NUM(r->SessionList);i++)
5718 	{
5719 		RUDP_SESSION *se = LIST_DATA(r->SessionList, i);
5720 
5721 		RUDPFreeSession(se);
5722 	}
5723 
5724 	ReleaseList(r->SessionList);
5725 
5726 	for (i = 0;i < LIST_NUM(r->SendPacketList);i++)
5727 	{
5728 		UDPPACKET *p = LIST_DATA(r->SendPacketList, i);
5729 
5730 		FreeUdpPacket(p);
5731 	}
5732 
5733 	while (true)
5734 	{
5735 		SOCK *s = GetNext(r->NewSockQueue);
5736 		if (s == NULL)
5737 		{
5738 			break;
5739 		}
5740 
5741 		Disconnect(s);
5742 		ReleaseSock(s);
5743 	}
5744 
5745 	for (i = 0;i < LIST_NUM(r->NatT_SourceIpList);i++)
5746 	{
5747 		RUDP_SOURCE_IP *sip = (RUDP_SOURCE_IP *)LIST_DATA(r->NatT_SourceIpList, i);
5748 
5749 		Free(sip);
5750 	}
5751 
5752 	ReleaseList(r->NatT_SourceIpList);
5753 
5754 	ReleaseQueue(r->NewSockQueue);
5755 
5756 	ReleaseList(r->SendPacketList);
5757 
5758 	FreeInterruptManager(r->Interrupt);
5759 
5760 	Disconnect(r->UdpSock);
5761 	ReleaseSock(r->UdpSock);
5762 	ReleaseSockEvent(r->SockEvent);
5763 	ReleaseEvent(r->HaltEvent);
5764 	ReleaseEvent(r->TargetConnectedEvent);
5765 
5766 	ReleaseEvent(r->NewSockConnectEvent);
5767 
5768 	Disconnect(r->TargetConnectedSock);
5769 	ReleaseSock(r->TargetConnectedSock);
5770 
5771 	DeleteLock(r->Lock);
5772 
5773 	if (r->RandPortId != 0)
5774 	{
5775 		rand_port_numbers[r->RandPortId] = 0;
5776 	}
5777 
5778 	Free(r);
5779 }
5780 
5781 // Generate a hash from the current computer name and the process name
GetCurrentMachineIpProcessHash(void * hash)5782 void GetCurrentMachineIpProcessHash(void *hash)
5783 {
5784 	// Validate arguments
5785 	if (hash == NULL)
5786 	{
5787 		return;
5788 	}
5789 
5790 	Lock(machine_ip_process_hash_lock);
5791 	{
5792 		if (IsZero(machine_ip_process_hash, SHA1_SIZE))
5793 		{
5794 			GetCurrentMachineIpProcessHashInternal(machine_ip_process_hash);
5795 		}
5796 
5797 		Copy(hash, machine_ip_process_hash, SHA1_SIZE);
5798 	}
5799 	Unlock(machine_ip_process_hash_lock);
5800 }
GetCurrentMachineIpProcessHashInternal(void * hash)5801 void GetCurrentMachineIpProcessHashInternal(void *hash)
5802 {
5803 	BUF *b;
5804 	LIST *ip_list;
5805 	char machine_name[MAX_SIZE];
5806 	wchar_t exe_path[MAX_PATH];
5807 	char *product_id = NULL;
5808 	// Validate arguments
5809 	if (hash == NULL)
5810 	{
5811 		return;
5812 	}
5813 
5814 #ifdef	OS_WIN32
5815 	product_id = MsRegReadStr(REG_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "ProductId");
5816 	if (product_id == NULL)
5817 	{
5818 		product_id = MsRegReadStr(REG_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion", "ProductId");
5819 	}
5820 #endif	// OS_WIN32
5821 
5822 	b = NewBuf();
5823 
5824 	GetMachineHostName(machine_name, sizeof(machine_name));
5825 	Trim(machine_name);
5826 	StrUpper(machine_name);
5827 
5828 	GetExeNameW(exe_path, sizeof(exe_path));
5829 	UniTrim(exe_path);
5830 	UniStrUpper(exe_path);
5831 
5832 	WriteBuf(b, machine_name, StrSize(machine_name));
5833 	WriteBuf(b, exe_path, UniStrSize(exe_path));
5834 	WriteBuf(b, product_id, StrSize(product_id));
5835 
5836 	ip_list = GetHostIPAddressList();
5837 	if (ip_list != NULL)
5838 	{
5839 		UINT i;
5840 		for (i = 0;i < LIST_NUM(ip_list);i++)
5841 		{
5842 			IP *ip = LIST_DATA(ip_list, i);
5843 
5844 			WriteBuf(b, ip, sizeof(IP));
5845 		}
5846 	}
5847 	FreeHostIPAddressList(ip_list);
5848 
5849 	HashSha1(hash, b->Buf, b->Size);
5850 
5851 	FreeBuf(b);
5852 
5853 	Free(product_id);
5854 }
5855 
5856 // Create a pair of pre-bound TCP sockets
NewTcpPair(SOCK ** s1,SOCK ** s2)5857 bool NewTcpPair(SOCK **s1, SOCK **s2)
5858 {
5859 	SOCK *a;
5860 	SOCK *s, *c;
5861 	TUBE *t1, *t2;
5862 	SOCK_EVENT *e1, *e2;
5863 	// Validate arguments
5864 	if (s1 == NULL || s2 == NULL)
5865 	{
5866 		return false;
5867 	}
5868 
5869 	a = ListenAnyPortEx2(true, true);
5870 	if (a == NULL)
5871 	{
5872 		return false;
5873 	}
5874 
5875 	c = Connect("127.0.0.1", a->LocalPort);
5876 	if (c == NULL)
5877 	{
5878 		ReleaseSock(a);
5879 		return false;
5880 	}
5881 
5882 	s = Accept(a);
5883 	if (s == NULL)
5884 	{
5885 		ReleaseSock(c);
5886 		ReleaseSock(a);
5887 		return false;
5888 	}
5889 
5890 	ReleaseSock(a);
5891 
5892 	if ((s->LocalPort != c->RemotePort) || (s->RemotePort != c->LocalPort))
5893 	{
5894 		ReleaseSock(s);
5895 		ReleaseSock(c);
5896 		return false;
5897 	}
5898 
5899 	NewTubePair(&t1, &t2, sizeof(TCP_PAIR_HEADER));
5900 
5901 	// Creating a socket event
5902 	e1 = NewSockEvent();
5903 	e2 = NewSockEvent();
5904 
5905 	SetTubeSockEvent(t1, e1);
5906 	SetTubeSockEvent(t2, e2);
5907 
5908 	AddRef(t1->Ref);
5909 	AddRef(t2->Ref);
5910 	s->BulkRecvTube = c->BulkSendTube = t1;
5911 	s->BulkSendTube = c->BulkRecvTube = t2;
5912 
5913 	ReleaseSockEvent(e1);
5914 	ReleaseSockEvent(e2);
5915 
5916 	*s1 = s;
5917 	*s2 = c;
5918 
5919 	return true;
5920 }
5921 
5922 // Listen in any available port
ListenAnyPortEx(bool local_only)5923 SOCK *ListenAnyPortEx(bool local_only)
5924 {
5925 	return ListenAnyPortEx2(local_only, false);
5926 }
ListenAnyPortEx2(bool local_only,bool disable_ca)5927 SOCK *ListenAnyPortEx2(bool local_only, bool disable_ca)
5928 {
5929 	UINT i;
5930 	SOCK *s;
5931 	for (i = 40000;i < 65536;i++)
5932 	{
5933 		s = ListenEx(i, local_only);
5934 		if (s != NULL)
5935 		{
5936 			return s;
5937 		}
5938 	}
5939 
5940 	return NULL;
5941 }
5942 
cb_test(int a,X509_STORE_CTX * ctx)5943 int cb_test(int a, X509_STORE_CTX *ctx)
5944 {
5945 	WHERE;
5946 	return 1;
5947 }
5948 
5949 #if OPENSSL_VERSION_NUMBER < 0x10100000L
5950 #define X509_STORE_CTX_get0_cert(o) ((o)->cert)
5951 #endif
5952 
5953 // Verify client SSL certificate during TLS handshake.
5954 //
5955 // (actually, only save the certificate for later authentication in Protocol.c)
SslCertVerifyCallback(int preverify_ok,X509_STORE_CTX * ctx)5956 int SslCertVerifyCallback(int preverify_ok, X509_STORE_CTX *ctx)
5957 {
5958 	SSL *ssl;
5959 	struct SslClientCertInfo *clientcert;
5960 	X509 *cert;
5961 
5962 	ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
5963 	clientcert = SSL_get_ex_data(ssl, GetSslClientCertIndex());
5964 
5965 	if (clientcert != NULL)
5966 	{
5967 		clientcert->PreverifyErr = X509_STORE_CTX_get_error(ctx);
5968 		clientcert->PreverifyErrMessage[0] = '\0';
5969 		if (!preverify_ok)
5970 		{
5971 			const char *msg = X509_verify_cert_error_string(clientcert->PreverifyErr);
5972 			StrCpy(clientcert->PreverifyErrMessage, PREVERIFY_ERR_MESSAGE_SIZE, (char *)msg);
5973 			Debug("SslCertVerifyCallback preverify error: '%s'\n", msg);
5974 		}
5975 		else
5976 		{
5977 			cert = X509_STORE_CTX_get0_cert(ctx);
5978 			if (cert != NULL)
5979 			{
5980 				X *tmpX = X509ToX(cert); // this only wraps cert, but we need to make a copy
5981 				X *copyX = CloneX(tmpX);
5982 				tmpX->do_not_free = true; // do not release inner X509 object
5983 				FreeX(tmpX);
5984 				clientcert->X = copyX;
5985 			}
5986 		}
5987 	}
5988 
5989 	return 1; /* allow the verification process to continue */
5990 }
5991 
5992 // Create a new SSL pipe
NewSslPipe(bool server_mode,X * x,K * k,DH_CTX * dh)5993 SSL_PIPE *NewSslPipe(bool server_mode, X *x, K *k, DH_CTX *dh)
5994 {
5995 	return NewSslPipeEx(server_mode, x, k, dh, false, NULL);
5996 }
5997 
5998 // Create a new SSL pipe with extended options
NewSslPipeEx(bool server_mode,X * x,K * k,DH_CTX * dh,bool verify_peer,struct SslClientCertInfo * clientcert)5999 SSL_PIPE *NewSslPipeEx(bool server_mode, X *x, K *k, DH_CTX *dh, bool verify_peer, struct SslClientCertInfo *clientcert)
6000 {
6001 	SSL_PIPE *s;
6002 	SSL *ssl;
6003 	SSL_CTX *ssl_ctx = NewSSLCtx(server_mode);
6004 
6005 	Lock(openssl_lock);
6006 	{
6007 		if (server_mode)
6008 		{
6009 			SSL_CTX_set_ssl_version(ssl_ctx, SSLv23_method());
6010 			SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSLv2);
6011 
6012 			AddChainSslCertOnDirectory(ssl_ctx);
6013 
6014 			if (dh != NULL)
6015 			{
6016 				SSL_CTX_set_tmp_dh(ssl_ctx, dh->dh);
6017 			}
6018 		}
6019 		else
6020 		{
6021 			SSL_CTX_set_ssl_version(ssl_ctx, SSLv23_client_method());
6022 		}
6023 
6024 		if (verify_peer)
6025 		{
6026 			SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, SslCertVerifyCallback);
6027 		}
6028 
6029 		if (dh != NULL)
6030 		{
6031 			SSL_CTX_set_options(ssl_ctx, SSL_OP_SINGLE_DH_USE);
6032 		}
6033 
6034 		if (server_mode == false)
6035 		{
6036 			SSL_CTX_set_options(ssl_ctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
6037 		}
6038 
6039 		ssl = SSL_new(ssl_ctx);
6040 
6041 		// Set the OpenSSL default cipher algorithms
6042 		SSL_set_cipher_list(ssl, OPENSSL_DEFAULT_CIPHER_LIST);
6043 
6044 		SSL_set_ex_data(ssl, GetSslClientCertIndex(), clientcert);
6045 	}
6046 	Unlock(openssl_lock);
6047 
6048 	s = ZeroMalloc(sizeof(SSL_PIPE));
6049 
6050 	s->ssl = ssl;
6051 	s->ssl_ctx = ssl_ctx;
6052 	s->ServerMode = server_mode;
6053 
6054 	s->SslInOut = NewSslBioSsl();
6055 	s->RawIn = NewSslBioMem();
6056 	s->RawOut = NewSslBioMem();
6057 
6058 	if (x != NULL && k != NULL)
6059 	{
6060 		Lock(openssl_lock);
6061 		{
6062 			SSL_use_certificate(s->ssl, x->x509);
6063 			SSL_use_PrivateKey(s->ssl, k->pkey);
6064 		}
6065 		Unlock(openssl_lock);
6066 	}
6067 
6068 	if (s->ServerMode == false)
6069 	{
6070 		SSL_set_connect_state(s->ssl);
6071 	}
6072 	else
6073 	{
6074 		SSL_set_accept_state(s->ssl);
6075 	}
6076 
6077 	SSL_set_bio(s->ssl, s->RawIn->bio, s->RawOut->bio);
6078 	BIO_set_ssl(s->SslInOut->bio, s->ssl, BIO_NOCLOSE);
6079 
6080 	//s->RawIn->NoFree = true;
6081 	s->RawOut->NoFree = true;
6082 
6083 	return s;
6084 }
6085 
6086 // Synchronization of the SSL pipe
SyncSslPipe(SSL_PIPE * s)6087 bool SyncSslPipe(SSL_PIPE *s)
6088 {
6089 	UINT i;
6090 	// Validate arguments
6091 	if (s == NULL || s->IsDisconnected)
6092 	{
6093 		return false;
6094 	}
6095 
6096 	for (i = 0;i < 2;i++)
6097 	{
6098 		if (SslBioSync(s->RawIn, true, false) == false)
6099 		{
6100 			s->IsDisconnected = true;
6101 			Debug("SyncSslPipe: s->RawIn error.\n");
6102 			return false;
6103 		}
6104 
6105 		if (SslBioSync(s->RawOut, false, true) == false)
6106 		{
6107 			s->IsDisconnected = true;
6108 			Debug("SyncSslPipe: s->RawOut error.\n");
6109 			return false;
6110 		}
6111 
6112 		if (SslBioSync(s->SslInOut, true, true) == false)
6113 		{
6114 			s->IsDisconnected = true;
6115 			Debug("SyncSslPipe: s->SslInOut error.\n");
6116 			return false;
6117 		}
6118 	}
6119 
6120 	return true;
6121 }
6122 
6123 // Release of the SSL pipe
FreeSslPipe(SSL_PIPE * s)6124 void FreeSslPipe(SSL_PIPE *s)
6125 {
6126 	// Validate arguments
6127 	if (s == NULL)
6128 	{
6129 		return;
6130 	}
6131 
6132 	FreeSslBio(s->SslInOut);
6133 	FreeSslBio(s->RawIn);
6134 	FreeSslBio(s->RawOut);
6135 
6136 	SSL_free(s->ssl);
6137 	SSL_CTX_free(s->ssl_ctx);
6138 
6139 	Free(s);
6140 }
6141 
6142 // Release of the SSL BIO
FreeSslBio(SSL_BIO * b)6143 void FreeSslBio(SSL_BIO *b)
6144 {
6145 	// Validate arguments
6146 	if (b == NULL)
6147 	{
6148 		return;
6149 	}
6150 
6151 	if (b->NoFree == false)
6152 	{
6153 		BIO_free(b->bio);
6154 	}
6155 
6156 	ReleaseFifo(b->RecvFifo);
6157 	ReleaseFifo(b->SendFifo);
6158 
6159 	Free(b);
6160 }
6161 
6162 // Create a new SSL BIO (SSL)
NewSslBioSsl()6163 SSL_BIO *NewSslBioSsl()
6164 {
6165 	SSL_BIO *b = ZeroMalloc(sizeof(SSL_BIO));
6166 
6167 	b->bio = BIO_new(BIO_f_ssl());
6168 
6169 	b->RecvFifo = NewFifo();
6170 	b->SendFifo = NewFifo();
6171 
6172 	return b;
6173 }
6174 
6175 // Create a new SSL BIO (memory)
NewSslBioMem()6176 SSL_BIO *NewSslBioMem()
6177 {
6178 	SSL_BIO *b = ZeroMalloc(sizeof(SSL_BIO));
6179 
6180 	b->bio = BIO_new(BIO_s_mem());
6181 
6182 	b->RecvFifo = NewFifo();
6183 	b->SendFifo = NewFifo();
6184 
6185 	return b;
6186 }
6187 
6188 // Synchronize memory contents of the SSL BIO with the FIFO
SslBioSync(SSL_BIO * b,bool sync_send,bool sync_recv)6189 bool SslBioSync(SSL_BIO *b, bool sync_send, bool sync_recv)
6190 {
6191 	// Validate arguments
6192 	if (b == NULL)
6193 	{
6194 		return false;
6195 	}
6196 
6197 	if (b->IsDisconnected)
6198 	{
6199 		return false;
6200 	}
6201 
6202 	// Write the contents of the SendFifo to the BIO
6203 	if (sync_send)
6204 	{
6205 		while (b->SendFifo->size >= 1)
6206 		{
6207 			int r = BIO_write(b->bio, GetFifoPointer(b->SendFifo), FifoSize(b->SendFifo));
6208 
6209 			if (r == 0)
6210 			{
6211 				b->IsDisconnected = true;
6212 				WHERE;
6213 				return false;
6214 			}
6215 			else
6216 			{
6217 				if (r < 0)
6218 				{
6219 					if (BIO_should_retry(b->bio))
6220 					{
6221 						break;
6222 					}
6223 					else
6224 					{
6225 						b->IsDisconnected = true;
6226 						WHERE;
6227 						return false;
6228 					}
6229 				}
6230 				else
6231 				{
6232 					ReadFifo(b->SendFifo, NULL, (UINT)r);
6233 				}
6234 			}
6235 		}
6236 	}
6237 
6238 	// Save to the RecvFifo by reading from the BIO
6239 	if (sync_recv)
6240 	{
6241 		while (true)
6242 		{
6243 			UCHAR tmp[4096];
6244 			int r;
6245 
6246 			r = BIO_read(b->bio, tmp, sizeof(tmp));
6247 
6248 			if (r == 0)
6249 			{
6250 				b->IsDisconnected = true;
6251 				WHERE;
6252 				return false;
6253 			}
6254 			else
6255 			{
6256 				if (r < 0)
6257 				{
6258 					if (BIO_should_retry(b->bio))
6259 					{
6260 						break;
6261 					}
6262 					else
6263 					{
6264 						b->IsDisconnected = true;
6265 						WHERE;
6266 						Debug("OpenSSL Error: %s\n", ERR_error_string(ERR_peek_last_error(), NULL));
6267 						return false;
6268 					}
6269 				}
6270 				else
6271 				{
6272 					WriteFifo(b->RecvFifo, tmp, (UINT)r);
6273 				}
6274 			}
6275 		}
6276 	}
6277 
6278 	return true;
6279 }
6280 
6281 // Release the memory for the return value of the ICMP API
IcmpApiFreeResult(ICMP_RESULT * ret)6282 void IcmpApiFreeResult(ICMP_RESULT *ret)
6283 {
6284 	// Validate arguments
6285 	if (ret == NULL)
6286 	{
6287 		return;
6288 	}
6289 
6290 	if (ret->Data != NULL)
6291 	{
6292 		Free(ret->Data);
6293 	}
6294 
6295 	Free(ret);
6296 }
6297 
6298 // Send an ICMP Echo using ICMP API
IcmpApiEchoSend(IP * dest_ip,UCHAR ttl,UCHAR * data,UINT size,UINT timeout)6299 ICMP_RESULT *IcmpApiEchoSend(IP *dest_ip, UCHAR ttl, UCHAR *data, UINT size, UINT timeout)
6300 {
6301 #ifdef	OS_WIN32
6302 	// Validate arguments
6303 	if (dest_ip == NULL || IsIP4(dest_ip) == false || (size != 0 && data == NULL))
6304 	{
6305 		return NULL;
6306 	}
6307 	if (ttl == 0)
6308 	{
6309 		ttl = 127;
6310 	}
6311 
6312 	if (IsIcmpApiSupported())
6313 	{
6314 		HANDLE h;
6315 		DWORD dw;
6316 		IPAddr dest_addr;
6317 		UINT reply_size;
6318 		ICMP_ECHO_REPLY *reply;
6319 		ICMP_RESULT *ret = NULL;
6320 		IP_OPTION_INFORMATION opt;
6321 
6322 		h = w32net->IcmpCreateFile();
6323 
6324 		if (h == INVALID_HANDLE_VALUE)
6325 		{
6326 			return NULL;
6327 		}
6328 
6329 		Zero(&opt, sizeof(opt));
6330 		opt.Ttl = ttl;
6331 
6332 		IPToInAddr((struct in_addr *)&dest_addr, dest_ip);
6333 
6334 		reply_size = sizeof(*reply) + size + 64;
6335 		reply = ZeroMalloc(reply_size);
6336 
6337 		dw = w32net->IcmpSendEcho(h, dest_addr, data, size, &opt, reply, reply_size, timeout);
6338 
6339 		ret = ZeroMalloc(sizeof(ICMP_RESULT));
6340 
6341 		if (dw >= 1 && reply->Status == IP_SUCCESS)
6342 		{
6343 			ret->Ok = true;
6344 		}
6345 		else
6346 		{
6347 			switch (reply->Status)
6348 			{
6349 			case IP_DEST_NET_UNREACHABLE:
6350 				ret->Type = ICMP_TYPE_DESTINATION_UNREACHABLE;
6351 				ret->Code = ICMP_CODE_NET_UNREACHABLE;
6352 				break;
6353 
6354 			case IP_DEST_HOST_UNREACHABLE:
6355 				ret->Type = ICMP_TYPE_DESTINATION_UNREACHABLE;
6356 				ret->Code = ICMP_CODE_HOST_UNREACHABLE;
6357 				break;
6358 
6359 			case IP_DEST_PROT_UNREACHABLE:
6360 				ret->Type = ICMP_TYPE_DESTINATION_UNREACHABLE;
6361 				ret->Code = ICMP_CODE_PROTOCOL_UNREACHABLE;
6362 				break;
6363 
6364 			case IP_DEST_PORT_UNREACHABLE:
6365 				ret->Type = ICMP_TYPE_DESTINATION_UNREACHABLE;
6366 				ret->Code = ICMP_CODE_PORT_UNREACHABLE;
6367 				break;
6368 
6369 			case IP_TTL_EXPIRED_TRANSIT:
6370 				ret->Type = ICMP_TYPE_TIME_EXCEEDED;
6371 				ret->Code = ICMP_CODE_TTL_EXCEEDED_IN_TRANSIT;
6372 				break;
6373 
6374 			case IP_TTL_EXPIRED_REASSEM:
6375 				ret->Type = ICMP_TYPE_TIME_EXCEEDED;
6376 				ret->Code = ICMP_CODE_FRAGMENT_REASSEMBLY_TIME_EXCEEDED;
6377 				break;
6378 
6379 			default:
6380 				ret->Timeout = true;
6381 				break;
6382 			}
6383 		}
6384 
6385 		if (ret->Timeout == false)
6386 		{
6387 			ret->Ttl = reply->Options.Ttl;
6388 			ret->Rtt = reply->RoundTripTime;
6389 			InAddrToIP(&ret->IpAddress, (struct in_addr *)&reply->Address);
6390 
6391 			if (reply->DataSize >= 1 && reply->Data != NULL)
6392 			{
6393 				ret->DataSize = reply->DataSize;
6394 				ret->Data = Clone(reply->Data, reply->DataSize);
6395 			}
6396 		}
6397 
6398 		Free(reply);
6399 
6400 		w32net->IcmpCloseHandle(h);
6401 
6402 		return ret;
6403 	}
6404 	else
6405 	{
6406 		return NULL;
6407 	}
6408 
6409 #else	// OS_WIN32
6410 	return NULL;
6411 #endif	// OS_WIN32
6412 }
6413 
6414 // Detect whether the ICMP API is supported
IsIcmpApiSupported()6415 bool IsIcmpApiSupported()
6416 {
6417 #ifdef	OS_WIN32
6418 	if (w32net->IcmpCloseHandle != NULL &&
6419 		w32net->IcmpCreateFile != NULL &&
6420 		w32net->IcmpSendEcho != NULL)
6421 	{
6422 		return true;
6423 	}
6424 #endif	// OS_WIN32
6425 
6426 	return false;
6427 }
6428 
6429 // Initialize the routing table change detector
NewRouteChange()6430 ROUTE_CHANGE *NewRouteChange()
6431 {
6432 #ifdef	OS_WIN32
6433 	return Win32NewRouteChange();
6434 #else	// OS_WIN32
6435 	return NULL;
6436 #endif	// OS_WIN32
6437 }
6438 
6439 // Release the routing table change detector
FreeRouteChange(ROUTE_CHANGE * r)6440 void FreeRouteChange(ROUTE_CHANGE *r)
6441 {
6442 #ifdef	OS_WIN32
6443 	Win32FreeRouteChange(r);
6444 #endif	// OS_WIN32
6445 }
6446 
6447 // Get whether the routing table has been changed
IsRouteChanged(ROUTE_CHANGE * r)6448 bool IsRouteChanged(ROUTE_CHANGE *r)
6449 {
6450 #ifdef	OS_WIN32
6451 	return Win32IsRouteChanged(r);
6452 #else	// OS_WIN32
6453 	return false;
6454 #endif	// OS_WIN32
6455 }
6456 
6457 // Routing table change detector function (Win32)
6458 #ifdef	OS_WIN32
Win32NewRouteChange()6459 ROUTE_CHANGE *Win32NewRouteChange()
6460 {
6461 	ROUTE_CHANGE *r;
6462 	bool ret;
6463 
6464 	if (MsIsNt() == false)
6465 	{
6466 		return NULL;
6467 	}
6468 
6469 	if (w32net->CancelIPChangeNotify == NULL ||
6470 		w32net->NotifyRouteChange == NULL)
6471 	{
6472 		return NULL;
6473 	}
6474 
6475 	r = ZeroMalloc(sizeof(ROUTE_CHANGE));
6476 
6477 	r->Data = ZeroMalloc(sizeof(ROUTE_CHANGE_DATA));
6478 
6479 	r->Data->Overlapped.hEvent = CreateEventA(NULL, false, true, NULL);
6480 
6481 	ret = w32net->NotifyRouteChange(&r->Data->Handle, &r->Data->Overlapped);
6482 	if (!(ret == NO_ERROR || ret == WSA_IO_PENDING || WSAGetLastError() == WSA_IO_PENDING))
6483 	{
6484 		Free(r->Data);
6485 		Free(r);
6486 
6487 		return NULL;
6488 	}
6489 
6490 	return r;
6491 }
6492 
Win32FreeRouteChange(ROUTE_CHANGE * r)6493 void Win32FreeRouteChange(ROUTE_CHANGE *r)
6494 {
6495 	// Validate arguments
6496 	if (r == NULL)
6497 	{
6498 		return;
6499 	}
6500 
6501 	w32net->CancelIPChangeNotify(&r->Data->Overlapped);
6502 	CloseHandle(r->Data->Overlapped.hEvent);
6503 
6504 	Free(r->Data);
6505 	Free(r);
6506 }
6507 
Win32IsRouteChanged(ROUTE_CHANGE * r)6508 bool Win32IsRouteChanged(ROUTE_CHANGE *r)
6509 {
6510 	// Validate arguments
6511 	if (r == NULL)
6512 	{
6513 		return false;
6514 	}
6515 
6516 	if ((r->Data->NumCalled++) == 0)
6517 	{
6518 		return true;
6519 	}
6520 
6521 	if (WaitForSingleObject(r->Data->Overlapped.hEvent, 0) == WAIT_OBJECT_0)
6522 	{
6523 		w32net->NotifyRouteChange(&r->Data->Handle, &r->Data->Overlapped);
6524 		return true;
6525 	}
6526 
6527 	return false;
6528 }
6529 
6530 typedef struct WIN32_ACCEPT_CHECK_DATA
6531 {
6532 	bool IsIPv6;
6533 	bool Rejected;
6534 } WIN32_ACCEPT_CHECK_DATA;
6535 
6536 // Function for determining  whether accept or not in Win32
Win32AcceptCheckCallback_Delay(LPWSABUF lpCallerId,LPWSABUF lpCallerData,LPQOS pQos,LPQOS lpGQOS,LPWSABUF lpCalleeId,LPWSABUF lpCalleeData,GROUP FAR * g,DWORD_PTR dwCallbackData)6537 int CALLBACK Win32AcceptCheckCallback_Delay(LPWSABUF lpCallerId, LPWSABUF lpCallerData, LPQOS pQos,
6538 									  LPQOS lpGQOS, LPWSABUF lpCalleeId, LPWSABUF lpCalleeData,
6539 									  GROUP FAR * g, DWORD_PTR dwCallbackData)
6540 {
6541 	return CF_DEFER;
6542 }
6543 
Win32AcceptCheckCallback(LPWSABUF lpCallerId,LPWSABUF lpCallerData,LPQOS pQos,LPQOS lpGQOS,LPWSABUF lpCalleeId,LPWSABUF lpCalleeData,GROUP FAR * g,DWORD_PTR dwCallbackData)6544 int CALLBACK Win32AcceptCheckCallback(LPWSABUF lpCallerId, LPWSABUF lpCallerData, LPQOS pQos,
6545 									  LPQOS lpGQOS, LPWSABUF lpCalleeId, LPWSABUF lpCalleeData,
6546 									  GROUP FAR * g, DWORD_PTR dwCallbackData)
6547 {
6548 	return CF_ACCEPT;
6549 }
6550 
6551 // Accept function for Win32
Win32Accept_XP(SOCK * sock,SOCKET s,struct sockaddr * addr,int * addrlen,bool ipv6)6552 SOCKET Win32Accept_XP(SOCK *sock, SOCKET s, struct sockaddr *addr, int *addrlen, bool ipv6)
6553 {
6554 	SOCKET ret;
6555 	WIN32_ACCEPT_CHECK_DATA d;
6556 	UINT err;
6557 	int initial_addrlen = *addrlen;
6558 	UINT num_error = 0;
6559 	// Validate arguments
6560 	if (s == INVALID_SOCKET)
6561 	{
6562 		return INVALID_SOCKET;
6563 	}
6564 
6565 L_LOOP:
6566 
6567 	Zero(&d, sizeof(d));
6568 
6569 	d.IsIPv6 = ipv6;
6570 
6571 	*addrlen = initial_addrlen;
6572 	Zero(addr, initial_addrlen);
6573 	ret = WSAAccept(s, addr, addrlen, Win32AcceptCheckCallback, (DWORD_PTR)&d);
6574 
6575 	if (ret == INVALID_SOCKET)
6576 	{
6577 		err = WSAGetLastError();
6578 
6579 		num_error++;
6580 
6581 		Debug("!!! WSAAccept Error: %u  rej=%u  num=%u  tick=%I64u\n", WSAGetLastError(), d.Rejected, num_error, Tick64());
6582 
6583 		if (d.Rejected && err == WSAECONNREFUSED)
6584 		{
6585 			goto L_LOOP;
6586 		}
6587 
6588 		if (err == WSAETIMEDOUT)
6589 		{
6590 			goto L_LOOP;
6591 		}
6592 	}
6593 
6594 	return ret;
6595 }
6596 
6597 // Accept function for Win32
Win32Accept(SOCK * sock,SOCKET s,struct sockaddr * addr,int * addrlen,bool ipv6)6598 SOCKET Win32Accept(SOCK *sock, SOCKET s, struct sockaddr *addr, int *addrlen, bool ipv6)
6599 {
6600 	SOCKET ret;
6601 	WIN32_ACCEPT_CHECK_DATA d;
6602 	UINT err;
6603 	int initial_addrlen = *addrlen;
6604 	UINT num_error = 0;
6605 	UINT zero = 0;
6606 	UINT tmp = 0;
6607 	UINT ret_size = 0;
6608 	// Validate arguments
6609 	if (sock == NULL || s == INVALID_SOCKET)
6610 	{
6611 		return INVALID_SOCKET;
6612 	}
6613 
6614 	if (sock->hAcceptEvent == NULL)
6615 	{
6616 		sock->hAcceptEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
6617 
6618 		WSAEventSelect(s, sock->hAcceptEvent, FD_ACCEPT | FD_CLOSE);
6619 	}
6620 
6621 L_LOOP:
6622 
6623 	if (sock->CancelAccept)
6624 	{
6625 		return INVALID_SOCKET;
6626 	}
6627 
6628 	Zero(&d, sizeof(d));
6629 
6630 	d.IsIPv6 = ipv6;
6631 
6632 	*addrlen = initial_addrlen;
6633 	Zero(addr, initial_addrlen);
6634 	ret = WSAAccept(s, addr, addrlen, Win32AcceptCheckCallback, (DWORD_PTR)&d);
6635 
6636 	if (ret == INVALID_SOCKET)
6637 	{
6638 		err = WSAGetLastError();
6639 
6640 		if (err == WSAEWOULDBLOCK)
6641 		{
6642 			//Debug("!!! WSAAccept: WSAEWOULDBLOCK\n");
6643 			UINT wait_ret = WaitForSingleObject(sock->hAcceptEvent, 1234);
6644 
6645 			if (wait_ret == WAIT_OBJECT_0 || wait_ret == WAIT_TIMEOUT)
6646 			{
6647 				goto L_LOOP;
6648 			}
6649 
6650 			Debug("!!! WaitForSingleObject Error. ret=%u GetLastError=%u\n", wait_ret, GetLastError());
6651 		}
6652 
6653 		num_error++;
6654 
6655 		Debug("!!! WSAAccept Error: %u  rej=%u  num=%u  tick=%I64u\n", err, d.Rejected, num_error, Tick64());
6656 
6657 		if (d.Rejected && err == WSAECONNREFUSED)
6658 		{
6659 			goto L_LOOP;
6660 		}
6661 
6662 		if (err == WSAETIMEDOUT)
6663 		{
6664 			goto L_LOOP;
6665 		}
6666 	}
6667 	else
6668 	{
6669 		// Remove a new socket from the event
6670 		WSAEventSelect(ret, sock->hAcceptEvent, 0);
6671 
6672 		// Restore the new socket to synchronized
6673 		WSAIoctl(ret, FIONBIO, &zero, sizeof(zero), &tmp, sizeof(tmp), &ret_size, NULL, NULL);
6674 	}
6675 
6676 	return ret;
6677 }
6678 
6679 #endif	// OS_WIN32
6680 
6681 
6682 // Get whether the aquirement of the Process ID of the TCP connection succeed
CanGetTcpProcessId()6683 bool CanGetTcpProcessId()
6684 {
6685 	UINT i;
6686 	bool ret = false;
6687 	LIST *o = GetTcpTableList();
6688 
6689 	if (o == NULL)
6690 	{
6691 		return false;
6692 	}
6693 
6694 	for (i = 0;i < LIST_NUM(o);i++)
6695 	{
6696 		TCPTABLE *t = LIST_DATA(o, i);
6697 
6698 		if (t->ProcessId != 0)
6699 		{
6700 			ret = true;
6701 			break;
6702 		}
6703 	}
6704 
6705 	FreeTcpTableList(o);
6706 
6707 	return ret;
6708 }
6709 
6710 
6711 
6712 
6713 #define	USE_OLD_GETIP
6714 
6715 // Set the arp_filter in Linux
SetLinuxArpFilter()6716 void SetLinuxArpFilter()
6717 {
6718 	char *filename = "/proc/sys/net/ipv4/conf/all/arp_filter";
6719 	char *data = "1\n";
6720 	IO *o;
6721 
6722 	o = FileCreate(filename);
6723 	if (o == NULL)
6724 	{
6725 		return;
6726 	}
6727 
6728 	FileWrite(o, data, StrLen(data));
6729 	FileFlush(o);
6730 
6731 	FileClose(o);
6732 }
6733 
6734 // Determine whether the string is a IPv6 mask
IsIpMask6(char * str)6735 bool IsIpMask6(char *str)
6736 {
6737 	IP mask;
6738 	// Validate arguments
6739 	if (str == NULL)
6740 	{
6741 		return false;
6742 	}
6743 
6744 	return StrToMask6(&mask, str);
6745 }
6746 
6747 // Determine whether the string is a IPv6 address
IsStrIPv6Address(char * str)6748 bool IsStrIPv6Address(char *str)
6749 {
6750 	IP ip;
6751 	// Validate arguments
6752 	if (str == NULL)
6753 	{
6754 		return false;
6755 	}
6756 
6757 	if (StrToIP6(&ip, str) == false)
6758 	{
6759 		return false;
6760 	}
6761 
6762 	return true;
6763 }
6764 
6765 // Convert the subnet mask to an integer
SubnetMaskToInt6(IP * a)6766 UINT SubnetMaskToInt6(IP *a)
6767 {
6768 	UINT i;
6769 	// Validate arguments
6770 	if (IsIP6(a) == false)
6771 	{
6772 		return 0;
6773 	}
6774 
6775 	for (i = 0;i <= 128;i++)
6776 	{
6777 		IP tmp;
6778 
6779 		IntToSubnetMask6(&tmp, i);
6780 
6781 		if (CmpIpAddr(a, &tmp) == 0)
6782 		{
6783 			return i;
6784 		}
6785 	}
6786 
6787 	return 0;
6788 }
SubnetMaskToInt4(IP * a)6789 UINT SubnetMaskToInt4(IP *a)
6790 {
6791 	UINT i;
6792 	// Validate arguments
6793 	if (IsIP4(a) == false)
6794 	{
6795 		return 0;
6796 	}
6797 
6798 	for (i = 0;i <= 32;i++)
6799 	{
6800 		IP tmp;
6801 
6802 		IntToSubnetMask4(&tmp, i);
6803 
6804 		if (CmpIpAddr(a, &tmp) == 0)
6805 		{
6806 			return i;
6807 		}
6808 	}
6809 
6810 	return 0;
6811 }
SubnetMaskToInt(IP * a)6812 UINT SubnetMaskToInt(IP *a)
6813 {
6814 	if (IsIP6(a))
6815 	{
6816 		return SubnetMaskToInt6(a);
6817 	}
6818 	else
6819 	{
6820 		return SubnetMaskToInt4(a);
6821 	}
6822 }
6823 
6824 // Determine whether the specified IP address is a subnet mask
IsSubnetMask6(IP * a)6825 bool IsSubnetMask6(IP *a)
6826 {
6827 	UINT i;
6828 	// Validate arguments
6829 	if (IsIP6(a) == false)
6830 	{
6831 		return false;
6832 	}
6833 
6834 	for (i = 0;i <= 128;i++)
6835 	{
6836 		IP tmp;
6837 
6838 		IntToSubnetMask6(&tmp, i);
6839 
6840 		if (CmpIpAddr(a, &tmp) == 0)
6841 		{
6842 			return true;
6843 		}
6844 	}
6845 
6846 	return false;
6847 }
6848 
6849 // Generate a global address from the MAC address
GenerateEui64GlobalAddress(IP * ip,IP * prefix,IP * subnet,UCHAR * mac)6850 void GenerateEui64GlobalAddress(IP *ip, IP *prefix, IP *subnet, UCHAR *mac)
6851 {
6852 	UCHAR tmp[8];
6853 	IP a;
6854 	IP subnet_not;
6855 	IP or1, or2;
6856 	// Validate arguments
6857 	if (ip == NULL || prefix == NULL || subnet == NULL || mac == NULL)
6858 	{
6859 		return;
6860 	}
6861 
6862 	GenerateEui64Address6(tmp, mac);
6863 
6864 	ZeroIP6(&a);
6865 
6866 	Copy(&a.ipv6_addr[8], tmp, 8);
6867 
6868 	IPNot6(&subnet_not, subnet);
6869 	IPAnd6(&or1, &a, &subnet_not);
6870 	IPAnd6(&or2, prefix, subnet);
6871 
6872 	IPOr6(ip, &or1, &or2);
6873 }
6874 
6875 // Generate a local address from the MAC address
GenerateEui64LocalAddress(IP * a,UCHAR * mac)6876 void GenerateEui64LocalAddress(IP *a, UCHAR *mac)
6877 {
6878 	UCHAR tmp[8];
6879 	// Validate arguments
6880 	if (a == NULL || mac == NULL)
6881 	{
6882 		return;
6883 	}
6884 
6885 	GenerateEui64Address6(tmp, mac);
6886 
6887 	ZeroIP6(a);
6888 	a->ipv6_addr[0] = 0xfe;
6889 	a->ipv6_addr[1] = 0x80;
6890 
6891 	Copy(&a->ipv6_addr[8], tmp, 8);
6892 }
6893 
6894 // Generate the EUI-64 address from the MAC address
GenerateEui64Address6(UCHAR * dst,UCHAR * mac)6895 void GenerateEui64Address6(UCHAR *dst, UCHAR *mac)
6896 {
6897 	// Validate arguments
6898 	if (dst == NULL || mac == NULL)
6899 	{
6900 		return;
6901 	}
6902 
6903 	Copy(dst, mac, 3);
6904 	Copy(dst + 5, mac, 3);
6905 
6906 	dst[3] = 0xff;
6907 	dst[4] = 0xfe;
6908 	dst[0] = ((~(dst[0] & 0x02)) & 0x02) | (dst[0] & 0xfd);
6909 }
6910 
6911 // Examine whether two IP addresses are in the same network
IsInSameNetwork6ByStr(char * ip1,char * ip2,char * subnet)6912 bool IsInSameNetwork6ByStr(char *ip1, char *ip2, char *subnet)
6913 {
6914 	IP p1, p2, s;
6915 
6916 	if (StrToIP6(&p1, ip1) == false)
6917 	{
6918 		return false;
6919 	}
6920 
6921 	if (StrToIP6(&p2, ip2) == false)
6922 	{
6923 		return false;
6924 	}
6925 
6926 	if (StrToMask6(&s, subnet) == false)
6927 	{
6928 		return false;
6929 	}
6930 
6931 	return IsInSameNetwork6(&p1, &p2, &s);
6932 }
IsInSameNetwork6(IP * a1,IP * a2,IP * subnet)6933 bool IsInSameNetwork6(IP *a1, IP *a2, IP *subnet)
6934 {
6935 	IP prefix1, prefix2;
6936 	// Validate arguments
6937 	if (IsIP6(a1) == false || IsIP6(a2) == false || IsIP6(subnet) == false)
6938 	{
6939 		return false;
6940 	}
6941 
6942 	if (a1->ipv6_scope_id != a2->ipv6_scope_id)
6943 	{
6944 		return false;
6945 	}
6946 
6947 	GetPrefixAddress6(&prefix1, a1, subnet);
6948 	GetPrefixAddress6(&prefix2, a2, subnet);
6949 
6950 	if (CmpIpAddr(&prefix1, &prefix2) == 0)
6951 	{
6952 		return true;
6953 	}
6954 
6955 	return false;
6956 }
IsInSameNetwork4(IP * a1,IP * a2,IP * subnet)6957 bool IsInSameNetwork4(IP *a1, IP *a2, IP *subnet)
6958 {
6959 	IP net1, net2;
6960 	// Validate arguments
6961 	if (IsIP4(a1) == false || IsIP4(a2) == false || IsIP4(subnet) == false)
6962 	{
6963 		return false;
6964 	}
6965 
6966 	IPAnd4(&net1, a1, subnet);
6967 	IPAnd4(&net2, a2, subnet);
6968 
6969 	if (CmpIpAddr(&net1, &net2) == 0)
6970 	{
6971 		return true;
6972 	}
6973 
6974 	return false;
6975 }
IsInSameNetwork4Standard(IP * a1,IP * a2)6976 bool IsInSameNetwork4Standard(IP *a1, IP *a2)
6977 {
6978 	IP subnet;
6979 
6980 	SetIP(&subnet, 255, 255, 0, 0);
6981 
6982 	return IsInSameNetwork4(a1, a2, &subnet);
6983 }
IsInSameLocalNetworkToMe4(IP * a)6984 bool IsInSameLocalNetworkToMe4(IP *a)
6985 {
6986 	IP g1, g2;
6987 
6988 	Zero(&g1, sizeof(g1));
6989 	Zero(&g2, sizeof(g2));
6990 
6991 	GetCurrentGlobalIPGuess(&g1, false);
6992 
6993 	if (IsZeroIp(&g1) == false)
6994 	{
6995 		if (IsInSameNetwork4Standard(&g1, a))
6996 		{
6997 			return true;
6998 		}
6999 	}
7000 
7001 	if (GetCurrentGlobalIP(&g2, false))
7002 	{
7003 		if (IsInSameNetwork4Standard(&g2, a))
7004 		{
7005 			return true;
7006 		}
7007 	}
7008 
7009 	if (IsIPAddressInSameLocalNetwork(a))
7010 	{
7011 		return true;
7012 	}
7013 
7014 	return false;
7015 }
7016 
7017 // Check whether it is a network address prefix
IsNetworkAddress6(IP * ip,IP * subnet)7018 bool IsNetworkAddress6(IP *ip, IP *subnet)
7019 {
7020 	return IsNetworkPrefixAddress6(ip, subnet);
7021 }
IsNetworkPrefixAddress6(IP * ip,IP * subnet)7022 bool IsNetworkPrefixAddress6(IP *ip, IP *subnet)
7023 {
7024 	IP host;
7025 	// Validate arguments
7026 	if (ip == NULL || subnet == NULL)
7027 	{
7028 		return false;
7029 	}
7030 
7031 	if (IsIP6(ip) == false || IsIP6(subnet) == false)
7032 	{
7033 		return false;
7034 	}
7035 
7036 	GetHostAddress6(&host, ip, subnet);
7037 
7038 	if (IsZeroIp(&host))
7039 	{
7040 		return true;
7041 	}
7042 
7043 	return false;
7044 }
7045 
7046 // Check whether the unicast address is available
CheckUnicastAddress(IP * ip)7047 bool CheckUnicastAddress(IP *ip)
7048 {
7049 	// Validate arguments
7050 	if (ip == NULL)
7051 	{
7052 		return false;
7053 	}
7054 
7055 	if ((GetIPAddrType6(ip) & IPV6_ADDR_UNICAST) == 0)
7056 	{
7057 		return false;
7058 	}
7059 
7060 	return true;
7061 }
7062 
7063 // Get the host address
GetHostAddress6(IP * dst,IP * ip,IP * subnet)7064 void GetHostAddress6(IP *dst, IP *ip, IP *subnet)
7065 {
7066 	IP not;
7067 	// Validate arguments
7068 	if (dst == NULL || ip == NULL || subnet == NULL)
7069 	{
7070 		return;
7071 	}
7072 
7073 	IPNot6(&not, subnet);
7074 
7075 	IPAnd6(dst, ip, &not);
7076 
7077 	dst->ipv6_scope_id = ip->ipv6_scope_id;
7078 }
7079 
7080 // Get the prefix address
GetPrefixAddress6(IP * dst,IP * ip,IP * subnet)7081 void GetPrefixAddress6(IP *dst, IP *ip, IP *subnet)
7082 {
7083 	// Validate arguments
7084 	if (dst == NULL || ip == NULL || subnet == NULL)
7085 	{
7086 		return;
7087 	}
7088 
7089 	IPAnd6(dst, ip, subnet);
7090 
7091 	dst->ipv6_scope_id = ip->ipv6_scope_id;
7092 }
7093 
7094 // Get the solicited-node multicast address
GetSoliciationMulticastAddr6(IP * dst,IP * src)7095 void GetSoliciationMulticastAddr6(IP *dst, IP *src)
7096 {
7097 	IP prefix;
7098 	IP mask104;
7099 	IP or1, or2;
7100 
7101 	// Validate arguments
7102 	if (dst == NULL || src == NULL)
7103 	{
7104 		return;
7105 	}
7106 
7107 	ZeroIP6(&prefix);
7108 	prefix.ipv6_addr[0] = 0xff;
7109 	prefix.ipv6_addr[1] = 0x02;
7110 	prefix.ipv6_addr[11] = 0x01;
7111 	prefix.ipv6_addr[12] = 0xff;
7112 
7113 	IntToSubnetMask6(&mask104, 104);
7114 
7115 	IPAnd6(&or1, &prefix, &mask104);
7116 	IPAnd6(&or2, src, &mask104);
7117 
7118 	IPOr6(dst, &or1, &or2);
7119 
7120 	dst->ipv6_scope_id = src->ipv6_scope_id;
7121 }
7122 
7123 // Generate a MAC address corresponding to the multicast address
GenerateMulticastMacAddress6(UCHAR * mac,IP * ip)7124 void GenerateMulticastMacAddress6(UCHAR *mac, IP *ip)
7125 {
7126 	// Validate arguments
7127 	if (mac == NULL)
7128 	{
7129 		return;
7130 	}
7131 
7132 	mac[0] = 0x33;
7133 	mac[1] = 0x33;
7134 	mac[2] = ip->ipv6_addr[12];
7135 	mac[3] = ip->ipv6_addr[13];
7136 	mac[4] = ip->ipv6_addr[14];
7137 	mac[5] = ip->ipv6_addr[15];
7138 }
7139 
7140 // Get the type of the IPv6 address
GetIPv6AddrType(IPV6_ADDR * addr)7141 UINT GetIPv6AddrType(IPV6_ADDR *addr)
7142 {
7143 	IP ip;
7144 	// Validate arguments
7145 	if (addr == NULL)
7146 	{
7147 		return 0;
7148 	}
7149 
7150 	IPv6AddrToIP(&ip, addr);
7151 
7152 	return GetIPAddrType6(&ip);
7153 }
GetIPAddrType6(IP * ip)7154 UINT GetIPAddrType6(IP *ip)
7155 {
7156 	UINT ret = 0;
7157 	// Validate arguments
7158 	if (IsIP6(ip) == false)
7159 	{
7160 		return 0;
7161 	}
7162 
7163 	if (ip->ipv6_addr[0] == 0xff)
7164 	{
7165 		IP all_node, all_router;
7166 
7167 		GetAllNodeMulticaseAddress6(&all_node);
7168 
7169 		GetAllRouterMulticastAddress6(&all_router);
7170 
7171 		ret |= IPV6_ADDR_MULTICAST;
7172 
7173 		if (Cmp(ip->ipv6_addr, all_node.ipv6_addr, 16) == 0)
7174 		{
7175 			ret |= IPV6_ADDR_ALL_NODE_MULTICAST;
7176 		}
7177 		else if (Cmp(ip->ipv6_addr, all_router.ipv6_addr, 16) == 0)
7178 		{
7179 			ret |= IPV6_ADDR_ALL_ROUTER_MULTICAST;
7180 		}
7181 		else
7182 		{
7183 			if (ip->ipv6_addr[1] == 0x02 && ip->ipv6_addr[2] == 0 && ip->ipv6_addr[3] == 0 &&
7184 				ip->ipv6_addr[4] == 0 && ip->ipv6_addr[5] == 0 && ip->ipv6_addr[6] == 0 &&
7185 				ip->ipv6_addr[7] == 0 && ip->ipv6_addr[8] == 0 && ip->ipv6_addr[9] == 0 &&
7186 				ip->ipv6_addr[10] == 0 && ip->ipv6_addr[11] == 0x01 && ip->ipv6_addr[12] == 0xff)
7187 			{
7188 				ret |= IPV6_ADDR_SOLICIATION_MULTICAST;
7189 			}
7190 		}
7191 	}
7192 	else
7193 	{
7194 		ret |= IPV6_ADDR_UNICAST;
7195 
7196 		if (ip->ipv6_addr[0] == 0xfe && (ip->ipv6_addr[1] & 0xc0) == 0x80)
7197 		{
7198 			ret |= IPV6_ADDR_LOCAL_UNICAST;
7199 		}
7200 		else
7201 		{
7202 			ret |= IPV6_ADDR_GLOBAL_UNICAST;
7203 
7204 			if (IsZero(&ip->ipv6_addr, 16))
7205 			{
7206 				ret |= IPV6_ADDR_ZERO;
7207 			}
7208 			else
7209 			{
7210 				IP loopback;
7211 
7212 				GetLoopbackAddress6(&loopback);
7213 
7214 				if (Cmp(ip->ipv6_addr, loopback.ipv6_addr, 16) == 0)
7215 				{
7216 					ret |= IPV6_ADDR_LOOPBACK;
7217 				}
7218 			}
7219 		}
7220 	}
7221 
7222 	return ret;
7223 }
7224 
7225 // Address that all of the bits are set
GetAllFilledAddress6(IP * ip)7226 void GetAllFilledAddress6(IP *ip)
7227 {
7228 	UINT i;
7229 	// Validate arguments
7230 	if (ip == NULL)
7231 	{
7232 		return;
7233 	}
7234 
7235 	ZeroIP6(ip);
7236 
7237 	for (i = 0;i < 15;i++)
7238 	{
7239 		ip->ipv6_addr[i] = 0xff;
7240 	}
7241 }
7242 
7243 // Loopback address
GetLoopbackAddress6(IP * ip)7244 void GetLoopbackAddress6(IP *ip)
7245 {
7246 	// Validate arguments
7247 	if (ip == NULL)
7248 	{
7249 		return;
7250 	}
7251 
7252 	ZeroIP6(ip);
7253 
7254 	ip->ipv6_addr[15] = 0x01;
7255 }
7256 
7257 // All-nodes multicast address
GetAllNodeMulticaseAddress6(IP * ip)7258 void GetAllNodeMulticaseAddress6(IP *ip)
7259 {
7260 	// Validate arguments
7261 	if (ip == NULL)
7262 	{
7263 		return;
7264 	}
7265 
7266 	ZeroIP6(ip);
7267 
7268 	ip->ipv6_addr[0] = 0xff;
7269 	ip->ipv6_addr[1] = 0x02;
7270 	ip->ipv6_addr[15] = 0x01;
7271 }
7272 
7273 // All-routers multicast address
GetAllRouterMulticastAddress6(IP * ip)7274 void GetAllRouterMulticastAddress6(IP *ip)
7275 {
7276 	// Validate arguments
7277 	if (ip == NULL)
7278 	{
7279 		return;
7280 	}
7281 
7282 	ZeroIP6(ip);
7283 
7284 	ip->ipv6_addr[0] = 0xff;
7285 	ip->ipv6_addr[1] = 0x02;
7286 	ip->ipv6_addr[15] = 0x02;
7287 }
7288 
7289 // Logical operation of the IPv4 address
IPNot4(IP * dst,IP * a)7290 void IPNot4(IP *dst, IP *a)
7291 {
7292 	UINT i;
7293 	// Validate arguments
7294 	if (dst == NULL || a == NULL || IsIP4(a) == false)
7295 	{
7296 		Zero(dst, sizeof(IP));
7297 		return;
7298 	}
7299 
7300 	i = IPToUINT(a);
7301 	i = ~i;
7302 
7303 	UINTToIP(dst, i);
7304 }
IPOr4(IP * dst,IP * a,IP * b)7305 void IPOr4(IP *dst, IP *a, IP *b)
7306 {
7307 	UINT i;
7308 	// Validate arguments
7309 	if (dst == NULL || a == NULL || b == NULL || IsIP4(a) == false || IsIP4(b) == false)
7310 	{
7311 		Zero(dst, sizeof(IP));
7312 		return;
7313 	}
7314 
7315 	i = IPToUINT(a) | IPToUINT(b);
7316 
7317 	UINTToIP(dst, i);
7318 }
IPAnd4(IP * dst,IP * a,IP * b)7319 void IPAnd4(IP *dst, IP *a, IP *b)
7320 {
7321 	UINT i;
7322 	// Validate arguments
7323 	if (dst == NULL || a == NULL || b == NULL || IsIP4(a) == false || IsIP4(b) == false)
7324 	{
7325 		Zero(dst, sizeof(IP));
7326 		return;
7327 	}
7328 
7329 	i = IPToUINT(a) & IPToUINT(b);
7330 
7331 	UINTToIP(dst, i);
7332 }
7333 
7334 // Logical operation of the IPv6 address
IPAnd6(IP * dst,IP * a,IP * b)7335 void IPAnd6(IP *dst, IP *a, IP *b)
7336 {
7337 	UINT i;
7338 	// Validate arguments
7339 	if (dst == NULL || IsIP6(a) == false || IsIP6(b) == false)
7340 	{
7341 		ZeroIP6(dst);
7342 		return;
7343 	}
7344 
7345 	ZeroIP6(dst);
7346 	for (i = 0;i < 16;i++)
7347 	{
7348 		dst->ipv6_addr[i] = a->ipv6_addr[i] & b->ipv6_addr[i];
7349 	}
7350 }
IPOr6(IP * dst,IP * a,IP * b)7351 void IPOr6(IP *dst, IP *a, IP *b)
7352 {
7353 	UINT i;
7354 	// Validate arguments
7355 	if (dst == NULL || IsIP6(a) == false || IsIP6(b) == false)
7356 	{
7357 		ZeroIP6(dst);
7358 		return;
7359 	}
7360 
7361 	ZeroIP6(dst);
7362 	for (i = 0;i < 16;i++)
7363 	{
7364 		dst->ipv6_addr[i] = a->ipv6_addr[i] | b->ipv6_addr[i];
7365 	}
7366 }
IPNot6(IP * dst,IP * a)7367 void IPNot6(IP *dst, IP *a)
7368 {
7369 	UINT i;
7370 	// Validate arguments
7371 	if (dst == NULL || IsIP6(a) == false)
7372 	{
7373 		ZeroIP6(dst);
7374 		return;
7375 	}
7376 
7377 	ZeroIP6(dst);
7378 	for (i = 0;i < 16;i++)
7379 	{
7380 		dst->ipv6_addr[i] = ~(a->ipv6_addr[i]);
7381 	}
7382 }
7383 
7384 // Creating a subnet mask
IntToSubnetMask6(IP * ip,UINT i)7385 void IntToSubnetMask6(IP *ip, UINT i)
7386 {
7387 	UINT j = i / 8;
7388 	UINT k = i % 8;
7389 	UINT z;
7390 	IP a;
7391 
7392 	ZeroIP6(&a);
7393 
7394 	for (z = 0;z < 16;z++)
7395 	{
7396 		if (z < j)
7397 		{
7398 			a.ipv6_addr[z] = 0xff;
7399 		}
7400 		else if (z == j)
7401 		{
7402 			a.ipv6_addr[z] = ~(0xff >> k);
7403 		}
7404 	}
7405 
7406 	Copy(ip, &a, sizeof(IP));
7407 }
7408 
7409 // Convert the IP address to a string
IP6AddrToStr(char * str,UINT size,IPV6_ADDR * addr)7410 void IP6AddrToStr(char *str, UINT size, IPV6_ADDR *addr)
7411 {
7412 	// Validate arguments
7413 	if (str == NULL || addr == NULL)
7414 	{
7415 		return;
7416 	}
7417 
7418 	IPToStr6Array(str, size, addr->Value);
7419 }
IPToStr6Array(char * str,UINT size,UCHAR * bytes)7420 void IPToStr6Array(char *str, UINT size, UCHAR *bytes)
7421 {
7422 	IP ip;
7423 	// Validate arguments
7424 	if (str == NULL || bytes == NULL)
7425 	{
7426 		return;
7427 	}
7428 
7429 	SetIP6(&ip, bytes);
7430 
7431 	IPToStr6(str, size, &ip);
7432 }
IPToStr6(char * str,UINT size,IP * ip)7433 void IPToStr6(char *str, UINT size, IP *ip)
7434 {
7435 	char tmp[MAX_SIZE];
7436 
7437 	IPToStr6Inner(tmp, ip);
7438 
7439 	StrCpy(str, size, tmp);
7440 }
IPToStr6Inner(char * str,IP * ip)7441 void IPToStr6Inner(char *str, IP *ip)
7442 {
7443 	UINT i;
7444 	USHORT values[8];
7445 	UINT zero_started_index;
7446 	UINT max_zero_len;
7447 	UINT max_zero_start;
7448 	IP a;
7449 	// Validate arguments
7450 	if (str == NULL || ip == NULL)
7451 	{
7452 		return;
7453 	}
7454 
7455 	Copy(&a, ip, sizeof(IP));
7456 
7457 	for (i = 0;i < 8;i++)
7458 	{
7459 		Copy(&values[i], &a.ipv6_addr[i * 2], sizeof(USHORT));
7460 		values[i] = Endian16(values[i]);
7461 	}
7462 
7463 	// Search for omitable part
7464 	zero_started_index = INFINITE;
7465 	max_zero_len = 0;
7466 	max_zero_start = INFINITE;
7467 	for (i = 0;i < 9;i++)
7468 	{
7469 		USHORT v = (i != 8 ? values[i] : 1);
7470 
7471 		if (v == 0)
7472 		{
7473 			if (zero_started_index == INFINITE)
7474 			{
7475 				zero_started_index = i;
7476 			}
7477 		}
7478 		else
7479 		{
7480 			UINT zero_len;
7481 
7482 			if (zero_started_index != INFINITE)
7483 			{
7484 				zero_len = i - zero_started_index;
7485 				if (zero_len >= 2)
7486 				{
7487 					if (max_zero_len < zero_len)
7488 					{
7489 						max_zero_start = zero_started_index;
7490 						max_zero_len = zero_len;
7491 					}
7492 				}
7493 
7494 				zero_started_index = INFINITE;
7495 			}
7496 		}
7497 	}
7498 
7499 	// Format a string
7500 	StrCpy(str, 0, "");
7501 	for (i = 0;i < 8;i++)
7502 	{
7503 		char tmp[16];
7504 
7505 		ToHex(tmp, values[i]);
7506 		StrLower(tmp);
7507 
7508 		if (i == max_zero_start)
7509 		{
7510 			if (i == 0)
7511 			{
7512 				StrCat(str, 0, "::");
7513 			}
7514 			else
7515 			{
7516 				StrCat(str, 0, ":");
7517 			}
7518 			i += max_zero_len - 1;
7519 		}
7520 		else
7521 		{
7522 			StrCat(str, 0, tmp);
7523 			if (i != 7)
7524 			{
7525 				StrCat(str, 0, ":");
7526 			}
7527 		}
7528 	}
7529 
7530 	// Scope ID
7531 	if (ip->ipv6_scope_id != 0)
7532 	{
7533 		char tmp[64];
7534 
7535 		StrCat(str, 0, "%");
7536 		ToStr(tmp, ip->ipv6_scope_id);
7537 
7538 		StrCat(str, 0, tmp);
7539 	}
7540 }
7541 
7542 // Convert the string to an IP address
StrToIP6(IP * ip,char * str)7543 bool StrToIP6(IP *ip, char *str)
7544 {
7545 	TOKEN_LIST *t;
7546 	char tmp[MAX_PATH];
7547 	IP a;
7548 	UINT i;
7549 	UINT scope_id = 0;
7550 	// Validate arguments
7551 	if (str == NULL || ip == NULL)
7552 	{
7553 		return false;
7554 	}
7555 
7556 	ZeroIP6(&a);
7557 
7558 	StrCpy(tmp, sizeof(tmp), str);
7559 	Trim(tmp);
7560 
7561 	if (StartWith(tmp, "[") && EndWith(tmp, "]"))
7562 	{
7563 		// If the string is enclosed in square brackets, remove brackets
7564 		StrCpyAllowOverlap(tmp, sizeof(tmp), &tmp[1]);
7565 
7566 		if (StrLen(tmp) >= 1)
7567 		{
7568 			tmp[StrLen(tmp) - 1] = 0;
7569 		}
7570 	}
7571 
7572 	// Remove the scope ID by analyzing if there is it
7573 	i = SearchStrEx(tmp, "%", 0, false);
7574 	if (i != INFINITE)
7575 	{
7576 		char ss[MAX_PATH];
7577 
7578 		StrCpy(ss, sizeof(ss), &tmp[i + 1]);
7579 
7580 		tmp[i] = 0;
7581 
7582 		Trim(tmp);
7583 
7584 		Trim(ss);
7585 
7586 		scope_id = ToInt(ss);
7587 	}
7588 
7589 	// Tokenize
7590 	t = ParseTokenWithNullStr(tmp, ":");
7591 	if (t->NumTokens >= 3 && t->NumTokens <= 8)
7592 	{
7593 		UINT i, n;
7594 		bool b = true;
7595 		UINT k = 0;
7596 
7597 		n = 0;
7598 
7599 		for (i = 0;i < t->NumTokens;i++)
7600 		{
7601 			char *str = t->Token[i];
7602 
7603 			if (i != 0 && i != (t->NumTokens - 1) && StrLen(str) == 0)
7604 			{
7605 				n++;
7606 				if (n == 1)
7607 				{
7608 					k += 2 * (8 - t->NumTokens + 1);
7609 				}
7610 				else
7611 				{
7612 					b = false;
7613 					break;
7614 				}
7615 			}
7616 			else
7617 			{
7618 				UCHAR chars[2];
7619 
7620 				if (CheckIPItemStr6(str) == false)
7621 				{
7622 					b = false;
7623 					break;
7624 				}
7625 
7626 				IPItemStrToChars6(chars, str);
7627 
7628 				a.ipv6_addr[k++] = chars[0];
7629 				a.ipv6_addr[k++] = chars[1];
7630 			}
7631 		}
7632 
7633 		if (n != 0 && n != 1)
7634 		{
7635 			b = false;
7636 		}
7637 		else if (n == 0 && t->NumTokens != 8)
7638 		{
7639 			b = false;
7640 		}
7641 
7642 		if (b == false)
7643 		{
7644 			FreeToken(t);
7645 			return false;
7646 		}
7647 	}
7648 	else
7649 	{
7650 		FreeToken(t);
7651 		return false;
7652 	}
7653 
7654 	FreeToken(t);
7655 
7656 	Copy(ip, &a, sizeof(IP));
7657 
7658 	ip->ipv6_scope_id = scope_id;
7659 
7660 	return true;
7661 }
StrToIP6Addr(IPV6_ADDR * ip,char * str)7662 bool StrToIP6Addr(IPV6_ADDR *ip, char *str)
7663 {
7664 	IP ip2;
7665 	// Validate arguments
7666 	if (ip == NULL || str == NULL)
7667 	{
7668 		Zero(ip, sizeof(IPV6_ADDR));
7669 		return false;
7670 	}
7671 
7672 	if (StrToIP6(&ip2, str) == false)
7673 	{
7674 		return false;
7675 	}
7676 
7677 	if (IPToIPv6Addr(ip, &ip2) == false)
7678 	{
7679 		return false;
7680 	}
7681 
7682 	return true;
7683 }
7684 
7685 // Convert an IP address character to the UCHAR type
IPItemStrToChars6(UCHAR * chars,char * str)7686 void IPItemStrToChars6(UCHAR *chars, char *str)
7687 {
7688 	char tmp[5];
7689 	BUF *b;
7690 	UINT len;
7691 	// Validate arguments
7692 	if (chars == NULL)
7693 	{
7694 		return;
7695 	}
7696 
7697 	Zero(tmp, sizeof(tmp));
7698 
7699 	len = StrLen(str);
7700 	switch (len)
7701 	{
7702 	case 0:
7703 		tmp[0] = tmp[1] = tmp[2] = tmp[3] = '0';
7704 		break;
7705 
7706 	case 1:
7707 		tmp[0] = tmp[1] = tmp[2] = '0';
7708 		tmp[3] = str[0];
7709 		break;
7710 
7711 	case 2:
7712 		tmp[0] = tmp[1] = '0';
7713 		tmp[2] = str[0];
7714 		tmp[3] = str[1];
7715 		break;
7716 
7717 	case 3:
7718 		tmp[0] = '0';
7719 		tmp[1] = str[0];
7720 		tmp[2] = str[1];
7721 		tmp[3] = str[2];
7722 		break;
7723 
7724 	case 4:
7725 		tmp[0] = str[0];
7726 		tmp[1] = str[1];
7727 		tmp[2] = str[2];
7728 		tmp[3] = str[3];
7729 		break;
7730 	}
7731 
7732 	b = StrToBin(tmp);
7733 
7734 	chars[0] = ((UCHAR *)b->Buf)[0];
7735 	chars[1] = ((UCHAR *)b->Buf)[1];
7736 
7737 	FreeBuf(b);
7738 }
7739 
7740 // Check whether invalid characters are included in the element string of the IP address
CheckIPItemStr6(char * str)7741 bool CheckIPItemStr6(char *str)
7742 {
7743 	UINT i, len;
7744 	// Validate arguments
7745 	if (str == NULL)
7746 	{
7747 		return false;
7748 	}
7749 
7750 	len = StrLen(str);
7751 	if (len >= 5)
7752 	{
7753 		// Invalid length
7754 		return false;
7755 	}
7756 
7757 	for (i = 0;i < len;i++)
7758 	{
7759 		char c = str[i];
7760 
7761 		if ((c >= 'a' && c <= 'f') ||
7762 			(c >= 'A' && c <= 'F') ||
7763 			(c >= '0' && c <= '9'))
7764 		{
7765 		}
7766 		else
7767 		{
7768 			return false;
7769 		}
7770 	}
7771 
7772 	return true;
7773 }
7774 
7775 // Create an IPv4 address of all zero
ZeroIP4(IP * ip)7776 void ZeroIP4(IP *ip)
7777 {
7778 	// Validate arguments
7779 	if (ip == NULL)
7780 	{
7781 		return;
7782 	}
7783 
7784 	Zero(ip, sizeof(IP));
7785 }
7786 
7787 // Create an IPv6 address of all zero
ZeroIP6(IP * ip)7788 void ZeroIP6(IP *ip)
7789 {
7790 	// Validate arguments
7791 	if (ip == NULL)
7792 	{
7793 		return;
7794 	}
7795 
7796 	SetIP6(ip, NULL);
7797 }
7798 
7799 // Get the IP address of the localhost
GetLocalHostIP6(IP * ip)7800 void GetLocalHostIP6(IP *ip)
7801 {
7802 	// Validate arguments
7803 	if (ip == NULL)
7804 	{
7805 		return;
7806 	}
7807 	ZeroIP6(ip);
7808 
7809 	ip->ipv6_addr[15] = 1;
7810 }
GetLocalHostIP4(IP * ip)7811 void GetLocalHostIP4(IP *ip)
7812 {
7813 	// Validate arguments
7814 	if (ip == NULL)
7815 	{
7816 		return;
7817 	}
7818 
7819 	SetIP(ip, 127, 0, 0, 1);
7820 }
7821 
7822 // Check whether the specified address is a localhost
IsLocalHostIP6(IP * ip)7823 bool IsLocalHostIP6(IP *ip)
7824 {
7825 	IP local;
7826 	// Validate arguments
7827 	if (ip == NULL)
7828 	{
7829 		return false;
7830 	}
7831 	if (IsIP6(ip) == false)
7832 	{
7833 		return false;
7834 	}
7835 
7836 	GetLocalHostIP6(&local);
7837 
7838 	if (CmpIpAddr(&local, ip) == 0)
7839 	{
7840 		return true;
7841 	}
7842 
7843 	return false;
7844 }
IsLocalHostIP4(IP * ip)7845 bool IsLocalHostIP4(IP *ip)
7846 {
7847 	// Validate arguments
7848 	if (ip == NULL)
7849 	{
7850 		return false;
7851 	}
7852 	if (IsIP4(ip) == false)
7853 	{
7854 		return false;
7855 	}
7856 
7857 	if (ip->addr[0] == 127)
7858 	{
7859 		return true;
7860 	}
7861 
7862 	return false;
7863 }
IsLocalHostIP(IP * ip)7864 bool IsLocalHostIP(IP *ip)
7865 {
7866 	// Validate arguments
7867 	if (ip == NULL)
7868 	{
7869 		return false;
7870 	}
7871 
7872 	if (IsIP4(ip))
7873 	{
7874 		return IsLocalHostIP4(ip);
7875 	}
7876 	else
7877 	{
7878 		return IsLocalHostIP6(ip);
7879 	}
7880 }
7881 
7882 // Convert the IPV6_ADDR to an IP
IPv6AddrToIP(IP * ip,IPV6_ADDR * addr)7883 void IPv6AddrToIP(IP *ip, IPV6_ADDR *addr)
7884 {
7885 	// Validate arguments
7886 	if (ip == NULL || addr == NULL)
7887 	{
7888 		return;
7889 	}
7890 
7891 	SetIP6(ip, addr->Value);
7892 }
7893 
7894 // Convert the IP to an IPV6_ADDR
IPToIPv6Addr(IPV6_ADDR * addr,IP * ip)7895 bool IPToIPv6Addr(IPV6_ADDR *addr, IP *ip)
7896 {
7897 	UINT i;
7898 	// Validate arguments
7899 	if (addr == NULL || ip == NULL)
7900 	{
7901 		Zero(addr, sizeof(IPV6_ADDR));
7902 		return false;
7903 	}
7904 
7905 	if (IsIP6(ip) == false)
7906 	{
7907 		Zero(addr, sizeof(IPV6_ADDR));
7908 		return false;
7909 	}
7910 
7911 	for (i = 0;i < 16;i++)
7912 	{
7913 		addr->Value[i] = ip->ipv6_addr[i];
7914 	}
7915 
7916 	return true;
7917 }
7918 
7919 // Set an IPv6 address
SetIP6(IP * ip,UCHAR * value)7920 void SetIP6(IP *ip, UCHAR *value)
7921 {
7922 	// Validate arguments
7923 	if (ip == NULL)
7924 	{
7925 		return;
7926 	}
7927 
7928 	Zero(ip, sizeof(IP));
7929 
7930 	ip->addr[0] = 223;
7931 	ip->addr[1] = 255;
7932 	ip->addr[2] = 255;
7933 	ip->addr[3] = 254;
7934 
7935 	if (value != NULL)
7936 	{
7937 		UINT i;
7938 
7939 		for (i = 0;i < 16;i++)
7940 		{
7941 			ip->ipv6_addr[i] = value[i];
7942 		}
7943 	}
7944 }
7945 
7946 // Check whether the specified address is a IPv6 address
IsIP6(IP * ip)7947 bool IsIP6(IP *ip)
7948 {
7949 	// Validate arguments
7950 	if (ip == NULL)
7951 	{
7952 		return false;
7953 	}
7954 
7955 	if (ip->addr[0] == 223 && ip->addr[1] == 255 && ip->addr[2] == 255 && ip->addr[3] == 254)
7956 	{
7957 		return true;
7958 	}
7959 
7960 	return false;
7961 }
IsIP4(IP * ip)7962 bool IsIP4(IP *ip)
7963 {
7964 	// Validate arguments
7965 	if (ip == NULL)
7966 	{
7967 		return false;
7968 	}
7969 
7970 	return (IsIP6(ip) ? false : true);
7971 }
7972 
7973 // Examine whether the version of the two IP addresses are same
IsSameIPVer(IP * ip1,IP * ip2)7974 bool IsSameIPVer(IP *ip1, IP *ip2)
7975 {
7976 	// Validate arguments
7977 	if (ip1 == NULL || ip2 == NULL)
7978 	{
7979 		return false;
7980 	}
7981 
7982 	if (IsIP4(ip1) && IsIP4(ip2))
7983 	{
7984 		return true;
7985 	}
7986 
7987 	if (IsIP6(ip1) && IsIP6(ip2))
7988 	{
7989 		return true;
7990 	}
7991 
7992 	return false;
7993 }
7994 
7995 // Copy the IP address
CopyIP(IP * dst,IP * src)7996 void CopyIP(IP *dst, IP *src)
7997 {
7998 	Copy(dst, src, sizeof(IP));
7999 }
8000 
8001 // Check the length of the IPv6 subnet
CheckSubnetLength6(UINT i)8002 bool CheckSubnetLength6(UINT i)
8003 {
8004 	if (i >= 1 && i <= 127)
8005 	{
8006 		return true;
8007 	}
8008 
8009 	return false;
8010 }
8011 
8012 // Get the process ID of the corresponding TCP connection by the socket
GetTcpProcessIdFromSocket(SOCK * s)8013 UINT GetTcpProcessIdFromSocket(SOCK *s)
8014 {
8015 	LIST *o;
8016 	TCPTABLE *t;
8017 	UINT pid = 0;
8018 	// Validate arguments
8019 	if (s == NULL)
8020 	{
8021 		return 0;
8022 	}
8023 
8024 	o = GetTcpTableList();
8025 	if (o == NULL)
8026 	{
8027 		return 0;
8028 	}
8029 
8030 	t = GetTcpTableFromEndPoint(o, &s->LocalIP, s->LocalPort,
8031 		&s->RemoteIP, s->RemotePort);
8032 
8033 	if (t != NULL)
8034 	{
8035 		pid = t->ProcessId;
8036 	}
8037 
8038 	FreeTcpTableList(o);
8039 
8040 	return pid;
8041 }
GetTcpProcessIdFromSocketReverse(SOCK * s)8042 UINT GetTcpProcessIdFromSocketReverse(SOCK *s)
8043 {
8044 	LIST *o;
8045 	TCPTABLE *t;
8046 	UINT pid = 0;
8047 	// Validate arguments
8048 	if (s == NULL)
8049 	{
8050 		return 0;
8051 	}
8052 
8053 	o = GetTcpTableList();
8054 	if (o == NULL)
8055 	{
8056 		return 0;
8057 	}
8058 
8059 	t = GetTcpTableFromEndPoint(o, &s->RemoteIP, s->RemotePort,
8060 		&s->LocalIP, s->LocalPort);
8061 
8062 	if (t != NULL)
8063 	{
8064 		pid = t->ProcessId;
8065 	}
8066 
8067 	FreeTcpTableList(o);
8068 
8069 	return pid;
8070 }
8071 
8072 // Search in the TCP table by the end point
GetTcpTableFromEndPoint(LIST * o,IP * local_ip,UINT local_port,IP * remote_ip,UINT remote_port)8073 TCPTABLE *GetTcpTableFromEndPoint(LIST *o, IP *local_ip, UINT local_port, IP *remote_ip, UINT remote_port)
8074 {
8075 	IP local;
8076 	UINT i;
8077 	// Validate arguments
8078 	if (o == NULL)
8079 	{
8080 		return NULL;
8081 	}
8082 
8083 	SetIP(&local, 127, 0, 0, 1);
8084 
8085 	if (local_ip == NULL)
8086 	{
8087 		local_ip = &local;
8088 	}
8089 
8090 	if (remote_ip == NULL)
8091 	{
8092 		remote_ip = &local;
8093 	}
8094 
8095 	for (i = 0;i < LIST_NUM(o);i++)
8096 	{
8097 		TCPTABLE *t = LIST_DATA(o, i);
8098 
8099 		if (t->Status == TCP_STATE_SYN_SENT || t->Status == TCP_STATE_SYN_RCVD ||
8100 			t->Status == TCP_STATE_ESTAB)
8101 		{
8102 			if (CmpIpAddr(&t->LocalIP, local_ip) == 0)
8103 			{
8104 				if (CmpIpAddr(&t->RemoteIP, remote_ip) == 0)
8105 				{
8106 					if (t->LocalPort == local_port)
8107 					{
8108 						if (t->RemotePort == remote_port)
8109 						{
8110 							return t;
8111 						}
8112 					}
8113 				}
8114 			}
8115 		}
8116 	}
8117 
8118 	return NULL;
8119 }
8120 
8121 // Get the TCP table list (Win32)
8122 #ifdef	OS_WIN32
Win32GetTcpTableList()8123 LIST *Win32GetTcpTableList()
8124 {
8125 	LIST *o;
8126 
8127 	// Windows XP SP2 or later
8128 	o = Win32GetTcpTableListByGetExtendedTcpTable();
8129 	if (o != NULL)
8130 	{
8131 		return o;
8132 	}
8133 
8134 	// Windows XP or later
8135 	o = Win32GetTcpTableListByAllocateAndGetTcpExTableFromStack();
8136 	if (o != NULL)
8137 	{
8138 		return o;
8139 	}
8140 
8141 	// For legacy Windows
8142 	return Win32GetTcpTableListByGetTcpTable();
8143 }
8144 
8145 // Get the TCP table list (for Windows XP SP2 or later)
Win32GetTcpTableListByGetExtendedTcpTable()8146 LIST *Win32GetTcpTableListByGetExtendedTcpTable()
8147 {
8148 	UINT need_size;
8149 	UINT i;
8150 	MIB_TCPTABLE_OWNER_PID *table;
8151 	bool ok = false;
8152 	LIST *o;
8153 	if (w32net->GetExtendedTcpTable == NULL)
8154 	{
8155 		return NULL;
8156 	}
8157 
8158 	for (i = 0;i < 128;i++)
8159 	{
8160 		UINT ret;
8161 		table = MallocFast(sizeof(MIB_TCPTABLE_OWNER_PID));
8162 		need_size = sizeof(MIB_TCPTABLE_OWNER_PID);
8163 		ret = w32net->GetExtendedTcpTable(table, &need_size, true, AF_INET, _TCP_TABLE_OWNER_PID_ALL, 0);
8164 		if (ret == NO_ERROR)
8165 		{
8166 			ok = true;
8167 			break;
8168 		}
8169 		else
8170 		{
8171 			Free(table);
8172 			if (ret != ERROR_INSUFFICIENT_BUFFER)
8173 			{
8174 				return NULL;
8175 			}
8176 		}
8177 
8178 		table = MallocFast(need_size);
8179 
8180 		ret = w32net->GetExtendedTcpTable(table, &need_size, true, AF_INET, _TCP_TABLE_OWNER_PID_ALL, 0);
8181 		if (ret == NO_ERROR)
8182 		{
8183 			ok = true;
8184 			break;
8185 		}
8186 		else
8187 		{
8188 			Free(table);
8189 
8190 			if (ret != ERROR_INSUFFICIENT_BUFFER)
8191 			{
8192 				return NULL;
8193 			}
8194 		}
8195 	}
8196 
8197 	if (ok == false)
8198 	{
8199 		return NULL;
8200 	}
8201 
8202 	o = NewListEx(NULL, true);
8203 
8204 	for (i = 0;i < table->dwNumEntries;i++)
8205 	{
8206 		MIB_TCPROW_OWNER_PID *r = &table->table[i];
8207 		TCPTABLE *t = ZeroMallocFast(sizeof(TCPTABLE));
8208 
8209 		UINTToIP(&t->LocalIP, r->dwLocalAddr);
8210 		t->LocalPort = Endian16((USHORT)r->dwLocalPort);
8211 
8212 		if (r->dwState != TCP_STATE_LISTEN)
8213 		{
8214 			UINTToIP(&t->RemoteIP, r->dwRemoteAddr);
8215 			t->RemotePort = Endian16((USHORT)r->dwRemotePort);
8216 		}
8217 
8218 		t->Status = r->dwState;
8219 		t->ProcessId = r->dwOwningPid;
8220 
8221 		Add(o, t);
8222 	}
8223 
8224 	Free(table);
8225 
8226 	return o;
8227 }
8228 
8229 // Get the TCP table list (Windows XP or later)
Win32GetTcpTableListByAllocateAndGetTcpExTableFromStack()8230 LIST *Win32GetTcpTableListByAllocateAndGetTcpExTableFromStack()
8231 {
8232 	HANDLE heap;
8233 	UINT i;
8234 	MIB_TCPTABLE_OWNER_PID *table;
8235 	bool ok = false;
8236 	LIST *o;
8237 	if (w32net->AllocateAndGetTcpExTableFromStack == NULL)
8238 	{
8239 		return NULL;
8240 	}
8241 
8242 	heap = GetProcessHeap();
8243 
8244 	if (w32net->AllocateAndGetTcpExTableFromStack(&table, true, heap, HEAP_GROWABLE, AF_INET) != ERROR_SUCCESS)
8245 	{
8246 		return NULL;
8247 	}
8248 
8249 	o = NewListEx(NULL, true);
8250 
8251 	for (i = 0;i < table->dwNumEntries;i++)
8252 	{
8253 		MIB_TCPROW_OWNER_PID *r = &table->table[i];
8254 		TCPTABLE *t = ZeroMallocFast(sizeof(TCPTABLE));
8255 
8256 		UINTToIP(&t->LocalIP, r->dwLocalAddr);
8257 		t->LocalPort = Endian16((USHORT)r->dwLocalPort);
8258 
8259 		if (r->dwState != TCP_STATE_LISTEN)
8260 		{
8261 			UINTToIP(&t->RemoteIP, r->dwRemoteAddr);
8262 			t->RemotePort = Endian16((USHORT)r->dwRemotePort);
8263 		}
8264 
8265 		t->ProcessId = r->dwOwningPid;
8266 		t->Status = r->dwState;
8267 
8268 		Add(o, t);
8269 	}
8270 
8271 	HeapFree(heap, 0, table);
8272 
8273 	return o;
8274 }
8275 
8276 // Get the TCP table list (For legacy Windows)
Win32GetTcpTableListByGetTcpTable()8277 LIST *Win32GetTcpTableListByGetTcpTable()
8278 {
8279 	UINT need_size;
8280 	UINT i;
8281 	MIB_TCPTABLE *table;
8282 	bool ok = false;
8283 	LIST *o;
8284 	if (w32net->GetTcpTable == NULL)
8285 	{
8286 		return NULL;
8287 	}
8288 
8289 	for (i = 0;i < 128;i++)
8290 	{
8291 		UINT ret;
8292 		table = MallocFast(sizeof(MIB_TCPTABLE));
8293 		need_size = sizeof(MIB_TCPTABLE);
8294 		ret = w32net->GetTcpTable(table, &need_size, true);
8295 		if (ret == NO_ERROR)
8296 		{
8297 			ok = true;
8298 			break;
8299 		}
8300 		else
8301 		{
8302 			Free(table);
8303 			if (ret != ERROR_INSUFFICIENT_BUFFER)
8304 			{
8305 				return NULL;
8306 			}
8307 		}
8308 
8309 		table = MallocFast(need_size);
8310 
8311 		ret = w32net->GetTcpTable(table, &need_size, true);
8312 		if (ret == NO_ERROR)
8313 		{
8314 			ok = true;
8315 			break;
8316 		}
8317 		else
8318 		{
8319 			Free(table);
8320 
8321 			if (ret != ERROR_INSUFFICIENT_BUFFER)
8322 			{
8323 				return NULL;
8324 			}
8325 		}
8326 	}
8327 
8328 	if (ok == false)
8329 	{
8330 		return NULL;
8331 	}
8332 
8333 	o = NewListEx(NULL, true);
8334 
8335 	for (i = 0;i < table->dwNumEntries;i++)
8336 	{
8337 		MIB_TCPROW *r = &table->table[i];
8338 		TCPTABLE *t = ZeroMallocFast(sizeof(TCPTABLE));
8339 
8340 		UINTToIP(&t->LocalIP, r->dwLocalAddr);
8341 		t->LocalPort = Endian16((USHORT)r->dwLocalPort);
8342 
8343 		if (r->dwState != TCP_STATE_LISTEN)
8344 		{
8345 			UINTToIP(&t->RemoteIP, r->dwRemoteAddr);
8346 			t->RemotePort = Endian16((USHORT)r->dwRemotePort);
8347 		}
8348 
8349 		t->Status = r->dwState;
8350 
8351 		Add(o, t);
8352 	}
8353 
8354 	Free(table);
8355 
8356 	return o;
8357 }
8358 
8359 #endif	// OS_WIN32
8360 
8361 // Display the TCP table
PrintTcpTableList(LIST * o)8362 void PrintTcpTableList(LIST *o)
8363 {
8364 	UINT i;
8365 	// Validate arguments
8366 	if (o == NULL)
8367 	{
8368 		Print("o == NULL\n\n");
8369 		return;
8370 	}
8371 
8372 	Print("--- TCPTABLE: %u Entries ---\n", LIST_NUM(o));
8373 	for (i = 0;i < LIST_NUM(o);i++)
8374 	{
8375 		char tmp1[MAX_PATH], tmp2[MAX_PATH];
8376 		TCPTABLE *t = LIST_DATA(o, i);
8377 
8378 		IPToStr(tmp1, sizeof(tmp1), &t->LocalIP);
8379 		IPToStr(tmp2, sizeof(tmp2), &t->RemoteIP);
8380 
8381 		Print("%s:%u <--> %s:%u  state=%u  pid=%u\n",
8382 			tmp1, t->LocalPort,
8383 			tmp2, t->RemotePort,
8384 			t->Status,
8385 			t->ProcessId);
8386 	}
8387 	Print("------\n\n");
8388 }
8389 
8390 // Comparison of TCP table items
CompareTcpTable(void * p1,void * p2)8391 int CompareTcpTable(void *p1, void *p2)
8392 {
8393 	TCPTABLE *t1, *t2;
8394 	if (p1 == NULL || p2 == NULL)
8395 	{
8396 		return 0;
8397 	}
8398 	t1 = *(TCPTABLE **)p1;
8399 	t2 = *(TCPTABLE **)p2;
8400 	if (t1 == NULL || t2 == NULL)
8401 	{
8402 		return 0;
8403 	}
8404 
8405 	return Cmp(t1, t2, sizeof(TCPTABLE));
8406 }
8407 
8408 // Get the TCP table list
GetTcpTableList()8409 LIST *GetTcpTableList()
8410 {
8411 #ifdef	OS_WIN32
8412 	return Win32GetTcpTableList();
8413 #else	// OS_WIN32
8414 	return NULL;
8415 #endif	// OS_WIN32
8416 }
8417 
8418 // Release the TCP table list
FreeTcpTableList(LIST * o)8419 void FreeTcpTableList(LIST *o)
8420 {
8421 	UINT i;
8422 	// Validate arguments
8423 	if (o == NULL)
8424 	{
8425 		return;
8426 	}
8427 
8428 	for (i = 0;i < LIST_NUM(o);i++)
8429 	{
8430 		TCPTABLE *t = LIST_DATA(o, i);
8431 
8432 		Free(t);
8433 	}
8434 
8435 	ReleaseList(o);
8436 }
8437 
8438 // Get the number of clients connected from the specified IP address
GetNumIpClient(IP * ip)8439 UINT GetNumIpClient(IP *ip)
8440 {
8441 	IP_CLIENT *c;
8442 	UINT ret = 0;
8443 	// Validate arguments
8444 	if (ip == NULL)
8445 	{
8446 		return 0;
8447 	}
8448 
8449 	LockList(ip_clients);
8450 	{
8451 		c = SearchIpClient(ip);
8452 
8453 		if (c != NULL)
8454 		{
8455 			ret = c->NumConnections;
8456 		}
8457 	}
8458 	UnlockList(ip_clients);
8459 
8460 	return ret;
8461 }
8462 
8463 // Add to the IP client entry
AddIpClient(IP * ip)8464 void AddIpClient(IP *ip)
8465 {
8466 	IP_CLIENT *c;
8467 	// Validate arguments
8468 	if (ip == NULL)
8469 	{
8470 		return;
8471 	}
8472 
8473 	LockList(ip_clients);
8474 	{
8475 		c = SearchIpClient(ip);
8476 
8477 		if (c == NULL)
8478 		{
8479 			c = ZeroMallocFast(sizeof(IP_CLIENT));
8480 			Copy(&c->IpAddress, ip, sizeof(IP));
8481 			c->NumConnections = 0;
8482 
8483 			Add(ip_clients, c);
8484 		}
8485 
8486 		c->NumConnections++;
8487 	}
8488 	UnlockList(ip_clients);
8489 
8490 	//Debug("AddIpClient: %r\n", ip);
8491 }
8492 
8493 // Remove from the IP client list
DelIpClient(IP * ip)8494 void DelIpClient(IP *ip)
8495 {
8496 	IP_CLIENT *c;
8497 	// Validate arguments
8498 	if (ip == NULL)
8499 	{
8500 		return;
8501 	}
8502 
8503 	LockList(ip_clients);
8504 	{
8505 		c = SearchIpClient(ip);
8506 
8507 		if (c != NULL)
8508 		{
8509 			c->NumConnections--;
8510 
8511 			if (c->NumConnections == 0)
8512 			{
8513 				Delete(ip_clients, c);
8514 				Free(c);
8515 			}
8516 		}
8517 	}
8518 	UnlockList(ip_clients);
8519 
8520 	//Debug("DelIpClient: %r\n", ip);
8521 }
8522 
8523 // Search for the IP client entry
SearchIpClient(IP * ip)8524 IP_CLIENT *SearchIpClient(IP *ip)
8525 {
8526 	IP_CLIENT t;
8527 	// Validate arguments
8528 	if (ip == NULL)
8529 	{
8530 		return NULL;
8531 	}
8532 
8533 	Zero(&t, sizeof(t));
8534 	Copy(&t.IpAddress, ip, sizeof(IP));
8535 
8536 	return Search(ip_clients, &t);
8537 }
8538 
8539 // Initialization of the client list
InitIpClientList()8540 void InitIpClientList()
8541 {
8542 	ip_clients = NewList(CompareIpClientList);
8543 }
8544 
8545 // Release of the client list
FreeIpClientList()8546 void FreeIpClientList()
8547 {
8548 	UINT i;
8549 
8550 	for (i = 0;i < LIST_NUM(ip_clients);i++)
8551 	{
8552 		IP_CLIENT *c = LIST_DATA(ip_clients, i);
8553 
8554 		Free(c);
8555 	}
8556 
8557 	ReleaseList(ip_clients);
8558 	ip_clients = NULL;
8559 }
8560 
8561 // Comparison of the client list entries
CompareIpClientList(void * p1,void * p2)8562 int CompareIpClientList(void *p1, void *p2)
8563 {
8564 	IP_CLIENT *c1, *c2;
8565 	if (p1 == NULL || p2 == NULL)
8566 	{
8567 		return 0;
8568 	}
8569 	c1 = *(IP_CLIENT **)p1;
8570 	c2 = *(IP_CLIENT **)p2;
8571 	if (c1 == NULL || c2 == NULL)
8572 	{
8573 		return 0;
8574 	}
8575 
8576 	return CmpIpAddr(&c1->IpAddress, &c2->IpAddress);
8577 }
8578 
8579 // Normalization of the MAC address
NormalizeMacAddress(char * dst,UINT size,char * src)8580 bool NormalizeMacAddress(char *dst, UINT size, char *src)
8581 {
8582 	BUF *b;
8583 	bool ret = false;
8584 	// Validate arguments
8585 	if (dst == NULL || src == NULL)
8586 	{
8587 		return false;
8588 	}
8589 
8590 	b = StrToBin(src);
8591 
8592 	if (b != NULL && b->Size == 6)
8593 	{
8594 		ret = true;
8595 
8596 		BinToStr(dst, size, b->Buf, b->Size);
8597 	}
8598 
8599 	FreeBuf(b);
8600 
8601 	return ret;
8602 }
8603 
8604 // Identify whether the IP address is empty
IsZeroIP(IP * ip)8605 bool IsZeroIP(IP *ip)
8606 {
8607 	return IsZeroIp(ip);
8608 }
IsZeroIp(IP * ip)8609 bool IsZeroIp(IP *ip)
8610 {
8611 	// Validate arguments
8612 	if (ip == NULL)
8613 	{
8614 		return true;
8615 	}
8616 
8617 	if (IsIP6(ip) == false)
8618 	{
8619 		return IsZero(ip->addr, sizeof(ip->addr));
8620 	}
8621 	else
8622 	{
8623 		return IsZero(ip->ipv6_addr, sizeof(ip->ipv6_addr));
8624 	}
8625 }
IsZeroIP6Addr(IPV6_ADDR * addr)8626 bool IsZeroIP6Addr(IPV6_ADDR *addr)
8627 {
8628 	// Validate arguments
8629 	if (addr == NULL)
8630 	{
8631 		return true;
8632 	}
8633 
8634 	return IsZero(addr, sizeof(IPV6_ADDR));
8635 }
8636 
8637 // Examine whether the specified IP address is meaningful as a host
IsHostIPAddress4(IP * ip)8638 bool IsHostIPAddress4(IP *ip)
8639 {
8640 	UINT a;
8641 	// Validate arguments
8642 	if (ip == NULL)
8643 	{
8644 		return false;
8645 	}
8646 
8647 	a = IPToUINT(ip);
8648 
8649 	if (a == 0 || a == 0xffffffff)
8650 	{
8651 		return false;
8652 	}
8653 
8654 	return true;
8655 }
IsHostIPAddress32(UINT ip)8656 bool IsHostIPAddress32(UINT ip)
8657 {
8658 	IP p;
8659 
8660 	UINTToIP(&p, ip);
8661 
8662 	return IsHostIPAddress4(&p);
8663 }
8664 
8665 // Check whether the specified IP address and subnet mask indicates a network correctly
IsNetworkAddress(IP * ip,IP * mask)8666 bool IsNetworkAddress(IP *ip, IP *mask)
8667 {
8668 	if (IsIP4(ip))
8669 	{
8670 		return IsNetworkAddress4(ip, mask);
8671 	}
8672 	else
8673 	{
8674 		return IsNetworkAddress6(ip, mask);
8675 	}
8676 }
IsNetworkAddress4(IP * ip,IP * mask)8677 bool IsNetworkAddress4(IP *ip, IP *mask)
8678 {
8679 	UINT a, b;
8680 	// Validate arguments
8681 	if (ip == NULL || mask == NULL)
8682 	{
8683 		return false;
8684 	}
8685 
8686 	if (IsIP4(ip) == false || IsIP4(mask) == false)
8687 	{
8688 		return false;
8689 	}
8690 
8691 	if (IsSubnetMask4(mask) == false)
8692 	{
8693 		return false;
8694 	}
8695 
8696 	a = IPToUINT(ip);
8697 	b = IPToUINT(mask);
8698 
8699 	if ((a & b) == a)
8700 	{
8701 		return true;
8702 	}
8703 
8704 	return false;
8705 }
IsNetworkAddress32(UINT ip,UINT mask)8706 bool IsNetworkAddress32(UINT ip, UINT mask)
8707 {
8708 	IP a, b;
8709 
8710 	UINTToIP(&a, ip);
8711 	UINTToIP(&b, mask);
8712 
8713 	return IsNetworkAddress4(&a, &b);
8714 }
8715 
8716 // Convert the integer to a subnet mask
IntToSubnetMask32(UINT i)8717 UINT IntToSubnetMask32(UINT i)
8718 {
8719 	UINT ret = 0xFFFFFFFF;
8720 
8721 	switch (i)
8722 	{
8723 	case 0:		ret = 0x00000000;	break;
8724 	case 1:		ret = 0x80000000;	break;
8725 	case 2:		ret = 0xC0000000;	break;
8726 	case 3:		ret = 0xE0000000;	break;
8727 	case 4:		ret = 0xF0000000;	break;
8728 	case 5:		ret = 0xF8000000;	break;
8729 	case 6:		ret = 0xFC000000;	break;
8730 	case 7:		ret = 0xFE000000;	break;
8731 	case 8:		ret = 0xFF000000;	break;
8732 	case 9:		ret = 0xFF800000;	break;
8733 	case 10:	ret = 0xFFC00000;	break;
8734 	case 11:	ret = 0xFFE00000;	break;
8735 	case 12:	ret = 0xFFF00000;	break;
8736 	case 13:	ret = 0xFFF80000;	break;
8737 	case 14:	ret = 0xFFFC0000;	break;
8738 	case 15:	ret = 0xFFFE0000;	break;
8739 	case 16:	ret = 0xFFFF0000;	break;
8740 	case 17:	ret = 0xFFFF8000;	break;
8741 	case 18:	ret = 0xFFFFC000;	break;
8742 	case 19:	ret = 0xFFFFE000;	break;
8743 	case 20:	ret = 0xFFFFF000;	break;
8744 	case 21:	ret = 0xFFFFF800;	break;
8745 	case 22:	ret = 0xFFFFFC00;	break;
8746 	case 23:	ret = 0xFFFFFE00;	break;
8747 	case 24:	ret = 0xFFFFFF00;	break;
8748 	case 25:	ret = 0xFFFFFF80;	break;
8749 	case 26:	ret = 0xFFFFFFC0;	break;
8750 	case 27:	ret = 0xFFFFFFE0;	break;
8751 	case 28:	ret = 0xFFFFFFF0;	break;
8752 	case 29:	ret = 0xFFFFFFF8;	break;
8753 	case 30:	ret = 0xFFFFFFFC;	break;
8754 	case 31:	ret = 0xFFFFFFFE;	break;
8755 	case 32:	ret = 0xFFFFFFFF;	break;
8756 	}
8757 
8758 	if (IsLittleEndian())
8759 	{
8760 		ret = Swap32(ret);
8761 	}
8762 
8763 	return ret;
8764 }
IntToSubnetMask4(IP * ip,UINT i)8765 void IntToSubnetMask4(IP *ip, UINT i)
8766 {
8767 	UINT m;
8768 	// Validate arguments
8769 	if (ip == NULL)
8770 	{
8771 		return;
8772 	}
8773 
8774 	m = IntToSubnetMask32(i);
8775 
8776 	UINTToIP(ip, m);
8777 }
8778 
8779 // Examine whether the specified IP address is a subnet mask
IsSubnetMask(IP * ip)8780 bool IsSubnetMask(IP *ip)
8781 {
8782 	if (IsIP6(ip))
8783 	{
8784 		return IsSubnetMask6(ip);
8785 	}
8786 	else
8787 	{
8788 		return IsSubnetMask4(ip);
8789 	}
8790 }
IsSubnetMask4(IP * ip)8791 bool IsSubnetMask4(IP *ip)
8792 {
8793 	UINT i;
8794 	// Validate arguments
8795 	if (ip == NULL)
8796 	{
8797 		return false;
8798 	}
8799 
8800 	if (IsIP6(ip))
8801 	{
8802 		return false;
8803 	}
8804 
8805 	i = IPToUINT(ip);
8806 
8807 	if (IsLittleEndian())
8808 	{
8809 		i = Swap32(i);
8810 	}
8811 
8812 	switch (i)
8813 	{
8814 	case 0x00000000:
8815 	case 0x80000000:
8816 	case 0xC0000000:
8817 	case 0xE0000000:
8818 	case 0xF0000000:
8819 	case 0xF8000000:
8820 	case 0xFC000000:
8821 	case 0xFE000000:
8822 	case 0xFF000000:
8823 	case 0xFF800000:
8824 	case 0xFFC00000:
8825 	case 0xFFE00000:
8826 	case 0xFFF00000:
8827 	case 0xFFF80000:
8828 	case 0xFFFC0000:
8829 	case 0xFFFE0000:
8830 	case 0xFFFF0000:
8831 	case 0xFFFF8000:
8832 	case 0xFFFFC000:
8833 	case 0xFFFFE000:
8834 	case 0xFFFFF000:
8835 	case 0xFFFFF800:
8836 	case 0xFFFFFC00:
8837 	case 0xFFFFFE00:
8838 	case 0xFFFFFF00:
8839 	case 0xFFFFFF80:
8840 	case 0xFFFFFFC0:
8841 	case 0xFFFFFFE0:
8842 	case 0xFFFFFFF0:
8843 	case 0xFFFFFFF8:
8844 	case 0xFFFFFFFC:
8845 	case 0xFFFFFFFE:
8846 	case 0xFFFFFFFF:
8847 		return true;
8848 	}
8849 
8850 	return false;
8851 }
IsSubnetMask32(UINT ip)8852 bool IsSubnetMask32(UINT ip)
8853 {
8854 	IP p;
8855 
8856 	UINTToIP(&p, ip);
8857 
8858 	return IsSubnetMask4(&p);
8859 }
8860 
8861 // Network release mode
SetNetworkReleaseMode()8862 void SetNetworkReleaseMode()
8863 {
8864 	NetworkReleaseMode = true;
8865 }
8866 
8867 #ifdef	OS_UNIX			// Code for UNIX
8868 
8869 // Turn on and off the non-blocking mode of the socket
UnixSetSocketNonBlockingMode(int fd,bool nonblock)8870 void UnixSetSocketNonBlockingMode(int fd, bool nonblock)
8871 {
8872 	UINT flag = 0;
8873 	// Validate arguments
8874 	if (fd == INVALID_SOCKET)
8875 	{
8876 		return;
8877 	}
8878 
8879 	if (nonblock)
8880 	{
8881 		flag = 1;
8882 	}
8883 
8884 #ifdef	FIONBIO
8885 	ioctl(fd, FIONBIO, &flag);
8886 #else	// FIONBIO
8887 	{
8888 		int flag = fcntl(fd, F_GETFL, 0);
8889 		if (flag != -1)
8890 		{
8891 			if (nonblock)
8892 			{
8893 				flag |= O_NONBLOCK;
8894 			}
8895 			else
8896 			{
8897 				flag = flag & ~O_NONBLOCK;
8898 
8899 				fcntl(fd, F_SETFL, flag);
8900 			}
8901 		}
8902 	}
8903 #endif	// FIONBIO
8904 }
8905 
8906 // Do Nothing
UnixIpForwardRowToRouteEntry(ROUTE_ENTRY * entry,void * ip_forward_row)8907 void UnixIpForwardRowToRouteEntry(ROUTE_ENTRY *entry, void *ip_forward_row)
8908 {
8909 }
8910 
8911 // Do Nothing
UnixRouteEntryToIpForwardRow(void * ip_forward_row,ROUTE_ENTRY * entry)8912 void UnixRouteEntryToIpForwardRow(void *ip_forward_row, ROUTE_ENTRY *entry)
8913 {
8914 }
8915 
8916 // Do Nothing
UnixCompareRouteEntryByMetric(void * p1,void * p2)8917 int UnixCompareRouteEntryByMetric(void *p1, void *p2)
8918 {
8919 	return 1;
8920 }
8921 
8922 // Do Nothing
UnixGetRouteTable()8923 ROUTE_TABLE *UnixGetRouteTable()
8924 {
8925 	ROUTE_TABLE *ret = ZeroMalloc(sizeof(ROUTE_TABLE));
8926 	ret->NumEntry = 0;
8927 	ret->Entry = ZeroMalloc(0);
8928 
8929 	return ret;
8930 }
8931 
8932 // Do Nothing
UnixAddRouteEntry(ROUTE_ENTRY * e,bool * already_exists)8933 bool UnixAddRouteEntry(ROUTE_ENTRY *e, bool *already_exists)
8934 {
8935 	return true;
8936 }
8937 
8938 // Do Nothing
UnixDeleteRouteEntry(ROUTE_ENTRY * e)8939 void UnixDeleteRouteEntry(ROUTE_ENTRY *e)
8940 {
8941 	return;
8942 }
8943 
8944 // Do Nothing
UnixGetVLanInterfaceID(char * instance_name)8945 UINT UnixGetVLanInterfaceID(char *instance_name)
8946 {
8947 	return 1;
8948 }
8949 
8950 // Do Nothing
UnixEnumVLan(char * tag_name)8951 char **UnixEnumVLan(char *tag_name)
8952 {
8953 	char **list;
8954 
8955 	list = ZeroMalloc(sizeof(char *));
8956 
8957 	return list;
8958 }
8959 
8960 // Do Nothing
UnixRenewDhcp()8961 void UnixRenewDhcp()
8962 {
8963 }
8964 
8965 // Get the IP address of the default DNS server
UnixGetDefaultDns(IP * ip)8966 bool UnixGetDefaultDns(IP *ip)
8967 {
8968 	BUF *b;
8969 	// Validate arguments
8970 	if (ip == NULL)
8971 	{
8972 		return false;
8973 	}
8974 
8975 	Lock(unix_dns_server_addr_lock);
8976 	{
8977 		if (IsZero(&unix_dns_server, sizeof(IP)) == false)
8978 		{
8979 			Copy(ip, &unix_dns_server, sizeof(IP));
8980 			Unlock(unix_dns_server_addr_lock);
8981 			return true;
8982 		}
8983 
8984 		ip->addr[0] = 127;
8985 		ip->addr[1] = 0;
8986 		ip->addr[2] = 0;
8987 		ip->addr[3] = 1;
8988 
8989 		b = ReadDump("/etc/resolv.conf");
8990 		if (b != NULL)
8991 		{
8992 			char *s;
8993 			bool f = false;
8994 			while ((s = CfgReadNextLine(b)) != NULL)
8995 			{
8996 				TOKEN_LIST *t = ParseToken(s, "\" \t,");
8997 				if (t->NumTokens == 2)
8998 				{
8999 					if (StrCmpi(t->Token[0], "nameserver") == 0)
9000 					{
9001 						StrToIP(ip, t->Token[1]);
9002 						f = true;
9003 					}
9004 				}
9005 				FreeToken(t);
9006 
9007 				Free(s);
9008 
9009 				if (f)
9010 				{
9011 					break;
9012 				}
9013 			}
9014 			FreeBuf(b);
9015 		}
9016 		Copy(&unix_dns_server, ip, sizeof(IP));
9017 	}
9018 	Unlock(unix_dns_server_addr_lock);
9019 
9020 	return true;
9021 }
9022 
9023 
9024 // Select procedure
UnixSelect(SOCKSET * set,UINT timeout,CANCEL * c1,CANCEL * c2)9025 void UnixSelect(SOCKSET *set, UINT timeout, CANCEL *c1, CANCEL *c2)
9026 {
9027 	UINT reads[MAXIMUM_WAIT_OBJECTS];
9028 	UINT writes[MAXIMUM_WAIT_OBJECTS];
9029 	UINT num_read, num_write, i;
9030 	UINT p1, p2;
9031 	SOCK_EVENT *sock_events[MAXIMUM_WAIT_OBJECTS];
9032 	UINT num_sock_events;
9033 	SOCK *s;
9034 	UCHAR tmp[MAX_SIZE];
9035 	int ret;
9036 	bool any_of_tubes_are_readable = false;
9037 	// Initialization of array
9038 	Zero(reads, sizeof(reads));
9039 	Zero(writes, sizeof(writes));
9040 	Zero(sock_events, sizeof(sock_events));
9041 	num_read = num_write = num_sock_events = 0;
9042 
9043 	// Setting the event array
9044 	if (set != NULL)
9045 	{
9046 		for (i = 0;i < set->NumSocket;i++)
9047 		{
9048 			s = set->Sock[i];
9049 			if (s != NULL)
9050 			{
9051 				UnixInitAsyncSocket(s);
9052 				if (s->Type == SOCK_INPROC)
9053 				{
9054 					TUBE *t = s->RecvTube;
9055 					if (t != NULL)
9056 					{
9057 						reads[num_read++] = t->SockEvent->pipe_read;
9058 
9059 						sock_events[num_sock_events++] = t->SockEvent;
9060 
9061 						if (t->SockEvent->current_pipe_data != 0)
9062 						{
9063 							any_of_tubes_are_readable = true;
9064 						}
9065 					}
9066 				}
9067 				else
9068 				{
9069 					if (s->NoNeedToRead == false)
9070 					{
9071 						reads[num_read++] = s->socket;
9072 					}
9073 				}
9074 
9075 				if (s->BulkRecvTube != NULL)
9076 				{
9077 					TUBE *t = s->BulkRecvTube;
9078 					if (t != NULL)
9079 					{
9080 						reads[num_read++] = t->SockEvent->pipe_read;
9081 
9082 						sock_events[num_sock_events++] = t->SockEvent;
9083 
9084 						if (t->SockEvent->current_pipe_data != 0)
9085 						{
9086 							any_of_tubes_are_readable = true;
9087 						}
9088 					}
9089 				}
9090 
9091 				if (s->WriteBlocked)
9092 				{
9093 					writes[num_write++] = s->socket;
9094 				}
9095 			}
9096 		}
9097 	}
9098 
9099 	if (timeout == 0)
9100 	{
9101 		return;
9102 	}
9103 
9104 	p1 = p2 = -1;
9105 
9106 	if (c1 != NULL)
9107 	{
9108 		reads[num_read++] = p1 = c1->pipe_read;
9109 
9110 		if (c1->SpecialFlag)
9111 		{
9112 			if (c1->pipe_special_read2 != -1 && c1->pipe_special_read2 != 0)
9113 			{
9114 				reads[num_read++] = c1->pipe_special_read2;
9115 			}
9116 
9117 			if (c1->pipe_special_read3 != -1 && c1->pipe_special_read3 != 0)
9118 			{
9119 				reads[num_read++] = c1->pipe_special_read3;
9120 			}
9121 		}
9122 	}
9123 	if (c2 != NULL)
9124 	{
9125 		reads[num_read++] = p2 = c2->pipe_read;
9126 
9127 		if (c2->SpecialFlag)
9128 		{
9129 			if (c2->pipe_special_read2 != -1 && c2->pipe_special_read2 != 0)
9130 			{
9131 				reads[num_read++] = c2->pipe_special_read2;
9132 			}
9133 
9134 			if (c2->pipe_special_read3 != -1 && c2->pipe_special_read3 != 0)
9135 			{
9136 				reads[num_read++] = c2->pipe_special_read3;
9137 			}
9138 		}
9139 	}
9140 
9141 	// Call the select
9142 	if (any_of_tubes_are_readable == false)
9143 	{
9144 		UnixSelectInner(num_read, reads, num_write, writes, timeout);
9145 	}
9146 
9147 	// Read from the pipe
9148 	if (c1 != NULL && c1->SpecialFlag == false && p1 != -1)
9149 	{
9150 		do
9151 		{
9152 			ret = read(p1, tmp, sizeof(tmp));
9153 		}
9154 		while (ret >= 1);
9155 	}
9156 	if (c2 != NULL && c2->SpecialFlag == false && p2 != -1)
9157 	{
9158 		do
9159 		{
9160 			ret = read(p2, tmp, sizeof(tmp));
9161 		}
9162 		while (ret >= 1);
9163 	}
9164 
9165 	// Read from the pipe of sockevent
9166 	for (i = 0;i < num_sock_events;i++)
9167 	{
9168 		SOCK_EVENT *e = sock_events[i];
9169 
9170 		e->current_pipe_data = 0;
9171 
9172 		do
9173 		{
9174 			ret = read(e->pipe_read, tmp, sizeof(tmp));
9175 		}
9176 		while (ret >= 1);
9177 	}
9178 }
9179 
9180 // Cancel
UnixCancel(CANCEL * c)9181 void UnixCancel(CANCEL *c)
9182 {
9183 	// Validate arguments
9184 	if (c == NULL)
9185 	{
9186 		return;
9187 	}
9188 
9189 	UnixWritePipe(c->pipe_write);
9190 }
9191 
9192 // Release of the cancel object
UnixCleanupCancel(CANCEL * c)9193 void UnixCleanupCancel(CANCEL *c)
9194 {
9195 	// Validate arguments
9196 	if (c == NULL)
9197 	{
9198 		return;
9199 	}
9200 
9201 	if (c->SpecialFlag == false)
9202 	{
9203 		UnixDeletePipe(c->pipe_read, c->pipe_write);
9204 	}
9205 
9206 	Free(c);
9207 }
9208 
9209 // Creating a new cancel object
UnixNewCancel()9210 CANCEL *UnixNewCancel()
9211 {
9212 	CANCEL *c = ZeroMallocFast(sizeof(CANCEL));
9213 
9214 	c->ref = NewRef();
9215 	c->SpecialFlag = false;
9216 
9217 	UnixNewPipe(&c->pipe_read, &c->pipe_write);
9218 
9219 	c->pipe_special_read2 = c->pipe_special_read3 = -1;
9220 
9221 	return c;
9222 }
9223 
9224 // Add the socket to the socket event
UnixJoinSockToSockEvent(SOCK * sock,SOCK_EVENT * event)9225 void UnixJoinSockToSockEvent(SOCK *sock, SOCK_EVENT *event)
9226 {
9227 	// Validate arguments
9228 	if (sock == NULL || event == NULL || sock->AsyncMode)
9229 	{
9230 		return;
9231 	}
9232 	if (sock->ListenMode != false || (sock->Type == SOCK_TCP && sock->Connected == false))
9233 	{
9234 		return;
9235 	}
9236 
9237 	sock->AsyncMode = true;
9238 
9239 	LockList(event->SockList);
9240 	{
9241 		Add(event->SockList, sock);
9242 		AddRef(sock->ref);
9243 	}
9244 	UnlockList(event->SockList);
9245 
9246 	// Make the socket asynchronous mode
9247 	if (sock->Type != SOCK_INPROC)
9248 	{
9249 		UnixSetSocketNonBlockingMode(sock->socket, true);
9250 	}
9251 
9252 	// Increase the reference count of the SOCK_EVENT
9253 	AddRef(event->ref);
9254 	sock->SockEvent = event;
9255 
9256 	// Set the socket event
9257 	SetSockEvent(event);
9258 }
9259 
9260 // Wait for a socket event
UnixWaitSockEvent(SOCK_EVENT * event,UINT timeout)9261 bool UnixWaitSockEvent(SOCK_EVENT *event, UINT timeout)
9262 {
9263 	UINT num_read, num_write;
9264 	UINT *reads, *writes;
9265 	UINT n;
9266 	char tmp[MAX_SIZE];
9267 	int readret = 0;
9268 	bool event_pipe_is_readable = false;
9269 	// Validate arguments
9270 	if (event == NULL)
9271 	{
9272 		return false;
9273 	}
9274 
9275 	LockList(event->SockList);
9276 	{
9277 		UINT i;
9278 		reads = ZeroMallocFast(sizeof(SOCK *) * (LIST_NUM(event->SockList) + 1));
9279 
9280 		num_write = 0;
9281 		num_read = 0;
9282 
9283 		for (i = 0;i < LIST_NUM(event->SockList);i++)
9284 		{
9285 			SOCK *s = LIST_DATA(event->SockList, i);
9286 
9287 			if (s->NoNeedToRead == false)
9288 			{
9289 				reads[num_read++] = s->socket;
9290 			}
9291 
9292 			if (s->WriteBlocked)
9293 			{
9294 				num_write++;
9295 			}
9296 		}
9297 
9298 		reads[num_read++] = event->pipe_read;
9299 
9300 		if (event->current_pipe_data != 0)
9301 		{
9302 			event_pipe_is_readable = true;
9303 		}
9304 
9305 		writes = ZeroMallocFast(sizeof(SOCK *) * num_write);
9306 
9307 		n = 0;
9308 
9309 		for (i = 0;i < (num_read - 1);i++)
9310 		{
9311 			SOCK *s = LIST_DATA(event->SockList, i);
9312 			if (s->WriteBlocked)
9313 			{
9314 				writes[n++] = s->socket;
9315 			}
9316 		}
9317 	}
9318 	UnlockList(event->SockList);
9319 
9320 	if (event_pipe_is_readable == false)
9321 	{
9322 		UnixSelectInner(num_read, reads, num_write, writes, timeout);
9323 	}
9324 
9325 	event->current_pipe_data = 0;
9326 	do
9327 	{
9328 		readret = read(event->pipe_read, tmp, sizeof(tmp));
9329 	}
9330 	while (readret >= 1);
9331 
9332 	Free(reads);
9333 	Free(writes);
9334 
9335 	return true;
9336 }
9337 
9338 // Set the socket event
UnixSetSockEvent(SOCK_EVENT * event)9339 void UnixSetSockEvent(SOCK_EVENT *event)
9340 {
9341 	// Validate arguments
9342 	if (event == NULL)
9343 	{
9344 		return;
9345 	}
9346 
9347 	if (event->current_pipe_data <= 100)
9348 	{
9349 		UnixWritePipe(event->pipe_write);
9350 		event->current_pipe_data++;
9351 	}
9352 }
9353 
9354 // This is a helper function for select()
safe_fd_set(int fd,fd_set * fds,int * max_fd)9355 int safe_fd_set(int fd, fd_set* fds, int* max_fd) {
9356 	FD_SET(fd, fds);
9357 	if (fd > *max_fd) {
9358 		*max_fd = fd;
9359     }
9360 	return 0;
9361 }
9362 
9363 // Execute 'select' for the socket
UnixSelectInner(UINT num_read,UINT * reads,UINT num_write,UINT * writes,UINT timeout)9364 void UnixSelectInner(UINT num_read, UINT *reads, UINT num_write, UINT *writes, UINT timeout)
9365 {
9366 #ifdef	UNIX_MACOS
9367 	fd_set rfds; //read descriptors
9368 	fd_set wfds; //write descriptors
9369 	int max_fd = 0; //maximum descriptor id
9370 	struct timeval tv; //timeval for timeout
9371 #else	// UNIX_MACOS
9372 	struct pollfd *p;
9373 #endif	// UNIX_MACOS
9374 	UINT num;
9375 	UINT i;
9376 	UINT n;
9377 	UINT num_read_total, num_write_total;
9378 
9379 	if (num_read != 0 && reads == NULL)
9380 	{
9381 		num_read = 0;
9382 	}
9383 	if (num_write != 0 && writes == NULL)
9384 	{
9385 		num_write = 0;
9386 	}
9387 
9388 	if (timeout == 0)
9389 	{
9390 		return;
9391 	}
9392 
9393 	num_read_total = num_write_total = 0;
9394 	for (i = 0;i < num_read;i++)
9395 	{
9396 		if (reads[i] != INVALID_SOCKET)
9397 		{
9398 			num_read_total++;
9399 		}
9400 	}
9401 	for (i = 0;i < num_write;i++)
9402 	{
9403 		if (writes[i] != INVALID_SOCKET)
9404 		{
9405 			num_write_total++;
9406 		}
9407 	}
9408 
9409 	num = num_read_total + num_write_total;
9410 #ifdef	UNIX_MACOS
9411 	FD_ZERO(&rfds); //zero out descriptor set for read descriptors
9412 	FD_ZERO(&wfds); //same for write
9413 #else	// UNIX_MACOS
9414 	p = ZeroMallocFast(sizeof(struct pollfd) * num);
9415 #endif	// UNIX_MACOS
9416 
9417 	n = 0;
9418 
9419 	for (i = 0;i < num_read;i++)
9420 	{
9421 		if (reads[i] != INVALID_SOCKET)
9422 		{
9423 #ifdef	UNIX_MACOS
9424 			safe_fd_set(reads[i], &rfds, &max_fd);
9425 #else	// UNIX_MACOS
9426 			struct pollfd *pfd = &p[n++];
9427 			pfd->fd = reads[i];
9428 			pfd->events = POLLIN | POLLPRI | POLLERR | POLLHUP;
9429 #endif	// UNIX_MACOS
9430 		}
9431 	}
9432 
9433 	for (i = 0;i < num_write;i++)
9434 	{
9435 		if (writes[i] != INVALID_SOCKET)
9436 		{
9437 #ifdef	UNIX_MACOS
9438 			safe_fd_set(writes[i], &wfds, &max_fd);
9439 #else	// UNIX_MACOS
9440 			struct pollfd *pfd = &p[n++];
9441 			pfd->fd = writes[i];
9442 			pfd->events = POLLIN | POLLPRI | POLLERR | POLLHUP | POLLOUT;
9443 #endif	// UNIX_MACOS
9444 		}
9445 	}
9446 
9447 	if (num != 0)
9448 	{
9449 #ifdef	UNIX_MACOS
9450 		tv.tv_sec = timeout / 1000;
9451 		tv.tv_usec = (timeout % 1000) * 1000l;
9452 		select(max_fd + 1, &rfds, &wfds, NULL, timeout == INFINITE ? NULL : &tv);
9453 #else	// UNIX_MACOS
9454 		poll(p, num, timeout == INFINITE ? -1 : (int)timeout);
9455 #endif	// UNIX_MACOS
9456 	}
9457 	else
9458 	{
9459 		SleepThread(timeout);
9460 	}
9461 
9462 #ifndef	UNIX_MACOS
9463 	Free(p);
9464 #endif	// not UNIX_MACOS
9465 }
9466 
9467 // Clean-up of the socket event
UnixCleanupSockEvent(SOCK_EVENT * event)9468 void UnixCleanupSockEvent(SOCK_EVENT *event)
9469 {
9470 	UINT i;
9471 	// Validate arguments
9472 	if (event == NULL)
9473 	{
9474 		return;
9475 	}
9476 
9477 	for (i = 0;i < LIST_NUM(event->SockList);i++)
9478 	{
9479 		SOCK *s = LIST_DATA(event->SockList, i);
9480 
9481 		ReleaseSock(s);
9482 	}
9483 
9484 	ReleaseList(event->SockList);
9485 
9486 	UnixDeletePipe(event->pipe_read, event->pipe_write);
9487 
9488 	Free(event);
9489 }
9490 
9491 // Create a socket event
UnixNewSockEvent()9492 SOCK_EVENT *UnixNewSockEvent()
9493 {
9494 	SOCK_EVENT *e = ZeroMallocFast(sizeof(SOCK_EVENT));
9495 
9496 	e->SockList = NewList(NULL);
9497 	e->ref = NewRef();
9498 
9499 	UnixNewPipe(&e->pipe_read, &e->pipe_write);
9500 
9501 	return e;
9502 }
9503 
9504 // Close the pipe
UnixDeletePipe(int p1,int p2)9505 void UnixDeletePipe(int p1, int p2)
9506 {
9507 	if (p1 != -1)
9508 	{
9509 		close(p1);
9510 	}
9511 
9512 	if (p2 != -1)
9513 	{
9514 		close(p2);
9515 	}
9516 }
9517 
9518 // Write to the pipe
UnixWritePipe(int pipe_write)9519 void UnixWritePipe(int pipe_write)
9520 {
9521 	char c = 1;
9522 	write(pipe_write, &c, 1);
9523 }
9524 
9525 // Create a new pipe
UnixNewPipe(int * pipe_read,int * pipe_write)9526 void UnixNewPipe(int *pipe_read, int *pipe_write)
9527 {
9528 	int fd[2];
9529 	// Validate arguments
9530 	if (pipe_read == NULL || pipe_write == NULL)
9531 	{
9532 		return;
9533 	}
9534 
9535 	fd[0] = fd[1] = 0;
9536 
9537 	pipe(fd);
9538 
9539 	*pipe_read = fd[0];
9540 	*pipe_write = fd[1];
9541 
9542 	UnixSetSocketNonBlockingMode(*pipe_write, true);
9543 	UnixSetSocketNonBlockingMode(*pipe_read, true);
9544 }
9545 
9546 // Release the asynchronous socket
UnixFreeAsyncSocket(SOCK * sock)9547 void UnixFreeAsyncSocket(SOCK *sock)
9548 {
9549 	UINT p;
9550 	// Validate arguments
9551 	if (sock == NULL)
9552 	{
9553 		return;
9554 	}
9555 
9556 	Lock(sock->lock);
9557 	{
9558 		if (sock->AsyncMode == false)
9559 		{
9560 			Unlock(sock->lock);
9561 			return;
9562 		}
9563 
9564 		sock->AsyncMode = false;
9565 
9566 		// Examine whether this socket are associated to SockEvent
9567 		if (sock->SockEvent != NULL)
9568 		{
9569 			SOCK_EVENT *e = sock->SockEvent;
9570 
9571 			AddRef(e->ref);
9572 
9573 			p = e->pipe_write;
9574 			LockList(e->SockList);
9575 			{
9576 				if (Delete(e->SockList, sock))
9577 				{
9578 					ReleaseSock(sock);
9579 				}
9580 			}
9581 			UnlockList(e->SockList);
9582 
9583 			// Release the socket event
9584 			ReleaseSockEvent(sock->SockEvent);
9585 			sock->SockEvent = NULL;
9586 
9587 			SetSockEvent(e);
9588 
9589 			ReleaseSockEvent(e);
9590 		}
9591 	}
9592 	Unlock(sock->lock);
9593 }
9594 
9595 // Set the socket to asynchronous mode
UnixInitAsyncSocket(SOCK * sock)9596 void UnixInitAsyncSocket(SOCK *sock)
9597 {
9598 	// Validate arguments
9599 	if (sock == NULL)
9600 	{
9601 		return;
9602 	}
9603 	if (sock->AsyncMode)
9604 	{
9605 		// The socket has been set in asynchronous mode already
9606 		return;
9607 	}
9608 	if (sock->ListenMode != false || ((sock->Type == SOCK_TCP || sock->Type == SOCK_INPROC) && sock->Connected == false))
9609 	{
9610 		return;
9611 	}
9612 
9613 	sock->AsyncMode = true;
9614 
9615 	if (sock->Type != SOCK_INPROC)
9616 	{
9617 		UnixSetSocketNonBlockingMode(sock->socket, true);
9618 	}
9619 
9620 #if OPENSSL_VERSION_NUMBER < 0x10100000L
9621 	if (sock->ssl != NULL && sock->ssl->s3 != NULL)
9622 	{
9623 		sock->Ssl_Init_Async_SendAlert[0] = sock->ssl->s3->send_alert[0];
9624 		sock->Ssl_Init_Async_SendAlert[1] = sock->ssl->s3->send_alert[1];
9625 	}
9626 #endif
9627 }
9628 
9629 // Initializing the socket library
UnixInitSocketLibrary()9630 void UnixInitSocketLibrary()
9631 {
9632 	// Do not do anything special
9633 }
9634 
9635 // Release of the socket library
UnixFreeSocketLibrary()9636 void UnixFreeSocketLibrary()
9637 {
9638 	// Do not do anything special
9639 }
9640 
9641 #endif	// OS_UNIX
9642 
9643 #ifdef	OS_WIN32		// Code for Windows
9644 
9645 NETWORK_WIN32_FUNCTIONS *w32net;
9646 
9647 // Comparison of IP_ADAPTER_INDEX_MAP
CompareIpAdapterIndexMap(void * p1,void * p2)9648 int CompareIpAdapterIndexMap(void *p1, void *p2)
9649 {
9650 	IP_ADAPTER_INDEX_MAP *a1, *a2;
9651 	if (p1 == NULL || p2 == NULL)
9652 	{
9653 		return 0;
9654 	}
9655 	a1 = *(IP_ADAPTER_INDEX_MAP **)p1;
9656 	a2 = *(IP_ADAPTER_INDEX_MAP **)p2;
9657 	if (a1 == NULL || a2 == NULL)
9658 	{
9659 		return 0;
9660 	}
9661 
9662 	if (a1->Index > a2->Index)
9663 	{
9664 		return 1;
9665 	}
9666 	else if (a1->Index < a2->Index)
9667 	{
9668 		return -1;
9669 	}
9670 	else
9671 	{
9672 		return 0;
9673 	}
9674 }
9675 
9676 // Update the IP address of the adapter
Win32RenewAddressByGuid(char * guid)9677 bool Win32RenewAddressByGuid(char *guid)
9678 {
9679 	IP_ADAPTER_INDEX_MAP a;
9680 	// Validate arguments
9681 	if (guid == NULL)
9682 	{
9683 		return false;
9684 	}
9685 
9686 	Zero(&a, sizeof(a));
9687 	if (Win32GetAdapterFromGuid(&a, guid) == false)
9688 	{
9689 		return false;
9690 	}
9691 
9692 	return Win32RenewAddress(&a);
9693 }
Win32RenewAddress(void * a)9694 bool Win32RenewAddress(void *a)
9695 {
9696 	DWORD ret;
9697 	// Validate arguments
9698 	if (a == NULL)
9699 	{
9700 		return false;
9701 	}
9702 	if (w32net->IpRenewAddress == NULL)
9703 	{
9704 		return false;
9705 	}
9706 
9707 	ret = w32net->IpRenewAddress(a);
9708 
9709 	if (ret == NO_ERROR)
9710 	{
9711 		return true;
9712 	}
9713 	else
9714 	{
9715 		Debug("IpRenewAddress: Error: %u\n", ret);
9716 		return false;
9717 	}
9718 }
9719 
9720 // Release the IP address of the adapter
Win32ReleaseAddress(void * a)9721 bool Win32ReleaseAddress(void *a)
9722 {
9723 	DWORD ret;
9724 	// Validate arguments
9725 	if (a == NULL)
9726 	{
9727 		return false;
9728 	}
9729 	if (w32net->IpReleaseAddress == NULL)
9730 	{
9731 		return false;
9732 	}
9733 
9734 	ret = w32net->IpReleaseAddress(a);
9735 
9736 	if (ret == NO_ERROR)
9737 	{
9738 		return true;
9739 	}
9740 	else
9741 	{
9742 		Debug("IpReleaseAddress: Error: %u\n", ret);
9743 		return false;
9744 	}
9745 }
Win32ReleaseAddressByGuid(char * guid)9746 bool Win32ReleaseAddressByGuid(char *guid)
9747 {
9748 	IP_ADAPTER_INDEX_MAP a;
9749 	// Validate arguments
9750 	if (guid == NULL)
9751 	{
9752 		return false;
9753 	}
9754 
9755 	Zero(&a, sizeof(a));
9756 	if (Win32GetAdapterFromGuid(&a, guid) == false)
9757 	{
9758 		return false;
9759 	}
9760 
9761 	return Win32ReleaseAddress(&a);
9762 }
Win32ReleaseAddressByGuidExThread(THREAD * t,void * param)9763 void Win32ReleaseAddressByGuidExThread(THREAD *t, void *param)
9764 {
9765 	WIN32_RELEASEADDRESS_THREAD_PARAM *p;
9766 	// Validate arguments
9767 	if (t == NULL || param == NULL)
9768 	{
9769 		return;
9770 	}
9771 
9772 	p = (WIN32_RELEASEADDRESS_THREAD_PARAM *)param;
9773 
9774 	AddRef(p->Ref);
9775 
9776 	NoticeThreadInit(t);
9777 
9778 	AddWaitThread(t);
9779 
9780 	if (p->Renew == false)
9781 	{
9782 		p->Ok = Win32ReleaseAddressByGuid(p->Guid);
9783 	}
9784 	else
9785 	{
9786 		p->Ok = Win32RenewAddressByGuid(p->Guid);
9787 	}
9788 
9789 	ReleaseWin32ReleaseAddressByGuidThreadParam(p);
9790 
9791 	DelWaitThread(t);
9792 }
Win32RenewAddressByGuidEx(char * guid,UINT timeout)9793 bool Win32RenewAddressByGuidEx(char *guid, UINT timeout)
9794 {
9795 	return Win32ReleaseOrRenewAddressByGuidEx(guid, timeout, true);
9796 }
Win32ReleaseAddressByGuidEx(char * guid,UINT timeout)9797 bool Win32ReleaseAddressByGuidEx(char *guid, UINT timeout)
9798 {
9799 	return Win32ReleaseOrRenewAddressByGuidEx(guid, timeout, false);
9800 }
Win32ReleaseOrRenewAddressByGuidEx(char * guid,UINT timeout,bool renew)9801 bool Win32ReleaseOrRenewAddressByGuidEx(char *guid, UINT timeout, bool renew)
9802 {
9803 	THREAD *t;
9804 	WIN32_RELEASEADDRESS_THREAD_PARAM *p;
9805 	bool ret = false;
9806 	UINT64 start_tick = 0;
9807 	UINT64 end_tick = 0;
9808 	// Validate arguments
9809 	if (guid == NULL)
9810 	{
9811 		return false;
9812 	}
9813 	if (timeout == 0)
9814 	{
9815 		timeout = INFINITE;
9816 	}
9817 
9818 	p = ZeroMalloc(sizeof(WIN32_RELEASEADDRESS_THREAD_PARAM));
9819 	p->Ref = NewRef();
9820 	StrCpy(p->Guid, sizeof(p->Guid), guid);
9821 	p->Timeout = timeout;
9822 	p->Renew = renew;
9823 
9824 	t = NewThread(Win32ReleaseAddressByGuidExThread, p);
9825 	WaitThreadInit(t);
9826 	start_tick = Tick64();
9827 	end_tick = start_tick + (UINT64)timeout;
9828 
9829 	while (true)
9830 	{
9831 		UINT64 now = Tick64();
9832 		UINT64 remain;
9833 		UINT remain32;
9834 
9835 		if (now >= end_tick)
9836 		{
9837 			break;
9838 		}
9839 
9840 		remain = end_tick - now;
9841 		remain32 = MIN((UINT)remain, 100);
9842 
9843 		if (WaitThread(t, remain32))
9844 		{
9845 			break;
9846 		}
9847 	}
9848 
9849 	ReleaseThread(t);
9850 
9851 	if (p->Ok)
9852 	{
9853 		ret = true;
9854 	}
9855 
9856 	ReleaseWin32ReleaseAddressByGuidThreadParam(p);
9857 
9858 	return ret;
9859 }
ReleaseWin32ReleaseAddressByGuidThreadParam(WIN32_RELEASEADDRESS_THREAD_PARAM * p)9860 void ReleaseWin32ReleaseAddressByGuidThreadParam(WIN32_RELEASEADDRESS_THREAD_PARAM *p)
9861 {
9862 	// Validate arguments
9863 	if (p == NULL)
9864 	{
9865 		return;
9866 	}
9867 
9868 	if (Release(p->Ref) == 0)
9869 	{
9870 		Free(p);
9871 	}
9872 }
9873 
9874 // Get the adapter by the GUID
Win32GetAdapterFromGuid(void * a,char * guid)9875 bool Win32GetAdapterFromGuid(void *a, char *guid)
9876 {
9877 	bool ret = false;
9878 	IP_INTERFACE_INFO *info;
9879 	UINT size;
9880 	int i;
9881 	LIST *o;
9882 	wchar_t tmp[MAX_SIZE];
9883 
9884 	// Validate arguments
9885 	if (a == NULL || guid == NULL)
9886 	{
9887 		return false;
9888 	}
9889 	if (w32net->GetInterfaceInfo == NULL)
9890 	{
9891 		return false;
9892 	}
9893 
9894 	UniFormat(tmp, sizeof(tmp), L"\\DEVICE\\TCPIP_%S", guid);
9895 
9896 	size = sizeof(IP_INTERFACE_INFO);
9897 	info = ZeroMallocFast(size);
9898 
9899 	if (w32net->GetInterfaceInfo(info, &size) == ERROR_INSUFFICIENT_BUFFER)
9900 	{
9901 		Free(info);
9902 		info = ZeroMallocFast(size);
9903 	}
9904 
9905 	if (w32net->GetInterfaceInfo(info, &size) != NO_ERROR)
9906 	{
9907 		Free(info);
9908 		return false;
9909 	}
9910 
9911 	o = NewListFast(CompareIpAdapterIndexMap);
9912 
9913 	for (i = 0;i < info->NumAdapters;i++)
9914 	{
9915 		IP_ADAPTER_INDEX_MAP *a = &info->Adapter[i];
9916 
9917 		Add(o, a);
9918 	}
9919 
9920 	Sort(o);
9921 
9922 	for (i = 0;i < (int)(LIST_NUM(o));i++)
9923 	{
9924 		IP_ADAPTER_INDEX_MAP *e = LIST_DATA(o, i);
9925 
9926 		if (UniStrCmpi(e->Name, tmp) == 0)
9927 		{
9928 			Copy(a, e, sizeof(IP_ADAPTER_INDEX_MAP));
9929 			ret = true;
9930 			break;
9931 		}
9932 	}
9933 
9934 	ReleaseList(o);
9935 
9936 	Free(info);
9937 
9938 	return ret;
9939 }
9940 
9941 // Test
Win32NetworkTest()9942 void Win32NetworkTest()
9943 {
9944 	IP_INTERFACE_INFO *info;
9945 	UINT size;
9946 	int i;
9947 	LIST *o;
9948 
9949 	size = sizeof(IP_INTERFACE_INFO);
9950 	info = ZeroMallocFast(size);
9951 
9952 	if (w32net->GetInterfaceInfo(info, &size) == ERROR_INSUFFICIENT_BUFFER)
9953 	{
9954 		Free(info);
9955 		info = ZeroMallocFast(size);
9956 	}
9957 
9958 	if (w32net->GetInterfaceInfo(info, &size) != NO_ERROR)
9959 	{
9960 		Free(info);
9961 		return;
9962 	}
9963 
9964 	o = NewListFast(CompareIpAdapterIndexMap);
9965 
9966 	for (i = 0;i < info->NumAdapters;i++)
9967 	{
9968 		IP_ADAPTER_INDEX_MAP *a = &info->Adapter[i];
9969 
9970 		Add(o, a);
9971 	}
9972 
9973 	Sort(o);
9974 
9975 	for (i = 0;i < (int)(LIST_NUM(o));i++)
9976 	{
9977 		IP_ADAPTER_INDEX_MAP *a = LIST_DATA(o, i);
9978 
9979 		DoNothing();
9980 	}
9981 
9982 	ReleaseList(o);
9983 
9984 	Free(info);
9985 }
9986 
9987 // Clear the DNS cache on Win32
Win32FlushDnsCache()9988 void Win32FlushDnsCache()
9989 {
9990 	Run("ipconfig.exe", "/flushdns", true, false);
9991 }
9992 
9993 // Update the DHCP address of the specified LAN card
Win32RenewDhcp9x(UINT if_id)9994 void Win32RenewDhcp9x(UINT if_id)
9995 {
9996 	IP_INTERFACE_INFO *info;
9997 	UINT size;
9998 	int i;
9999 	LIST *o;
10000 	// Validate arguments
10001 	if (if_id == 0)
10002 	{
10003 		return;
10004 	}
10005 
10006 	size = sizeof(IP_INTERFACE_INFO);
10007 	info = ZeroMallocFast(size);
10008 
10009 	if (w32net->GetInterfaceInfo(info, &size) == ERROR_INSUFFICIENT_BUFFER)
10010 	{
10011 		Free(info);
10012 		info = ZeroMallocFast(size);
10013 	}
10014 
10015 	if (w32net->GetInterfaceInfo(info, &size) != NO_ERROR)
10016 	{
10017 		Free(info);
10018 		return;
10019 	}
10020 
10021 	o = NewListFast(CompareIpAdapterIndexMap);
10022 
10023 	for (i = 0;i < info->NumAdapters;i++)
10024 	{
10025 		IP_ADAPTER_INDEX_MAP *a = &info->Adapter[i];
10026 
10027 		Add(o, a);
10028 	}
10029 
10030 	Sort(o);
10031 
10032 	for (i = 0;i < (int)(LIST_NUM(o));i++)
10033 	{
10034 		IP_ADAPTER_INDEX_MAP *a = LIST_DATA(o, i);
10035 
10036 		if (a->Index == if_id)
10037 		{
10038 			char arg[MAX_PATH];
10039 			Format(arg, sizeof(arg), "/renew %u", i);
10040 			Run("ipconfig.exe", arg, true, false);
10041 		}
10042 	}
10043 
10044 	ReleaseList(o);
10045 
10046 	Free(info);
10047 }
10048 
10049 // Release the DHCP address of the specified LAN card
Win32ReleaseDhcp9x(UINT if_id,bool wait)10050 void Win32ReleaseDhcp9x(UINT if_id, bool wait)
10051 {
10052 	IP_INTERFACE_INFO *info;
10053 	UINT size;
10054 	int i;
10055 	LIST *o;
10056 	// Validate arguments
10057 	if (if_id == 0)
10058 	{
10059 		return;
10060 	}
10061 
10062 	size = sizeof(IP_INTERFACE_INFO);
10063 	info = ZeroMallocFast(size);
10064 
10065 	if (w32net->GetInterfaceInfo(info, &size) == ERROR_INSUFFICIENT_BUFFER)
10066 	{
10067 		Free(info);
10068 		info = ZeroMallocFast(size);
10069 	}
10070 
10071 	if (w32net->GetInterfaceInfo(info, &size) != NO_ERROR)
10072 	{
10073 		Free(info);
10074 		return;
10075 	}
10076 
10077 	o = NewListFast(CompareIpAdapterIndexMap);
10078 
10079 	for (i = 0;i < info->NumAdapters;i++)
10080 	{
10081 		IP_ADAPTER_INDEX_MAP *a = &info->Adapter[i];
10082 
10083 		Add(o, a);
10084 	}
10085 
10086 	Sort(o);
10087 
10088 	for (i = 0;i < (int)(LIST_NUM(o));i++)
10089 	{
10090 		IP_ADAPTER_INDEX_MAP *a = LIST_DATA(o, i);
10091 
10092 		if (a->Index == if_id)
10093 		{
10094 			char arg[MAX_PATH];
10095 			Format(arg, sizeof(arg), "/release %u", i);
10096 			Run("ipconfig.exe", arg, true, wait);
10097 		}
10098 	}
10099 
10100 	ReleaseList(o);
10101 
10102 	Free(info);
10103 }
10104 
10105 // Re-obtain an IP address from a DHCP server
Win32RenewDhcp()10106 void Win32RenewDhcp()
10107 {
10108 	if (OS_IS_WINDOWS_NT(GetOsInfo()->OsType))
10109 	{
10110 		Run("ipconfig.exe", "/renew", true, false);
10111 		if (MsIsVista())
10112 		{
10113 			Run("ipconfig.exe", "/renew6", true, false);
10114 		}
10115 		else
10116 		{
10117 			Run("netsh.exe", "int ipv6 renew", true, false);
10118 		}
10119 	}
10120 	else
10121 	{
10122 		Run("ipconfig.exe", "/renew_all", true, false);
10123 	}
10124 }
10125 
10126 // Enumerate a list of virtual LAN cards that contains the specified string
Win32EnumVLan(char * tag_name)10127 char **Win32EnumVLan(char *tag_name)
10128 {
10129 	MIB_IFTABLE *p;
10130 	UINT ret;
10131 	UINT size_needed;
10132 	UINT num_retry = 0;
10133 	UINT i;
10134 	LIST *o;
10135 	char **ss;
10136 	// Validate arguments
10137 	if (tag_name == 0)
10138 	{
10139 		return NULL;
10140 	}
10141 
10142 RETRY:
10143 	p = ZeroMallocFast(sizeof(MIB_IFTABLE));
10144 	size_needed = 0;
10145 
10146 	// Examine the needed size
10147 	ret = w32net->GetIfTable(p, &size_needed, 0);
10148 	if (ret == ERROR_INSUFFICIENT_BUFFER)
10149 	{
10150 		// Re-allocate the memory block of the needed size
10151 		Free(p);
10152 		p = ZeroMallocFast(size_needed);
10153 	}
10154 	else if (ret != NO_ERROR)
10155 	{
10156 		// Acquisition failure
10157 FAILED:
10158 		Free(p);
10159 		return NULL;
10160 	}
10161 
10162 	// Actually get
10163 	ret = w32net->GetIfTable(p, &size_needed, FALSE);
10164 	if (ret != NO_ERROR)
10165 	{
10166 		// Acquisition failure
10167 		if ((++num_retry) >= 5)
10168 		{
10169 			goto FAILED;
10170 		}
10171 		Free(p);
10172 		goto RETRY;
10173 	}
10174 
10175 	// Search
10176 	ret = 0;
10177 	o = NewListFast(CompareStr);
10178 	for (i = 0;i < p->dwNumEntries;i++)
10179 	{
10180 		MIB_IFROW *r = &p->table[i];
10181 		if (SearchStrEx(r->bDescr, tag_name, 0, false) != INFINITE)
10182 		{
10183 			char *s = CopyStr(r->bDescr);
10184 			Add(o, s);
10185 		}
10186 	}
10187 
10188 	Free(p);
10189 
10190 	// Sort
10191 	Sort(o);
10192 
10193 	// Convert to string
10194 	ss = ZeroMallocFast(sizeof(char *) * (LIST_NUM(o) + 1));
10195 	for (i = 0;i < LIST_NUM(o);i++)
10196 	{
10197 		ss[i] = LIST_DATA(o, i);
10198 	}
10199 	ss[LIST_NUM(o)] = NULL;
10200 
10201 	ReleaseList(o);
10202 
10203 	return ss;
10204 }
10205 
10206 // Get the ID of the virtual LAN card from the instance name of the virtual LAN card
Win32GetVLanInterfaceID(char * instance_name)10207 UINT Win32GetVLanInterfaceID(char *instance_name)
10208 {
10209 	MIB_IFTABLE *p;
10210 	UINT ret;
10211 	UINT size_needed;
10212 	UINT num_retry = 0;
10213 	UINT i;
10214 	char ps_miniport_str[MAX_SIZE];
10215 	char ps_miniport_str2[MAX_SIZE];
10216 	UINT min_len = 0x7FFFFFFF;
10217 	// Validate arguments
10218 	if (instance_name == 0)
10219 	{
10220 		return 0;
10221 	}
10222 
10223 RETRY:
10224 	p = ZeroMallocFast(sizeof(MIB_IFTABLE));
10225 	size_needed = 0;
10226 
10227 	// Examine the needed size
10228 	ret = w32net->GetIfTable(p, &size_needed, 0);
10229 	if (ret == ERROR_INSUFFICIENT_BUFFER)
10230 	{
10231 		// Re-allocate the memory block of the needed size
10232 		Free(p);
10233 		p = ZeroMallocFast(size_needed);
10234 	}
10235 	else if (ret != NO_ERROR)
10236 	{
10237 		// Acquisition failure
10238 FAILED:
10239 		Free(p);
10240 		Debug("******** GetIfTable Failed 1. Err = %u\n", ret);
10241 		return 0;
10242 	}
10243 
10244 	// Actually get
10245 	ret = w32net->GetIfTable(p, &size_needed, FALSE);
10246 	if (ret != NO_ERROR)
10247 	{
10248 		// Acquisition failure
10249 		if ((++num_retry) >= 5)
10250 		{
10251 			goto FAILED;
10252 		}
10253 		Free(p);
10254 		Debug("******** GetIfTable Failed 2. Err = %u\n", ret);
10255 		goto RETRY;
10256 	}
10257 
10258 	// "%s - Packet scheduler miniport"
10259 	Format(ps_miniport_str, sizeof(ps_miniport_str), "%s - ", instance_name);
10260 	Format(ps_miniport_str2, sizeof(ps_miniport_str2), "%s (Microsoft", instance_name);
10261 
10262 	// Search
10263 	ret = 0;
10264 	for (i = 0;i < p->dwNumEntries;i++)
10265 	{
10266 		MIB_IFROW *r = &p->table[i];
10267 		if (instance_name[0] != '@')
10268 		{
10269 			if (StrCmpi(r->bDescr, instance_name) == 0 || StartWith(r->bDescr, ps_miniport_str) || StartWith(r->bDescr, ps_miniport_str2))
10270 			{
10271 				UINT len = StrLen(r->bDescr);
10272 
10273 				if (len < min_len)
10274 				{
10275 					ret = r->dwIndex;
10276 
10277 					min_len = len;
10278 				}
10279 			}
10280 		}
10281 		else
10282 		{
10283 			if (SearchStrEx(r->bDescr, &instance_name[1], 0, false) != INFINITE)
10284 			{
10285 				ret = r->dwIndex;
10286 			}
10287 		}
10288 
10289 		//Debug("if[%u] (dwIndex=%u): %u, %s\n", i, r->dwIndex, r->dwType, r->bDescr);
10290 	}
10291 
10292 	Free(p);
10293 
10294 	return ret;
10295 }
10296 
10297 // Get the DNS suffix in another way
Win32GetDnsSuffix(char * domain,UINT size)10298 bool Win32GetDnsSuffix(char *domain, UINT size)
10299 {
10300 	IP_ADAPTER_ADDRESSES_XP *info;
10301 	IP_ADAPTER_ADDRESSES_XP *cur;
10302 	UINT info_size;
10303 	bool ret = false;
10304 	// Validate arguments
10305 	ClearStr(domain, size);
10306 	if (domain == NULL)
10307 	{
10308 		return false;
10309 	}
10310 	if (w32net->GetAdaptersAddresses == NULL)
10311 	{
10312 		return false;
10313 	}
10314 
10315 	info_size = 0;
10316 	info = ZeroMalloc(sizeof(IP_ADAPTER_ADDRESSES_XP));
10317 	if (w32net->GetAdaptersAddresses(AF_INET, 0, NULL, info, &info_size) == ERROR_BUFFER_OVERFLOW)
10318 	{
10319 		Free(info);
10320 		info = ZeroMalloc(info_size);
10321 	}
10322 	if (w32net->GetAdaptersAddresses(AF_INET, 0, NULL, info, &info_size) != NO_ERROR)
10323 	{
10324 		Free(info);
10325 		return false;
10326 	}
10327 
10328 	cur = info;
10329 
10330 	while (cur != NULL)
10331 	{
10332 		if (UniIsEmptyStr(cur->DnsSuffix) == false)
10333 		{
10334 			UniToStr(domain, size, cur->DnsSuffix);
10335 			ret = true;
10336 			break;
10337 		}
10338 
10339 		cur = cur->Next;
10340 	}
10341 
10342 	Free(info);
10343 
10344 	return ret;
10345 }
10346 
10347 // Get the DNS server address of the default
Win32GetDefaultDns(IP * ip,char * domain,UINT size)10348 bool Win32GetDefaultDns(IP *ip, char *domain, UINT size)
10349 {
10350 	FIXED_INFO *info;
10351 	UINT info_size;
10352 	char *dns_name;
10353 	// Validate arguments
10354 	ClearStr(domain, size);
10355 	if (ip == NULL)
10356 	{
10357 		return false;
10358 	}
10359 	Zero(ip, sizeof(IP));
10360 	if (w32net->GetNetworkParams == NULL)
10361 	{
10362 		return false;
10363 	}
10364 	info_size = 0;
10365 	info = ZeroMallocFast(sizeof(FIXED_INFO));
10366 	if (w32net->GetNetworkParams(info, &info_size) == ERROR_BUFFER_OVERFLOW)
10367 	{
10368 		Free(info);
10369 		info = ZeroMallocFast(info_size);
10370 	}
10371 	if (w32net->GetNetworkParams(info, &info_size) != NO_ERROR)
10372 	{
10373 		Free(info);
10374 		return false;
10375 	}
10376 
10377 	if (info->DnsServerList.IpAddress.String == NULL)
10378 	{
10379 		Free(info);
10380 		return false;
10381 	}
10382 
10383 	dns_name = info->DnsServerList.IpAddress.String;
10384 	StrToIP(ip, dns_name);
10385 
10386 	if (domain != NULL)
10387 	{
10388 		StrCpy(domain, size, info->DomainName);
10389 		Trim(domain);
10390 	}
10391 
10392 	Free(info);
10393 
10394 	return true;
10395 }
10396 
10397 // IP conversion function for Win32
Win32UINTToIP(IP * ip,UINT i)10398 void Win32UINTToIP(IP *ip, UINT i)
10399 {
10400 	UINTToIP(ip, i);
10401 }
10402 
10403 // IP conversion function for Win32
Win32IPToUINT(IP * ip)10404 UINT Win32IPToUINT(IP *ip)
10405 {
10406 	return IPToUINT(ip);
10407 }
10408 
10409 // Remove a routing entry from the routing table
Win32DeleteRouteEntry(ROUTE_ENTRY * e)10410 void Win32DeleteRouteEntry(ROUTE_ENTRY *e)
10411 {
10412 	MIB_IPFORWARDROW *p;
10413 	// Validate arguments
10414 	if (e == NULL)
10415 	{
10416 		return;
10417 	}
10418 
10419 	p = ZeroMallocFast(sizeof(MIB_IPFORWARDROW));
10420 	Win32RouteEntryToIpForwardRow(p, e);
10421 
10422 	// Delete
10423 	w32net->DeleteIpForwardEntry(p);
10424 
10425 	Free(p);
10426 }
10427 
10428 // Add a routing entry to the routing table
Win32AddRouteEntry(ROUTE_ENTRY * e,bool * already_exists)10429 bool Win32AddRouteEntry(ROUTE_ENTRY *e, bool *already_exists)
10430 {
10431 	bool ret = false;
10432 	bool dummy = false;
10433 	MIB_IPFORWARDROW *p;
10434 	UINT err = 0;
10435 	// Validate arguments
10436 	if (e == NULL)
10437 	{
10438 		return false;
10439 	}
10440 	if (already_exists == NULL)
10441 	{
10442 		already_exists = &dummy;
10443 	}
10444 
10445 	*already_exists = false;
10446 
10447 	p = ZeroMallocFast(sizeof(MIB_IPFORWARDROW));
10448 	Win32RouteEntryToIpForwardRow(p, e);
10449 
10450 	// Adding
10451 	err = w32net->CreateIpForwardEntry(p);
10452 	if (err != 0)
10453 	{
10454 		if (err == ERROR_OBJECT_ALREADY_EXISTS)
10455 		{
10456 			Debug("CreateIpForwardEntry: Already Exists\n");
10457 			*already_exists = true;
10458 			ret = true;
10459 		}
10460 		else
10461 		{
10462 			Debug("CreateIpForwardEntry Error: %u\n", err);
10463 			ret = false;
10464 		}
10465 	}
10466 	else
10467 	{
10468 		ret = true;
10469 	}
10470 
10471 	Free(p);
10472 
10473 	return ret;
10474 }
10475 
10476 // Get the routing table
Win32GetRouteTable()10477 ROUTE_TABLE *Win32GetRouteTable()
10478 {
10479 	ROUTE_TABLE *t = ZeroMallocFast(sizeof(ROUTE_TABLE));
10480 	MIB_IPFORWARDTABLE *p;
10481 	UINT ret;
10482 	UINT size_needed;
10483 	UINT num_retry = 0;
10484 	LIST *o;
10485 	UINT i;
10486 	ROUTE_ENTRY *e;
10487 
10488 RETRY:
10489 	p = ZeroMallocFast(sizeof(MIB_IFTABLE));
10490 	size_needed = 0;
10491 
10492 	// Examine the needed size
10493 	ret = w32net->GetIpForwardTable(p, &size_needed, 0);
10494 	if (ret == ERROR_INSUFFICIENT_BUFFER)
10495 	{
10496 		// Re-allocate the memory block of the needed size
10497 		Free(p);
10498 		p = ZeroMallocFast(size_needed);
10499 	}
10500 	else if (ret != NO_ERROR)
10501 	{
10502 		// Acquisition failure
10503 FAILED:
10504 		Free(p);
10505 		t->Entry = MallocFast(0);
10506 		return t;
10507 	}
10508 
10509 	// Actually get
10510 	ret = w32net->GetIpForwardTable(p, &size_needed, FALSE);
10511 	if (ret != NO_ERROR)
10512 	{
10513 		// Acquisition failure
10514 		if ((++num_retry) >= 5)
10515 		{
10516 			goto FAILED;
10517 		}
10518 		Free(p);
10519 		goto RETRY;
10520 	}
10521 
10522 	// Add to the list along
10523 	o = NewListFast(Win32CompareRouteEntryByMetric);
10524 	for (i = 0;i < p->dwNumEntries;i++)
10525 	{
10526 		e = ZeroMallocFast(sizeof(ROUTE_ENTRY));
10527 		Win32IpForwardRowToRouteEntry(e, &p->table[i]);
10528 		Add(o, e);
10529 	}
10530 	Free(p);
10531 
10532 	// Sort by metric
10533 	Sort(o);
10534 
10535 	// Combine the results
10536 	t->NumEntry = LIST_NUM(o);
10537 	t->Entry = ToArrayEx(o, true);
10538 	ReleaseList(o);
10539 
10540 	return t;
10541 }
10542 
10543 // Sort the routing entries by metric
Win32CompareRouteEntryByMetric(void * p1,void * p2)10544 int Win32CompareRouteEntryByMetric(void *p1, void *p2)
10545 {
10546 	ROUTE_ENTRY *e1, *e2;
10547 	// Validate arguments
10548 	if (p1 == NULL || p2 == NULL)
10549 	{
10550 		return 0;
10551 	}
10552 
10553 	e1 = *(ROUTE_ENTRY **)p1;
10554 	e2 = *(ROUTE_ENTRY **)p2;
10555 	if (e1 == NULL || e2 == NULL)
10556 	{
10557 		return 0;
10558 	}
10559 
10560 	if (e1->Metric > e2->Metric)
10561 	{
10562 		return 1;
10563 	}
10564 	else if (e1->Metric == e2->Metric)
10565 	{
10566 		return 0;
10567 	}
10568 	else
10569 	{
10570 		return -1;
10571 	}
10572 }
10573 
10574 // Convert the ROUTE_ENTRY to a MIB_IPFORWARDROW
Win32RouteEntryToIpForwardRow(void * ip_forward_row,ROUTE_ENTRY * entry)10575 void Win32RouteEntryToIpForwardRow(void *ip_forward_row, ROUTE_ENTRY *entry)
10576 {
10577 	MIB_IPFORWARDROW *r;
10578 	// Validate arguments
10579 	if (entry == NULL || ip_forward_row == NULL)
10580 	{
10581 		return;
10582 	}
10583 
10584 	r = (MIB_IPFORWARDROW *)ip_forward_row;
10585 	Zero(r, sizeof(MIB_IPFORWARDROW));
10586 
10587 	// IP address
10588 	r->dwForwardDest = Win32IPToUINT(&entry->DestIP);
10589 	// Subnet mask
10590 	r->dwForwardMask = Win32IPToUINT(&entry->DestMask);
10591 	// Gateway IP address
10592 	r->dwForwardNextHop = Win32IPToUINT(&entry->GatewayIP);
10593 	// Local routing flag
10594 	if (entry->LocalRouting)
10595 	{
10596 		// Local
10597 		r->dwForwardType = 3;
10598 	}
10599 	else
10600 	{
10601 		// Remote router
10602 		r->dwForwardType = 4;
10603 	}
10604 	// Protocol
10605 	r->dwForwardProto = r->dwForwardType - 1;	// Subtract by 1 in most cases
10606 	if (entry->PPPConnection)
10607 	{
10608 		// Isn't this a PPP? Danger!
10609 		r->dwForwardProto++;
10610 	}
10611 	// Metric
10612 	r->dwForwardMetric1 = entry->Metric;
10613 
10614 	if (MsIsVista() == false)
10615 	{
10616 		r->dwForwardMetric2 = r->dwForwardMetric3 = r->dwForwardMetric4 = r->dwForwardMetric5 = INFINITE;
10617 	}
10618 	else
10619 	{
10620 		r->dwForwardMetric2 = r->dwForwardMetric3 = r->dwForwardMetric4 = r->dwForwardMetric5 = 0;
10621 		r->dwForwardAge = 163240;
10622 	}
10623 
10624 	// Interface ID
10625 	r->dwForwardIfIndex = entry->InterfaceID;
10626 
10627 	Debug("Win32RouteEntryToIpForwardRow()\n");
10628 	Debug(" r->dwForwardDest=%X\n", r->dwForwardDest);
10629 	Debug(" r->dwForwardMask=%X\n", r->dwForwardMask);
10630 	Debug(" r->dwForwardNextHop=%X\n", r->dwForwardNextHop);
10631 	Debug(" r->dwForwardType=%u\n", r->dwForwardType);
10632 	Debug(" r->dwForwardProto=%u\n", r->dwForwardProto);
10633 	Debug(" r->dwForwardMetric1=%u\n", r->dwForwardMetric1);
10634 	Debug(" r->dwForwardMetric2=%u\n", r->dwForwardMetric2);
10635 	Debug(" r->dwForwardIfIndex=%u\n", r->dwForwardIfIndex);
10636 }
10637 
10638 // Convert the MIB_IPFORWARDROW to a ROUTE_ENTRY
Win32IpForwardRowToRouteEntry(ROUTE_ENTRY * entry,void * ip_forward_row)10639 void Win32IpForwardRowToRouteEntry(ROUTE_ENTRY *entry, void *ip_forward_row)
10640 {
10641 	MIB_IPFORWARDROW *r;
10642 	// Validate arguments
10643 	if (entry == NULL || ip_forward_row == NULL)
10644 	{
10645 		return;
10646 	}
10647 
10648 	r = (MIB_IPFORWARDROW *)ip_forward_row;
10649 
10650 	Zero(entry, sizeof(ROUTE_ENTRY));
10651 	// IP address
10652 	Win32UINTToIP(&entry->DestIP, r->dwForwardDest);
10653 	// Subnet mask
10654 	Win32UINTToIP(&entry->DestMask, r->dwForwardMask);
10655 	// Gateway IP address
10656 	Win32UINTToIP(&entry->GatewayIP, r->dwForwardNextHop);
10657 	// Local routing flag
10658 	if (r->dwForwardType == 3)
10659 	{
10660 		entry->LocalRouting = true;
10661 	}
10662 	else
10663 	{
10664 		entry->LocalRouting = false;
10665 	}
10666 	if (entry->LocalRouting && r->dwForwardProto == 3)
10667 	{
10668 		// PPP. Danger!
10669 		entry->PPPConnection = true;
10670 	}
10671 	// Metric
10672 	entry->Metric = r->dwForwardMetric1;
10673 	// Interface ID
10674 	entry->InterfaceID = r->dwForwardIfIndex;
10675 }
10676 
10677 // Initializing the socket library
Win32InitSocketLibrary()10678 void Win32InitSocketLibrary()
10679 {
10680 	WSADATA data;
10681 	Zero(&data, sizeof(data));
10682 	WSAStartup(MAKEWORD(2, 2), &data);
10683 
10684 	// Load the DLL functions
10685 	w32net = ZeroMalloc(sizeof(NETWORK_WIN32_FUNCTIONS));
10686 	w32net->hIpHlpApi32 = LoadLibrary("iphlpapi.dll");
10687 	w32net->hIcmp = LoadLibrary("icmp.dll");
10688 
10689 	if (w32net->hIpHlpApi32 != NULL)
10690 	{
10691 		w32net->CreateIpForwardEntry =
10692 			(DWORD (__stdcall *)(PMIB_IPFORWARDROW))
10693 			GetProcAddress(w32net->hIpHlpApi32, "CreateIpForwardEntry");
10694 
10695 		w32net->DeleteIpForwardEntry =
10696 			(DWORD (__stdcall *)(PMIB_IPFORWARDROW))
10697 			GetProcAddress(w32net->hIpHlpApi32, "DeleteIpForwardEntry");
10698 
10699 		w32net->GetIfTable =
10700 			(DWORD (__stdcall *)(PMIB_IFTABLE, PULONG, BOOL))
10701 			GetProcAddress(w32net->hIpHlpApi32, "GetIfTable");
10702 
10703 		w32net->GetIfTable2 =
10704 			(DWORD (__stdcall *)(void **))
10705 			GetProcAddress(w32net->hIpHlpApi32, "GetIfTable2");
10706 
10707 		w32net->FreeMibTable =
10708 			(void (__stdcall *)(PVOID))
10709 			GetProcAddress(w32net->hIpHlpApi32, "FreeMibTable");
10710 
10711 		w32net->GetIpForwardTable =
10712 			(DWORD (__stdcall *)(PMIB_IPFORWARDTABLE, PULONG, BOOL))
10713 			GetProcAddress(w32net->hIpHlpApi32, "GetIpForwardTable");
10714 
10715 		w32net->GetNetworkParams =
10716 			(DWORD (__stdcall *)(PFIXED_INFO,PULONG))
10717 			GetProcAddress(w32net->hIpHlpApi32, "GetNetworkParams");
10718 
10719 		w32net->GetAdaptersAddresses =
10720 			(ULONG (__stdcall *)(ULONG,ULONG,PVOID,PIP_ADAPTER_ADDRESSES,PULONG))
10721 			GetProcAddress(w32net->hIpHlpApi32, "GetAdaptersAddresses");
10722 
10723 		w32net->IpRenewAddress =
10724 			(DWORD (__stdcall *)(PIP_ADAPTER_INDEX_MAP))
10725 			GetProcAddress(w32net->hIpHlpApi32, "IpRenewAddress");
10726 
10727 		w32net->IpReleaseAddress =
10728 			(DWORD (__stdcall *)(PIP_ADAPTER_INDEX_MAP))
10729 			GetProcAddress(w32net->hIpHlpApi32, "IpReleaseAddress");
10730 
10731 		w32net->GetInterfaceInfo =
10732 			(DWORD (__stdcall *)(PIP_INTERFACE_INFO, PULONG))
10733 			GetProcAddress(w32net->hIpHlpApi32, "GetInterfaceInfo");
10734 
10735 		w32net->GetAdaptersInfo =
10736 			(DWORD (__stdcall *)(PIP_ADAPTER_INFO, PULONG))
10737 			GetProcAddress(w32net->hIpHlpApi32, "GetAdaptersInfo");
10738 
10739 		w32net->GetExtendedTcpTable =
10740 			(DWORD (__stdcall *)(PVOID,PDWORD,BOOL,ULONG,_TCP_TABLE_CLASS,ULONG))
10741 			GetProcAddress(w32net->hIpHlpApi32, "GetExtendedTcpTable");
10742 
10743 		w32net->AllocateAndGetTcpExTableFromStack =
10744 			(DWORD (__stdcall *)(PVOID *,BOOL,HANDLE,DWORD,DWORD))
10745 			GetProcAddress(w32net->hIpHlpApi32, "AllocateAndGetTcpExTableFromStack");
10746 
10747 		w32net->GetTcpTable =
10748 			(DWORD (__stdcall *)(PMIB_TCPTABLE,PDWORD,BOOL))
10749 			GetProcAddress(w32net->hIpHlpApi32, "GetTcpTable");
10750 
10751 		w32net->NotifyRouteChange =
10752 			(DWORD (__stdcall *)(PHANDLE,LPOVERLAPPED))
10753 			GetProcAddress(w32net->hIpHlpApi32, "NotifyRouteChange");
10754 
10755 		w32net->CancelIPChangeNotify =
10756 			(BOOL (__stdcall *)(LPOVERLAPPED))
10757 			GetProcAddress(w32net->hIpHlpApi32, "CancelIPChangeNotify");
10758 
10759 		w32net->NhpAllocateAndGetInterfaceInfoFromStack =
10760 			(DWORD (__stdcall *)(IP_INTERFACE_NAME_INFO **,PDWORD,BOOL,HANDLE,DWORD))
10761 			GetProcAddress(w32net->hIpHlpApi32, "NhpAllocateAndGetInterfaceInfoFromStack");
10762 
10763 		w32net->IcmpCreateFile =
10764 			(HANDLE (__stdcall *)())
10765 			GetProcAddress(w32net->hIpHlpApi32, "IcmpCreateFile");
10766 
10767 		w32net->IcmpCloseHandle =
10768 			(BOOL (__stdcall *)(HANDLE))
10769 			GetProcAddress(w32net->hIpHlpApi32, "IcmpCloseHandle");
10770 
10771 		w32net->IcmpSendEcho =
10772 			(DWORD (__stdcall *)(HANDLE,IPAddr,LPVOID,WORD,PIP_OPTION_INFORMATION,LPVOID,DWORD,DWORD))
10773 			GetProcAddress(w32net->hIpHlpApi32, "IcmpSendEcho");
10774 	}
10775 
10776 	if (w32net->hIcmp != NULL)
10777 	{
10778 		if (w32net->IcmpCreateFile == NULL || w32net->IcmpCloseHandle == NULL || w32net->IcmpSendEcho == NULL)
10779 		{
10780 			w32net->IcmpCreateFile =
10781 				(HANDLE (__stdcall *)())
10782 				GetProcAddress(w32net->hIcmp, "IcmpCreateFile");
10783 
10784 			w32net->IcmpCloseHandle =
10785 				(BOOL (__stdcall *)(HANDLE))
10786 				GetProcAddress(w32net->hIcmp, "IcmpCloseHandle");
10787 
10788 			w32net->IcmpSendEcho =
10789 				(DWORD (__stdcall *)(HANDLE,IPAddr,LPVOID,WORD,PIP_OPTION_INFORMATION,LPVOID,DWORD,DWORD))
10790 				GetProcAddress(w32net->hIcmp, "IcmpSendEcho");
10791 		}
10792 	}
10793 
10794 	if (w32net->IcmpCreateFile == NULL || w32net->IcmpCloseHandle == NULL || w32net->IcmpSendEcho == NULL)
10795 	{
10796 		w32net->IcmpCreateFile = NULL;
10797 		w32net->IcmpCloseHandle = NULL;
10798 		w32net->IcmpSendEcho = NULL;
10799 	}
10800 }
10801 
10802 // Release of the socket library
Win32FreeSocketLibrary()10803 void Win32FreeSocketLibrary()
10804 {
10805 	if (w32net != NULL)
10806 	{
10807 		if (w32net->hIpHlpApi32 != NULL)
10808 		{
10809 			FreeLibrary(w32net->hIpHlpApi32);
10810 		}
10811 
10812 		if (w32net->hIcmp != NULL)
10813 		{
10814 			FreeLibrary(w32net->hIcmp);
10815 		}
10816 
10817 		Free(w32net);
10818 		w32net = NULL;
10819 	}
10820 
10821 	WSACleanup();
10822 }
10823 
10824 // Cancel
Win32Cancel(CANCEL * c)10825 void Win32Cancel(CANCEL *c)
10826 {
10827 	// Validate arguments
10828 	if (c == NULL)
10829 	{
10830 		return;
10831 	}
10832 
10833 	SetEvent((HANDLE)c->hEvent);
10834 }
10835 
10836 // Cleanup of the cancel object
Win32CleanupCancel(CANCEL * c)10837 void Win32CleanupCancel(CANCEL *c)
10838 {
10839 	// Validate arguments
10840 	if (c == NULL)
10841 	{
10842 		return;
10843 	}
10844 
10845 	if (c->SpecialFlag == false)
10846 	{
10847 		CloseHandle(c->hEvent);
10848 	}
10849 
10850 	Free(c);
10851 }
10852 
10853 // New cancel object
Win32NewCancel()10854 CANCEL *Win32NewCancel()
10855 {
10856 	CANCEL *c = ZeroMallocFast(sizeof(CANCEL));
10857 	c->ref = NewRef();
10858 	c->SpecialFlag = false;
10859 	c->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
10860 
10861 	return c;
10862 }
10863 
10864 // Waiting for a socket event
Win32WaitSockEvent(SOCK_EVENT * event,UINT timeout)10865 bool Win32WaitSockEvent(SOCK_EVENT *event, UINT timeout)
10866 {
10867 	// Validate arguments
10868 	if (event == NULL || timeout == 0)
10869 	{
10870 		return false;
10871 	}
10872 
10873 	if (WaitForSingleObject((HANDLE)event->hEvent, timeout) == WAIT_OBJECT_0)
10874 	{
10875 		return true;
10876 	}
10877 	else
10878 	{
10879 		return false;
10880 	}
10881 }
10882 
10883 // Clean-up of the socket event
Win32CleanupSockEvent(SOCK_EVENT * event)10884 void Win32CleanupSockEvent(SOCK_EVENT *event)
10885 {
10886 	// Validate arguments
10887 	if (event == NULL)
10888 	{
10889 		return;
10890 	}
10891 
10892 	CloseHandle((HANDLE)event->hEvent);
10893 
10894 	Free(event);
10895 }
10896 
10897 // Set of the socket event
Win32SetSockEvent(SOCK_EVENT * event)10898 void Win32SetSockEvent(SOCK_EVENT *event)
10899 {
10900 	// Validate arguments
10901 	if (event == NULL)
10902 	{
10903 		return;
10904 	}
10905 
10906 	SetEvent((HANDLE)event->hEvent);
10907 }
10908 
10909 // Creating a socket event
Win32NewSockEvent()10910 SOCK_EVENT *Win32NewSockEvent()
10911 {
10912 	SOCK_EVENT *e = ZeroMallocFast(sizeof(SOCK_EVENT));
10913 
10914 	e->ref = NewRef();
10915 	e->hEvent = (void *)CreateEvent(NULL, FALSE, FALSE, NULL);
10916 
10917 	return e;
10918 }
10919 
10920 // Associate the socket with socket event and set it to asynchronous mode
Win32JoinSockToSockEvent(SOCK * sock,SOCK_EVENT * event)10921 void Win32JoinSockToSockEvent(SOCK *sock, SOCK_EVENT *event)
10922 {
10923 	HANDLE hEvent;
10924 	// Validate arguments
10925 	if (sock == NULL || event == NULL || sock->AsyncMode)
10926 	{
10927 		return;
10928 	}
10929 	if (sock->ListenMode != false || (sock->Type != SOCK_UDP && sock->Connected == false))
10930 	{
10931 		return;
10932 	}
10933 
10934 	sock->AsyncMode = true;
10935 
10936 	hEvent = event->hEvent;
10937 
10938 	// Association
10939 	WSAEventSelect(sock->socket, hEvent, FD_READ | FD_WRITE | FD_CLOSE);
10940 
10941 	// Increase the reference count of the SOCK_EVENT
10942 	AddRef(event->ref);
10943 	sock->SockEvent = event;
10944 }
10945 
10946 // Set the socket to asynchronous mode
Win32InitAsyncSocket(SOCK * sock)10947 void Win32InitAsyncSocket(SOCK *sock)
10948 {
10949 	// Validate arguments
10950 	if (sock == NULL)
10951 	{
10952 		return;
10953 	}
10954 	if (sock->AsyncMode)
10955 	{
10956 		// This socket is already in asynchronous mode
10957 		return;
10958 	}
10959 	if (sock->ListenMode || ((sock->Type == SOCK_TCP || sock->Type == SOCK_INPROC) && sock->Connected == false))
10960 	{
10961 		return;
10962 	}
10963 
10964 	sock->AsyncMode = true;
10965 
10966 	if (sock->Type == SOCK_INPROC)
10967 	{
10968 		// Fetch the event of the TUBE
10969 		TUBE *t = sock->RecvTube;
10970 
10971 		if (t != NULL)
10972 		{
10973 			if (t->SockEvent != NULL)
10974 			{
10975 				sock->hEvent = t->SockEvent->hEvent;
10976 			}
10977 		}
10978 	}
10979 	else
10980 	{
10981 		// Creating an Event
10982 		sock->hEvent = (void *)CreateEvent(NULL, FALSE, FALSE, NULL);
10983 
10984 		// Association
10985 		WSAEventSelect(sock->socket, sock->hEvent, FD_READ | FD_WRITE | FD_CLOSE);
10986 	}
10987 }
10988 
10989 // Release the asynchronous socket
Win32FreeAsyncSocket(SOCK * sock)10990 void Win32FreeAsyncSocket(SOCK *sock)
10991 {
10992 	// Validate arguments
10993 	if (sock == NULL)
10994 	{
10995 		return;
10996 	}
10997 
10998 	// Asynchronous socket
10999 	if (sock->hEvent != NULL)
11000 	{
11001 		if (sock->Type != SOCK_INPROC)
11002 		{
11003 			CloseHandle((HANDLE)sock->hEvent);
11004 		}
11005 	}
11006 	sock->hEvent = NULL;
11007 	sock->AsyncMode = false;
11008 
11009 	// Socket event
11010 	if (sock->SockEvent != NULL)
11011 	{
11012 		ReleaseSockEvent(sock->SockEvent);
11013 		sock->SockEvent = NULL;
11014 	}
11015 }
11016 
11017 // Select function for Win32
Win32Select(SOCKSET * set,UINT timeout,CANCEL * c1,CANCEL * c2)11018 void Win32Select(SOCKSET *set, UINT timeout, CANCEL *c1, CANCEL *c2)
11019 {
11020 	HANDLE array[MAXIMUM_WAIT_OBJECTS];
11021 	UINT n, i;
11022 	SOCK *s;
11023 	// Initialization of array
11024 	Zero(array, sizeof(array));
11025 	n = 0;
11026 
11027 	// Setting the event array
11028 	if (set != NULL)
11029 	{
11030 		for (i = 0;i < set->NumSocket;i++)
11031 		{
11032 			s = set->Sock[i];
11033 			if (s != NULL)
11034 			{
11035 				Win32InitAsyncSocket(s);
11036 				if (s->hEvent != NULL)
11037 				{
11038 					array[n++] = (HANDLE)s->hEvent;
11039 				}
11040 
11041 				if (s->BulkRecvTube != NULL)
11042 				{
11043 					array[n++] = (HANDLE)s->BulkRecvTube->SockEvent->hEvent;
11044 				}
11045 			}
11046 		}
11047 	}
11048 	if (c1 != NULL && c1->hEvent != NULL)
11049 	{
11050 		array[n++] = c1->hEvent;
11051 	}
11052 	if (c2 != NULL && c2->hEvent != NULL)
11053 	{
11054 		array[n++] = c2->hEvent;
11055 	}
11056 
11057 	if (timeout == 0)
11058 	{
11059 		return;
11060 	}
11061 
11062 	if (n == 0)
11063 	{
11064 		// Call normal waiting function if no events to wait are registered
11065 		SleepThread(timeout);
11066 	}
11067 	else
11068 	{
11069 		// Wait for the event if events are registered at least one
11070 		if (n == 1)
11071 		{
11072 			// Calling a lightweight version If the event is only one
11073 			WaitForSingleObject(array[0], timeout);
11074 		}
11075 		else
11076 		{
11077 			// In case of multiple events
11078 			WaitForMultipleObjects(n, array, false, timeout);
11079 		}
11080 	}
11081 }
11082 
11083 #endif	// OS_WIN32
11084 
11085 // Check whether the IPv6 is supported
IsIPv6Supported()11086 bool IsIPv6Supported()
11087 {
11088 #ifdef	NO_IPV6
11089 	return false;
11090 #else	// NO_IPV6
11091 	SOCKET s;
11092 
11093 	s = socket(AF_INET6, SOCK_STREAM, 0);
11094 	if (s == INVALID_SOCKET)
11095 	{
11096 		return false;
11097 	}
11098 
11099 	closesocket(s);
11100 
11101 	return true;
11102 #endif	// NO_IPV6
11103 }
11104 
11105 // Get the host name from the host cache
GetHostCache(char * hostname,UINT size,IP * ip)11106 bool GetHostCache(char *hostname, UINT size, IP *ip)
11107 {
11108 	bool ret;
11109 	// Validate arguments
11110 	if (hostname == NULL || ip == NULL)
11111 	{
11112 		return false;
11113 	}
11114 
11115 	ret = false;
11116 
11117 	LockList(HostCacheList);
11118 	{
11119 		HOSTCACHE t, *c;
11120 		Zero(&t, sizeof(t));
11121 		Copy(&t.IpAddress, ip, sizeof(IP));
11122 
11123 		c = Search(HostCacheList, &t);
11124 		if (c != NULL)
11125 		{
11126 			if (IsEmptyStr(c->HostName) == false)
11127 			{
11128 				ret = true;
11129 				StrCpy(hostname, size, c->HostName);
11130 			}
11131 			else
11132 			{
11133 				ret = true;
11134 				StrCpy(hostname, size, "");
11135 			}
11136 		}
11137 	}
11138 	UnlockList(HostCacheList);
11139 
11140 	return ret;
11141 }
11142 
11143 // Add to the host name cache
AddHostCache(IP * ip,char * hostname)11144 void AddHostCache(IP *ip, char *hostname)
11145 {
11146 	// Validate arguments
11147 	if (ip == NULL || hostname == NULL)
11148 	{
11149 		return;
11150 	}
11151 	if (IsNetworkNameCacheEnabled() == false)
11152 	{
11153 		return;
11154 	}
11155 
11156 	LockList(HostCacheList);
11157 	{
11158 		HOSTCACHE t, *c;
11159 		UINT i;
11160 		LIST *o;
11161 
11162 		Zero(&t, sizeof(t));
11163 		Copy(&t.IpAddress, ip, sizeof(IP));
11164 
11165 		c = Search(HostCacheList, &t);
11166 		if (c == NULL)
11167 		{
11168 			c = ZeroMalloc(sizeof(HOSTCACHE));
11169 			Copy(&c->IpAddress, ip, sizeof(IP));
11170 			Add(HostCacheList, c);
11171 		}
11172 
11173 		StrCpy(c->HostName, sizeof(c->HostName), hostname);
11174 		c->Expires = Tick64() + (UINT64)EXPIRES_HOSTNAME;
11175 
11176 		o = NewListFast(NULL);
11177 
11178 		for (i = 0;i < LIST_NUM(HostCacheList);i++)
11179 		{
11180 			HOSTCACHE *c = LIST_DATA(HostCacheList, i);
11181 
11182 			if (c->Expires <= Tick64())
11183 			{
11184 				Add(o, c);
11185 			}
11186 		}
11187 
11188 		for (i = 0;i < LIST_NUM(o);i++)
11189 		{
11190 			HOSTCACHE *c = LIST_DATA(o, i);
11191 
11192 			if (Delete(HostCacheList, c))
11193 			{
11194 				Free(c);
11195 			}
11196 		}
11197 
11198 		ReleaseList(o);
11199 	}
11200 	UnlockList(HostCacheList);
11201 }
11202 
11203 // Comparison of host name cache entries
CompareHostCache(void * p1,void * p2)11204 int CompareHostCache(void *p1, void *p2)
11205 {
11206 	HOSTCACHE *c1, *c2;
11207 	if (p1 == NULL || p2 == NULL)
11208 	{
11209 		return 0;
11210 	}
11211 	c1 = *(HOSTCACHE **)p1;
11212 	c2 = *(HOSTCACHE **)p2;
11213 	if (c1 == NULL || c2 == NULL)
11214 	{
11215 		return 0;
11216 	}
11217 
11218 	return CmpIpAddr(&c1->IpAddress, &c2->IpAddress);
11219 }
11220 
11221 // Release of the host name cache
FreeHostCache()11222 void FreeHostCache()
11223 {
11224 	UINT i;
11225 
11226 	for (i = 0;i < LIST_NUM(HostCacheList);i++)
11227 	{
11228 		HOSTCACHE *c = LIST_DATA(HostCacheList, i);
11229 
11230 		Free(c);
11231 	}
11232 
11233 	ReleaseList(HostCacheList);
11234 	HostCacheList = NULL;
11235 }
11236 
11237 // Initialization of the host name cache
InitHostCache()11238 void InitHostCache()
11239 {
11240 	HostCacheList = NewList(CompareHostCache);
11241 }
11242 
11243 // Get the number of wait threads
GetNumWaitThread()11244 UINT GetNumWaitThread()
11245 {
11246 	UINT ret = 0;
11247 
11248 	LockList(WaitThreadList);
11249 	{
11250 		ret = LIST_NUM(WaitThreadList);
11251 	}
11252 	UnlockList(WaitThreadList);
11253 
11254 	return ret;
11255 }
11256 
11257 // Add the thread to the thread waiting list
AddWaitThread(THREAD * t)11258 void AddWaitThread(THREAD *t)
11259 {
11260 	// Validate arguments
11261 	if (t == NULL)
11262 	{
11263 		return;
11264 	}
11265 
11266 	AddRef(t->ref);
11267 
11268 	LockList(WaitThreadList);
11269 	{
11270 		Add(WaitThreadList, t);
11271 	}
11272 	UnlockList(WaitThreadList);
11273 }
11274 
11275 // Remove the thread from the waiting list
DelWaitThread(THREAD * t)11276 void DelWaitThread(THREAD *t)
11277 {
11278 	// Validate arguments
11279 	if (t == NULL)
11280 	{
11281 		return;
11282 	}
11283 
11284 	LockList(WaitThreadList);
11285 	{
11286 		if (Delete(WaitThreadList, t))
11287 		{
11288 			ReleaseThread(t);
11289 		}
11290 	}
11291 	UnlockList(WaitThreadList);
11292 }
11293 
11294 // Creating a thread waiting list
InitWaitThread()11295 void InitWaitThread()
11296 {
11297 	WaitThreadList = NewList(NULL);
11298 }
11299 
11300 // Release of the thread waiting list
FreeWaitThread()11301 void FreeWaitThread()
11302 {
11303 	UINT i, num;
11304 	THREAD **threads;
11305 
11306 	LockList(WaitThreadList);
11307 	{
11308 		num = LIST_NUM(WaitThreadList);
11309 		threads = ToArray(WaitThreadList);
11310 		DeleteAll(WaitThreadList);
11311 	}
11312 	UnlockList(WaitThreadList);
11313 
11314 	for (i = 0;i < num;i++)
11315 	{
11316 		THREAD *t = threads[i];
11317 		WaitThread(t, INFINITE);
11318 		ReleaseThread(t);
11319 	}
11320 
11321 	Free(threads);
11322 
11323 	ReleaseList(WaitThreadList);
11324 	WaitThreadList = NULL;
11325 }
11326 
11327 // Check the cipher list name
CheckCipherListName(char * name)11328 bool CheckCipherListName(char *name)
11329 {
11330 	UINT i;
11331 	// Validate arguments
11332 	if (name == NULL)
11333 	{
11334 		return false;
11335 	}
11336 
11337 	for (i = 0;i < cipher_list_token->NumTokens;i++)
11338 	{
11339 		if (StrCmpi(cipher_list_token->Token[i], name) == 0)
11340 		{
11341 			return true;
11342 		}
11343 	}
11344 
11345 	return false;
11346 }
11347 
11348 // Renewing the IP address of the DHCP server
RenewDhcp()11349 void RenewDhcp()
11350 {
11351 #ifdef	OS_WIN32
11352 	Win32RenewDhcp();
11353 #else
11354 	UnixRenewDhcp();
11355 #endif
11356 }
11357 
11358 // Get a domain name for UNIX
UnixGetDomainName(char * name,UINT size)11359 bool UnixGetDomainName(char *name, UINT size)
11360 {
11361 	bool ret = false;
11362 	BUF *b = ReadDump("/etc/resolv.conf");
11363 
11364 	if (b == NULL)
11365 	{
11366 		return false;
11367 	}
11368 
11369 	while (true)
11370 	{
11371 		char *s = CfgReadNextLine(b);
11372 		TOKEN_LIST *t;
11373 
11374 		if (s == NULL)
11375 		{
11376 			break;
11377 		}
11378 
11379 		Trim(s);
11380 
11381 		t = ParseToken(s, " \t");
11382 		if (t != NULL)
11383 		{
11384 			if (t->NumTokens == 2)
11385 			{
11386 				if (StrCmpi(t->Token[0], "domain") == 0)
11387 				{
11388 					StrCpy(name, size, t->Token[1]);
11389 					ret = true;
11390 				}
11391 			}
11392 			FreeToken(t);
11393 		}
11394 
11395 		Free(s);
11396 	}
11397 
11398 	FreeBuf(b);
11399 
11400 	return ret;
11401 }
11402 
11403 // Get the domain name
GetDomainName(char * name,UINT size)11404 bool GetDomainName(char *name, UINT size)
11405 {
11406 	bool ret = false;
11407 	IP ip;
11408 	// Validate arguments
11409 	ClearStr(name, size);
11410 	if (name == NULL)
11411 	{
11412 		return false;
11413 	}
11414 
11415 #ifdef	OS_WIN32
11416 	ClearStr(name, size);
11417 	ret = Win32GetDefaultDns(&ip, name, size);
11418 
11419 	if (ret == false || IsEmptyStr(name))
11420 	{
11421 		ret = Win32GetDnsSuffix(name, size);
11422 	}
11423 #else	// OS_WIN32
11424 	ret = UnixGetDomainName(name, size);
11425 #endif	// OS_WIN32
11426 
11427 	if (ret == false)
11428 	{
11429 		return false;
11430 	}
11431 
11432 	return (IsEmptyStr(name) ? false : true);
11433 }
11434 
11435 // Get the default DNS server
GetDefaultDns(IP * ip)11436 bool GetDefaultDns(IP *ip)
11437 {
11438 	bool ret = false;
11439 #ifdef	OS_WIN32
11440 	ret = Win32GetDefaultDns(ip, NULL, 0);
11441 #else
11442 	ret = UnixGetDefaultDns(ip);
11443 #endif	// OS_WIN32
11444 	return ret;
11445 }
11446 
11447 // Creating a socket event
NewSockEvent()11448 SOCK_EVENT *NewSockEvent()
11449 {
11450 	SOCK_EVENT *e = NULL;
11451 #ifdef	OS_WIN32
11452 	e = Win32NewSockEvent();
11453 #else
11454 	e = UnixNewSockEvent();
11455 #endif	// OS_WIN32
11456 	return e;
11457 }
11458 
11459 // Set of the socket event
SetSockEvent(SOCK_EVENT * event)11460 void SetSockEvent(SOCK_EVENT *event)
11461 {
11462 #ifdef	OS_WIN32
11463 	Win32SetSockEvent(event);
11464 #else
11465 	UnixSetSockEvent(event);
11466 #endif	// OS_WIN32
11467 }
11468 
11469 // Clean-up of the socket event
CleanupSockEvent(SOCK_EVENT * event)11470 void CleanupSockEvent(SOCK_EVENT *event)
11471 {
11472 #ifdef	OS_WIN32
11473 	Win32CleanupSockEvent(event);
11474 #else
11475 	UnixCleanupSockEvent(event);
11476 #endif	// OS_WIN32
11477 }
11478 
11479 // Waiting for the socket event
WaitSockEvent(SOCK_EVENT * event,UINT timeout)11480 bool WaitSockEvent(SOCK_EVENT *event, UINT timeout)
11481 {
11482 	bool ret = false;
11483 #ifdef	OS_WIN32
11484 	ret = Win32WaitSockEvent(event, timeout);
11485 #else
11486 	ret = UnixWaitSockEvent(event, timeout);
11487 #endif	// OS_WIN32
11488 	return ret;
11489 }
11490 
11491 // Release of the socket event
ReleaseSockEvent(SOCK_EVENT * event)11492 void ReleaseSockEvent(SOCK_EVENT *event)
11493 {
11494 	// Validate arguments
11495 	if (event == NULL)
11496 	{
11497 		return;
11498 	}
11499 
11500 	if (Release(event->ref) == 0)
11501 	{
11502 		CleanupSockEvent(event);
11503 	}
11504 }
11505 
11506 // Let belonging the socket to the socket event
JoinSockToSockEvent(SOCK * sock,SOCK_EVENT * event)11507 void JoinSockToSockEvent(SOCK *sock, SOCK_EVENT *event)
11508 {
11509 	// Validate arguments
11510 	if (sock == NULL || event == NULL)
11511 	{
11512 		return;
11513 	}
11514 
11515 	if (sock->Type == SOCK_INPROC)
11516 	{
11517 		// Set the SockEvent on the receiver TUBE for in-process type socket
11518 		SetTubeSockEvent(sock->RecvTube, event);
11519 		return;
11520 	}
11521 
11522 	if (sock->BulkRecvTube != NULL)
11523 	{
11524 		// Set the SockEvent on the receiver TUBE in case of R-UDP socket
11525 		SetTubeSockEvent(sock->BulkRecvTube, event);
11526 	}
11527 
11528 #ifdef	OS_WIN32
11529 	Win32JoinSockToSockEvent(sock, event);
11530 #else
11531 	UnixJoinSockToSockEvent(sock, event);
11532 #endif	// OS_WIN32
11533 }
11534 
11535 // New special cancel object
NewCancelSpecial(void * hEvent)11536 CANCEL *NewCancelSpecial(void *hEvent)
11537 {
11538 	CANCEL *c;
11539 	// Validate arguments
11540 	if (hEvent == NULL)
11541 	{
11542 		return NULL;
11543 	}
11544 
11545 	c = ZeroMalloc(sizeof(CANCEL));
11546 	c->ref = NewRef();
11547 	c->SpecialFlag = true;
11548 
11549 #ifdef	OS_WIN32
11550 	c->hEvent = (HANDLE)hEvent;
11551 #else	// OS_WIN32
11552 	c->pipe_read = (int)hEvent;
11553 	c->pipe_write = -1;
11554 #endif	// OS_WIN32
11555 
11556 	return c;
11557 }
11558 
11559 // Creating a cancel object
NewCancel()11560 CANCEL *NewCancel()
11561 {
11562 	CANCEL *c = NULL;
11563 #ifdef	OS_WIN32
11564 	c = Win32NewCancel();
11565 #else
11566 	c = UnixNewCancel();
11567 #endif	// OS_WIN32
11568 	return c;
11569 }
11570 
11571 // Release of the cancel object
ReleaseCancel(CANCEL * c)11572 void ReleaseCancel(CANCEL *c)
11573 {
11574 	// Validate arguments
11575 	if (c == NULL)
11576 	{
11577 		return;
11578 	}
11579 
11580 	if (Release(c->ref) == 0)
11581 	{
11582 		CleanupCancel(c);
11583 	}
11584 }
11585 
11586 // Clean up of the cancel object
CleanupCancel(CANCEL * c)11587 void CleanupCancel(CANCEL *c)
11588 {
11589 #ifdef	OS_WIN32
11590 	Win32CleanupCancel(c);
11591 #else
11592 	UnixCleanupCancel(c);
11593 #endif
11594 }
11595 
11596 // Cancellation triggered
Cancel(CANCEL * c)11597 void Cancel(CANCEL *c)
11598 {
11599 #ifdef	OS_WIN32
11600 	Win32Cancel(c);
11601 #else
11602 	UnixCancel(c);
11603 #endif
11604 }
11605 
11606 // Calculate the optimal route from the specified routing table
GetBestRouteEntryFromRouteTable(ROUTE_TABLE * table,IP * ip)11607 ROUTE_ENTRY *GetBestRouteEntryFromRouteTable(ROUTE_TABLE *table, IP *ip)
11608 {
11609 	return GetBestRouteEntryFromRouteTableEx(table, ip, 0);
11610 }
GetBestRouteEntryFromRouteTableEx(ROUTE_TABLE * table,IP * ip,UINT exclude_if_id)11611 ROUTE_ENTRY *GetBestRouteEntryFromRouteTableEx(ROUTE_TABLE *table, IP *ip, UINT exclude_if_id)
11612 {
11613 	UINT i;
11614 	ROUTE_ENTRY *ret = NULL;
11615 	ROUTE_ENTRY *tmp = NULL;
11616 	UINT64 min_score = 0;
11617 	// Validate arguments
11618 	if (ip == NULL || table == NULL)
11619 	{
11620 		return NULL;
11621 	}
11622 
11623 	if (IsIP6(ip))
11624 	{
11625 		// IPv6 is not supported
11626 		return NULL;
11627 	}
11628 
11629 	// Select routing table entry by following rule
11630 	// 1. Largest subnet mask
11631 	// 2. Smallest metric value
11632 	for (i = 0;i < table->NumEntry;i++)
11633 	{
11634 		ROUTE_ENTRY *e = table->Entry[i];
11635 		UINT dest, net, mask;
11636 
11637 		dest = IPToUINT(ip);
11638 		net = IPToUINT(&e->DestIP);
11639 		mask = IPToUINT(&e->DestMask);
11640 
11641 		if (exclude_if_id != 0)
11642 		{
11643 			if (e->InterfaceID == exclude_if_id)
11644 			{
11645 				continue;
11646 			}
11647 		}
11648 
11649 		// Mask test
11650 		if ((dest & mask) == (net & mask))
11651 		{
11652 			// Calculate the score
11653 			UINT score_high32 = mask;
11654 			UINT score_low32 = 0xFFFFFFFF - e->Metric;
11655 			UINT64 score64 = (UINT64)score_high32 * (UINT64)0x80000000 * (UINT64)2 + (UINT64)score_low32;
11656 			if (score64 == 0)
11657 			{
11658 				score64 = 1;
11659 			}
11660 
11661 			e->InnerScore = score64;
11662 		}
11663 	}
11664 
11665 	tmp = NULL;
11666 
11667 	// Search for the item with maximum score
11668 	for (i = 0;i < table->NumEntry;i++)
11669 	{
11670 		ROUTE_ENTRY *e = table->Entry[i];
11671 
11672 		if (e->InnerScore != 0)
11673 		{
11674 			if (e->InnerScore >= min_score)
11675 			{
11676 				tmp = e;
11677 				min_score = e->InnerScore;
11678 			}
11679 		}
11680 	}
11681 
11682 	if (tmp != NULL)
11683 	{
11684 		UINT dest, gateway, mask;
11685 
11686 		// Generate an entry
11687 		ret = ZeroMallocFast(sizeof(ROUTE_ENTRY));
11688 
11689 		Copy(&ret->DestIP, ip, sizeof(IP));
11690 		ret->DestMask.addr[0] = 255;
11691 		ret->DestMask.addr[1] = 255;
11692 		ret->DestMask.addr[2] = 255;
11693 		ret->DestMask.addr[3] = 255;
11694 		Copy(&ret->GatewayIP, &tmp->GatewayIP, sizeof(IP));
11695 		ret->InterfaceID = tmp->InterfaceID;
11696 		ret->LocalRouting = tmp->LocalRouting;
11697 		ret->OldIfMetric = tmp->Metric;
11698 		ret->Metric = 1;
11699 		ret->PPPConnection = tmp->PPPConnection;
11700 
11701 		// Calculation related to routing control
11702 		dest = IPToUINT(&tmp->DestIP);
11703 		gateway = IPToUINT(&tmp->GatewayIP);
11704 		mask = IPToUINT(&tmp->DestMask);
11705 		if ((dest & mask) == (gateway & mask))
11706 		{
11707 #ifdef	OS_WIN32
11708 			if (MsIsVista() == false)
11709 			{
11710 				// Adjust for Windows
11711 				ret->PPPConnection = true;
11712 			}
11713 #endif	// OS_WIN32
11714 		}
11715 	}
11716 
11717 	return ret;
11718 }
11719 
11720 // Release the routing entry
FreeRouteEntry(ROUTE_ENTRY * e)11721 void FreeRouteEntry(ROUTE_ENTRY *e)
11722 {
11723 	// Validate arguments
11724 	if (e == NULL)
11725 	{
11726 		return;
11727 	}
11728 
11729 	Free(e);
11730 }
11731 
11732 // Get the best route entry by analyzing the current routing table
GetBestRouteEntry(IP * ip)11733 ROUTE_ENTRY *GetBestRouteEntry(IP *ip)
11734 {
11735 	return GetBestRouteEntryEx(ip, 0);
11736 }
GetBestRouteEntryEx(IP * ip,UINT exclude_if_id)11737 ROUTE_ENTRY *GetBestRouteEntryEx(IP *ip, UINT exclude_if_id)
11738 {
11739 	ROUTE_TABLE *table;
11740 	ROUTE_ENTRY *e = NULL;
11741 	// Validate arguments
11742 	if (ip == NULL)
11743 	{
11744 		return NULL;
11745 	}
11746 
11747 	table = GetRouteTable();
11748 	if (table == NULL)
11749 	{
11750 		return NULL;
11751 	}
11752 
11753 	e = GetBestRouteEntryFromRouteTableEx(table, ip, exclude_if_id);
11754 	FreeRouteTable(table);
11755 
11756 	return e;
11757 }
11758 
11759 // Get the interface ID of the virtual LAN card
GetVLanInterfaceID(char * tag_name)11760 UINT GetVLanInterfaceID(char *tag_name)
11761 {
11762 	UINT ret = 0;
11763 #ifdef	OS_WIN32
11764 	ret = Win32GetVLanInterfaceID(tag_name);
11765 #else	// OS_WIN32
11766 	ret = UnixGetVLanInterfaceID(tag_name);
11767 #endif	// OS_WIN32
11768 	return ret;
11769 }
11770 
11771 // Release of enumeration variable of virtual LAN card
FreeEnumVLan(char ** s)11772 void FreeEnumVLan(char **s)
11773 {
11774 	char *a;
11775 	UINT i;
11776 	// Validate arguments
11777 	if (s == NULL)
11778 	{
11779 		return;
11780 	}
11781 
11782 	i = 0;
11783 	while (true)
11784 	{
11785 		a = s[i++];
11786 		if (a == NULL)
11787 		{
11788 			break;
11789 		}
11790 		Free(a);
11791 	}
11792 
11793 	Free(s);
11794 }
11795 
11796 // Enumeration of virtual LAN cards
EnumVLan(char * tag_name)11797 char **EnumVLan(char *tag_name)
11798 {
11799 	char **ret = NULL;
11800 #ifdef	OS_WIN32
11801 	ret = Win32EnumVLan(tag_name);
11802 #else	// OS_WIN32
11803 	ret = UnixEnumVLan(tag_name);
11804 #endif	// OS_WIN32
11805 	return ret;
11806 }
11807 
11808 // Display the routing table
DebugPrintRouteTable(ROUTE_TABLE * r)11809 void DebugPrintRouteTable(ROUTE_TABLE *r)
11810 {
11811 	UINT i;
11812 	// Validate arguments
11813 	if (r == NULL)
11814 	{
11815 		return;
11816 	}
11817 
11818 	if (IsDebug() == false)
11819 	{
11820 		return;
11821 	}
11822 
11823 	Debug("---- Routing Table (%u Entries) ----\n", r->NumEntry);
11824 
11825 	for (i = 0;i < r->NumEntry;i++)
11826 	{
11827 		Debug("   ");
11828 
11829 		DebugPrintRoute(r->Entry[i]);
11830 	}
11831 
11832 	Debug("------------------------------------\n");
11833 }
11834 
11835 // Display the routing table entry
DebugPrintRoute(ROUTE_ENTRY * e)11836 void DebugPrintRoute(ROUTE_ENTRY *e)
11837 {
11838 	char tmp[MAX_SIZE];
11839 	// Validate arguments
11840 	if (e == NULL)
11841 	{
11842 		return;
11843 	}
11844 
11845 	if (IsDebug() == false)
11846 	{
11847 		return;
11848 	}
11849 
11850 	RouteToStr(tmp, sizeof(tmp), e);
11851 
11852 	Debug("%s\n", tmp);
11853 }
11854 
11855 // Convert the routing table entry to string
RouteToStr(char * str,UINT str_size,ROUTE_ENTRY * e)11856 void RouteToStr(char *str, UINT str_size, ROUTE_ENTRY *e)
11857 {
11858 	char dest_ip[MAX_PATH];
11859 	char dest_mask[MAX_PATH];
11860 	char gateway_ip[MAX_PATH];
11861 	// Validate arguments
11862 	if (str == NULL || e == NULL)
11863 	{
11864 		return;
11865 	}
11866 
11867 	IPToStr(dest_ip, sizeof(dest_ip), &e->DestIP);
11868 	IPToStr(dest_mask, sizeof(dest_mask), &e->DestMask);
11869 	IPToStr(gateway_ip, sizeof(gateway_ip), &e->GatewayIP);
11870 
11871 	Format(str, str_size, "%s/%s %s m=%u oif=%u if=%u lo=%u p=%u",
11872 		dest_ip, dest_mask, gateway_ip,
11873 		e->Metric, e->OldIfMetric, e->InterfaceID,
11874 		e->LocalRouting, e->PPPConnection);
11875 }
11876 
11877 // Delete the routing table
DeleteRouteEntry(ROUTE_ENTRY * e)11878 void DeleteRouteEntry(ROUTE_ENTRY *e)
11879 {
11880 	Debug("DeleteRouteEntry();\n");
11881 #ifdef	OS_WIN32
11882 	Win32DeleteRouteEntry(e);
11883 #else	// OS_WIN32
11884 	UnixDeleteRouteEntry(e);
11885 #endif
11886 }
11887 
11888 // Add to the routing table
AddRouteEntry(ROUTE_ENTRY * e)11889 bool AddRouteEntry(ROUTE_ENTRY *e)
11890 {
11891 	bool dummy = false;
11892 	return AddRouteEntryEx(e, &dummy);
11893 }
AddRouteEntryEx(ROUTE_ENTRY * e,bool * already_exists)11894 bool AddRouteEntryEx(ROUTE_ENTRY *e, bool *already_exists)
11895 {
11896 	bool ret = false;
11897 	Debug("AddRouteEntryEx();\n");
11898 #ifdef	OS_WIN32
11899 	ret = Win32AddRouteEntry(e, already_exists);
11900 #else	// OS_WIN32
11901 	ret = UnixAddRouteEntry(e, already_exists);
11902 #endif
11903 	return ret;
11904 }
11905 
11906 // Get the routing table
GetRouteTable()11907 ROUTE_TABLE *GetRouteTable()
11908 {
11909 	ROUTE_TABLE *t = NULL;
11910 	UINT i;
11911 	BUF *buf = NewBuf();
11912 	UCHAR hash[MD5_SIZE];
11913 
11914 #ifdef	OS_WIN32
11915 	t = Win32GetRouteTable();
11916 #else	//OS_WIN32
11917 	t = UnixGetRouteTable();
11918 #endif	// OS_WIN32
11919 
11920 	WriteBuf(buf, &t->NumEntry, sizeof(t->NumEntry));
11921 
11922 	for (i = 0;i < t->NumEntry;i++)
11923 	{
11924 		ROUTE_ENTRY *e = t->Entry[i];
11925 
11926 		WriteBuf(buf, e, sizeof(ROUTE_ENTRY));
11927 	}
11928 
11929 	Hash(hash, buf->Buf, buf->Size, false);
11930 
11931 	FreeBuf(buf);
11932 
11933 	Copy(&t->HashedValue, hash, sizeof(t->HashedValue));
11934 
11935 	return t;
11936 }
11937 
11938 // Release of the routing table
FreeRouteTable(ROUTE_TABLE * t)11939 void FreeRouteTable(ROUTE_TABLE *t)
11940 {
11941 	UINT i;
11942 	// Validate arguments
11943 	if (t == NULL)
11944 	{
11945 		return;
11946 	}
11947 
11948 	for (i = 0;i < t->NumEntry;i++)
11949 	{
11950 		Free(t->Entry[i]);
11951 	}
11952 	Free(t->Entry);
11953 	Free(t);
11954 }
11955 
11956 // UDP receiving
RecvFrom(SOCK * sock,IP * src_addr,UINT * src_port,void * data,UINT size)11957 UINT RecvFrom(SOCK *sock, IP *src_addr, UINT *src_port, void *data, UINT size)
11958 {
11959 	SOCKET s;
11960 	int ret, sz;
11961 	struct sockaddr_in addr;
11962 	// Validate arguments
11963 	if (sock != NULL)
11964 	{
11965 		sock->IgnoreRecvErr = false;
11966 	}
11967 	if (sock == NULL || src_addr == NULL || src_port == NULL || data == NULL)
11968 	{
11969 		return false;
11970 	}
11971 	if (sock->Type != SOCK_UDP || sock->socket == INVALID_SOCKET)
11972 	{
11973 		return false;
11974 	}
11975 	if (size == 0)
11976 	{
11977 		return false;
11978 	}
11979 
11980 	if (sock->IPv6)
11981 	{
11982 		return RecvFrom6(sock, src_addr, src_port, data, size);
11983 	}
11984 
11985 	s = sock->socket;
11986 
11987 	sz = sizeof(addr);
11988 	ret = recvfrom(s, data, size, 0, (struct sockaddr *)&addr, (int *)&sz);
11989 	if (ret > 0)
11990 	{
11991 		InAddrToIP(src_addr, &addr.sin_addr);
11992 		*src_port = (UINT)ntohs(addr.sin_port);
11993 		if (sock->IsRawSocket)
11994 		{
11995 			*src_port = sock->LocalPort;
11996 /*
11997 			{
11998 				char tmp[MAX_SIZE];
11999 
12000 				IPToStr(tmp, sizeof(tmp), &sock->LocalIP);
12001 				Debug("Raw: %u from %s\n", sock->LocalPort, tmp);
12002 			}*/
12003 		}
12004 
12005 		Lock(sock->lock);
12006 		{
12007 			sock->RecvNum++;
12008 			sock->RecvSize += (UINT64)ret;
12009 		}
12010 		Unlock(sock->lock);
12011 
12012 		// Debug("UDP RecvFrom: %u\n", ret);
12013 
12014 		return (UINT)ret;
12015 	}
12016 	else
12017 	{
12018 		sock->IgnoreRecvErr = false;
12019 
12020 #ifdef	OS_WIN32
12021 		if (WSAGetLastError() == WSAECONNRESET || WSAGetLastError() == WSAENETRESET || WSAGetLastError() == WSAEMSGSIZE || WSAGetLastError() == WSAENETUNREACH ||
12022 			WSAGetLastError() == WSAENOBUFS || WSAGetLastError() == WSAEHOSTUNREACH || WSAGetLastError() == WSAEUSERS || WSAGetLastError() == WSAEADDRNOTAVAIL || WSAGetLastError() == WSAEADDRNOTAVAIL)
12023 		{
12024 			sock->IgnoreRecvErr = true;
12025 		}
12026 		else if (WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINPROGRESS)
12027 		{
12028 			return SOCK_LATER;
12029 		}
12030 		else
12031 		{
12032 			UINT e = WSAGetLastError();
12033 //			Debug("RecvFrom Error: %u\n", e);
12034 		}
12035 #else	// OS_WIN32
12036 		if (errno == ECONNREFUSED || errno == ECONNRESET || errno == EMSGSIZE || errno == ENOBUFS || errno == ENOMEM || errno == EINTR)
12037 		{
12038 			sock->IgnoreRecvErr = true;
12039 		}
12040 		else if (errno == EAGAIN)
12041 		{
12042 			return SOCK_LATER;
12043 		}
12044 #endif	// OS_WIN32
12045 		return 0;
12046 	}
12047 }
RecvFrom6(SOCK * sock,IP * src_addr,UINT * src_port,void * data,UINT size)12048 UINT RecvFrom6(SOCK *sock, IP *src_addr, UINT *src_port, void *data, UINT size)
12049 {
12050 	SOCKET s;
12051 	int ret, sz;
12052 	struct sockaddr_in6 addr;
12053 	// Validate arguments
12054 	if (sock != NULL)
12055 	{
12056 		sock->IgnoreRecvErr = false;
12057 	}
12058 	if (sock == NULL || src_addr == NULL || src_port == NULL || data == NULL)
12059 	{
12060 		return false;
12061 	}
12062 	if (sock->Type != SOCK_UDP || sock->socket == INVALID_SOCKET)
12063 	{
12064 		return false;
12065 	}
12066 	if (size == 0)
12067 	{
12068 		return false;
12069 	}
12070 
12071 	s = sock->socket;
12072 
12073 	sz = sizeof(addr);
12074 	ret = recvfrom(s, data, size, 0, (struct sockaddr *)&addr, (int *)&sz);
12075 	if (ret > 0)
12076 	{
12077 		InAddrToIP6(src_addr, &addr.sin6_addr);
12078 		src_addr->ipv6_scope_id = addr.sin6_scope_id;
12079 		*src_port = (UINT)ntohs(addr.sin6_port);
12080 		if (sock->IsRawSocket)
12081 		{
12082 			*src_port = sock->LocalPort;
12083 		}
12084 
12085 		Lock(sock->lock);
12086 		{
12087 			sock->RecvNum++;
12088 			sock->RecvSize += (UINT64)ret;
12089 		}
12090 		Unlock(sock->lock);
12091 
12092 		// Debug("UDP RecvFrom: %u\n", ret);
12093 
12094 		return (UINT)ret;
12095 	}
12096 	else
12097 	{
12098 		sock->IgnoreRecvErr = false;
12099 
12100 #ifdef	OS_WIN32
12101 		if (WSAGetLastError() == WSAECONNRESET || WSAGetLastError() == WSAENETRESET || WSAGetLastError() == WSAEMSGSIZE || WSAGetLastError() == WSAENETUNREACH ||
12102 			WSAGetLastError() == WSAENOBUFS || WSAGetLastError() == WSAEHOSTUNREACH || WSAGetLastError() == WSAEUSERS || WSAGetLastError() == WSAEADDRNOTAVAIL || WSAGetLastError() == WSAEADDRNOTAVAIL)
12103 		{
12104 			sock->IgnoreRecvErr = true;
12105 		}
12106 		else if (WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINPROGRESS)
12107 		{
12108 			return SOCK_LATER;
12109 		}
12110 		else
12111 		{
12112 			UINT e = WSAGetLastError();
12113 			//			Debug("RecvFrom Error: %u\n", e);
12114 		}
12115 #else	// OS_WIN32
12116 		if (errno == ECONNREFUSED || errno == ECONNRESET || errno == EMSGSIZE || errno == ENOBUFS || errno == ENOMEM || errno == EINTR)
12117 		{
12118 			sock->IgnoreRecvErr = true;
12119 		}
12120 		else if (errno == EAGAIN)
12121 		{
12122 			return SOCK_LATER;
12123 		}
12124 #endif	// OS_WIN32
12125 		return 0;
12126 	}
12127 }
12128 
12129 // Lock the OpenSSL
LockOpenSSL()12130 void LockOpenSSL()
12131 {
12132 	Lock(openssl_lock);
12133 }
12134 
12135 // Unlock the OpenSSL
UnlockOpenSSL()12136 void UnlockOpenSSL()
12137 {
12138 	Unlock(openssl_lock);
12139 }
12140 
12141 // UDP transmission
SendTo(SOCK * sock,IP * dest_addr,UINT dest_port,void * data,UINT size)12142 UINT SendTo(SOCK *sock, IP *dest_addr, UINT dest_port, void *data, UINT size)
12143 {
12144 	return SendToEx(sock, dest_addr, dest_port, data, size, false);
12145 }
SendToEx(SOCK * sock,IP * dest_addr,UINT dest_port,void * data,UINT size,bool broadcast)12146 UINT SendToEx(SOCK *sock, IP *dest_addr, UINT dest_port, void *data, UINT size, bool broadcast)
12147 {
12148 	SOCKET s;
12149 	int ret;
12150 	struct sockaddr_in addr;
12151 	// Validate arguments
12152 	if (sock != NULL)
12153 	{
12154 		sock->IgnoreSendErr = false;
12155 	}
12156 	if (sock == NULL || dest_addr == NULL || (sock->IsRawSocket == false && dest_port == 0) || data == NULL)
12157 	{
12158 		return 0;
12159 	}
12160 	if (dest_port >= 65536 && sock->IsRawSocket == false)
12161 	{
12162 		return 0;
12163 	}
12164 	if (sock->Type != SOCK_UDP || sock->socket == INVALID_SOCKET)
12165 	{
12166 		return 0;
12167 	}
12168 	if (size == 0)
12169 	{
12170 		return 0;
12171 	}
12172 
12173 	if (sock->IPv6)
12174 	{
12175 		return SendTo6Ex(sock, dest_addr, dest_port, data, size, broadcast);
12176 	}
12177 
12178 	if (IsIP4(dest_addr) == false)
12179 	{
12180 		return 0;
12181 	}
12182 
12183 	s = sock->socket;
12184 	Zero(&addr, sizeof(addr));
12185 	addr.sin_family = AF_INET;
12186 	if (sock->IsRawSocket == false)
12187 	{
12188 		addr.sin_port = htons((USHORT)dest_port);
12189 	}
12190 	IPToInAddr(&addr.sin_addr, dest_addr);
12191 
12192 	if ((dest_addr->addr[0] == 255 && dest_addr->addr[1] == 255 &&
12193 		dest_addr->addr[2] == 255 && dest_addr->addr[3] == 255) ||
12194 		(dest_addr->addr[0] >= 224 && dest_addr->addr[0] <= 239)
12195 		|| broadcast)
12196 	{
12197 		if (sock->UdpBroadcast == false)
12198 		{
12199 			bool yes = true;
12200 
12201 			sock->UdpBroadcast = true;
12202 
12203 			setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char *)&yes, sizeof(yes));
12204 		}
12205 	}
12206 
12207 	ret = sendto(s, data, size, 0, (struct sockaddr *)&addr, sizeof(addr));
12208 	if (ret != (int)size)
12209 	{
12210 		sock->IgnoreSendErr = false;
12211 
12212 #ifdef	OS_WIN32
12213 		if (WSAGetLastError() == WSAECONNRESET || WSAGetLastError() == WSAENETRESET || WSAGetLastError() == WSAEMSGSIZE || WSAGetLastError() == WSAENETUNREACH ||
12214 			WSAGetLastError() == WSAENOBUFS || WSAGetLastError() == WSAEHOSTUNREACH || WSAGetLastError() == WSAEUSERS || WSAGetLastError() == WSAEINVAL || WSAGetLastError() == WSAEADDRNOTAVAIL)
12215 		{
12216 			sock->IgnoreSendErr = true;
12217 		}
12218 		else if (WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINPROGRESS)
12219 		{
12220 			return SOCK_LATER;
12221 		}
12222 		else
12223 		{
12224 			UINT e = WSAGetLastError();
12225 			Debug("SendTo Error; %u\n", e);
12226 		}
12227 #else	// OS_WIN32
12228 		if (errno == ECONNREFUSED || errno == ECONNRESET || errno == EMSGSIZE || errno == ENOBUFS || errno == ENOMEM || errno == EINTR)
12229 		{
12230 			sock->IgnoreSendErr = true;
12231 		}
12232 		else if (errno == EAGAIN)
12233 		{
12234 			return SOCK_LATER;
12235 		}
12236 #endif	// OS_WIN32
12237 		return 0;
12238 	}
12239 
12240 	Lock(sock->lock);
12241 	{
12242 		sock->SendSize += (UINT64)size;
12243 		sock->SendNum++;
12244 	}
12245 	Unlock(sock->lock);
12246 
12247 	return ret;
12248 }
SendTo6(SOCK * sock,IP * dest_addr,UINT dest_port,void * data,UINT size)12249 UINT SendTo6(SOCK *sock, IP *dest_addr, UINT dest_port, void *data, UINT size)
12250 {
12251 	return SendTo6Ex(sock, dest_addr, dest_port, data, size, false);
12252 }
SendTo6Ex(SOCK * sock,IP * dest_addr,UINT dest_port,void * data,UINT size,bool broadcast)12253 UINT SendTo6Ex(SOCK *sock, IP *dest_addr, UINT dest_port, void *data, UINT size, bool broadcast)
12254 {
12255 	SOCKET s;
12256 	int ret;
12257 	struct sockaddr_in6 addr;
12258 	UINT type;
12259 	// Validate arguments
12260 	if (sock != NULL)
12261 	{
12262 		sock->IgnoreSendErr = false;
12263 	}
12264 	if (sock == NULL || dest_addr == NULL || (sock->IsRawSocket == false && dest_port == 0) || data == NULL)
12265 	{
12266 		return 0;
12267 	}
12268 	if (dest_port >= 65536 && sock->IsRawSocket == false)
12269 	{
12270 		return 0;
12271 	}
12272 	if (sock->Type != SOCK_UDP || sock->socket == INVALID_SOCKET)
12273 	{
12274 		return 0;
12275 	}
12276 	if (size == 0)
12277 	{
12278 		return 0;
12279 	}
12280 
12281 	if (IsIP6(dest_addr) == false)
12282 	{
12283 		return 0;
12284 	}
12285 
12286 	s = sock->socket;
12287 	Zero(&addr, sizeof(addr));
12288 	addr.sin6_family = AF_INET6;
12289 	if (sock->IsRawSocket == false)
12290 	{
12291 		addr.sin6_port = htons((USHORT)dest_port);
12292 	}
12293 	IPToInAddr6(&addr.sin6_addr, dest_addr);
12294 	addr.sin6_scope_id = dest_addr->ipv6_scope_id;
12295 
12296 	type = GetIPAddrType6(dest_addr);
12297 
12298 	if ((type & IPV6_ADDR_MULTICAST) || broadcast)
12299 	{
12300 		if (sock->UdpBroadcast == false)
12301 		{
12302 			bool yes = true;
12303 
12304 			sock->UdpBroadcast = true;
12305 
12306 			setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char *)&yes, sizeof(yes));
12307 		}
12308 	}
12309 
12310 	ret = sendto(s, data, size, 0, (struct sockaddr *)&addr, sizeof(addr));
12311 	if (ret != (int)size)
12312 	{
12313 		sock->IgnoreSendErr = false;
12314 
12315 #ifdef	OS_WIN32
12316 		if (WSAGetLastError() == WSAECONNRESET || WSAGetLastError() == WSAENETRESET || WSAGetLastError() == WSAEMSGSIZE || WSAGetLastError() == WSAENETUNREACH ||
12317 			WSAGetLastError() == WSAENOBUFS || WSAGetLastError() == WSAEHOSTUNREACH || WSAGetLastError() == WSAEUSERS || WSAGetLastError() == WSAEINVAL || WSAGetLastError() == WSAEADDRNOTAVAIL)
12318 		{
12319 			sock->IgnoreSendErr = true;
12320 		}
12321 		else if (WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINPROGRESS)
12322 		{
12323 			return SOCK_LATER;
12324 		}
12325 		else
12326 		{
12327 			UINT e = WSAGetLastError();
12328 		}
12329 #else	// OS_WIN32
12330 		if (errno == ECONNREFUSED || errno == ECONNRESET || errno == EMSGSIZE || errno == ENOBUFS || errno == ENOMEM || errno == EINTR)
12331 		{
12332 			sock->IgnoreSendErr = true;
12333 		}
12334 		else if (errno == EAGAIN)
12335 		{
12336 			return SOCK_LATER;
12337 		}
12338 #endif	// OS_WIN32
12339 		return 0;
12340 	}
12341 
12342 	Lock(sock->lock);
12343 	{
12344 		sock->SendSize += (UINT64)size;
12345 		sock->SendNum++;
12346 	}
12347 	Unlock(sock->lock);
12348 
12349 	return ret;
12350 }
12351 
12352 // Disable the UDP checksum
DisableUDPChecksum(SOCK * s)12353 void DisableUDPChecksum(SOCK *s)
12354 {
12355 	bool true_flag = true;
12356 	// Validate arguments
12357 	if (s == NULL || s->Type != SOCK_UDP)
12358 	{
12359 		return;
12360 	}
12361 
12362 	if (s->socket != INVALID_SOCKET)
12363 	{
12364 		if (s->IPv6 == false)
12365 		{
12366 #ifdef	UDP_NOCHECKSUM
12367 			setsockopt(s->socket, IPPROTO_UDP, UDP_NOCHECKSUM, (char *)&true_flag, sizeof(bool));
12368 #endif	// UDP_NOCHECKSUM
12369 		}
12370 	}
12371 }
12372 
12373 // Set the socket to asynchronous mode
InitAsyncSocket(SOCK * sock)12374 void InitAsyncSocket(SOCK *sock)
12375 {
12376 #ifdef	OS_WIN32
12377 	Win32InitAsyncSocket(sock);
12378 #else	// OS_WIN32
12379 	UnixInitAsyncSocket(sock);
12380 #endif	// OS_WIN32
12381 }
12382 
12383 // Get a new available UDP port number
GetNewAvailableUdpPortRand()12384 UINT GetNewAvailableUdpPortRand()
12385 {
12386 	UINT num_retry = 8;
12387 	UINT i;
12388 	UINT ret = 0;
12389 	UCHAR seed[SHA1_SIZE];
12390 
12391 	Rand(seed, sizeof(seed));
12392 
12393 	for (i = 0;i < num_retry;i++)
12394 	{
12395 		SOCK *s = NewUDPEx2Rand(false, NULL, seed, sizeof(seed), RAND_UDP_PORT_DEFAULT_NUM_RETRY);
12396 
12397 		if (s != NULL)
12398 		{
12399 			ret = s->LocalPort;
12400 
12401 			Disconnect(s);
12402 			ReleaseSock(s);
12403 		}
12404 
12405 		if (ret != 0)
12406 		{
12407 			break;
12408 		}
12409 	}
12410 
12411 	return ret;
12412 }
12413 
12414 // Open a UDP port (port number is random, but determine the randomness in the seed)
NewUDPEx2Rand(bool ipv6,IP * ip,void * rand_seed,UINT rand_seed_size,UINT num_retry)12415 SOCK *NewUDPEx2Rand(bool ipv6, IP *ip, void *rand_seed, UINT rand_seed_size, UINT num_retry)
12416 {
12417 	UINT i;
12418 	// Validate arguments
12419 	if (rand_seed == NULL || rand_seed_size == 0)
12420 	{
12421 		return NULL;
12422 	}
12423 	if (num_retry == 0)
12424 	{
12425 		num_retry = RAND_UDP_PORT_DEFAULT_NUM_RETRY;
12426 	}
12427 
12428 	for (i = 0; i < (num_retry + 1);i++)
12429 	{
12430 		BUF *buf = NewBuf();
12431 		UCHAR hash[SHA1_SIZE];
12432 		UINT port = 0;
12433 		SOCK *s;
12434 
12435 		WriteBuf(buf, rand_seed, rand_seed_size);
12436 		WriteBufInt(buf, i);
12437 
12438 		HashSha1(hash, buf->Buf, buf->Size);
12439 
12440 		FreeBuf(buf);
12441 
12442 		port = READ_UINT(hash);
12443 
12444 		port = RAND_UDP_PORT_START + (port % (RAND_UDP_PORT_END - RAND_UDP_PORT_START));
12445 
12446 		s = NewUDPEx2(port, ipv6, ip);
12447 
12448 		if (s != NULL)
12449 		{
12450 			return s;
12451 		}
12452 	}
12453 
12454 	return NewUDPEx2(0, ipv6, ip);
12455 }
12456 
12457 // Generate a random port number (based on the EXE path and machine key)
NewRandPortByMachineAndExePath(UINT start_port,UINT end_port,UINT additional_int)12458 UINT NewRandPortByMachineAndExePath(UINT start_port, UINT end_port, UINT additional_int)
12459 {
12460 	BUF *b;
12461 	char machine_name[MAX_SIZE];
12462 	wchar_t exe_path[MAX_PATH];
12463 	char *product_id = NULL;
12464 	UCHAR hash[SHA1_SIZE];
12465 
12466 #ifdef	OS_WIN32
12467 	product_id = MsRegReadStr(REG_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "ProductId");
12468 	if (product_id == NULL)
12469 	{
12470 		product_id = MsRegReadStr(REG_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion", "ProductId");
12471 	}
12472 #endif	// OS_WIN32
12473 
12474 	b = NewBuf();
12475 
12476 	GetMachineHostName(machine_name, sizeof(machine_name));
12477 	Trim(machine_name);
12478 	StrUpper(machine_name);
12479 
12480 	GetExeNameW(exe_path, sizeof(exe_path));
12481 	UniTrim(exe_path);
12482 	UniStrUpper(exe_path);
12483 
12484 	WriteBuf(b, machine_name, StrSize(machine_name));
12485 	WriteBuf(b, exe_path, UniStrSize(exe_path));
12486 	WriteBuf(b, product_id, StrSize(product_id));
12487 	WriteBufInt(b, additional_int);
12488 
12489 	HashSha1(hash, b->Buf, b->Size);
12490 
12491 	FreeBuf(b);
12492 
12493 	Free(product_id);
12494 
12495 	return (READ_UINT(hash) % (end_port - start_port)) + start_port;
12496 }
12497 
12498 // Open the UDP port (based on the EXE path and machine key)
NewUDPEx2RandMachineAndExePath(bool ipv6,IP * ip,UINT num_retry,UCHAR rand_port_id)12499 SOCK *NewUDPEx2RandMachineAndExePath(bool ipv6, IP *ip, UINT num_retry, UCHAR rand_port_id)
12500 {
12501 	BUF *b;
12502 	char machine_name[MAX_SIZE];
12503 	wchar_t exe_path[MAX_PATH];
12504 	char *product_id = NULL;
12505 	UCHAR hash[SHA1_SIZE];
12506 
12507 #ifdef	OS_WIN32
12508 	product_id = MsRegReadStr(REG_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "ProductId");
12509 	if (product_id == NULL)
12510 	{
12511 		product_id = MsRegReadStr(REG_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion", "ProductId");
12512 	}
12513 #endif	// OS_WIN32
12514 
12515 	b = NewBuf();
12516 
12517 	GetMachineHostName(machine_name, sizeof(machine_name));
12518 	Trim(machine_name);
12519 	StrUpper(machine_name);
12520 
12521 	GetExeNameW(exe_path, sizeof(exe_path));
12522 	UniTrim(exe_path);
12523 	UniStrUpper(exe_path);
12524 
12525 	WriteBuf(b, machine_name, StrSize(machine_name));
12526 	WriteBuf(b, exe_path, UniStrSize(exe_path));
12527 	WriteBuf(b, product_id, StrSize(product_id));
12528 	WriteBufChar(b, rand_port_id);
12529 	//WriteBufInt(b, GetHostIPAddressHash32());
12530 
12531 	HashSha1(hash, b->Buf, b->Size);
12532 
12533 	FreeBuf(b);
12534 
12535 	Free(product_id);
12536 
12537 	return NewUDPEx2Rand(ipv6, ip, hash, sizeof(hash), num_retry);
12538 }
12539 
12540 // Set the DF bit of the socket
ClearSockDfBit(SOCK * s)12541 void ClearSockDfBit(SOCK *s)
12542 {
12543 #ifdef	IP_PMTUDISC_DONT
12544 #ifdef	IP_MTU_DISCOVER
12545 	UINT value = IP_PMTUDISC_DONT;
12546 	if (s == NULL)
12547 	{
12548 		return;
12549 	}
12550 
12551 	setsockopt(s->socket, IPPROTO_IP, IP_MTU_DISCOVER, (char *)&value, sizeof(value));
12552 #endif	// IP_MTU_DISCOVER
12553 #endif	// IP_PMTUDISC_DONT
12554 }
12555 
12556 // Set the header-include option
SetRawSockHeaderIncludeOption(SOCK * s,bool enable)12557 void SetRawSockHeaderIncludeOption(SOCK *s, bool enable)
12558 {
12559 	UINT value = BOOL_TO_INT(enable);
12560 	if (s == NULL || s->IsRawSocket == false)
12561 	{
12562 		return;
12563 	}
12564 
12565 	setsockopt(s->socket, IPPROTO_IP, IP_HDRINCL, (char *)&value, sizeof(value));
12566 
12567 	s->RawIP_HeaderIncludeFlag = enable;
12568 }
12569 
12570 // Create and initialize the UDP socket
12571 // If port is specified as 0, system assigns a certain port.
NewUDP(UINT port)12572 SOCK *NewUDP(UINT port)
12573 {
12574 	return NewUDPEx(port, false);
12575 }
NewUDPEx(UINT port,bool ipv6)12576 SOCK *NewUDPEx(UINT port, bool ipv6)
12577 {
12578 	return NewUDPEx2(port, ipv6, NULL);
12579 }
NewUDPEx2(UINT port,bool ipv6,IP * ip)12580 SOCK *NewUDPEx2(UINT port, bool ipv6, IP *ip)
12581 {
12582 	if (ipv6 == false)
12583 	{
12584 		return NewUDP4(port, ip);
12585 	}
12586 	else
12587 	{
12588 		return NewUDP6(port, ip);
12589 	}
12590 }
NewUDPEx3(UINT port,IP * ip)12591 SOCK *NewUDPEx3(UINT port, IP *ip)
12592 {
12593 	// Validate arguments
12594 	if (ip == NULL)
12595 	{
12596 		return NewUDPEx2(port, false, NULL);
12597 	}
12598 
12599 	if (IsIP4(ip))
12600 	{
12601 		return NewUDPEx2(port, false, ip);
12602 	}
12603 	else
12604 	{
12605 		return NewUDPEx2(port, true, ip);
12606 	}
12607 }
NewUDP4(UINT port,IP * ip)12608 SOCK *NewUDP4(UINT port, IP *ip)
12609 {
12610 	SOCK *sock;
12611 	SOCKET s;
12612 	struct sockaddr_in addr;
12613 	// Validate arguments
12614 	if (ip != NULL && IsIP4(ip) == false)
12615 	{
12616 		return NULL;
12617 	}
12618 
12619 	if (IS_SPECIAL_PORT(port) == false)
12620 	{
12621 		s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
12622 	}
12623 	else
12624 	{
12625 		s = socket(AF_INET, SOCK_RAW, GET_SPECIAL_PORT(port));
12626 	}
12627 	if (s == INVALID_SOCKET)
12628 	{
12629 		return NULL;
12630 	}
12631 
12632 	Zero(&addr, sizeof(addr));
12633 	addr.sin_family = AF_INET;
12634 
12635 	if (ip == NULL || IsZeroIP(ip))
12636 	{
12637 		addr.sin_addr.s_addr = htonl(INADDR_ANY);
12638 	}
12639 	else
12640 	{
12641 		IPToInAddr(&addr.sin_addr, ip);
12642 	}
12643 
12644 	if (port == 0 || IS_SPECIAL_PORT(port))
12645 	{
12646 		addr.sin_port = 0;
12647 	}
12648 	else
12649 	{
12650 		addr.sin_port = htons((USHORT)port);
12651 	}
12652 
12653 	if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) != 0)
12654 	{
12655 		// Failure
12656 		if (port != 0)
12657 		{
12658 			bool true_flag = true;
12659 			setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&true_flag, sizeof(bool));
12660 			if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) != 0)
12661 			{
12662 				bool false_flag = false;
12663 				setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&false_flag, sizeof(bool));
12664 #ifdef	SO_EXCLUSIVEADDRUSE
12665 				setsockopt(s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char *)&true_flag, sizeof(bool));
12666 #endif	// SO_EXCLUSIVEADDRUSE
12667 				if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) != 0)
12668 				{
12669 					closesocket(s);
12670 					return NULL;
12671 				}
12672 			}
12673 		}
12674 		else
12675 		{
12676 			closesocket(s);
12677 			return NULL;
12678 		}
12679 	}
12680 
12681 	sock = NewSock();
12682 
12683 	sock->Type = SOCK_UDP;
12684 	sock->Connected = false;
12685 	sock->AsyncMode = false;
12686 	sock->ServerMode = false;
12687 	if (port != 0)
12688 	{
12689 		sock->ServerMode = true;
12690 	}
12691 
12692 	sock->socket = s;
12693 
12694 	InitUdpSocketBufferSize((int)s);
12695 
12696 	if (IS_SPECIAL_PORT(port))
12697 	{
12698 		bool no = false;
12699 		setsockopt(sock->socket, IPPROTO_IP, IP_HDRINCL, (char *)&no, sizeof(no));
12700 
12701 		sock->IsRawSocket = true;
12702 		sock->RawSocketIPProtocol = GET_SPECIAL_PORT(port);
12703 	}
12704 
12705 	QuerySocketInformation(sock);
12706 
12707 	return sock;
12708 }
NewUDP6(UINT port,IP * ip)12709 SOCK *NewUDP6(UINT port, IP *ip)
12710 {
12711 	SOCK *sock;
12712 	SOCKET s;
12713 	struct sockaddr_in6 addr;
12714 	// Validate arguments
12715 	if (ip != NULL && IsIP6(ip) == false)
12716 	{
12717 		return NULL;
12718 	}
12719 
12720 	if (IS_SPECIAL_PORT(port) == false)
12721 	{
12722 		s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
12723 	}
12724 	else
12725 	{
12726 		s = socket(AF_INET6, SOCK_RAW, GET_SPECIAL_PORT(port));
12727 	}
12728 	if (s == INVALID_SOCKET)
12729 	{
12730 		return NULL;
12731 	}
12732 
12733 	Zero(&addr, sizeof(addr));
12734 	addr.sin6_family = AF_INET6;
12735 	if (port == 0)
12736 	{
12737 		addr.sin6_port = 0;
12738 	}
12739 	else
12740 	{
12741 		addr.sin6_port = htons((USHORT)port);
12742 	}
12743 
12744 	if (ip != NULL && IsZeroIP(ip) == false)
12745 	{
12746 		IPToInAddr6(&addr.sin6_addr, ip);
12747 		addr.sin6_scope_id = ip->ipv6_scope_id;
12748 	}
12749 
12750 	if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) != 0)
12751 	{
12752 		// Failure
12753 		if (port != 0)
12754 		{
12755 			bool true_flag = true;
12756 			setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&true_flag, sizeof(bool));
12757 			if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) != 0)
12758 			{
12759 				bool false_flag = false;
12760 				setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&false_flag, sizeof(bool));
12761 #ifdef	SO_EXCLUSIVEADDRUSE
12762 				setsockopt(s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char *)&true_flag, sizeof(bool));
12763 #endif	// SO_EXCLUSIVEADDRUSE
12764 				if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) != 0)
12765 				{
12766 					closesocket(s);
12767 					return NULL;
12768 				}
12769 			}
12770 		}
12771 		else
12772 		{
12773 			closesocket(s);
12774 			return NULL;
12775 		}
12776 	}
12777 
12778 	sock = NewSock();
12779 
12780 	sock->Type = SOCK_UDP;
12781 	sock->Connected = false;
12782 	sock->AsyncMode = false;
12783 	sock->ServerMode = false;
12784 	sock->IPv6 = true;
12785 	if (port != 0)
12786 	{
12787 		sock->ServerMode = true;
12788 	}
12789 
12790 	sock->socket = s;
12791 
12792 	InitUdpSocketBufferSize(s);
12793 
12794 	if (IS_SPECIAL_PORT(port))
12795 	{
12796 		bool no = false;
12797 #ifdef	IPV6_HDRINCL
12798 		setsockopt(sock->socket, IPPROTO_IP, IPV6_HDRINCL, (char *)&no, sizeof(no));
12799 #endif	// IPV6_HDRINCL
12800 		setsockopt(sock->socket, IPPROTO_IP, IP_HDRINCL, (char *)&no, sizeof(no));
12801 
12802 		sock->IsRawSocket = true;
12803 		sock->RawSocketIPProtocol = GET_SPECIAL_PORT(port);
12804 	}
12805 
12806 	QuerySocketInformation(sock);
12807 
12808 	return sock;
12809 }
12810 
12811 // Select function
Select(SOCKSET * set,UINT timeout,CANCEL * c1,CANCEL * c2)12812 void Select(SOCKSET *set, UINT timeout, CANCEL *c1, CANCEL *c2)
12813 {
12814 #ifdef	OS_WIN32
12815 	Win32Select(set, timeout, c1, c2);
12816 #else
12817 	UnixSelect(set, timeout, c1, c2);
12818 #endif	// OS_WIN32
12819 }
12820 
12821 // Add a socket to the socket set
AddSockSet(SOCKSET * set,SOCK * sock)12822 void AddSockSet(SOCKSET *set, SOCK *sock)
12823 {
12824 	// Validate arguments
12825 	if (set == NULL || sock == NULL)
12826 	{
12827 		return;
12828 	}
12829 	if (sock->Type == SOCK_TCP && sock->Connected == false)
12830 	{
12831 		return;
12832 	}
12833 
12834 	if (set->NumSocket >= MAX_SOCKSET_NUM)
12835 	{
12836 		// Upper limit
12837 		return;
12838 	}
12839 	set->Sock[set->NumSocket++] = sock;
12840 }
12841 
12842 // Initializing the socket set
InitSockSet(SOCKSET * set)12843 void InitSockSet(SOCKSET *set)
12844 {
12845 	// Validate arguments
12846 	if (set == NULL)
12847 	{
12848 		return;
12849 	}
12850 
12851 	Zero(set, sizeof(SOCKSET));
12852 }
12853 
12854 // Receive data and discard all of them
RecvAllWithDiscard(SOCK * sock,UINT size,bool secure)12855 bool RecvAllWithDiscard(SOCK *sock, UINT size, bool secure)
12856 {
12857 	static UCHAR buffer[4096];
12858 	UINT recv_size, sz, ret;
12859 	if (sock == NULL)
12860 	{
12861 		return false;
12862 	}
12863 	if (size == 0)
12864 	{
12865 		return true;
12866 	}
12867 	if (sock->AsyncMode)
12868 	{
12869 		return false;
12870 	}
12871 
12872 	recv_size = 0;
12873 
12874 	while (true)
12875 	{
12876 		sz = MIN(size - recv_size, sizeof(buffer));
12877 		ret = Recv(sock, buffer, sz, secure);
12878 		if (ret == 0)
12879 		{
12880 			return false;
12881 		}
12882 		if (ret == SOCK_LATER)
12883 		{
12884 			// I suppose that this is safe because the RecvAll() function is used only
12885 			// if the sock->AsyncMode == true. And the Recv() function may return
12886 			// SOCK_LATER only if the sock->AsyncMode == false. Therefore the call of
12887 			// Recv() function in the RecvAll() function never returns SOCK_LATER.
12888 			return false;
12889 		}
12890 		recv_size += ret;
12891 		if (recv_size >= size)
12892 		{
12893 			return true;
12894 		}
12895 	}
12896 }
12897 
12898 // Receive all by TCP
RecvAll(SOCK * sock,void * data,UINT size,bool secure)12899 bool RecvAll(SOCK *sock, void *data, UINT size, bool secure)
12900 {
12901 	UINT recv_size, sz, ret;
12902 	// Validate arguments
12903 	if (sock == NULL || data == NULL)
12904 	{
12905 		return false;
12906 	}
12907 	if (size == 0)
12908 	{
12909 		return true;
12910 	}
12911 	if (sock->AsyncMode)
12912 	{
12913 		return false;
12914 	}
12915 
12916 	recv_size = 0;
12917 
12918 	while (true)
12919 	{
12920 		sz = size - recv_size;
12921 		ret = Recv(sock, (UCHAR *)data + recv_size, sz, secure);
12922 		if (ret == 0)
12923 		{
12924 			return false;
12925 		}
12926 		if (ret == SOCK_LATER)
12927 		{
12928 			// I suppose that this is safe because the RecvAll() function is used only
12929 			// if the sock->AsyncMode == true. And the Recv() function may return
12930 			// SOCK_LATER only if the sock->AsyncMode == false. Therefore the call of
12931 			// Recv() function in the RecvAll() function never returns SOCK_LATER.
12932 			return false;
12933 		}
12934 		recv_size += ret;
12935 		if (recv_size >= size)
12936 		{
12937 			return true;
12938 		}
12939 	}
12940 }
12941 
12942 // Send the TCP send buffer
SendNow(SOCK * sock,int secure)12943 bool SendNow(SOCK *sock, int secure)
12944 {
12945 	bool ret;
12946 	// Validate arguments
12947 	if (sock == NULL || sock->AsyncMode != false)
12948 	{
12949 		return false;
12950 	}
12951 	if (sock->SendBuf->Size == 0)
12952 	{
12953 		return true;
12954 	}
12955 
12956 	ret = SendAll(sock, sock->SendBuf->Buf, sock->SendBuf->Size, secure);
12957 	ClearBuf(sock->SendBuf);
12958 
12959 	return ret;
12960 }
12961 
12962 // Append to the TCP send buffer
SendAdd(SOCK * sock,void * data,UINT size)12963 void SendAdd(SOCK *sock, void *data, UINT size)
12964 {
12965 	// Validate arguments
12966 	if (sock == NULL || data == NULL || size == 0 || sock->AsyncMode != false)
12967 	{
12968 		return;
12969 	}
12970 
12971 	WriteBuf(sock->SendBuf, data, size);
12972 }
12973 
12974 // Send all by TCP
SendAll(SOCK * sock,void * data,UINT size,bool secure)12975 bool SendAll(SOCK *sock, void *data, UINT size, bool secure)
12976 {
12977 	UCHAR *buf;
12978 	UINT sent_size;
12979 	UINT ret;
12980 	// Validate arguments
12981 	if (sock == NULL || data == NULL)
12982 	{
12983 		return false;
12984 	}
12985 	if (sock->AsyncMode)
12986 	{
12987 		return false;
12988 	}
12989 	if (size == 0)
12990 	{
12991 		return true;
12992 	}
12993 
12994 	buf = (UCHAR *)data;
12995 	sent_size = 0;
12996 
12997 	while (true)
12998 	{
12999 		ret = Send(sock, buf, size - sent_size, secure);
13000 		if (ret == 0)
13001 		{
13002 			return false;
13003 		}
13004 		sent_size += ret;
13005 		buf += ret;
13006 		if (sent_size >= size)
13007 		{
13008 			return true;
13009 		}
13010 	}
13011 }
13012 
13013 // Set the cipher algorithm name to want to use
SetWantToUseCipher(SOCK * sock,char * name)13014 void SetWantToUseCipher(SOCK *sock, char *name)
13015 {
13016 	char tmp[2048];
13017 	// Validate arguments
13018 	if (sock == NULL || name == NULL)
13019 	{
13020 		return;
13021 	}
13022 
13023 	if (sock->WaitToUseCipher)
13024 	{
13025 		Free(sock->WaitToUseCipher);
13026 	}
13027 
13028 	Zero(tmp, sizeof(tmp));
13029 	StrCpy(tmp, sizeof(tmp), name);
13030 	StrCat(tmp, sizeof(tmp), " ");
13031 	StrCat(tmp, sizeof(tmp), cipher_list);
13032 
13033 	sock->WaitToUseCipher = CopyStr(tmp);
13034 }
13035 
13036 // Add all the chain certificates in the chain_certs directory
AddChainSslCertOnDirectory(struct ssl_ctx_st * ctx)13037 void AddChainSslCertOnDirectory(struct ssl_ctx_st *ctx)
13038 {
13039 	wchar_t dirname[MAX_SIZE];
13040 	wchar_t exedir[MAX_SIZE];
13041 	wchar_t txtname[MAX_SIZE];
13042 	DIRLIST *dir;
13043 	LIST *o;
13044 	UINT i;
13045 
13046 	// Validate arguments
13047 	if (ctx == NULL)
13048 	{
13049 		return;
13050 	}
13051 
13052 	o = NewListFast(NULL);
13053 
13054 	GetDbDirW(exedir, sizeof(exedir));
13055 
13056 	CombinePathW(dirname, sizeof(dirname), exedir, L"chain_certs");
13057 
13058 	MakeDirExW(dirname);
13059 
13060 	CombinePathW(txtname, sizeof(txtname), dirname, L"Readme_Chain_Certs.txt");
13061 
13062 	if (IsFileExistsW(txtname) == false)
13063 	{
13064 		FileCopyW(L"|chain_certs.txt", txtname);
13065 	}
13066 
13067 	dir = EnumDirW(dirname);
13068 
13069 	if (dir != NULL)
13070 	{
13071 		for (i = 0;i < dir->NumFiles;i++)
13072 		{
13073 			DIRENT *e = dir->File[i];
13074 
13075 			if (e->Folder == false)
13076 			{
13077 				wchar_t tmp[MAX_SIZE];
13078 				X *x;
13079 
13080 				CombinePathW(tmp, sizeof(tmp), dirname, e->FileNameW);
13081 
13082 				x = FileToXW(tmp);
13083 
13084 				if (x != NULL)
13085 				{
13086 					UINT j;
13087 					bool exists = false;
13088 					UCHAR hash[SHA1_SIZE];
13089 
13090 					GetXDigest(x, hash, true);
13091 
13092 					for (j = 0;j < LIST_NUM(o);j++)
13093 					{
13094 						UCHAR *hash2 = LIST_DATA(o, j);
13095 
13096 						if (Cmp(hash, hash2, SHA1_SIZE) == 0)
13097 						{
13098 							exists = true;
13099 						}
13100 					}
13101 
13102 					if (exists == false)
13103 					{
13104 						AddChainSslCert(ctx, x);
13105 
13106 						Add(o, Clone(hash, SHA1_SIZE));
13107 					}
13108 
13109 					FreeX(x);
13110 				}
13111 			}
13112 		}
13113 
13114 		FreeDir(dir);
13115 	}
13116 
13117 	for (i = 0;i < LIST_NUM(o);i++)
13118 	{
13119 		UCHAR *hash = LIST_DATA(o, i);
13120 
13121 		Free(hash);
13122 	}
13123 
13124 	ReleaseList(o);
13125 }
13126 
13127 // Add the chain certificate
AddChainSslCert(struct ssl_ctx_st * ctx,X * x)13128 bool AddChainSslCert(struct ssl_ctx_st *ctx, X *x)
13129 {
13130 	bool ret = false;
13131 	X *x_copy;
13132 	// Validate arguments
13133 	if (ctx == NULL || x == NULL)
13134 	{
13135 		return ret;
13136 	}
13137 
13138 	x_copy = CloneX(x);
13139 
13140 	if (x_copy != NULL)
13141 	{
13142 		SSL_CTX_add_extra_chain_cert(ctx, x_copy->x509);
13143 		x_copy->do_not_free = true;
13144 
13145 		ret = true;
13146 
13147 		FreeX(x_copy);
13148 	}
13149 
13150 	return ret;
13151 }
13152 
13153 // Start a TCP-SSL communication
StartSSL(SOCK * sock,X * x,K * priv)13154 bool StartSSL(SOCK *sock, X *x, K *priv)
13155 {
13156 	return StartSSLEx(sock, x, priv, true, 0, NULL);
13157 }
StartSSLEx(SOCK * sock,X * x,K * priv,bool client_tls,UINT ssl_timeout,char * sni_hostname)13158 bool StartSSLEx(SOCK *sock, X *x, K *priv, bool client_tls, UINT ssl_timeout, char *sni_hostname)
13159 {
13160 	X509 *x509;
13161 	EVP_PKEY *key;
13162 	UINT prev_timeout = 1024;
13163 	SSL_CTX *ssl_ctx;
13164 
13165 #ifdef UNIX_SOLARIS
13166 	SOCKET_TIMEOUT_PARAM *ttparam;
13167 #endif //UNIX_SOLARIS
13168 
13169 	// Validate arguments
13170 	if (sock == NULL)
13171 	{
13172 		Debug("StartSSL Error: #0\n");
13173 		return false;
13174 	}
13175 	if (sock->Connected && sock->Type == SOCK_INPROC && sock->ListenMode == false)
13176 	{
13177 		sock->SecureMode = true;
13178 		return true;
13179 	}
13180 	if (sock->Connected == false || sock->socket == INVALID_SOCKET ||
13181 		sock->ListenMode != false)
13182 	{
13183 		Debug("StartSSL Error: #1\n");
13184 		return false;
13185 	}
13186 	if (x != NULL && priv == NULL)
13187 	{
13188 		Debug("StartSSL Error: #2\n");
13189 		return false;
13190 	}
13191 	if (ssl_timeout == 0)
13192 	{
13193 		ssl_timeout = TIMEOUT_SSL_CONNECT;
13194 	}
13195 
13196 	if (sock->SecureMode)
13197 	{
13198 		//Debug("StartSSL Error: #3\n");
13199 		// SSL communication has already started
13200 		return true;
13201 	}
13202 
13203 	Lock(sock->ssl_lock);
13204 	if (sock->SecureMode)
13205 	{
13206 		//Debug("StartSSL Error: #4\n");
13207 		// SSL communication has already started
13208 		Unlock(sock->ssl_lock);
13209 		return true;
13210 	}
13211 
13212 	ssl_ctx = NewSSLCtx(sock->ServerMode);
13213 
13214 	Lock(openssl_lock);
13215 	{
13216 		if (sock->ServerMode)
13217 		{
13218 			SSL_CTX_set_ssl_version(ssl_ctx, SSLv23_method());
13219 
13220 #ifdef	SSL_OP_NO_SSLv2
13221 			SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSLv2);
13222 #endif	// SSL_OP_NO_SSLv2
13223 
13224 			if (sock->SslAcceptSettings.AcceptOnlyTls)
13225 			{
13226 #ifdef	SSL_OP_NO_SSLv3
13227 				SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSLv3);
13228 #endif	// SSL_OP_NO_SSLv3
13229 			}
13230 
13231 			if (sock->SslAcceptSettings.Tls_Disable1_0)
13232 			{
13233 #ifdef	SSL_OP_NO_TLSv1
13234 				SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TLSv1);
13235 #endif	// SSL_OP_NO_TLSv1
13236 			}
13237 
13238 			if (sock->SslAcceptSettings.Tls_Disable1_1)
13239 			{
13240 #ifdef	SSL_OP_NO_TLSv1_1
13241 				SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TLSv1_1);
13242 #endif	// SSL_OP_NO_TLSv1_1
13243 			}
13244 
13245 			if (sock->SslAcceptSettings.Tls_Disable1_2)
13246 			{
13247 #ifdef	SSL_OP_NO_TLSv1_2
13248 				SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TLSv1_2);
13249 #endif	// SSL_OP_NO_TLSv1_2
13250 			}
13251 
13252 			if (sock->SslAcceptSettings.Tls_Disable1_3)
13253 			{
13254 #ifdef	SSL_OP_NO_TLSv1_3
13255 				SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TLSv1_3);
13256 #endif	// SSL_OP_NO_TLSv1_3
13257 			}
13258 
13259 			Unlock(openssl_lock);
13260 			AddChainSslCertOnDirectory(ssl_ctx);
13261 			Lock(openssl_lock);
13262 		}
13263 		else
13264 		{
13265 			if (client_tls == false)
13266 			{
13267 				// Use SSL v3
13268 #ifndef SSL_OP_NO_SSL_MASK
13269 #if OPENSSL_VERSION_NUMBER < 0x10100000L
13270 				SSL_CTX_set_ssl_version(ssl_ctx, SSLv3_method());
13271 #else
13272 				SSL_CTX_set_ssl_version(ssl_ctx, SSLv23_method());
13273 #endif
13274 #else	// SSL_OP_NO_SSL_MASK
13275 				SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSL_MASK & ~SSL_OP_NO_SSLv3);
13276 #endif	// SSL_OP_NO_SSL_MASK
13277 			}
13278 			else
13279 			{
13280 				// Use TLS 1.0 or later
13281 				SSL_CTX_set_ssl_version(ssl_ctx, SSLv23_client_method());
13282 			}
13283 		}
13284 		sock->ssl = SSL_new(ssl_ctx);
13285 		SSL_set_fd(sock->ssl, (int)sock->socket);
13286 
13287 #ifdef	SSL_CTRL_SET_TLSEXT_HOSTNAME
13288 		if (sock->ServerMode == false && client_tls)
13289 		{
13290 			if (IsEmptyStr(sni_hostname) == false)
13291 			{
13292 				// Set the SNI host name
13293 				SSL_set_tlsext_host_name(sock->ssl, sni_hostname);
13294 			}
13295 		}
13296 #endif	// SSL_CTRL_SET_TLSEXT_HOSTNAME
13297 
13298 	}
13299 	Unlock(openssl_lock);
13300 
13301 	if (x != NULL)
13302 	{
13303 		// Check the certificate and the private key
13304 		if (CheckXandK(x, priv))
13305 		{
13306 			// Use the certificate
13307 			x509 = x->x509;
13308 			key = priv->pkey;
13309 
13310 			Lock(openssl_lock);
13311 			{
13312 				SSL_use_certificate(sock->ssl, x509);
13313 				SSL_use_PrivateKey(sock->ssl, key);
13314 			}
13315 			Unlock(openssl_lock);
13316 		}
13317 	}
13318 
13319 	if (sock->WaitToUseCipher != NULL)
13320 	{
13321 		// Set the cipher algorithm name to want to use
13322 		Lock(openssl_lock);
13323 		{
13324 			SSL_set_cipher_list(sock->ssl, sock->WaitToUseCipher);
13325 		}
13326 		Unlock(openssl_lock);
13327 	}
13328 	else
13329 	{
13330 		// Set the OpenSSL default cipher algorithms
13331 		Lock(openssl_lock);
13332 		{
13333 			SSL_set_cipher_list(sock->ssl, OPENSSL_DEFAULT_CIPHER_LIST);
13334 		}
13335 		Unlock(openssl_lock);
13336 	}
13337 
13338 	if (sock->ServerMode)
13339 	{
13340 //		Lock(ssl_connect_lock);
13341 
13342 // Run the time-out thread for SOLARIS
13343 #ifdef UNIX_SOLARIS
13344 		ttparam = NewSocketTimeout(sock);
13345 #endif // UNIX_SOLARIS
13346 
13347 		// Server mode
13348 		if (SSL_accept(sock->ssl) <= 0)
13349 		{
13350 
13351 // Stop the timeout thread
13352 #ifdef UNIX_SOLARIS
13353 			FreeSocketTimeout(ttparam);
13354 #endif // UNIX_SOLARIS
13355 
13356 			//			Unlock(ssl_connect_lock);
13357 			// SSL-Accept failure
13358 			Lock(openssl_lock);
13359 			{
13360 				SSL_free(sock->ssl);
13361 				sock->ssl = NULL;
13362 			}
13363 			Unlock(openssl_lock);
13364 
13365 			Unlock(sock->ssl_lock);
13366 			Debug("StartSSL Error: #5\n");
13367 			FreeSSLCtx(ssl_ctx);
13368 			return false;
13369 		}
13370 
13371 #ifdef	SSL_CTRL_SET_TLSEXT_HOSTNAME
13372 #ifdef	TLSEXT_NAMETYPE_host_name
13373 		if (true)
13374 		{
13375 			// Get the SNI host name
13376 			const char *sni_recv_hostname = SSL_get_servername(sock->ssl, TLSEXT_NAMETYPE_host_name);
13377 
13378 			if (IsEmptyStr((char *)sni_recv_hostname) == false)
13379 			{
13380 				StrCpy(sock->SniHostname, sizeof(sock->SniHostname), (char *)sni_recv_hostname);
13381 			}
13382 		}
13383 #endif	// TLSEXT_NAMETYPE_host_name
13384 #endif	// SSL_CTRL_SET_TLSEXT_HOSTNAME
13385 
13386 // Stop the timeout thread
13387 #ifdef UNIX_SOLARIS
13388 		FreeSocketTimeout(ttparam);
13389 #endif // UNIX_SOLARIS
13390 
13391 		//		Unlock(ssl_connect_lock);
13392 	}
13393 	else
13394 	{
13395 		prev_timeout = GetTimeout(sock);
13396 		SetTimeout(sock, ssl_timeout);
13397 		Lock(ssl_connect_lock);
13398 		// Client mode
13399 		if (SSL_connect(sock->ssl) <= 0)
13400 		{
13401 			Unlock(ssl_connect_lock);
13402 			// SSL-connect failure
13403 			Lock(openssl_lock);
13404 			{
13405 				SSL_free(sock->ssl);
13406 				sock->ssl = NULL;
13407 			}
13408 			Unlock(openssl_lock);
13409 
13410 			Unlock(sock->ssl_lock);
13411 			Debug("StartSSL Error: #5\n");
13412 			SetTimeout(sock, prev_timeout);
13413 			FreeSSLCtx(ssl_ctx);
13414 			return false;
13415 		}
13416 		Unlock(ssl_connect_lock);
13417 		SetTimeout(sock, prev_timeout);
13418 	}
13419 
13420 	// SSL communication is initiated
13421 	sock->SecureMode = true;
13422 
13423 	// Get the certificate of the remote host
13424 	Lock(openssl_lock);
13425 	{
13426 		x509 = SSL_get_peer_certificate(sock->ssl);
13427 
13428 		sock->SslVersion = SSL_get_version(sock->ssl);
13429 	}
13430 	Unlock(openssl_lock);
13431 
13432 	if (x509 == NULL)
13433 	{
13434 		// The certificate does not exist on the remote host
13435 		sock->RemoteX = NULL;
13436 	}
13437 	else
13438 	{
13439 		// Got a certificate
13440 		sock->RemoteX = X509ToX(x509);
13441 	}
13442 
13443 	// Get the certificate of local host
13444 	Lock(openssl_lock);
13445 	{
13446 		x509 = SSL_get_certificate(sock->ssl);
13447 	}
13448 	Unlock(openssl_lock);
13449 
13450 	if (x509 == NULL)
13451 	{
13452 		// The certificate does not exist on the remote host
13453 		sock->LocalX = NULL;
13454 	}
13455 	else
13456 	{
13457 		X *local_x;
13458 		// Got a certificate
13459 		local_x = X509ToX(x509);
13460 		local_x->do_not_free = true;
13461 		sock->LocalX = CloneX(local_x);
13462 		FreeX(local_x);
13463 	}
13464 
13465 	// Automatic retry mode
13466 	SSL_set_mode(sock->ssl, SSL_MODE_AUTO_RETRY);
13467 
13468 	// Strange flag
13469 	SSL_set_mode(sock->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
13470 
13471 	sock->ssl_ctx = ssl_ctx;
13472 
13473 	// Get the algorithm name used to encrypt
13474 	Lock(openssl_lock);
13475 	{
13476 		sock->CipherName = CopyStr((char *)SSL_get_cipher(sock->ssl));
13477 	}
13478 	Unlock(openssl_lock);
13479 	Debug("SSL connected with %s\n", SSL_get_version(sock->ssl));
13480 
13481 	Unlock(sock->ssl_lock);
13482 
13483 #ifdef	ENABLE_SSL_LOGGING
13484 	if (sock->ServerMode)
13485 	{
13486 		SockEnableSslLogging(sock);
13487 	}
13488 #endif	// ENABLE_SSL_LOGGING
13489 
13490 	return true;
13491 }
13492 
13493 
13494 
13495 #ifdef	ENABLE_SSL_LOGGING
13496 
13497 // Enable SSL logging
SockEnableSslLogging(SOCK * s)13498 void SockEnableSslLogging(SOCK *s)
13499 {
13500 	char dirname[MAX_PATH];
13501 	char tmp[MAX_PATH];
13502 	char dtstr[MAX_PATH];
13503 	char fn1[MAX_PATH], fn2[MAX_PATH];
13504 	// Validate arguments
13505 	if (s == NULL)
13506 	{
13507 		return;
13508 	}
13509 
13510 	if (s->IsSslLoggingEnabled)
13511 	{
13512 		return;
13513 	}
13514 
13515 	s->IsSslLoggingEnabled = true;
13516 
13517 	GetDateTimeStrMilli64ForFileName(dtstr, sizeof(dtstr), LocalTime64());
13518 	Format(tmp, sizeof(tmp), "%s__%r_%u__%r_%u", dtstr,
13519 		&s->LocalIP, s->LocalPort, &s->RemoteIP, s->RemotePort);
13520 
13521 	CombinePath(dirname, sizeof(dirname), SSL_LOGGING_DIRNAME, tmp);
13522 
13523 	MakeDirEx(dirname);
13524 
13525 	CombinePath(fn1, sizeof(fn1), dirname, "send.c");
13526 	CombinePath(fn2, sizeof(fn2), dirname, "recv.c");
13527 
13528 	s->SslLogging_Send = FileCreate(fn1);
13529 	s->SslLogging_Recv = FileCreate(fn2);
13530 
13531 	s->SslLogging_Lock = NewLock();
13532 }
13533 
13534 // Close SSL logging
SockCloseSslLogging(SOCK * s)13535 void SockCloseSslLogging(SOCK *s)
13536 {
13537 	// Validate arguments
13538 	if (s == NULL)
13539 	{
13540 		return;
13541 	}
13542 
13543 	if (s->IsSslLoggingEnabled == false)
13544 	{
13545 		return;
13546 	}
13547 
13548 	s->IsSslLoggingEnabled = false;
13549 
13550 	FileClose(s->SslLogging_Recv);
13551 	s->SslLogging_Recv = NULL;
13552 
13553 	FileClose(s->SslLogging_Send);
13554 	s->SslLogging_Send = NULL;
13555 
13556 	DeleteLock(s->SslLogging_Lock);
13557 	s->SslLogging_Lock = NULL;
13558 }
13559 
13560 // Write SSL log
SockWriteSslLog(SOCK * s,void * send_data,UINT send_size,void * recv_data,UINT recv_size)13561 void SockWriteSslLog(SOCK *s, void *send_data, UINT send_size, void *recv_data, UINT recv_size)
13562 {
13563 	// Validate arguments
13564 	if (s == NULL)
13565 	{
13566 		return;
13567 	}
13568 
13569 	if (s->IsSslLoggingEnabled == false)
13570 	{
13571 		return;
13572 	}
13573 
13574 	Lock(s->SslLogging_Lock);
13575 	{
13576 		if (s->SslLogging_Send != NULL)
13577 		{
13578 			if (send_size >= 1 && send_data != NULL)
13579 			{
13580 				FileWrite(s->SslLogging_Send, send_data, send_size);
13581 			}
13582 		}
13583 
13584 		if (s->SslLogging_Recv != NULL)
13585 		{
13586 			if (recv_size >= 1 && recv_data != NULL)
13587 			{
13588 				FileWrite(s->SslLogging_Recv, recv_data, recv_size);
13589 			}
13590 		}
13591 	}
13592 	Unlock(s->SslLogging_Lock);
13593 }
13594 
13595 #endif	// ENABLE_SSL_LOGGING
13596 
13597 // Set the flag to indicate that the socket doesn't require reading
SetNoNeedToRead(SOCK * sock)13598 void SetNoNeedToRead(SOCK *sock)
13599 {
13600 	// Validate arguments
13601 	if (sock == NULL)
13602 	{
13603 		return;
13604 	}
13605 
13606 	sock->NoNeedToRead = true;
13607 }
13608 
13609 // TCP-SSL receive
SecureRecv(SOCK * sock,void * data,UINT size)13610 UINT SecureRecv(SOCK *sock, void *data, UINT size)
13611 {
13612 	SOCKET s;
13613 	int ret, e = 0;
13614 	SSL *ssl;
13615 
13616 #ifdef UNIX_SOLARIS
13617 	SOCKET_TIMEOUT_PARAM *ttparam;
13618 #endif //UNIX_SOLARIS
13619 
13620 	s = sock->socket;
13621 	ssl = sock->ssl;
13622 
13623 	if (sock->AsyncMode)
13624 	{
13625 		// Confirm whether the data is readable even 1 byte in the case of asynchronous mode.
13626 		// To read data results blocking, if there is no readable data.
13627 		// We must avoid blocking.
13628 		char c;
13629 		Lock(sock->ssl_lock);
13630 		{
13631 			if (sock->Connected == false)
13632 			{
13633 				Unlock(sock->ssl_lock);
13634 				Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__);
13635 				return 0;
13636 			}
13637 			ret = SSL_peek(ssl, &c, sizeof(c));
13638 		}
13639 		Unlock(sock->ssl_lock);
13640 		if (ret == 0)
13641 		{
13642 			// The communication have been disconnected
13643 			Disconnect(sock);
13644 			Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__);
13645 			return 0;
13646 		}
13647 		if (ret < 0)
13648 		{
13649 			// An error has occurred
13650 			e = SSL_get_error(ssl, ret);
13651 			if (e == SSL_ERROR_WANT_READ || e == SSL_ERROR_WANT_WRITE || e == SSL_ERROR_SSL)
13652 			{
13653 				if (e == SSL_ERROR_SSL
13654 #if OPENSSL_VERSION_NUMBER < 0x10100000L
13655 					&&
13656 					sock->ssl->s3->send_alert[0] == SSL3_AL_FATAL &&
13657 					sock->ssl->s3->send_alert[0] != sock->Ssl_Init_Async_SendAlert[0] &&
13658 					sock->ssl->s3->send_alert[1] != sock->Ssl_Init_Async_SendAlert[1]
13659 #endif
13660 					)
13661 				{
13662 					Debug("%s %u SSL Fatal Error on ASYNC socket !!!\n", __FILE__, __LINE__);
13663 					Disconnect(sock);
13664 					return 0;
13665 				}
13666 				// Packet has not arrived yet, that is not to be read
13667 				return SOCK_LATER;
13668 			}
13669 		}
13670 	}
13671 
13672 	// Receive
13673 	Lock(sock->ssl_lock);
13674 	{
13675 		if (sock->Connected == false)
13676 		{
13677 			Unlock(sock->ssl_lock);
13678 			Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__);
13679 			return 0;
13680 		}
13681 
13682 #ifdef	OS_UNIX
13683 		if (sock->AsyncMode == false)
13684 		{
13685 			sock->CallingThread = pthread_self();
13686 		}
13687 #endif	// OS_UNIX
13688 
13689 // Run the time-out thread for SOLARIS
13690 #ifdef UNIX_SOLARIS
13691 		ttparam = NewSocketTimeout(sock);
13692 #endif // UNIX_SOLARIS
13693 
13694 		ret = SSL_read(ssl, data, size);
13695 
13696 // Stop the timeout thread
13697 #ifdef UNIX_SOLARIS
13698 		FreeSocketTimeout(ttparam);
13699 #endif // UNIX_SOLARIS
13700 
13701 
13702 #ifdef	OS_UNIX
13703 		if (sock->AsyncMode == false)
13704 		{
13705 			sock->CallingThread = 0;
13706 		}
13707 #endif	// OS_UNIX
13708 
13709 		if (ret < 0)
13710 		{
13711 			e = SSL_get_error(ssl, ret);
13712 		}
13713 
13714 	}
13715 	Unlock(sock->ssl_lock);
13716 
13717 #ifdef	ENABLE_SSL_LOGGING
13718 	if (ret > 0)
13719 	{
13720 		SockWriteSslLog(sock, NULL, 0, data, ret);
13721 	}
13722 #endif	// ENABLE_SSL_LOGGING
13723 
13724 	if (ret > 0)
13725 	{
13726 		// Successful reception
13727 		sock->RecvSize += (UINT64)ret;
13728 		sock->RecvNum++;
13729 
13730 		return (UINT)ret;
13731 	}
13732 	if (ret == 0)
13733 	{
13734 		// Disconnect the communication
13735 		Disconnect(sock);
13736 		//Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__);
13737 		return 0;
13738 	}
13739 	if (sock->AsyncMode)
13740 	{
13741 		if (e == SSL_ERROR_WANT_READ || e == SSL_ERROR_WANT_WRITE || e == SSL_ERROR_SSL)
13742 		{
13743 			if (e == SSL_ERROR_SSL
13744 #if OPENSSL_VERSION_NUMBER < 0x10100000L
13745 				&&
13746 				sock->ssl->s3->send_alert[0] == SSL3_AL_FATAL &&
13747 				sock->ssl->s3->send_alert[0] != sock->Ssl_Init_Async_SendAlert[0] &&
13748 				sock->ssl->s3->send_alert[1] != sock->Ssl_Init_Async_SendAlert[1]
13749 #endif
13750 				)
13751 			{
13752 				Debug("%s %u SSL Fatal Error on ASYNC socket !!!\n", __FILE__, __LINE__);
13753 				Disconnect(sock);
13754 				return 0;
13755 			}
13756 
13757 			// Packet has not yet arrived
13758 			return SOCK_LATER;
13759 		}
13760 	}
13761 	Disconnect(sock);
13762 	Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__);
13763 	return 0;
13764 }
13765 
13766 // TCP-SSL transmission
SecureSend(SOCK * sock,void * data,UINT size)13767 UINT SecureSend(SOCK *sock, void *data, UINT size)
13768 {
13769 	SOCKET s;
13770 	int ret, e;
13771 	SSL *ssl;
13772 	s = sock->socket;
13773 	ssl = sock->ssl;
13774 
13775 	if (sock->AsyncMode)
13776 	{
13777 		// Asynchronous mode
13778 		SSL_set_mode(ssl, SSL_MODE_ENABLE_PARTIAL_WRITE);
13779 	}
13780 
13781 	// Transmission
13782 	Lock(sock->ssl_lock);
13783 	{
13784 		if (sock->Connected == false)
13785 		{
13786 			Unlock(sock->ssl_lock);
13787 			Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__);
13788 			return 0;
13789 		}
13790 
13791 		ret = SSL_write(ssl, data, size);
13792 		if (ret < 0)
13793 		{
13794 			e = SSL_get_error(ssl, ret);
13795 		}
13796 	}
13797 	Unlock(sock->ssl_lock);
13798 
13799 #ifdef	ENABLE_SSL_LOGGING
13800 	if (ret > 0)
13801 	{
13802 		SockWriteSslLog(sock, data, ret, NULL, 0);
13803 	}
13804 #endif	// ENABLE_SSL_LOGGING
13805 
13806 	if (ret > 0)
13807 	{
13808 		// Successful transmission
13809 		sock->SendSize += (UINT64)ret;
13810 		sock->SendNum++;
13811 		sock->WriteBlocked = false;
13812 		return (UINT)ret;
13813 	}
13814 	if (ret == 0)
13815 	{
13816 		// Disconnect
13817 		Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__);
13818 		Disconnect(sock);
13819 		return 0;
13820 	}
13821 
13822 	if (sock->AsyncMode)
13823 	{
13824 		// Confirmation of the error value
13825 		if (e == SSL_ERROR_WANT_READ || e == SSL_ERROR_WANT_WRITE || e == SSL_ERROR_SSL)
13826 		{
13827 			sock->WriteBlocked = true;
13828 			return SOCK_LATER;
13829 		}
13830 		Debug("%s %u e=%u\n", __FILE__, __LINE__, e);
13831 	}
13832 	//Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__);
13833 	Disconnect(sock);
13834 	return 0;
13835 }
13836 
13837 // Peep the TCP
Peek(SOCK * sock,void * data,UINT size)13838 UINT Peek(SOCK *sock, void *data, UINT size)
13839 {
13840 	SOCKET s;
13841 	int ret;
13842 
13843 	// Validate arguments
13844 	if (sock == NULL || data == NULL || size == 0)
13845 	{
13846 		return 0;
13847 	}
13848 	if (sock->Type == SOCK_INPROC)
13849 	{
13850 		return 0;
13851 	}
13852 	if (sock->Type != SOCK_TCP || sock->Connected == false || sock->ListenMode != false ||
13853 		sock->socket == INVALID_SOCKET)
13854 	{
13855 		return 0;
13856 	}
13857 	if (sock->AsyncMode)
13858 	{
13859 		return 0;
13860 	}
13861 
13862 	// Receive
13863 	s = sock->socket;
13864 
13865 	ret = recv(s, data, size, MSG_PEEK);
13866 
13867 	//Debug("Peek: %u\n", ret);
13868 
13869 	if (ret > 0)
13870 	{
13871 		return ret;
13872 	}
13873 
13874 	return 0;
13875 }
13876 
13877 // TCP receive
Recv(SOCK * sock,void * data,UINT size,bool secure)13878 UINT Recv(SOCK *sock, void *data, UINT size, bool secure)
13879 {
13880 	SOCKET s;
13881 	int ret;
13882 
13883 #ifdef UNIX_SOLARIS
13884 	SOCKET_TIMEOUT_PARAM *ttparam;
13885 #endif //UNIX_SOLARIS
13886 
13887 	// Validate arguments
13888 	if (sock == NULL || data == NULL || size == 0)
13889 	{
13890 		return 0;
13891 	}
13892 
13893 	sock->NoNeedToRead = false;
13894 
13895 	if (sock->Type == SOCK_INPROC)
13896 	{
13897 		return RecvInProc(sock, data, size);
13898 	}
13899 	if (sock->Type != SOCK_TCP || sock->Connected == false || sock->ListenMode != false ||
13900 		sock->socket == INVALID_SOCKET)
13901 	{
13902 		return 0;
13903 	}
13904 	if (secure != false && sock->SecureMode == false)
13905 	{
13906 		return 0;
13907 	}
13908 
13909 	if (secure)
13910 	{
13911 		return SecureRecv(sock, data, size);
13912 	}
13913 
13914 	// Receive
13915 	s = sock->socket;
13916 
13917 
13918 #ifdef	OS_UNIX
13919 	if (sock->AsyncMode == false)
13920 	{
13921 		sock->CallingThread = pthread_self();
13922 	}
13923 #endif	// OS_UNIX
13924 
13925 // Start of the timeout thread for SOLARIS
13926 #ifdef UNIX_SOLARIS
13927 	ttparam = NewSocketTimeout(sock);
13928 #endif // UNIX_SOLARIS
13929 
13930 	ret = recv(s, data, size, 0);
13931 
13932 // Stop the timeout thread
13933 #ifdef UNIX_SOLARIS
13934 	FreeSocketTimeout(ttparam);
13935 #endif // UNIX_SOLARIS
13936 
13937 #ifdef	OS_UNIX
13938 	if (sock->AsyncMode == false)
13939 	{
13940 		sock->CallingThread = 0;
13941 	}
13942 #endif	// OS_UNIX
13943 
13944 	if (ret > 0)
13945 	{
13946 		// Successful reception
13947 		Lock(sock->lock);
13948 		{
13949 			sock->RecvSize += (UINT64)ret;
13950 			sock->SendNum++;
13951 		}
13952 		Unlock(sock->lock);
13953 		return (UINT)ret;
13954 	}
13955 
13956 	// Transmission failure
13957 	if (sock->AsyncMode)
13958 	{
13959 		// In asynchronous mode, examine the error
13960 		if (ret == SOCKET_ERROR)
13961 		{
13962 #ifdef	OS_WIN32
13963 			if (WSAGetLastError() == WSAEWOULDBLOCK)
13964 			{
13965 				// In blocking
13966 				return SOCK_LATER;
13967 			}
13968 			else
13969 			{
13970 				//Debug("Socket Error: %u\n", WSAGetLastError());
13971 			}
13972 #else	// OS_WIN32
13973 			if (errno == EAGAIN)
13974 			{
13975 				// In blocking
13976 				return SOCK_LATER;
13977 			}
13978 #endif	// OS_WIN32
13979 		}
13980 	}
13981 
13982 	// Disconnected
13983 	Disconnect(sock);
13984 	return 0;
13985 }
13986 
13987 // TCP transmission
Send(SOCK * sock,void * data,UINT size,bool secure)13988 UINT Send(SOCK *sock, void *data, UINT size, bool secure)
13989 {
13990 	SOCKET s;
13991 	int ret;
13992 	// Validate arguments
13993 	if (sock == NULL || data == NULL || size == 0)
13994 	{
13995 		return 0;
13996 	}
13997 	if (sock->Type == SOCK_INPROC)
13998 	{
13999 		return SendInProc(sock, data, size);
14000 	}
14001 	size = MIN(size, MAX_SEND_BUF_MEM_SIZE);
14002 	if (sock->Type != SOCK_TCP || sock->Connected == false || sock->ListenMode != false ||
14003 		sock->socket == INVALID_SOCKET)
14004 	{
14005 		return 0;
14006 	}
14007 	if (secure != false && sock->SecureMode == false)
14008 	{
14009 		return 0;
14010 	}
14011 
14012 	if (secure)
14013 	{
14014 		return SecureSend(sock, data, size);
14015 	}
14016 
14017 	// Transmission
14018 	s = sock->socket;
14019 	ret = send(s, data, size, 0);
14020 	if (ret > 0)
14021 	{
14022 		// Successful transmission
14023 		Lock(sock->lock);
14024 		{
14025 			sock->SendSize += (UINT64)ret;
14026 			sock->SendNum++;
14027 		}
14028 		Unlock(sock->lock);
14029 		sock->WriteBlocked = false;
14030 		return (UINT)ret;
14031 	}
14032 
14033 	// Transmission failure
14034 	if (sock->AsyncMode)
14035 	{
14036 		// In asynchronous mode, examine the error
14037 		if (ret == SOCKET_ERROR)
14038 		{
14039 #ifdef	OS_WIN32
14040 			if (WSAGetLastError() == WSAEWOULDBLOCK)
14041 			{
14042 				// In blocking
14043 				sock->WriteBlocked = true;
14044 				return SOCK_LATER;
14045 			}
14046 			else
14047 			{
14048 				//Debug("Socket Error: %u\n", WSAGetLastError());
14049 			}
14050 #else	// OS_WIN32
14051 			if (errno == EAGAIN)
14052 			{
14053 				// In blocking
14054 				sock->WriteBlocked = true;
14055 				return SOCK_LATER;
14056 			}
14057 #endif	// OS_WIN32
14058 		}
14059 	}
14060 
14061 	// Disconnected
14062 	Disconnect(sock);
14063 	return 0;
14064 }
14065 
14066 // Get the time-out value (in milliseconds)
GetTimeout(SOCK * sock)14067 UINT GetTimeout(SOCK *sock)
14068 {
14069 	// Validate arguments
14070 	if (sock == NULL)
14071 	{
14072 		return INFINITE;
14073 	}
14074 	if (sock->Type != SOCK_TCP && sock->Type != SOCK_INPROC)
14075 	{
14076 		return INFINITE;
14077 	}
14078 
14079 	return sock->TimeOut;
14080 }
14081 
14082 // Setting the time-out value (in milliseconds)
SetTimeout(SOCK * sock,UINT timeout)14083 void SetTimeout(SOCK *sock, UINT timeout)
14084 {
14085 	// Validate arguments
14086 	if (sock == NULL)
14087 	{
14088 		return;
14089 	}
14090 	if (sock->Type == SOCK_UDP)
14091 	{
14092 		return;
14093 	}
14094 
14095 	if (timeout == INFINITE)
14096 	{
14097 		timeout = TIMEOUT_INFINITE;
14098 	}
14099 
14100 	sock->TimeOut = timeout;
14101 
14102 //	Debug("SetTimeout(%u)\n",timeout);
14103 
14104 	if (sock->Type != SOCK_INPROC)
14105 	{
14106 #ifdef OS_WIN32
14107 		setsockopt(sock->socket, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(UINT));
14108 		setsockopt(sock->socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(UINT));
14109 #endif
14110 
14111 #ifdef OS_UNIX
14112 #ifndef UNIX_SOLARIS
14113 		{
14114 			struct timeval tv_timeout;
14115 
14116 			tv_timeout.tv_sec = timeout / 1000; // miliseconds to seconds
14117 			tv_timeout.tv_usec = (timeout % 1000) * 1000; // miliseconds to microseconds
14118 
14119 			setsockopt(sock->socket, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv_timeout, sizeof(tv_timeout));
14120 			setsockopt(sock->socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv_timeout, sizeof(tv_timeout));
14121 		}
14122 #endif // UNIX_SOLARIS
14123 #endif // OS_UNIX
14124 	}
14125 }
14126 
14127 // Disable GetHostName call by accepting new TCP connection
DisableGetHostNameWhenAcceptInit()14128 void DisableGetHostNameWhenAcceptInit()
14129 {
14130 	disable_gethostname_by_accept = true;
14131 }
14132 
14133 // Initialize the connection acceptance
AcceptInit(SOCK * s)14134 void AcceptInit(SOCK *s)
14135 {
14136 	AcceptInitEx(s, false);
14137 }
AcceptInitEx(SOCK * s,bool no_lookup_hostname)14138 void AcceptInitEx(SOCK *s, bool no_lookup_hostname)
14139 {
14140 	char tmp[MAX_SIZE];
14141 	// Validate arguments
14142 	if (s == NULL)
14143 	{
14144 		return;
14145 	}
14146 
14147 	Zero(tmp, sizeof(tmp));
14148 
14149 	if (disable_gethostname_by_accept == false && no_lookup_hostname == false)
14150 	{
14151 		if (GetHostName(tmp, sizeof(tmp), &s->RemoteIP) == false ||
14152 			IsEmptyStr(tmp))
14153 		{
14154 			IPToStr(tmp, sizeof(tmp), &s->RemoteIP);
14155 		}
14156 	}
14157 	else
14158 	{
14159 		IPToStr(tmp, sizeof(tmp), &s->RemoteIP);
14160 	}
14161 
14162 	if (s->RemoteHostname != NULL)
14163 	{
14164 		Free(s->RemoteHostname);
14165 	}
14166 
14167 	s->RemoteHostname = CopyStr(tmp);
14168 }
14169 
14170 // TCP connection acceptance (IPv4)
Accept(SOCK * sock)14171 SOCK *Accept(SOCK *sock)
14172 {
14173 	SOCK *ret;
14174 	SOCKET s, new_socket;
14175 	int size;
14176 	struct sockaddr_in addr;
14177 	bool true_flag = true;
14178 	// Validate arguments
14179 	if (sock == NULL)
14180 	{
14181 		return NULL;
14182 	}
14183 	if (sock->Type == SOCK_INPROC)
14184 	{
14185 		return AcceptInProc(sock);
14186 	}
14187 	if (sock->Type == SOCK_REVERSE_LISTEN)
14188 	{
14189 		return AcceptReverse(sock);
14190 	}
14191 	if (sock->Type == SOCK_RUDP_LISTEN)
14192 	{
14193 		return AcceptRUDP(sock);
14194 	}
14195 	if (sock->ListenMode == false || sock->Type != SOCK_TCP || sock->ServerMode == false)
14196 	{
14197 		return NULL;
14198 	}
14199 	if (sock->CancelAccept)
14200 	{
14201 		return NULL;
14202 	}
14203 	if (sock->IPv6)
14204 	{
14205 		return Accept6(sock);
14206 	}
14207 
14208 	s = sock->socket;
14209 	if (s == INVALID_SOCKET)
14210 	{
14211 		return NULL;
14212 	}
14213 	Zero(&addr, sizeof(addr));
14214 	size = sizeof(addr);
14215 
14216 #ifdef	OS_UNIX
14217 #if	defined(UNIX_LINUX) || defined(UNIX_MACOS)
14218 	UnixIgnoreSignalForThread(SIGUSR1);
14219 #endif	// defined(UNIX_LINUX) || defined(UNIX_MACOS)
14220 	sock->CallingThread = pthread_self();
14221 #endif	// OS_UNIX
14222 
14223 #ifdef	OS_WIN32
14224 	if (sock->EnableConditionalAccept)
14225 	{
14226 		new_socket = Win32Accept(sock, s, (struct sockaddr *)&addr,(int *)&size, false);
14227 	}
14228 	else
14229 	{
14230 		new_socket = accept(s, (struct sockaddr *)&addr,(int *)&size);
14231 	}
14232 #else	// OS_WIN32
14233 	new_socket = accept(s, (struct sockaddr *)&addr,(int *)&size);
14234 #endif	// OS_WIN32
14235 
14236 #ifdef	OS_UNIX
14237 	sock->CallingThread = 0;
14238 #endif	// OS_UNIX
14239 
14240 	if (new_socket == INVALID_SOCKET)
14241 	{
14242 		if (sock->CancelAccept)
14243 		{
14244 			sock->AcceptCanceled = true;
14245 		}
14246 		return NULL;
14247 	}
14248 	if (sock->CancelAccept)
14249 	{
14250 		sock->AcceptCanceled = true;
14251 		closesocket(new_socket);
14252 		return NULL;
14253 	}
14254 
14255 	ret = NewSock();
14256 	ret->socket = new_socket;
14257 	ret->Connected = true;
14258 	ret->AsyncMode = false;
14259 	ret->Type = SOCK_TCP;
14260 	ret->ServerMode = true;
14261 	ret->SecureMode = false;
14262 
14263 	// Configuring the TCP options
14264 	setsockopt(ret->socket, IPPROTO_TCP, TCP_NODELAY, (char *)&true_flag, sizeof(bool));
14265 
14266 	// Initialization of the time-out value
14267 	SetTimeout(ret, TIMEOUT_INFINITE);
14268 
14269 	// Socket information
14270 	QuerySocketInformation(ret);
14271 
14272 	if (IsLocalHostIP(&ret->RemoteIP) == false)
14273 	{
14274 		ret->IpClientAdded = true;
14275 		AddIpClient(&ret->RemoteIP);
14276 	}
14277 
14278 	if (IsZeroIp(&sock->LocalIP) == false && IsLocalHostIP(&sock->LocalIP) == false)
14279 	{
14280 		IP current_ip;
14281 
14282 		if (GetCurrentGlobalIP(&current_ip, false) == false)
14283 		{
14284 			SetCurrentGlobalIP(&sock->LocalIP, false);
14285 		}
14286 	}
14287 
14288 	StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_NATIVE_V4);
14289 
14290 	AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails), "IPv4");
14291 
14292 	return ret;
14293 }
14294 
14295 // TCP connection acceptance (IPv6)
Accept6(SOCK * sock)14296 SOCK *Accept6(SOCK *sock)
14297 {
14298 	SOCK *ret;
14299 	SOCKET s, new_socket;
14300 	int size;
14301 	struct sockaddr_in6 addr;
14302 	bool true_flag = true;
14303 	// Validate arguments
14304 	if (sock == NULL)
14305 	{
14306 		return NULL;
14307 	}
14308 	if (sock->ListenMode == false || sock->Type != SOCK_TCP || sock->ServerMode == false)
14309 	{
14310 		return NULL;
14311 	}
14312 	if (sock->CancelAccept)
14313 	{
14314 		return NULL;
14315 	}
14316 	if (sock->IPv6 == false)
14317 	{
14318 		return NULL;
14319 	}
14320 
14321 	s = sock->socket;
14322 	if (s == INVALID_SOCKET)
14323 	{
14324 		return NULL;
14325 	}
14326 	Zero(&addr, sizeof(addr));
14327 	size = sizeof(addr);
14328 
14329 #ifdef	OS_UNIX
14330 #if	defined(UNIX_LINUX) || defined(UNIX_MACOS)
14331 	UnixIgnoreSignalForThread(SIGUSR1);
14332 #endif	// defined(UNIX_LINUX) || defined(UNIX_MACOS)
14333 	sock->CallingThread = pthread_self();
14334 #endif	// OS_UNIX
14335 
14336 #ifdef	OS_WIN32
14337 	if (sock->EnableConditionalAccept)
14338 	{
14339 		new_socket = Win32Accept(sock, s, (struct sockaddr *)&addr,(int *)&size, true);
14340 	}
14341 	else
14342 	{
14343 		new_socket = accept(s, (struct sockaddr *)&addr,(int *)&size);
14344 	}
14345 #else	// OS_WIN32
14346 	new_socket = accept(s, (struct sockaddr *)&addr,(int *)&size);
14347 #endif	// OS_WIN32
14348 
14349 #ifdef	OS_UNIX
14350 	sock->CallingThread = 0;
14351 #endif	// OS_UNIX
14352 
14353 	if (new_socket == INVALID_SOCKET)
14354 	{
14355 		if (sock->CancelAccept)
14356 		{
14357 			sock->AcceptCanceled = true;
14358 		}
14359 		return NULL;
14360 	}
14361 	if (sock->CancelAccept)
14362 	{
14363 		sock->AcceptCanceled = true;
14364 		closesocket(new_socket);
14365 		return NULL;
14366 	}
14367 
14368 	ret = NewSock();
14369 	ret->socket = new_socket;
14370 	ret->Connected = true;
14371 	ret->AsyncMode = false;
14372 	ret->Type = SOCK_TCP;
14373 	ret->ServerMode = true;
14374 	ret->SecureMode = false;
14375 
14376 	// Configuring the TCP options
14377 	setsockopt(ret->socket, IPPROTO_TCP, TCP_NODELAY, (char *)&true_flag, sizeof(bool));
14378 
14379 	// Initialize the time-out value
14380 	SetTimeout(ret, TIMEOUT_INFINITE);
14381 
14382 	// Socket information
14383 	QuerySocketInformation(ret);
14384 
14385 	if (IsLocalHostIP(&ret->RemoteIP) == false)
14386 	{
14387 		ret->IpClientAdded = true;
14388 		AddIpClient(&ret->RemoteIP);
14389 	}
14390 	if (IsZeroIp(&sock->LocalIP) == false && IsLocalHostIP(&sock->LocalIP) == false)
14391 	{
14392 		IP current_ip;
14393 
14394 		if (GetCurrentGlobalIP(&current_ip, true) == false)
14395 		{
14396 			SetCurrentGlobalIP(&sock->LocalIP, true);
14397 		}
14398 	}
14399 
14400 	StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_NATIVE_V6);
14401 
14402 	AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails), "IPv6");
14403 
14404 	return ret;
14405 }
14406 
14407 // Standby for TCP (IPv6)
Listen6(UINT port)14408 SOCK *Listen6(UINT port)
14409 {
14410 	return ListenEx6(port, false);
14411 }
ListenEx6(UINT port,bool local_only)14412 SOCK *ListenEx6(UINT port, bool local_only)
14413 {
14414 	return ListenEx62(port, local_only, false);
14415 }
ListenEx62(UINT port,bool local_only,bool enable_ca)14416 SOCK *ListenEx62(UINT port, bool local_only, bool enable_ca)
14417 {
14418 	SOCKET s;
14419 	SOCK *sock;
14420 	struct sockaddr_in6 addr;
14421 	struct in6_addr in;
14422 	bool true_flag = true;
14423 	bool disable_conditional_accept = false;
14424 	IP localhost;
14425 	UINT backlog = SOMAXCONN;
14426 	// Validate arguments
14427 	if (port == 0 || port >= 65536)
14428 	{
14429 		return NULL;
14430 	}
14431 
14432 #ifdef	OS_WIN32
14433 	if (MsIsVista() == false)
14434 	{
14435 		// Disable the Conditional Accept due to a bug in Windows
14436 		enable_ca = false;
14437 	}
14438 #endif	// OS_WIN32
14439 
14440 	// Initialization
14441 	Zero(&addr, sizeof(addr));
14442 	Zero(&in, sizeof(in));
14443 	GetLocalHostIP6(&localhost);
14444 
14445 	addr.sin6_port = htons((UINT)port);
14446 	addr.sin6_family = AF_INET6;
14447 
14448 	if (local_only)
14449 	{
14450 		IPToInAddr6(&addr.sin6_addr, &localhost);
14451 
14452 		enable_ca = false;
14453 	}
14454 
14455 	// Creating a socket
14456 	s = socket(AF_INET6, SOCK_STREAM, 0);
14457 	if (s == INVALID_SOCKET)
14458 	{
14459 		return NULL;
14460 	}
14461 
14462 #ifdef	OS_UNIX
14463 	// It is necessary to set the IPv6 Only flag on a UNIX system
14464 	setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &true_flag, sizeof(true_flag));
14465 #endif	// OS_UNIX
14466 
14467 	//SetSocketSendRecvBufferSize(s, SOCKET_BUFFER_SIZE);
14468 
14469 #ifdef	OS_UNIX
14470 	// This only have enabled for UNIX system since there is a bug
14471 	// in the implementation of REUSEADDR in Windows OS
14472 	setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&true_flag, sizeof(bool));
14473 #endif	// OS_UNIX
14474 
14475 	if (bind(s, (struct sockaddr *)&addr, sizeof(struct sockaddr_in6)) != 0)
14476 	{
14477 		// Bind failure
14478 		closesocket(s);
14479 		return NULL;
14480 	}
14481 
14482 #ifdef	OS_WIN32
14483 	if (enable_ca)
14484 	{
14485 		if (MsIsWinXPOrGreater())
14486 		{
14487 			setsockopt(s, SOL_SOCKET, SO_CONDITIONAL_ACCEPT, (char *)&true_flag, sizeof(bool));
14488 
14489 			backlog = 1;
14490 		}
14491 	}
14492 #endif	// OS_WIN32
14493 
14494 	if (listen(s, backlog))
14495 	{
14496 		// Listen failure
14497 		closesocket(s);
14498 		return NULL;
14499 	}
14500 
14501 	// Success
14502 	sock = NewSock();
14503 	sock->Connected = false;
14504 	sock->AsyncMode = false;
14505 	sock->ServerMode = true;
14506 	sock->Type = SOCK_TCP;
14507 	sock->socket = s;
14508 	sock->ListenMode = true;
14509 	sock->SecureMode = false;
14510 	sock->LocalPort = port;
14511 	sock->IPv6 = true;
14512 	sock->LocalOnly = local_only;
14513 	sock->EnableConditionalAccept = enable_ca;
14514 
14515 	return sock;
14516 }
14517 
14518 // Standby for the TCP
Listen(UINT port)14519 SOCK *Listen(UINT port)
14520 {
14521 	return ListenEx(port, false);
14522 }
ListenEx(UINT port,bool local_only)14523 SOCK *ListenEx(UINT port, bool local_only)
14524 {
14525 	return ListenEx2(port, local_only, false);
14526 }
ListenEx2(UINT port,bool local_only,bool enable_ca)14527 SOCK *ListenEx2(UINT port, bool local_only, bool enable_ca)
14528 {
14529 	SOCKET s;
14530 	SOCK *sock;
14531 	struct sockaddr_in addr;
14532 	struct in_addr in;
14533 	bool true_flag = true;
14534 	IP localhost;
14535 	UINT backlog = SOMAXCONN;
14536 	// Validate arguments
14537 	if (port == 0 || port >= 65536)
14538 	{
14539 		return NULL;
14540 	}
14541 
14542 #ifdef	OS_WIN32
14543 	if (MsIsVista() == false)
14544 	{
14545 		// Disable the Conditional Accept due to a bug in Windows
14546 		enable_ca = false;
14547 	}
14548 #endif	// OS_WIN32
14549 
14550 	// Initialization
14551 	Zero(&addr, sizeof(addr));
14552 	Zero(&in, sizeof(in));
14553 	SetIP(&localhost, 127, 0, 0, 1);
14554 
14555 	addr.sin_port = htons((UINT)port);
14556 	*((UINT *)&addr.sin_addr) = htonl(INADDR_ANY);
14557 	addr.sin_family = AF_INET;
14558 
14559 	if (local_only)
14560 	{
14561 		IPToInAddr(&addr.sin_addr, &localhost);
14562 
14563 		enable_ca = false;
14564 	}
14565 
14566 	// Creating a socket
14567 	s = socket(AF_INET, SOCK_STREAM, 0);
14568 	if (s == INVALID_SOCKET)
14569 	{
14570 		return NULL;
14571 	}
14572 
14573 	//SetSocketSendRecvBufferSize(s, SOCKET_BUFFER_SIZE);
14574 
14575 #ifdef	OS_UNIX
14576 	// This only have enabled for UNIX system since there is a bug
14577 	// in the implementation of REUSEADDR in Windows OS
14578 	setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&true_flag, sizeof(bool));
14579 #endif	// OS_UNIX
14580 
14581 	if (bind(s, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) != 0)
14582 	{
14583 		// Bind failure
14584 		closesocket(s);
14585 		return NULL;
14586 	}
14587 
14588 #ifdef	OS_WIN32
14589 	if (enable_ca)
14590 	{
14591 		if (MsIsWinXPOrGreater())
14592 		{
14593 			setsockopt(s, SOL_SOCKET, SO_CONDITIONAL_ACCEPT, (char *)&true_flag, sizeof(bool));
14594 
14595 			backlog = 1;
14596 		}
14597 	}
14598 #endif	// OS_WIN32
14599 
14600 	if (listen(s, backlog))
14601 	{
14602 		// Listen failure
14603 		closesocket(s);
14604 		return NULL;
14605 	}
14606 
14607 	// Success
14608 	sock = NewSock();
14609 	sock->Connected = false;
14610 	sock->AsyncMode = false;
14611 	sock->ServerMode = true;
14612 	sock->Type = SOCK_TCP;
14613 	sock->socket = s;
14614 	sock->ListenMode = true;
14615 	sock->SecureMode = false;
14616 	sock->LocalPort = port;
14617 	sock->LocalOnly = local_only;
14618 	sock->EnableConditionalAccept = enable_ca;
14619 
14620 	return sock;
14621 }
14622 
14623 // TCP disconnect
Disconnect(SOCK * sock)14624 void Disconnect(SOCK *sock)
14625 {
14626 	SOCKET s;
14627 	bool true_flag = true;
14628 	bool false_flag = false;
14629 	// Validate arguments
14630 	if (sock == NULL)
14631 	{
14632 		return;
14633 	}
14634 
14635 	sock->Disconnecting = true;
14636 
14637 #ifdef	ENABLE_SSL_LOGGING
14638 	SockCloseSslLogging(sock);
14639 #endif	// ENABLE_SSL_LOGGING
14640 
14641 #ifdef	OS_UNIX
14642 	UnixFreeAsyncSocket(sock);
14643 #endif	// UnixFreeAsyncSocket
14644 
14645 	if (sock->Type == SOCK_TCP && sock->ListenMode)
14646 	{
14647 		bool no_tcp_check_port = false;
14648 
14649 		// Connect to localhost if the socket is in listening
14650 		sock->CancelAccept = true;
14651 
14652 #if	defined(UNIX_LINUX) || defined(UNIX_MACOS)
14653 		{
14654 			pthread_t t = sock->CallingThread;
14655 
14656 			// Send a signal to the socket to abort accept() forcibly on Linux
14657 			if (t != 0)
14658 			{
14659 				pthread_kill(t, SIGUSR1);
14660 
14661 				SleepThread(200);
14662 			}
14663 		}
14664 #endif	// defined(UNIX_LINUX) || defined(UNIX_MACOS)
14665 
14666 #ifdef	OS_WIN32
14667 		if (sock->hAcceptEvent != NULL)
14668 		{
14669 			SetEvent(sock->hAcceptEvent);
14670 
14671 			no_tcp_check_port = true;
14672 		}
14673 #endif	// OS_WIN32
14674 
14675 		if (sock->AcceptCanceled == false)
14676 		{
14677 			if (no_tcp_check_port == false)
14678 			{
14679 				if (sock->IPv6 == false)
14680 				{
14681 					CheckTCPPort("127.0.0.1", sock->LocalPort);
14682 				}
14683 				else
14684 				{
14685 					CheckTCPPort("::1", sock->LocalPort);
14686 				}
14687 			}
14688 		}
14689 	}
14690 
14691 	Lock(disconnect_function_lock);
14692 
14693 	Lock(sock->disconnect_lock);
14694 
14695 	if (sock->Type == SOCK_TCP)
14696 	{
14697 		if (sock->socket != INVALID_SOCKET)
14698 		{
14699 			// Forced disconnection flag
14700 			#ifdef	SO_DONTLINGER
14701 				setsockopt(sock->socket, SOL_SOCKET, SO_DONTLINGER, (char *)&true_flag, sizeof(bool));
14702 			#else	// SO_DONTLINGER
14703 				setsockopt(sock->socket, SOL_SOCKET, SO_LINGER, (char *)&false_flag, sizeof(bool));
14704 			#endif	// SO_DONTLINGER
14705 //			setsockopt(sock->socket, SOL_SOCKET, SO_REUSEADDR, (char *)&true_flag, sizeof(bool));
14706 		}
14707 
14708 		// TCP socket
14709 		Lock(sock->lock);
14710 		{
14711 			if (sock->socket == INVALID_SOCKET)
14712 			{
14713 				Unlock(sock->lock);
14714 				Unlock(sock->disconnect_lock);
14715 				Unlock(disconnect_function_lock);
14716 				return;
14717 			}
14718 			s = sock->socket;
14719 
14720 			if (sock->Connected)
14721 			{
14722 				struct linger ling;
14723 				Zero(&ling, sizeof(ling));
14724 
14725 
14726 #if	0
14727 				// SSL disconnect
14728 				Lock(sock->ssl_lock);
14729 				{
14730 					if (sock->SecureMode)
14731 					{
14732 						SSL_shutdown(sock->ssl);
14733 					}
14734 				}
14735 				Unlock(sock->ssl_lock);
14736 #endif
14737 				// Disconnect
14738 				shutdown(s, 2);
14739 			}
14740 
14741 			// Close the socket
14742 			closesocket(s);
14743 
14744 #ifdef	OS_UNIX
14745 #ifdef	FIX_SSL_BLOCKING
14746 			if (sock->CallingThread != NULL)
14747 			{
14748 				pthread_kill(sock->CallingThread, 64);
14749 			}
14750 #endif	// FIX_SSL_BLOCKING
14751 #endif	// OS_UNIX
14752 
14753 			// Release the SSL
14754 			Lock(sock->ssl_lock);
14755 			{
14756 				if (sock->SecureMode)
14757 				{
14758 					if (sock->ssl != NULL)
14759 					{
14760 						Lock(openssl_lock);
14761 						{
14762 							SSL_free(sock->ssl);
14763 							FreeSSLCtx(sock->ssl_ctx);
14764 						}
14765 						Unlock(openssl_lock);
14766 						sock->ssl = NULL;
14767 						sock->ssl_ctx = NULL;
14768 					}
14769 					sock->Connected = false;
14770 					sock->SecureMode = false;
14771 				}
14772 			}
14773 			Unlock(sock->ssl_lock);
14774 
14775 			// Initialization
14776 			sock->socket = INVALID_SOCKET;
14777 			sock->Type = 0;
14778 			sock->AsyncMode = false;
14779 			sock->Connected = false;
14780 			sock->ListenMode = false;
14781 			sock->SecureMode = false;
14782 
14783 			if (sock->IpClientAdded)
14784 			{
14785 				DelIpClient(&sock->RemoteIP);
14786 				sock->IpClientAdded = false;
14787 			}
14788 		}
14789 		Unlock(sock->lock);
14790 
14791 		if (sock->BulkSendTube != NULL)
14792 		{
14793 			TubeDisconnect(sock->BulkSendTube);
14794 		}
14795 
14796 		if (sock->BulkRecvTube != NULL)
14797 		{
14798 			TubeDisconnect(sock->BulkRecvTube);
14799 		}
14800 	}
14801 	else if (sock->Type == SOCK_UDP)
14802 	{
14803 		// UDP socket
14804 		Lock(sock->lock);
14805 		{
14806 			if (sock->socket == INVALID_SOCKET)
14807 			{
14808 				Unlock(sock->lock);
14809 				Unlock(sock->disconnect_lock);
14810 				Unlock(disconnect_function_lock);
14811 				return;
14812 			}
14813 
14814 			s = sock->socket;
14815 
14816 			// Close the socket
14817 			closesocket(s);
14818 
14819 			// Initialization
14820 			sock->socket = INVALID_SOCKET;
14821 			sock->Type = 0;
14822 			sock->AsyncMode = false;
14823 			sock->Connected = false;
14824 			sock->ListenMode = false;
14825 			sock->SecureMode = false;
14826 		}
14827 		Unlock(sock->lock);
14828 	}
14829 	else if (sock->Type == SOCK_INPROC)
14830 	{
14831 		// In-process socket
14832 		if (sock->ListenMode)
14833 		{
14834 			// Stop the Accept process
14835 			sock->CancelAccept = true;
14836 
14837 			Set(sock->InProcAcceptEvent);
14838 
14839 			LockQueue(sock->InProcAcceptQueue);
14840 			{
14841 				while (true)
14842 				{
14843 					SOCK *ss = GetNext(sock->InProcAcceptQueue);
14844 					if (ss == NULL)
14845 					{
14846 						break;
14847 					}
14848 
14849 					Disconnect(ss);
14850 					ReleaseSock(ss);
14851 				}
14852 			}
14853 			UnlockQueue(sock->InProcAcceptQueue);
14854 		}
14855 		else
14856 		{
14857 			// Disconnect the Tube
14858 			TubeDisconnect(sock->SendTube);
14859 			TubeDisconnect(sock->RecvTube);
14860 
14861 			sock->socket = INVALID_SOCKET;
14862 			sock->AsyncMode = false;
14863 			sock->Connected = false;
14864 			sock->ListenMode = false;
14865 			sock->SecureMode = false;
14866 		}
14867 	}
14868 	else if (sock->Type == SOCK_RUDP_LISTEN)
14869 	{
14870 		// RUDP Listen socket
14871 		if (sock->ListenMode)
14872 		{
14873 			// Stop the Accept process
14874 			sock->CancelAccept = true;
14875 
14876 			Set(sock->R_UDP_Stack->NewSockConnectEvent);
14877 
14878 			sock->R_UDP_Stack->Halt = true;
14879 			Set(sock->R_UDP_Stack->HaltEvent);
14880 			SetSockEvent(sock->R_UDP_Stack->SockEvent);
14881 		}
14882 	}
14883 	else if (sock->Type == SOCK_REVERSE_LISTEN)
14884 	{
14885 		// Reverse Listen socket
14886 		if (sock->ListenMode)
14887 		{
14888 			// Stop the Accept process
14889 			sock->CancelAccept = true;
14890 
14891 			Set(sock->ReverseAcceptEvent);
14892 
14893 			LockQueue(sock->ReverseAcceptQueue);
14894 			{
14895 				while (true)
14896 				{
14897 					SOCK *ss = GetNext(sock->ReverseAcceptQueue);
14898 					if (ss == NULL)
14899 					{
14900 						break;
14901 					}
14902 
14903 					Disconnect(ss);
14904 					ReleaseSock(ss);
14905 				}
14906 			}
14907 			UnlockQueue(sock->ReverseAcceptQueue);
14908 		}
14909 	}
14910 	Unlock(sock->disconnect_lock);
14911 
14912 	Unlock(disconnect_function_lock);
14913 }
14914 
14915 typedef struct TCP_PORT_CHECK
14916 {
14917 	REF *ref;
14918 	char hostname[MAX_SIZE];
14919 	UINT port;
14920 	bool ok;
14921 } TCP_PORT_CHECK;
14922 
14923 // The thread to check the TCP port
CheckTCPPortThread(THREAD * thread,void * param)14924 void CheckTCPPortThread(THREAD *thread, void *param)
14925 {
14926 	TCP_PORT_CHECK *c;
14927 	SOCK *s;
14928 	// Validate arguments
14929 	if (thread == NULL || param == NULL)
14930 	{
14931 		return;
14932 	}
14933 
14934 	c = (TCP_PORT_CHECK *)param;
14935 	AddRef(c->ref);
14936 	NoticeThreadInit(thread);
14937 
14938 	AddWaitThread(thread);
14939 
14940 	s = Connect(c->hostname, c->port);
14941 	if (s != NULL)
14942 	{
14943 		c->ok = true;
14944 		Disconnect(s);
14945 		ReleaseSock(s);
14946 	}
14947 
14948 	if (Release(c->ref) == 0)
14949 	{
14950 		Free(c);
14951 	}
14952 
14953 	DelWaitThread(thread);
14954 }
14955 
14956 // Check whether the TCP port can be connected
CheckTCPPortEx(char * hostname,UINT port,UINT timeout)14957 bool CheckTCPPortEx(char *hostname, UINT port, UINT timeout)
14958 {
14959 	SOCK *s;
14960 	// Validate arguments
14961 	if (hostname == NULL || port == 0 || port >= 65536)
14962 	{
14963 		return false;
14964 	}
14965 
14966 	if (timeout == 0)
14967 	{
14968 		timeout = TIMEOUT_TCP_PORT_CHECK;
14969 	}
14970 
14971 	s = ConnectEx(hostname, port, timeout);
14972 	if (s == NULL)
14973 	{
14974 		return false;
14975 	}
14976 	else
14977 	{
14978 		Disconnect(s);
14979 		ReleaseSock(s);
14980 		return true;
14981 	}
14982 }
CheckTCPPort(char * hostname,UINT port)14983 bool CheckTCPPort(char *hostname, UINT port)
14984 {
14985 	return CheckTCPPortEx(hostname, port, TIMEOUT_TCP_PORT_CHECK);
14986 }
14987 
14988 #ifdef	OS_UNIX
14989 // Connection with timeout (UNIX version)
connect_timeout(SOCKET s,struct sockaddr * addr,int size,int timeout,bool * cancel_flag)14990 int connect_timeout(SOCKET s, struct sockaddr *addr, int size, int timeout, bool *cancel_flag)
14991 {
14992 	SOCKSET set;
14993 	bool ok = false;
14994 	UINT64 start_time;
14995 	// Validate arguments
14996 	if (s == INVALID_SOCKET || addr == NULL)
14997 	{
14998 		return -1;
14999 	}
15000 	if (timeout == 0)
15001 	{
15002 		timeout = TIMEOUT_TCP_PORT_CHECK;
15003 	}
15004 
15005 	UnixSetSocketNonBlockingMode(s, true);
15006 
15007 	start_time = Tick64();
15008 
15009 	while (true)
15010 	{
15011 		int ret;
15012 		ret = connect(s, addr, size);
15013 		if (ret == 0 || errno == EISCONN)
15014 		{
15015 			ok = true;
15016 			break;
15017 		}
15018 		else
15019 		{
15020 			if (((start_time + (UINT64)timeout) <= Tick64()) || (errno != EAGAIN && errno != EINPROGRESS && errno != EALREADY))
15021 			{
15022 				// Failure
15023 				break;
15024 			}
15025 			else if (*cancel_flag)
15026 			{
15027 				// Cancel
15028 				break;
15029 			}
15030 			else
15031 			{
15032 				// Connecting
15033 				SleepThread(50);
15034 				UnixSelectInner(1, (UINT *)&s, 1, (UINT *)&s, 100);
15035 			}
15036 		}
15037 	}
15038 
15039 	UnixSetSocketNonBlockingMode(s, false);
15040 
15041 	if (ok)
15042 	{
15043 		return 0;
15044 	}
15045 	else
15046 	{
15047 		return -1;
15048 	}
15049 }
15050 #else
15051 // Connection with timeout (Win32 version)
connect_timeout(SOCKET s,struct sockaddr * addr,int size,int timeout,bool * cancel_flag)15052 int connect_timeout(SOCKET s, struct sockaddr *addr, int size, int timeout, bool *cancel_flag)
15053 {
15054 	UINT64 start_time;
15055 	bool ok = false;
15056 	bool timeouted = false;
15057 	WSAEVENT hEvent;
15058 	UINT zero = 0;
15059 	UINT tmp = 0;
15060 	UINT ret_size = 0;
15061 	bool is_nt = false;
15062 	// Validate arguments
15063 	if (s == INVALID_SOCKET || addr == NULL)
15064 	{
15065 		return -1;
15066 	}
15067 	if (timeout == 0)
15068 	{
15069 		timeout = TIMEOUT_TCP_PORT_CHECK;
15070 	}
15071 
15072 	is_nt = OS_IS_WINDOWS_NT(GetOsInfo()->OsType);
15073 
15074 	// Create an event
15075 	hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
15076 
15077 	// Associate the socket with the event
15078 	WSAEventSelect(s, hEvent, FD_CONNECT);
15079 
15080 	start_time = Tick64();
15081 
15082 	while (true)
15083 	{
15084 		int ret;
15085 
15086 		ret = connect(s, addr, size);
15087 
15088 		if (ret == 0)
15089 		{
15090 			ok = true;
15091 			break;
15092 		}
15093 		else
15094 		{
15095 			int err = WSAGetLastError();
15096 			//Debug("err=%u\n", err);
15097 			//Debug("cancel_flag=%u\n", *cancel_flag);
15098 			if (timeouted && ((err == WSAEALREADY) || (err == WSAEWOULDBLOCK && !is_nt)))
15099 			{
15100 				// Time-out
15101 				ok = false;
15102 				break;
15103 			}
15104 			if (*cancel_flag)
15105 			{
15106 				// Cancel
15107 				ok = false;
15108 				break;
15109 			}
15110 			if (err == WSAEISCONN || (err == WSAEINVAL && is_nt))
15111 			{
15112 				ok = true;
15113 				break;
15114 			}
15115 			if (((start_time + (UINT64)timeout) <= Tick64()) || (err != WSAEWOULDBLOCK && err != WSAEALREADY && (is_nt || err != WSAEINVAL)))
15116 			{
15117 				// Failure (timeout)
15118 				break;
15119 			}
15120 			else
15121 			{
15122 				SleepThread(10);
15123 				// Connecting
15124 				if (WaitForSingleObject(hEvent, 100) == WAIT_OBJECT_0)
15125 				{
15126 					timeouted = true;
15127 				}
15128 			}
15129 		}
15130 	}
15131 
15132 	// Remove the socket from the event
15133 	WSAEventSelect(s, hEvent, 0);
15134 
15135 	// Restore to synchronized socket
15136 	WSAIoctl(s, FIONBIO, &zero, sizeof(zero), &tmp, sizeof(tmp), &ret_size, NULL, NULL);
15137 
15138 	// Close the event
15139 	CloseHandle(hEvent);
15140 
15141 	if (ok)
15142 	{
15143 		return 0;
15144 	}
15145 	else
15146 	{
15147 		return -1;
15148 	}
15149 }
15150 #endif	// OS_UNIX
15151 
15152 // Set the TOS value of the socket
SetSockTos(SOCK * s,int tos)15153 void SetSockTos(SOCK *s, int tos)
15154 {
15155 	// Validate arguments
15156 	if (s == NULL)
15157 	{
15158 		return;
15159 	}
15160 
15161 	if (s->CurrentTos == tos)
15162 	{
15163 		return;
15164 	}
15165 
15166 #ifdef	IP_TOS
15167 	setsockopt(s->socket, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int));
15168 #endif	// IP_TOS
15169 
15170 	s->CurrentTos = tos;
15171 }
15172 
15173 // Set the priority of the socket
SetSockHighPriority(SOCK * s,bool flag)15174 void SetSockHighPriority(SOCK *s, bool flag)
15175 {
15176 	// Validate arguments
15177 	if (s == NULL)
15178 	{
15179 		return;
15180 	}
15181 
15182 	SetSockTos(s, (flag ? 16 : 0));
15183 }
15184 
15185 // Connect to the IPv4 host using a socket
ConnectTimeoutIPv4(IP * ip,UINT port,UINT timeout,bool * cancel_flag)15186 SOCKET ConnectTimeoutIPv4(IP *ip, UINT port, UINT timeout, bool *cancel_flag)
15187 {
15188 	SOCKET s;
15189 	struct sockaddr_in sockaddr4;
15190 	struct in_addr addr4;
15191 
15192 	Zero(&sockaddr4, sizeof(sockaddr4));
15193 	Zero(&addr4, sizeof(addr4));
15194 
15195 	// Generate a sockaddr_in
15196 	IPToInAddr(&addr4, ip);
15197 	sockaddr4.sin_port = htons((USHORT)port);
15198 	sockaddr4.sin_family = AF_INET;
15199 	sockaddr4.sin_addr.s_addr = addr4.s_addr;
15200 
15201 	// Socket creation
15202 	s = socket(AF_INET, SOCK_STREAM, 0);
15203 	if (s != INVALID_SOCKET)
15204 	{
15205 		// Connection
15206 		if (connect_timeout(s, (struct sockaddr *)&sockaddr4, sizeof(struct sockaddr_in), timeout, cancel_flag) != 0)
15207 		{
15208 			// Connection failure
15209 			closesocket(s);
15210 			s = INVALID_SOCKET;
15211 		}
15212 	}
15213 
15214 	return s;
15215 }
15216 
15217 // Identify whether the HTTPS server to be connected is a SoftEther VPN
DetectIsServerSoftEtherVPN(SOCK * s)15218 bool DetectIsServerSoftEtherVPN(SOCK *s)
15219 {
15220 	HTTP_HEADER *h;
15221 	char ip_str[MAX_SIZE];
15222 	char *send_str;
15223 	UINT content_len;
15224 	BUF *recv_buf;
15225 	void *socket_buffer;
15226 	UINT socket_buffer_size = 32768;
15227 	bool ok = false;
15228 	// Validate arguments
15229 	if (s == NULL)
15230 	{
15231 		return false;
15232 	}
15233 
15234 	IPToStr(ip_str, sizeof(ip_str), &s->RemoteIP);
15235 
15236 	// Request generation
15237 	h = NewHttpHeaderEx("GET", "/", "HTTP/1.1", true);
15238 	AddHttpValue(h, NewHttpValue("X-VPN", "1"));
15239 	AddHttpValue(h, NewHttpValue("Host", ip_str));
15240 	AddHttpValue(h, NewHttpValue("Keep-Alive", HTTP_KEEP_ALIVE));
15241 	AddHttpValue(h, NewHttpValue("Connection", "Keep-Alive"));
15242 	AddHttpValue(h, NewHttpValue("Accept-Language", "ja"));
15243 	AddHttpValue(h, NewHttpValue("User-Agent", DEFAULT_USER_AGENT));
15244 	AddHttpValue(h, NewHttpValue("Pragma", "no-cache"));
15245 	AddHttpValue(h, NewHttpValue("Cache-Control", "no-cache"));
15246 
15247 
15248 
15249 	send_str = HttpHeaderToStr(h);
15250 	FreeHttpHeader(h);
15251 
15252 	// Transmission
15253 	if (SendAll(s, send_str, StrLen(send_str), true) == false)
15254 	{
15255 		Free(send_str);
15256 		return false;
15257 	}
15258 
15259 	Free(send_str);
15260 
15261 	// Receive
15262 	h = RecvHttpHeader(s);
15263 	if (h == NULL)
15264 	{
15265 		return false;
15266 	}
15267 
15268 	// Get the length of the content
15269 	content_len = GetContentLength(h);
15270 	FreeHttpHeader(h);
15271 
15272 	if (content_len == 0 || content_len >= (1024 * 1024))
15273 	{
15274 		return false;
15275 	}
15276 
15277 	// Receive contents
15278 	recv_buf = NewBuf();
15279 	socket_buffer = Malloc(socket_buffer_size);
15280 
15281 	while (true)
15282 	{
15283 		UINT recvsize = MIN(socket_buffer_size, content_len - recv_buf->Size);
15284 		UINT size;
15285 
15286 		if (recvsize == 0)
15287 		{
15288 			ok = true;
15289 			break;
15290 		}
15291 
15292 		size = Recv(s, socket_buffer, recvsize, true);
15293 		if (size == 0)
15294 		{
15295 			// Disconnected
15296 			break;
15297 		}
15298 
15299 		WriteBuf(recv_buf, socket_buffer, size);
15300 	}
15301 
15302 	SeekBuf(recv_buf, 0, 0);
15303 	Free(socket_buffer);
15304 
15305 	if (ok)
15306 	{
15307 		// Examine to confirm whether the incoming data is a SoftEther VPN protocol
15308 		char tmp[1024];
15309 
15310 		Zero(tmp, sizeof(tmp));
15311 
15312 		Copy(tmp, recv_buf->Buf, MIN(recv_buf->Size, (sizeof(tmp) - 1)));
15313 
15314 		ok = false;
15315 
15316 		if (StartWith(tmp, http_detect_server_startwith))
15317 		{
15318 			ok = true;
15319 		}
15320 		else if (InStr(tmp, http_detect_server_tag_future))
15321 		{
15322 			ok = true;
15323 		}
15324 	}
15325 
15326 	FreeBuf(recv_buf);
15327 
15328 	return ok;
15329 }
15330 
15331 // TCP connection thread
ConnectThreadForTcp(THREAD * thread,void * param)15332 void ConnectThreadForTcp(THREAD *thread, void *param)
15333 {
15334 	SOCK *sock;
15335 	char hostname[MAX_SIZE];
15336 	CONNECT_TCP_RUDP_PARAM *p = (CONNECT_TCP_RUDP_PARAM *)param;
15337 	if (thread == NULL || p == NULL)
15338 	{
15339 		return;
15340 	}
15341 
15342 	// Delay
15343 	if (p->Delay >= 1)
15344 	{
15345 		WaitEx(NULL, p->Delay, p->CancelFlag);
15346 	}
15347 
15348 	// Connecting process
15349 	IPToStr(hostname, sizeof(hostname), &p->Ip);
15350 	sock = ConnectEx3(hostname, p->Port, p->Timeout, p->CancelFlag, NULL, NULL, false, false, true);
15351 
15352 	if (sock != NULL && p->Tcp_TryStartSsl)
15353 	{
15354 		bool ssl_ret = false;
15355 
15356 		p->Tcp_InNegotiation = true;
15357 
15358 		// Attempt the SSL negotiation to take this opportunity
15359 		Lock(p->CancelLock);
15360 		{
15361 			if ((*p->CancelFlag) == false)
15362 			{
15363 				p->CancelDisconnectSock = sock;
15364 				AddRef(sock->ref);
15365 			}
15366 			else
15367 			{
15368 				Debug("User Cancel to StartSSL.\n");
15369 				goto LABEL_CANCEL;
15370 			}
15371 		}
15372 		Unlock(p->CancelLock);
15373 
15374 		// Start the SSL communication
15375 		ssl_ret = StartSSLEx(sock, NULL, NULL, p->Tcp_SslNoTls, 0, p->Hostname);
15376 
15377 		if (ssl_ret)
15378 		{
15379 			// Identify whether the HTTPS server to be connected is a SoftEther VPN
15380 			SetTimeout(sock, (10 * 1000));
15381 			ssl_ret = DetectIsServerSoftEtherVPN(sock);
15382 			SetTimeout(sock, INFINITE);
15383 
15384 			if (ssl_ret == false)
15385 			{
15386 				Debug("DetectIsServerSoftEtherVPN Error.\n");
15387 			}
15388 		}
15389 
15390 		Lock(p->CancelLock);
15391 		{
15392 			ReleaseSock(p->CancelDisconnectSock);
15393 			p->CancelDisconnectSock = NULL;
15394 LABEL_CANCEL:
15395 			DoNothing();
15396 		}
15397 		Unlock(p->CancelLock);
15398 
15399 		if (ssl_ret == false)
15400 		{
15401 			// SSL negotiation failure
15402 			Disconnect(sock);
15403 			ReleaseSock(sock);
15404 
15405 			Debug("Fail to StartSSL.\n");
15406 
15407 			sock = NULL;
15408 		}
15409 	}
15410 
15411 	p->Result_Tcp_Sock = sock;
15412 	p->Ok = (p->Result_Tcp_Sock == NULL ? false : true);
15413 	p->FinishedTick = Tick64();
15414 	p->Finished = true;
15415 	p->Tcp_InNegotiation = false;
15416 
15417 	Set(p->FinishEvent);
15418 }
15419 
15420 // R-UDP over ICMP / over DNS connection thread
ConnectThreadForOverDnsOrIcmp(THREAD * thread,void * param)15421 void ConnectThreadForOverDnsOrIcmp(THREAD *thread, void *param)
15422 {
15423 	SOCK *sock;
15424 	CONNECT_TCP_RUDP_PARAM *p = (CONNECT_TCP_RUDP_PARAM *)param;
15425 	if (thread == NULL || p == NULL)
15426 	{
15427 		return;
15428 	}
15429 
15430 	// Delay
15431 	if (p->Delay >= 1)
15432 	{
15433 		WaitEx(NULL, p->Delay, p->CancelFlag);
15434 	}
15435 
15436 	// Connecting process
15437 	sock = NewRUDPClientDirect(p->SvcName, &p->Ip,
15438 		(p->RUdpProtocol == RUDP_PROTOCOL_DNS ? 53 : MAKE_SPECIAL_PORT(IP_PROTO_ICMPV4)),
15439 		&p->NatT_ErrorCode, p->Timeout, p->CancelFlag, NULL, NULL,
15440 		(p->RUdpProtocol == RUDP_PROTOCOL_DNS ? 0 : MAKE_SPECIAL_PORT(IP_PROTO_ICMPV4)),
15441 		(p->RUdpProtocol == RUDP_PROTOCOL_DNS ? true : false));
15442 
15443 	p->Result_Nat_T_Sock = sock;
15444 	p->Ok = (p->Result_Nat_T_Sock == NULL ? false : true);
15445 	p->FinishedTick = Tick64();
15446 	p->Finished = true;
15447 
15448 	Set(p->FinishEvent);
15449 }
15450 
15451 // R-UDP (via NAT-T) connection thread
ConnectThreadForRUDP(THREAD * thread,void * param)15452 void ConnectThreadForRUDP(THREAD *thread, void *param)
15453 {
15454 	SOCK *sock;
15455 	CONNECT_TCP_RUDP_PARAM *p = (CONNECT_TCP_RUDP_PARAM *)param;
15456 	if (thread == NULL || p == NULL)
15457 	{
15458 		return;
15459 	}
15460 
15461 	// Delay
15462 	if (p->Delay >= 1)
15463 	{
15464 		WaitEx(NULL, p->Delay, p->CancelFlag);
15465 	}
15466 
15467 	// Connecting process
15468 	sock = NewRUDPClientNatT(p->SvcName, &p->Ip, &p->NatT_ErrorCode, p->Timeout, p->CancelFlag, p->HintStr, p->TargetHostname);
15469 
15470 	p->Result_Nat_T_Sock = sock;
15471 	p->Ok = (p->Result_Nat_T_Sock == NULL ? false : true);
15472 	p->FinishedTick = Tick64();
15473 	p->Finished = true;
15474 
15475 	Set(p->FinishEvent);
15476 }
15477 
15478 // TCP connection
Connect(char * hostname,UINT port)15479 SOCK *Connect(char *hostname, UINT port)
15480 {
15481 	return ConnectEx(hostname, port, 0);
15482 }
ConnectEx(char * hostname,UINT port,UINT timeout)15483 SOCK *ConnectEx(char *hostname, UINT port, UINT timeout)
15484 {
15485 	return ConnectEx2(hostname, port, timeout, NULL);
15486 }
ConnectEx2(char * hostname,UINT port,UINT timeout,bool * cancel_flag)15487 SOCK *ConnectEx2(char *hostname, UINT port, UINT timeout, bool *cancel_flag)
15488 {
15489 	return ConnectEx3(hostname, port, timeout, cancel_flag, NULL, NULL, false, false, true);
15490 }
ConnectEx3(char * hostname,UINT port,UINT timeout,bool * cancel_flag,char * nat_t_svc_name,UINT * nat_t_error_code,bool try_start_ssl,bool ssl_no_tls,bool no_get_hostname)15491 SOCK *ConnectEx3(char *hostname, UINT port, UINT timeout, bool *cancel_flag, char *nat_t_svc_name, UINT *nat_t_error_code, bool try_start_ssl, bool ssl_no_tls, bool no_get_hostname)
15492 {
15493 	return ConnectEx4(hostname, port, timeout, cancel_flag, nat_t_svc_name, nat_t_error_code, try_start_ssl, ssl_no_tls,
15494 		no_get_hostname, NULL);
15495 }
ConnectEx4(char * hostname,UINT port,UINT timeout,bool * cancel_flag,char * nat_t_svc_name,UINT * nat_t_error_code,bool try_start_ssl,bool ssl_no_tls,bool no_get_hostname,IP * ret_ip)15496 SOCK *ConnectEx4(char *hostname, UINT port, UINT timeout, bool *cancel_flag, char *nat_t_svc_name, UINT *nat_t_error_code, bool try_start_ssl, bool ssl_no_tls, bool no_get_hostname, IP *ret_ip)
15497 {
15498 	SOCK *sock;
15499 	SOCKET s;
15500 	struct linger ling;
15501 	IP ip4;
15502 	IP ip6;
15503 	bool true_flag = true;
15504 	bool false_flag = false;
15505 	char tmp[MAX_SIZE];
15506 	IP current_ip;
15507 	bool is_ipv6 = false;
15508 	bool dummy = false;
15509 	bool use_natt = false;
15510 	char hostname_original[MAX_SIZE];
15511 	char hint_str[MAX_SIZE];
15512 	bool force_use_natt = false;
15513 	UINT dummy_int = 0;
15514 	IP dummy_ret_ip;
15515 	// Validate arguments
15516 	if (hostname == NULL || port == 0 || port >= 65536 || IsEmptyStr(hostname))
15517 	{
15518 		return NULL;
15519 	}
15520 	if (timeout == 0)
15521 	{
15522 		timeout = TIMEOUT_TCP_PORT_CHECK;
15523 	}
15524 	if (cancel_flag == NULL)
15525 	{
15526 		cancel_flag = &dummy;
15527 	}
15528 	if (nat_t_error_code == NULL)
15529 	{
15530 		nat_t_error_code = &dummy_int;
15531 	}
15532 
15533 	Zero(&dummy_ret_ip, sizeof(IP));
15534 	if (ret_ip == NULL)
15535 	{
15536 		ret_ip = &dummy_ret_ip;
15537 	}
15538 
15539 	Zero(hint_str, sizeof(hint_str));
15540 	StrCpy(hostname_original, sizeof(hostname_original), hostname);
15541 
15542 	use_natt = (IsEmptyStr(nat_t_svc_name) ? false : true);
15543 
15544 	if (use_natt)
15545 	{
15546 		// In case of using NAT-T, split host name if the '/' is included in the host name
15547 		UINT i = SearchStrEx(hostname, "/", 0, false);
15548 
15549 		if (i == INFINITE)
15550 		{
15551 			// Not included
15552 			StrCpy(hostname_original, sizeof(hostname_original), hostname);
15553 		}
15554 		else
15555 		{
15556 			// Included
15557 			StrCpy(hostname_original, sizeof(hostname_original), hostname);
15558 			hostname_original[i] = 0;
15559 
15560 			// Force to use the NAT-T
15561 			force_use_natt = true;
15562 
15563 			// Copy the hint string
15564 			StrCpy(hint_str, sizeof(hint_str), hostname + i + 1);
15565 
15566 			if (StrCmpi(hint_str, "tcp") == 0 || StrCmpi(hint_str, "disable") == 0
15567 				|| StrCmpi(hint_str, "disabled") == 0
15568 				|| StrCmpi(hint_str, "no") == 0 || StrCmpi(hint_str, "none") == 0)
15569 			{
15570 				// Force not to use the NAT-T
15571 				force_use_natt = false;
15572 				use_natt = false;
15573 			}
15574 		}
15575 	}
15576 	else
15577 	{
15578 		StrCpy(hostname_original, sizeof(hostname_original), hostname);
15579 	}
15580 
15581 	Zero(&current_ip, sizeof(current_ip));
15582 
15583 	Zero(&ip4, sizeof(ip4));
15584 	Zero(&ip6, sizeof(ip6));
15585 
15586 	if (IsZeroIp(ret_ip) == false)
15587 	{
15588 		// Skip name resolution
15589 		if (IsIP6(ret_ip))
15590 		{
15591 			Copy(&ip6, ret_ip, sizeof(IP));
15592 		}
15593 		else
15594 		{
15595 			Copy(&ip4, ret_ip, sizeof(IP));
15596 		}
15597 
15598 		//Debug("Using cached IP address: %s = %r\n", hostname_original, ret_ip);
15599 	}
15600 	else
15601 	{
15602 		// Forward resolution
15603 		if (GetIP46Ex(&ip4, &ip6, hostname_original, 0, cancel_flag) == false)
15604 		{
15605 			return NULL;
15606 		}
15607 	}
15608 
15609 	if (IsZeroIp(&ip4) == false && IsIPLocalHostOrMySelf(&ip4))
15610 	{
15611 		// NAT-T isn't used in the case of connection to localhost
15612 		force_use_natt = false;
15613 		use_natt = false;
15614 	}
15615 
15616 	s = INVALID_SOCKET;
15617 
15618 	// Attempt to connect with IPv4
15619 	if (IsZeroIp(&ip4) == false)
15620 	{
15621 		if (use_natt == false)
15622 		{
15623 			// Normal connection without using NAT-T
15624 			s = ConnectTimeoutIPv4(&ip4, port, timeout, cancel_flag);
15625 
15626 			if (s != INVALID_SOCKET)
15627 			{
15628 				Copy(&current_ip, &ip4, sizeof(IP));
15629 
15630 				Copy(ret_ip, &ip4, sizeof(IP));
15631 			}
15632 		}
15633 		else if (force_use_natt)
15634 		{
15635 			// The connection by forcing the use of NAT-T (not to connection with normal TCP)
15636 			SOCK *nat_t_sock = NewRUDPClientNatT(nat_t_svc_name, &ip4, nat_t_error_code, timeout, cancel_flag,
15637 				hint_str, hostname);
15638 
15639 			if (nat_t_sock != NULL)
15640 			{
15641 				StrCpy(nat_t_sock->UnderlayProtocol, sizeof(nat_t_sock->UnderlayProtocol), SOCK_UNDERLAY_NAT_T);
15642 				AddProtocolDetailsStr(nat_t_sock->ProtocolDetails, sizeof(nat_t_sock->ProtocolDetails),
15643 					"RUDP");
15644 			}
15645 
15646 			Copy(ret_ip, &ip4, sizeof(IP));
15647 
15648 			return nat_t_sock;
15649 		}
15650 		else
15651 		{
15652 			// Use the connections using NAT-T with normal TCP connection together
15653 			// (Use multiple threads to try to connect in four connection methods concurrently)
15654 			CONNECT_TCP_RUDP_PARAM p1, p2, p3, p4;
15655 			EVENT *finish_event;
15656 			THREAD *t1, *t2, *t3, *t4;
15657 			UINT64 start_tick = Tick64();
15658 			UINT64 giveup_for_all_tick = start_tick + (UINT64)SOCK_CONNECT_WAIT_FOR_ICMP_AND_DNS_AT_LEAST;
15659 			bool cancel_flag2 = false;
15660 			SOCK *cancel_sock = NULL;
15661 
15662 			finish_event = NewEvent();
15663 
15664 			Zero(&p1, sizeof(p1));
15665 			Zero(&p2, sizeof(p2));
15666 			Zero(&p3, sizeof(p3));
15667 			Zero(&p4, sizeof(p4));
15668 
15669 			// p1: TCP
15670 			StrCpy(p1.Hostname, sizeof(p1.Hostname), hostname_original);
15671 			Copy(&p1.Ip, &ip4, sizeof(IP));
15672 			p1.Port = port;
15673 			p1.Timeout = timeout;
15674 			p1.CancelFlag = &cancel_flag2;
15675 			p1.FinishEvent = finish_event;
15676 			p1.Tcp_TryStartSsl = try_start_ssl;
15677 			p1.Tcp_SslNoTls = ssl_no_tls;
15678 			p1.CancelLock = NewLock();
15679 
15680 			// p2: NAT-T
15681 			StrCpy(p2.Hostname, sizeof(p2.Hostname), hostname_original);
15682 			Copy(&p2.Ip, &ip4, sizeof(IP));
15683 			p2.Port = port;
15684 			p2.Timeout = timeout;
15685 			p2.CancelFlag = &cancel_flag2;
15686 			p2.FinishEvent = finish_event;
15687 
15688 			StrCpy(p2.HintStr, sizeof(p2.HintStr), hint_str);
15689 			StrCpy(p2.TargetHostname, sizeof(p2.TargetHostname), hostname);
15690 			StrCpy(p2.SvcName, sizeof(p2.SvcName), nat_t_svc_name);
15691 			p2.Delay = 30;		// Delay by 30ms
15692 
15693 			// p3: over ICMP
15694 			StrCpy(p3.Hostname, sizeof(p3.Hostname), hostname_original);
15695 			Copy(&p3.Ip, &ip4, sizeof(IP));
15696 			p3.Port = port;
15697 			p3.Timeout = timeout;
15698 			p3.CancelFlag = &cancel_flag2;
15699 			p3.FinishEvent = finish_event;
15700 			StrCpy(p3.SvcName, sizeof(p3.SvcName), nat_t_svc_name);
15701 			p3.RUdpProtocol = RUDP_PROTOCOL_ICMP;
15702 			p3.Delay = 200;		// Delay by 200ms
15703 
15704 			// p4: over DNS
15705 			StrCpy(p4.Hostname, sizeof(p4.Hostname), hostname_original);
15706 			Copy(&p4.Ip, &ip4, sizeof(IP));
15707 			p4.Port = port;
15708 			p4.Timeout = timeout;
15709 			p4.CancelFlag = &cancel_flag2;
15710 			p4.FinishEvent = finish_event;
15711 			StrCpy(p4.SvcName, sizeof(p4.SvcName), nat_t_svc_name);
15712 			p4.RUdpProtocol = RUDP_PROTOCOL_DNS;
15713 			p4.Delay = 100;		// Delay by 100ms
15714 
15715 			t1 = NewThread(ConnectThreadForTcp, &p1);
15716 			t2 = NewThread(ConnectThreadForRUDP, &p2);
15717 			t4 = NewThread(ConnectThreadForOverDnsOrIcmp, &p4);
15718 			t3 = NewThread(ConnectThreadForOverDnsOrIcmp, &p3);
15719 
15720 			while (true)
15721 			{
15722 				UINT64 now = Tick64();
15723 
15724 				if (*cancel_flag)
15725 				{
15726 					// Cancel by the user
15727 					break;
15728 				}
15729 
15730 				if (p1.Finished && p2.Finished)
15731 				{
15732 					// Results for both the TCP and the NAT-T were confirmed
15733 					if (now >= giveup_for_all_tick)
15734 					{
15735 						// Wait at least minimum time until successful of the ICMP or the DNS
15736 						break;
15737 					}
15738 
15739 					if (p3.Ok || p4.Ok)
15740 					{
15741 						// Exit the loop immediately if any of the ICMP or the DNS is successful
15742 						break;
15743 					}
15744 				}
15745 
15746 				if (p1.Finished && p1.Ok)
15747 				{
15748 					// Have successfully connected by TCP
15749 					break;
15750 				}
15751 
15752 				if (p2.Finished && p2.Ok)
15753 				{
15754 					UINT p1_wait_time;
15755 					UINT64 tcp_giveup_tick;
15756 					UINT p2_spent_time;
15757 					// Have successfully connected by R-UDP
15758 					if (p1.Finished)
15759 					{
15760 						// Result of TCP is confirmed
15761 						break;
15762 					}
15763 
15764 					// Calculate the time takes to complete connection of R-UDP
15765 					p2_spent_time = (UINT)(p2.FinishedTick - start_tick);
15766 
15767 					// Decide the grace time for results of TCP until settled.
15768 					// The grace time is four times the duration of the R-UDP, and at least 400 milliseconds from the start,
15769 					// and up to 2500 milliseconds after the R-UDP results settled
15770 					p1_wait_time = p2_spent_time * 4;
15771 					p1_wait_time = MAX(p1_wait_time, 400);
15772 					//Debug("p2_spent_time = %u,   p1_wait_time = %u\n", p2_spent_time, p1_wait_time);
15773 
15774 					tcp_giveup_tick = start_tick + (UINT64)p1_wait_time;
15775 					tcp_giveup_tick = MIN(tcp_giveup_tick, (p2.FinishedTick + 2500ULL));
15776 
15777 					if (now >= tcp_giveup_tick)
15778 					{
15779 						// Result of the TCP is uncertain, but give up
15780 						if (p1.Finished || p1.Tcp_InNegotiation == false)
15781 						{
15782 							// Break only when TCP SSL negotiation is not being processed
15783 							break;
15784 						}
15785 					}
15786 				}
15787 
15788 				Wait(finish_event, 25);
15789 			}
15790 
15791 			cancel_flag2 = true;
15792 
15793 			Lock(p1.CancelLock);
15794 			{
15795 				if (p1.CancelDisconnectSock != NULL)
15796 				{
15797 					cancel_sock = p1.CancelDisconnectSock;
15798 
15799 					AddRef(cancel_sock->ref);
15800 				}
15801 			}
15802 			Unlock(p1.CancelLock);
15803 
15804 			if (cancel_sock != NULL)
15805 			{
15806 				Disconnect(cancel_sock);
15807 				ReleaseSock(cancel_sock);
15808 			}
15809 
15810 			WaitThread(t1, INFINITE);
15811 			WaitThread(t2, INFINITE);
15812 			WaitThread(t3, INFINITE);
15813 			WaitThread(t4, INFINITE);
15814 			ReleaseThread(t1);
15815 			ReleaseThread(t2);
15816 			ReleaseThread(t3);
15817 			ReleaseThread(t4);
15818 			ReleaseEvent(finish_event);
15819 
15820 			DeleteLock(p1.CancelLock);
15821 
15822 			if (*cancel_flag)
15823 			{
15824 				// Abandon all the results because the user canceled
15825 				Disconnect(p1.Result_Nat_T_Sock);
15826 				ReleaseSock(p1.Result_Nat_T_Sock);
15827 				Disconnect(p2.Result_Nat_T_Sock);
15828 				ReleaseSock(p2.Result_Nat_T_Sock);
15829 				Disconnect(p3.Result_Nat_T_Sock);
15830 				ReleaseSock(p3.Result_Nat_T_Sock);
15831 				Disconnect(p4.Result_Nat_T_Sock);
15832 				ReleaseSock(p4.Result_Nat_T_Sock);
15833 
15834 				return NULL;
15835 			}
15836 
15837 			if (p1.Ok)
15838 			{
15839 				char hostname[MAX_SIZE];
15840 
15841 				// Use the results of the TCP
15842 				// Dispose other results
15843 				Disconnect(p2.Result_Nat_T_Sock);
15844 				ReleaseSock(p2.Result_Nat_T_Sock);
15845 				Disconnect(p3.Result_Nat_T_Sock);
15846 				ReleaseSock(p3.Result_Nat_T_Sock);
15847 				Disconnect(p4.Result_Nat_T_Sock);
15848 				ReleaseSock(p4.Result_Nat_T_Sock);
15849 
15850 				if (GetHostName(hostname, sizeof(hostname), &ip4))
15851 				{
15852 					Free(p1.Result_Tcp_Sock->RemoteHostname);
15853 					p1.Result_Tcp_Sock->RemoteHostname = CopyStr(hostname);
15854 				}
15855 
15856 				Copy(ret_ip, &ip4, sizeof(IP));
15857 
15858 				return p1.Result_Tcp_Sock;
15859 			}
15860 			else if (p2.Ok)
15861 			{
15862 				// Use the results of the R-UDP
15863 				// Dispose other results
15864 				Disconnect(p3.Result_Nat_T_Sock);
15865 				ReleaseSock(p3.Result_Nat_T_Sock);
15866 				Disconnect(p4.Result_Nat_T_Sock);
15867 				ReleaseSock(p4.Result_Nat_T_Sock);
15868 
15869 				StrCpy(p2.Result_Nat_T_Sock->UnderlayProtocol, sizeof(p2.Result_Nat_T_Sock->UnderlayProtocol),
15870 					SOCK_UNDERLAY_NAT_T);
15871 				AddProtocolDetailsStr(p2.Result_Nat_T_Sock->UnderlayProtocol, sizeof(p2.Result_Nat_T_Sock->UnderlayProtocol),
15872 					"RUDP/UDP");
15873 
15874 				Copy(ret_ip, &ip4, sizeof(IP));
15875 
15876 				return p2.Result_Nat_T_Sock;
15877 			}
15878 			else if (p4.Ok)
15879 			{
15880 				// Use this if over-DNS success
15881 				// Dispose other results
15882 				Disconnect(p3.Result_Nat_T_Sock);
15883 				ReleaseSock(p3.Result_Nat_T_Sock);
15884 
15885 				StrCpy(p4.Result_Nat_T_Sock->UnderlayProtocol, sizeof(p4.Result_Nat_T_Sock->UnderlayProtocol),
15886 					SOCK_UNDERLAY_DNS);
15887 				AddProtocolDetailsStr(p4.Result_Nat_T_Sock->UnderlayProtocol, sizeof(p4.Result_Nat_T_Sock->UnderlayProtocol),
15888 					"RUDP/DNS");
15889 
15890 				Copy(ret_ip, &ip4, sizeof(IP));
15891 
15892 				return p4.Result_Nat_T_Sock;
15893 			}
15894 			else if (p3.Ok)
15895 			{
15896 				// Use this if over ICMP success
15897 				StrCpy(p3.Result_Nat_T_Sock->UnderlayProtocol, sizeof(p3.Result_Nat_T_Sock->UnderlayProtocol),
15898 					SOCK_UNDERLAY_ICMP);
15899 				AddProtocolDetailsStr(p3.Result_Nat_T_Sock->UnderlayProtocol, sizeof(p3.Result_Nat_T_Sock->UnderlayProtocol),
15900 					"RUDP/ICMP");
15901 
15902 				Copy(ret_ip, &ip4, sizeof(IP));
15903 
15904 				return p3.Result_Nat_T_Sock;
15905 			}
15906 			else
15907 			{
15908 				// Continue the process if all trials failed
15909 				*nat_t_error_code = p2.NatT_ErrorCode;
15910 			}
15911 		}
15912 	}
15913 
15914 	// Attempt to connect with IPv6
15915 	if (s == INVALID_SOCKET && IsZeroIp(&ip6) == false)
15916 	{
15917 		struct sockaddr_in6 sockaddr6;
15918 		struct in6_addr addr6;
15919 
15920 		Zero(&sockaddr6, sizeof(sockaddr6));
15921 		Zero(&addr6, sizeof(addr6));
15922 
15923 		// Generation of the sockaddr_in6
15924 		IPToInAddr6(&addr6, &ip6);
15925 		sockaddr6.sin6_port = htons((USHORT)port);
15926 		sockaddr6.sin6_family = AF_INET6;
15927 		sockaddr6.sin6_scope_id = ip6.ipv6_scope_id;
15928 		Copy(&sockaddr6.sin6_addr, &addr6, sizeof(addr6));
15929 
15930 		// Socket creation
15931 		s = socket(AF_INET6, SOCK_STREAM, 0);
15932 		if (s != INVALID_SOCKET)
15933 		{
15934 			// Connection
15935 			if (connect_timeout(s, (struct sockaddr *)&sockaddr6, sizeof(struct sockaddr_in6), timeout, cancel_flag) != 0)
15936 			{
15937 				// Connection failure
15938 				closesocket(s);
15939 				s = INVALID_SOCKET;
15940 			}
15941 			else
15942 			{
15943 				Copy(&current_ip, &ip6, sizeof(IP));
15944 
15945 				is_ipv6 = true;
15946 
15947 				Copy(ret_ip, &ip6, sizeof(IP));
15948 			}
15949 		}
15950 	}
15951 
15952 	if (s == INVALID_SOCKET)
15953 	{
15954 		// Connection fails on both of IPv4, IPv6
15955 		return NULL;
15956 	}
15957 
15958 	// Creating a SOCK
15959 	sock = NewSock();
15960 	sock->socket = s;
15961 	sock->Type = SOCK_TCP;
15962 	sock->ServerMode = false;
15963 
15964 	StrCpy(sock->UnderlayProtocol, sizeof(sock->UnderlayProtocol),
15965 		(is_ipv6 ? SOCK_UNDERLAY_NATIVE_V6 : SOCK_UNDERLAY_NATIVE_V4));
15966 
15967 	AddProtocolDetailsStr(sock->ProtocolDetails, sizeof(sock->ProtocolDetails),
15968 		is_ipv6 ? "IPv6" : "IPv4");
15969 
15970 	// Host name resolution
15971 	if (no_get_hostname || (GetHostName(tmp, sizeof(tmp), &current_ip) == false))
15972 	{
15973 		StrCpy(tmp, sizeof(tmp), hostname_original);
15974 	}
15975 
15976 	//Debug("PTR: %s\n", tmp);
15977 
15978 	sock->RemoteHostname = CopyStr(tmp);
15979 
15980 //	Debug("new socket: %u\n", s);
15981 
15982 	Zero(&ling, sizeof(ling));
15983 	// Forced disconnection flag
15984 #ifdef	SO_DONTLINGER
15985 	setsockopt(sock->socket, SOL_SOCKET, SO_DONTLINGER, (char *)&true_flag, sizeof(bool));
15986 #else	// SO_DONTLINGER
15987 	setsockopt(sock->socket, SOL_SOCKET, SO_LINGER, (char *)&false_flag, sizeof(bool));
15988 #endif	// SO_DONTLINGER
15989 //	setsockopt(sock->socket, SOL_SOCKET, SO_REUSEADDR, (char *)&true_flag, sizeof(bool));
15990 
15991 	// Configuring TCP options
15992 	setsockopt(sock->socket, IPPROTO_TCP, TCP_NODELAY, (char *)&true_flag, sizeof(bool));
15993 
15994 	// Initialization of the time-out value
15995 	SetTimeout(sock, TIMEOUT_INFINITE);
15996 
15997 	// Get the socket information
15998 	QuerySocketInformation(sock);
15999 
16000 	if (IsZeroIp(&sock->LocalIP) == false && IsLocalHostIP(&sock->LocalIP) == false)
16001 	{
16002 		IP current_ip;
16003 
16004 		if (GetCurrentGlobalIP(&current_ip, is_ipv6) == false)
16005 		{
16006 			SetCurrentGlobalIP(&sock->LocalIP, is_ipv6);
16007 		}
16008 	}
16009 
16010 	sock->Connected = true;
16011 	sock->AsyncMode = false;
16012 	sock->SecureMode = false;
16013 	sock->IPv6 = is_ipv6;
16014 
16015 	return sock;
16016 }
16017 
16018 // Get the current accepting IPv4 address
TryGetCurrentAcceptingIPv4Address(IP * ip)16019 void TryGetCurrentAcceptingIPv4Address(IP *ip)
16020 {
16021 	SOCK *s = ConnectEx(UDP_NAT_T_GET_PRIVATE_IP_TCP_SERVER, 80, 2000);
16022 
16023 	if (s != NULL)
16024 	{
16025 		Disconnect(s);
16026 		ReleaseSock(s);
16027 	}
16028 
16029 	if (GetCurrentGlobalIP(ip, false))
16030 	{
16031 		return;
16032 	}
16033 
16034 	GetCurrentGlobalIPGuess(ip, false);
16035 }
16036 
16037 // Add a protocol details strings
AddProtocolDetailsStr(char * dst,UINT dst_size,char * str)16038 void AddProtocolDetailsStr(char *dst, UINT dst_size, char *str)
16039 {
16040 	TOKEN_LIST *t1, *t2;
16041 	UINT i, j;
16042 	if (dst == NULL || str == NULL)
16043 	{
16044 		return;
16045 	}
16046 
16047 	t1 = ParseTokenWithoutNullStr(dst, " ");
16048 	t2 = ParseTokenWithoutNullStr(str, " ");
16049 
16050 	for (i = 0;i < t2->NumTokens;i++)
16051 	{
16052 		bool exists = false;
16053 		for (j = 0;j < t1->NumTokens;j++)
16054 		{
16055 			if (StrCmpi(t1->Token[j], t2->Token[i]) == 0)
16056 			{
16057 				exists = true;
16058 				break;
16059 			}
16060 		}
16061 
16062 		if (exists == false)
16063 		{
16064 			StrCat(dst, dst_size, t2->Token[i]);
16065 			StrCat(dst, dst_size, " ");
16066 		}
16067 	}
16068 
16069 	FreeToken(t1);
16070 	FreeToken(t2);
16071 }
AddProtocolDetailsKeyValueStr(char * dst,UINT dst_size,char * key,char * value)16072 void AddProtocolDetailsKeyValueStr(char *dst, UINT dst_size, char *key, char *value)
16073 {
16074 	char tmp[128];
16075 	StrCpy(tmp, sizeof(tmp), key);
16076 	StrCat(tmp, sizeof(tmp), "=");
16077 	StrCat(tmp, sizeof(tmp), value);
16078 	AddProtocolDetailsStr(dst, dst_size, tmp);
16079 }
AddProtocolDetailsKeyValueInt(char * dst,UINT dst_size,char * key,UINT value)16080 void AddProtocolDetailsKeyValueInt(char *dst, UINT dst_size, char *key, UINT value)
16081 {
16082 	char tmp[128];
16083 	ToStr(tmp, value);
16084 	AddProtocolDetailsKeyValueStr(dst, dst_size, key, tmp);
16085 }
16086 
16087 // Maximize the I/O buffer size of the socket
SetSocketSendRecvBufferSize(SOCKET s,UINT size)16088 void SetSocketSendRecvBufferSize(SOCKET s, UINT size)
16089 {
16090 	int value = (int)size;
16091 	// Validate arguments
16092 	if (s == INVALID_SOCKET)
16093 	{
16094 		return;
16095 	}
16096 
16097 	setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&value, sizeof(int));
16098 	setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *)&value, sizeof(int));
16099 }
16100 
16101 // Get the buffer size of the socket
GetSocketBufferSize(SOCKET s,bool send)16102 UINT GetSocketBufferSize(SOCKET s, bool send)
16103 {
16104 	int value = 0;
16105 	int len = sizeof(int);
16106 	// Validate arguments
16107 	if (s == INVALID_SOCKET)
16108 	{
16109 		return 0;
16110 	}
16111 
16112 	if (getsockopt(s, SOL_SOCKET, (send ? SO_SNDBUF : SO_RCVBUF), (char *)&value, &len) != 0)
16113 	{
16114 		return 0;
16115 	}
16116 
16117 	return value;
16118 }
16119 
16120 // Setting the buffer size of the socket
SetSocketBufferSize(SOCKET s,bool send,UINT size)16121 bool SetSocketBufferSize(SOCKET s, bool send, UINT size)
16122 {
16123 	int value = (int)size;
16124 	// Validate arguments
16125 	if (s == INVALID_SOCKET)
16126 	{
16127 		return false;
16128 	}
16129 
16130 	if (setsockopt(s, SOL_SOCKET, (send ? SO_SNDBUF : SO_RCVBUF), (char *)&value, sizeof(int)) != 0)
16131 	{
16132 		return false;
16133 	}
16134 
16135 	return true;
16136 }
SetSocketBufferSizeWithBestEffort(SOCKET s,bool send,UINT size)16137 UINT SetSocketBufferSizeWithBestEffort(SOCKET s, bool send, UINT size)
16138 {
16139 	// Validate arguments
16140 	if (s == INVALID_SOCKET)
16141 	{
16142 		return 0;
16143 	}
16144 
16145 	while (true)
16146 	{
16147 		if (SetSocketBufferSize(s, send, size))
16148 		{
16149 			return size;
16150 		}
16151 
16152 		size = (UINT)((double)size / 1.5);
16153 
16154 		if (size <= 32767)
16155 		{
16156 			return 0;
16157 		}
16158 	}
16159 }
16160 
16161 // Initialize the buffer size of the UDP socket
InitUdpSocketBufferSize(SOCKET s)16162 void InitUdpSocketBufferSize(SOCKET s)
16163 {
16164 	SetSocketBufferSizeWithBestEffort(s, true, UDP_MAX_BUFFER_SIZE);
16165 	SetSocketBufferSizeWithBestEffort(s, false, UDP_MAX_BUFFER_SIZE);
16166 }
16167 
16168 // Get the socket information
QuerySocketInformation(SOCK * sock)16169 void QuerySocketInformation(SOCK *sock)
16170 {
16171 	// Validate arguments
16172 	if (sock == NULL)
16173 	{
16174 		return;
16175 	}
16176 
16177 	Lock(sock->lock);
16178 	{
16179 		struct sockaddr_in6 sockaddr6;
16180 		struct in6_addr *addr6;
16181 		int size;
16182 		DWORD dw;
16183 		UINT opt_value = 0;
16184 
16185 		if (sock->Type == SOCK_TCP)
16186 		{
16187 			// Get the information of the remote host
16188 			size = sizeof(sockaddr6);
16189 			if (getpeername(sock->socket, (struct sockaddr *)&sockaddr6, (int *)&size) == 0)
16190 			{
16191 				if (size >= sizeof(struct sockaddr_in6))
16192 				{
16193 					sock->RemotePort = (UINT)ntohs(sockaddr6.sin6_port);
16194 					addr6 = &sockaddr6.sin6_addr;
16195 					InAddrToIP6(&sock->RemoteIP, addr6);
16196 					sock->RemoteIP.ipv6_scope_id = sockaddr6.sin6_scope_id;
16197 				}
16198 				else
16199 				{
16200 					struct sockaddr_in *sockaddr;
16201 					struct in_addr *addr;
16202 
16203 					sockaddr = (struct sockaddr_in *)&sockaddr6;
16204 					sock->RemotePort = (UINT)ntohs(sockaddr->sin_port);
16205 					addr = &sockaddr->sin_addr;
16206 					InAddrToIP(&sock->RemoteIP, addr);
16207 				}
16208 			}
16209 		}
16210 
16211 		// Get the local host information
16212 		size = sizeof(sockaddr6);
16213 		if (getsockname(sock->socket, (struct sockaddr *)&sockaddr6, (int *)&size) == 0)
16214 		{
16215 			if (size >= sizeof(struct sockaddr_in6))
16216 			{
16217 				sock->LocalPort = (UINT)ntohs(sockaddr6.sin6_port);
16218 				addr6 = &sockaddr6.sin6_addr;
16219 				InAddrToIP6(&sock->LocalIP, addr6);
16220 				sock->LocalIP.ipv6_scope_id = sockaddr6.sin6_scope_id;
16221 			}
16222 			else
16223 			{
16224 				struct sockaddr_in *sockaddr;
16225 				struct in_addr *addr;
16226 
16227 				sockaddr = (struct sockaddr_in *)&sockaddr6;
16228 				sock->LocalPort = (UINT)ntohs(sockaddr->sin_port);
16229 				addr = &sockaddr->sin_addr;
16230 				InAddrToIP(&sock->LocalIP, addr);
16231 			}
16232 		}
16233 
16234 		if (sock->IsRawSocket)
16235 		{
16236 			sock->LocalPort = sock->RemotePort = MAKE_SPECIAL_PORT(sock->RawSocketIPProtocol);
16237 		}
16238 
16239 		if (sock->Type == SOCK_UDP)
16240 		{
16241 			sock->UdpMaxMsgSize = UDP_MAX_MSG_SIZE_DEFAULT;
16242 
16243 #ifdef	OS_WIN32
16244 			if (true)
16245 			{
16246 				// Get the buffer size that can be transmitted and received at once
16247 				UINT max_value = 0;
16248 				int len = sizeof(UINT);
16249 
16250 				if (getsockopt(sock->socket, SOL_SOCKET, SO_MAX_MSG_SIZE, (char *)&max_value, &len) == 0)
16251 				{
16252 					sock->UdpMaxMsgSize = max_value;
16253 				}
16254 			}
16255 #endif	// OS_WIN32
16256 		}
16257 
16258 		if (sock->IPv6)
16259 		{
16260 #ifdef	IPV6_UNICAST_HOPS
16261 			opt_value = IPV6_UNICAST_HOPS;
16262 #endif	// IPV6_UNICAST_HOPS
16263 		}
16264 		else
16265 		{
16266 #ifdef	IP_TTL
16267 			opt_value = IP_TTL;
16268 #endif	// IP_TTL
16269 		}
16270 
16271 		// Support of the TTL value
16272 		size = sizeof(DWORD);
16273 		if (opt_value == 0 ||
16274 			getsockopt(sock->socket, (sock->IPv6 ? IPPROTO_IPV6 : IPPROTO_IP), opt_value, (char *)&dw, &size) != 0)
16275 		{
16276 			sock->IsTtlSupported = false;
16277 		}
16278 		else
16279 		{
16280 			sock->IsTtlSupported = true;
16281 			sock->CurrentTtl = dw;
16282 		}
16283 	}
16284 	Unlock(sock->lock);
16285 }
16286 
16287 // Setting the TTL value
SetTtl(SOCK * sock,UINT ttl)16288 bool SetTtl(SOCK *sock, UINT ttl)
16289 {
16290 	DWORD dw;
16291 	int size;
16292 	UINT opt_value = 0;
16293 	// Validate arguments
16294 	if (sock == NULL)
16295 	{
16296 		return false;
16297 	}
16298 
16299 	if (sock->IsTtlSupported == false)
16300 	{
16301 		return false;
16302 	}
16303 
16304 	if (sock->CurrentTtl == ttl)
16305 	{
16306 		return true;
16307 	}
16308 
16309 	dw = ttl;
16310 	size = sizeof(DWORD);
16311 
16312 	if (sock->IPv6)
16313 	{
16314 #ifdef	IPV6_UNICAST_HOPS
16315 		opt_value = IPV6_UNICAST_HOPS;
16316 #endif	// IPV6_UNICAST_HOPS
16317 	}
16318 	else
16319 	{
16320 #ifdef	IP_TTL
16321 		opt_value = IP_TTL;
16322 #endif	// IP_TTL
16323 	}
16324 
16325 	if (opt_value == 0 ||
16326 		setsockopt(sock->socket, (sock->IPv6 ? IPPROTO_IPV6 : IPPROTO_IP), opt_value, (char *)&dw, size) == false)
16327 	{
16328 		return false;
16329 	}
16330 
16331 	sock->CurrentTtl = ttl;
16332 
16333 	return true;
16334 }
16335 
16336 // Release of the socket
ReleaseSock(SOCK * s)16337 void ReleaseSock(SOCK *s)
16338 {
16339 	// Validate arguments
16340 	if (s == NULL)
16341 	{
16342 		return;
16343 	}
16344 
16345 	if (Release(s->ref) == 0)
16346 	{
16347 		if (s->ListenMode == false && s->ServerMode)
16348 		{
16349 			Print("");
16350 		}
16351 		CleanupSock(s);
16352 	}
16353 }
16354 
16355 // Clean-up of the socket
CleanupSock(SOCK * s)16356 void CleanupSock(SOCK *s)
16357 {
16358 	// Validate arguments
16359 	if (s == NULL)
16360 	{
16361 		return;
16362 	}
16363 
16364 //	{Debug("CleanupSock: Disconnect() Called: %s %u\n", __FILE__, __LINE__);Disconnect(s);}
16365 	Disconnect(s);
16366 
16367 	if (s->InProcAcceptQueue != NULL)
16368 	{
16369 		while (true)
16370 		{
16371 			SOCK *ss = GetNext(s->InProcAcceptQueue);
16372 			if (ss == NULL)
16373 			{
16374 				break;
16375 			}
16376 
16377 			Disconnect(ss);
16378 			ReleaseSock(ss);
16379 		}
16380 
16381 		ReleaseQueue(s->InProcAcceptQueue);
16382 	}
16383 
16384 	if (s->InProcAcceptEvent != NULL)
16385 	{
16386 		ReleaseEvent(s->InProcAcceptEvent);
16387 	}
16388 
16389 	if (s->ReverseAcceptQueue != NULL)
16390 	{
16391 		while (true)
16392 		{
16393 			SOCK *ss = GetNext(s->ReverseAcceptQueue);
16394 			if (ss == NULL)
16395 			{
16396 				break;
16397 			}
16398 
16399 			Disconnect(ss);
16400 			ReleaseSock(ss);
16401 		}
16402 
16403 		ReleaseQueue(s->ReverseAcceptQueue);
16404 	}
16405 
16406 	if (s->ReverseAcceptEvent != NULL)
16407 	{
16408 		ReleaseEvent(s->ReverseAcceptEvent);
16409 	}
16410 
16411 	if (s->SendTube != NULL)
16412 	{
16413 		TubeDisconnect(s->SendTube);
16414 		ReleaseTube(s->SendTube);
16415 	}
16416 
16417 	if (s->RecvTube != NULL)
16418 	{
16419 		TubeDisconnect(s->RecvTube);
16420 		ReleaseTube(s->RecvTube);
16421 	}
16422 
16423 	if (s->BulkRecvTube != NULL)
16424 	{
16425 		TubeDisconnect(s->BulkRecvTube);
16426 		ReleaseTube(s->BulkRecvTube);
16427 	}
16428 
16429 	if (s->BulkSendTube != NULL)
16430 	{
16431 		TubeDisconnect(s->BulkSendTube);
16432 		ReleaseTube(s->BulkSendTube);
16433 	}
16434 
16435 	if (s->BulkSendKey != NULL)
16436 	{
16437 		ReleaseSharedBuffer(s->BulkSendKey);
16438 	}
16439 
16440 	if (s->BulkRecvKey != NULL)
16441 	{
16442 		ReleaseSharedBuffer(s->BulkRecvKey);
16443 	}
16444 
16445 	if (s->InProcRecvFifo != NULL)
16446 	{
16447 		ReleaseFifo(s->InProcRecvFifo);
16448 	}
16449 
16450 	if (s->R_UDP_Stack != NULL)
16451 	{
16452 		FreeRUDP(s->R_UDP_Stack);
16453 	}
16454 
16455 #ifdef	OS_WIN32
16456 	Win32FreeAsyncSocket(s);
16457 #else	// OS_WIN32
16458 	UnixFreeAsyncSocket(s);
16459 #endif	// OS_WIN32
16460 
16461 	FreeBuf(s->SendBuf);
16462 	if (s->socket != INVALID_SOCKET)
16463 	{
16464 #ifdef	OS_WIN32
16465 		closesocket(s->socket);
16466 #else	// OS_WIN32
16467 		close(s->socket);
16468 #endif	// OS_WIN32
16469 	}
16470 	Free(s->RemoteHostname);
16471 
16472 #ifdef	OS_WIN32
16473 	if (s->hAcceptEvent != NULL)
16474 	{
16475 		CloseHandle(s->hAcceptEvent);
16476 	}
16477 #endif	// OS_WIN32
16478 
16479 	// Release the certificate
16480 	if (s->RemoteX != NULL)
16481 	{
16482 		FreeX(s->RemoteX);
16483 		s->RemoteX = NULL;
16484 	}
16485 	if (s->LocalX != NULL)
16486 	{
16487 		FreeX(s->LocalX);
16488 		s->LocalX = NULL;
16489 	}
16490 
16491 	// Cipher algorithm name
16492 	if (s->CipherName != NULL)
16493 	{
16494 		Free(s->CipherName);
16495 		s->CipherName = NULL;
16496 	}
16497 
16498 	Free(s->WaitToUseCipher);
16499 	DeleteLock(s->lock);
16500 	DeleteLock(s->ssl_lock);
16501 	DeleteLock(s->disconnect_lock);
16502 
16503 	Dec(num_tcp_connections);
16504 
16505 	Free(s);
16506 }
16507 
16508 // Creating a new socket
NewSock()16509 SOCK *NewSock()
16510 {
16511 	SOCK *s = ZeroMallocFast(sizeof(SOCK));
16512 
16513 	s->ref = NewRef();
16514 	s->lock = NewLock();
16515 	s->SendBuf = NewBuf();
16516 	s->socket = INVALID_SOCKET;
16517 	s->ssl_lock = NewLock();
16518 	s->disconnect_lock = NewLock();
16519 
16520 	Inc(num_tcp_connections);
16521 
16522 	return s;
16523 }
16524 
16525 // Convert the IP to UINT
IPToUINT(IP * ip)16526 UINT IPToUINT(IP *ip)
16527 {
16528 	UCHAR *b;
16529 	UINT i, value = 0;
16530 	// Validate arguments
16531 	if (ip == NULL)
16532 	{
16533 		return 0;
16534 	}
16535 
16536 	b = (UCHAR *)&value;
16537 	for (i = 0;i < 4;i++)
16538 	{
16539 		b[i] = ip->addr[i];
16540 	}
16541 
16542 	return value;
16543 }
16544 
16545 // Convert UINT to IP
UINTToIP(IP * ip,UINT value)16546 void UINTToIP(IP *ip, UINT value)
16547 {
16548 	UCHAR *b;
16549 	UINT i;
16550 	// Validate arguments
16551 	if (ip == NULL)
16552 	{
16553 		return;
16554 	}
16555 
16556 	ZeroIP4(ip);
16557 
16558 	b = (UCHAR *)&value;
16559 	for (i = 0;i < 4;i++)
16560 	{
16561 		ip->addr[i] = b[i];
16562 	}
16563 }
16564 
16565 // Get the host name of the computer
GetMachineHostName(char * name,UINT size)16566 void GetMachineHostName(char *name, UINT size)
16567 {
16568 	char tmp[MAX_SIZE];
16569 	UINT i, len;
16570 	// Validate arguments
16571 	if (name == NULL)
16572 	{
16573 		return;
16574 	}
16575 
16576 	GetMachineName(tmp, sizeof(tmp));
16577 
16578 	len = StrLen(tmp);
16579 	for (i = 0;i < len;i++)
16580 	{
16581 		if (tmp[i] == '.')
16582 		{
16583 			tmp[i] = 0;
16584 		}
16585 	}
16586 
16587 	ConvertSafeFileName(name, size, tmp);
16588 }
16589 
16590 // Get the IP address of this computer
GetMachineIp(IP * ip)16591 void GetMachineIp(IP *ip)
16592 {
16593 	char tmp[MAX_SIZE];
16594 	// Validate arguments
16595 	if (ip == NULL)
16596 	{
16597 		return;
16598 	}
16599 
16600 	Zero(ip, sizeof(IP));
16601 	SetIP(ip, 127, 0, 0, 1);
16602 
16603 	GetMachineName(tmp, sizeof(tmp));
16604 	GetIP(ip, tmp);
16605 }
16606 
16607 // Get the computer name from 'hosts'
GetMachineNameFromHosts(char * name,UINT size)16608 bool GetMachineNameFromHosts(char *name, UINT size)
16609 {
16610 	bool ret = false;
16611 	char *s;
16612 	BUF *b;
16613 	// Validate arguments
16614 	if (name == NULL)
16615 	{
16616 		return false;
16617 	}
16618 
16619 	b = ReadDump("/etc/hosts");
16620 	if (b == NULL)
16621 	{
16622 		return false;
16623 	}
16624 
16625 	while (true)
16626 	{
16627 		s = CfgReadNextLine(b);
16628 		if (s == NULL)
16629 		{
16630 			break;
16631 		}
16632 		else
16633 		{
16634 			TOKEN_LIST *t = ParseToken(s, " \t");
16635 
16636 			if (t != NULL)
16637 			{
16638 				if (t->NumTokens >= 2)
16639 				{
16640 					if (StrCmpi(t->Token[0], "127.0.0.1") == 0)
16641 					{
16642 						UINT i;
16643 
16644 						for (i = 1;i < t->NumTokens;i++)
16645 						{
16646 							if (StartWith(t->Token[i], "localhost") == false)
16647 							{
16648 								StrCpy(name, size, t->Token[i]);
16649 								ret = true;
16650 							}
16651 						}
16652 					}
16653 				}
16654 			}
16655 			FreeToken(t);
16656 		}
16657 
16658 		Free(s);
16659 	}
16660 
16661 	FreeBuf(b);
16662 
16663 	return ret;
16664 }
16665 
16666 // Get the computer name of this computer
GetMachineName(char * name,UINT size)16667 void GetMachineName(char *name, UINT size)
16668 {
16669 	GetMachineNameEx(name, size, false);
16670 }
GetMachineNameEx(char * name,UINT size,bool no_load_hosts)16671 void GetMachineNameEx(char *name, UINT size, bool no_load_hosts)
16672 {
16673 	static char name_cache[MAX_SIZE];
16674 	static bool name_cached = false;
16675 	char tmp[MAX_SIZE];
16676 	char tmp2[MAX_SIZE];
16677 	// Validate arguments
16678 	if (name == NULL)
16679 	{
16680 		return;
16681 	}
16682 
16683 	Lock(machine_name_lock);
16684 	{
16685 		if (name_cached != false)
16686 		{
16687 			StrCpy(name, size, name_cache);
16688 			Unlock(machine_name_lock);
16689 			return;
16690 		}
16691 		ClearStr(tmp, sizeof(tmp));
16692 		if (gethostname(tmp, MAX_SIZE) != 0)
16693 		{
16694 			StrCpy(name, size, "Unknown");
16695 			Unlock(machine_name_lock);
16696 			return;
16697 		}
16698 		ClearStr(name, size);
16699 		StrCpy(name, size, tmp);
16700 		if (IsEmptyStr(name) || StartWith(name, "localhost"))
16701 		{
16702 #ifdef	OS_WIN32
16703 			ClearStr(name, size);
16704 			MsGetComputerName(name, size);
16705 #endif	// OS_WIN32
16706 		}
16707 		if (IsEmptyStr(name) || StartWith(name, "localhost"))
16708 		{
16709 			if (no_load_hosts == false && OS_IS_UNIX(GetOsInfo()->OsType))
16710 			{
16711 				if (GetMachineNameFromHosts(tmp2, sizeof(tmp2)))
16712 				{
16713 					StrCpy(name, sizeof(name), tmp2); // 2019/02/09 by Dayiuu Nobori: DO NOT fix it! It affects DDNS configs.
16714 				}
16715 			}
16716 		}
16717 
16718 		StrCpy(name_cache, sizeof(name_cache), name);
16719 		name_cached = true;
16720 	}
16721 	Unlock(machine_name_lock);
16722 }
16723 
16724 // Host name acquisition thread
GetHostNameThread(THREAD * t,void * p)16725 void GetHostNameThread(THREAD *t, void *p)
16726 {
16727 	IP *ip;
16728 	char hostname[256];
16729 	// Validate arguments
16730 	if (t == NULL || p == NULL)
16731 	{
16732 		return;
16733 	}
16734 
16735 	ip = (IP *)p;
16736 
16737 	AddWaitThread(t);
16738 
16739 	NoticeThreadInit(t);
16740 
16741 	if (GetHostNameInner(hostname, sizeof(hostname), ip))
16742 	{
16743 		AddHostCache(ip, hostname);
16744 	}
16745 
16746 	Free(ip);
16747 
16748 	DelWaitThread(t);
16749 }
16750 
16751 // Get the host name
GetHostName(char * hostname,UINT size,IP * ip)16752 bool GetHostName(char *hostname, UINT size, IP *ip)
16753 {
16754 	THREAD *t;
16755 	IP *p_ip;
16756 	bool ret;
16757 	// Validate arguments
16758 	if (hostname == NULL || ip == NULL)
16759 	{
16760 		return false;
16761 	}
16762 
16763 	if (GetHostCache(hostname, size, ip))
16764 	{
16765 		if (IsEmptyStr(hostname) == false)
16766 		{
16767 			return true;
16768 		}
16769 		else
16770 		{
16771 			return false;
16772 		}
16773 	}
16774 
16775 	p_ip = ZeroMalloc(sizeof(IP));
16776 	Copy(p_ip, ip, sizeof(IP));
16777 
16778 	t = NewThread(GetHostNameThread, p_ip);
16779 
16780 	WaitThreadInit(t);
16781 
16782 	WaitThread(t, TIMEOUT_HOSTNAME);
16783 
16784 	ReleaseThread(t);
16785 
16786 	ret = GetHostCache(hostname, size, ip);
16787 	if (ret == false)
16788 	{
16789 		if (IsIP4(ip))
16790 		{
16791 			ret = GetNetBiosName(hostname, size, ip);
16792 			if (ret)
16793 			{
16794 				AddHostCache(ip, hostname);
16795 			}
16796 		}
16797 	}
16798 	else
16799 	{
16800 		if (IsEmptyStr(hostname))
16801 		{
16802 			ret = false;
16803 		}
16804 	}
16805 	if (ret == false)
16806 	{
16807 		AddHostCache(ip, "");
16808 		StrCpy(hostname, size, "");
16809 	}
16810 
16811 	return ret;
16812 }
16813 
16814 // Perform a DNS reverse query
GetHostNameInner(char * hostname,UINT size,IP * ip)16815 bool GetHostNameInner(char *hostname, UINT size, IP *ip)
16816 {
16817 	struct in_addr addr;
16818 	struct sockaddr_in sa;
16819 	char tmp[MAX_SIZE];
16820 	char ip_str[64];
16821 	// Validate arguments
16822 	if (hostname == NULL || ip == NULL)
16823 	{
16824 		return false;
16825 	}
16826 
16827 	if (IsIP6(ip))
16828 	{
16829 		return GetHostNameInner6(hostname, size, ip);
16830 	}
16831 
16832 	// Reverse resolution
16833 	IPToInAddr(&addr, ip);
16834 	Zero(&sa, sizeof(sa));
16835 	sa.sin_family = AF_INET;
16836 
16837 #if	defined(UNIX_BSD) || defined(UNIX_MACOS)
16838 	sa.sin_len = INET_ADDRSTRLEN;
16839 #endif	// UNIX_BSD || UNIX_MACOS
16840 
16841 	Copy(&sa.sin_addr, &addr, sizeof(struct in_addr));
16842 	sa.sin_port = 0;
16843 
16844 	if (getnameinfo((struct sockaddr *)&sa, sizeof(sa), tmp, sizeof(tmp), NULL, 0, 0) != 0)
16845 	{
16846 		return false;
16847 	}
16848 
16849 	IPToStr(ip_str, sizeof(ip_str), ip);
16850 
16851 	if (StrCmpi(tmp, ip_str) == 0)
16852 	{
16853 		return false;
16854 	}
16855 
16856 	if (IsEmptyStr(tmp))
16857 	{
16858 		return false;
16859 	}
16860 
16861 	StrCpy(hostname, size, tmp);
16862 
16863 	return true;
16864 }
GetHostNameInner6(char * hostname,UINT size,IP * ip)16865 bool GetHostNameInner6(char *hostname, UINT size, IP *ip)
16866 {
16867 	struct in6_addr addr;
16868 	struct sockaddr_in6 sa;
16869 	char tmp[MAX_SIZE];
16870 	char ip_str[256];
16871 	// Validate arguments
16872 	if (hostname == NULL || ip == NULL)
16873 	{
16874 		return false;
16875 	}
16876 
16877 	// Reverse resolution
16878 	IPToInAddr6(&addr, ip);
16879 	Zero(&sa, sizeof(sa));
16880 	sa.sin6_family = AF_INET6;
16881 
16882 #if	defined(UNIX_BSD) || defined(UNIX_MACOS)
16883 	sa.sin6_len = INET6_ADDRSTRLEN;
16884 #endif	// UNIX_BSD || UNIX_MACOS
16885 
16886 	Copy(&sa.sin6_addr, &addr, sizeof(struct in6_addr));
16887 	sa.sin6_port = 0;
16888 
16889 	if (getnameinfo((struct sockaddr *)&sa, sizeof(sa), tmp, sizeof(tmp), NULL, 0, 0) != 0)
16890 	{
16891 		return false;
16892 	}
16893 
16894 	IPToStr(ip_str, sizeof(ip_str), ip);
16895 
16896 	if (StrCmpi(tmp, ip_str) == 0)
16897 	{
16898 		return false;
16899 	}
16900 
16901 	if (IsEmptyStr(tmp))
16902 	{
16903 		return false;
16904 	}
16905 
16906 	StrCpy(hostname, size, tmp);
16907 
16908 	return true;
16909 }
16910 
16911 #define	NUM_NBT_QUERYS_SEND			3
16912 
16913 // Get the NetBIOS name of the machine from the IP address
GetNetBiosName(char * name,UINT size,IP * ip)16914 bool GetNetBiosName(char *name, UINT size, IP *ip)
16915 {
16916 	SOCK *s;
16917 	UINT i, j;
16918 	bool flag = false;
16919 	bool ok = false;
16920 	NBTREQUEST req;
16921 	UCHAR buf[1024];
16922 	USHORT tran_id[NUM_NBT_QUERYS_SEND];
16923 	UINT64 timeout_tick;
16924 	// Validate arguments
16925 	if (name == NULL || ip == NULL)
16926 	{
16927 		return false;
16928 	}
16929 
16930 	IPToStr(name, size, ip);
16931 
16932 	for (i = 0;i < NUM_NBT_QUERYS_SEND;i++)
16933 	{
16934 		tran_id[i] = Rand16();
16935 	}
16936 
16937 	s = NewUDP(0);
16938 	if (s == NULL)
16939 	{
16940 		return false;
16941 	}
16942 
16943 	for (j = 0;j < NUM_NBT_QUERYS_SEND;j++)
16944 	{
16945 		Zero(&req, sizeof(req));
16946 		req.TransactionId = Endian16(tran_id[j]);
16947 		req.NumQuestions = Endian16(1);
16948 		req.Query[0] = 0x20;
16949 		req.Query[1] = 0x43;
16950 		req.Query[2] = 0x4b;
16951 		for (i = 3;i <= 32;i++)
16952 		{
16953 			req.Query[i] = 0x41;
16954 		}
16955 		req.Query[35] = 0x21;
16956 		req.Query[37] = 0x01;
16957 
16958 		if (SendTo(s, ip, 137, &req, sizeof(req)) == 0)
16959 		{
16960 			ReleaseSock(s);
16961 			return false;
16962 		}
16963 	}
16964 
16965 	timeout_tick = Tick64() + (UINT64)TIMEOUT_NETBIOS_HOSTNAME;
16966 
16967 	while (1)
16968 	{
16969 		UINT ret;
16970 		IP src_ip;
16971 		UINT src_port;
16972 		SOCKSET set;
16973 		if (Tick64() >= timeout_tick)
16974 		{
16975 			break;
16976 		}
16977 		InitSockSet(&set);
16978 		AddSockSet(&set, s);
16979 		Select(&set, 100, NULL, NULL);
16980 
16981 		if (flag == false)
16982 		{
16983 			flag = true;
16984 		}
16985 		else
16986 		{
16987 			SleepThread(10);
16988 		}
16989 
16990 		ret = RecvFrom(s, &src_ip, &src_port, buf, sizeof(buf));
16991 
16992 		if (ret == SOCK_LATER)
16993 		{
16994 			continue;
16995 		}
16996 		else if (ret == 0)
16997 		{
16998 			break;
16999 		}
17000 		else
17001 		{
17002 			if (ret >= sizeof(NBTRESPONSE))
17003 			{
17004 				NBTRESPONSE *r = (NBTRESPONSE *)buf;
17005 				bool b = false;
17006 				UINT i;
17007 				USHORT id = Endian16(r->TransactionId);
17008 				for (i = 0;i < NUM_NBT_QUERYS_SEND;i++)
17009 				{
17010 					if (id == tran_id[i])
17011 					{
17012 						b = true;
17013 						break;
17014 					}
17015 				}
17016 				if (b)
17017 				{
17018 					if (r->Flags != 0 && r->NumQuestions == 0 && r->AnswerRRs >= 1)
17019 					{
17020 						if (r->Response[0] == 0x20 && r->Response[1] == 0x43 &&
17021 							r->Response[2] == 0x4b)
17022 						{
17023 							if (r->Response[34] == 0x00 && r->Response[35] == 0x21 &&
17024 								r->Response[36] == 0x00 && r->Response[37] == 0x01)
17025 							{
17026 								char *a = (char *)(&r->Response[45]);
17027 								if (StrCheckLen(a, 15))
17028 								{
17029 									if (IsEmptyStr(a) == false)
17030 									{
17031 										StrCpy(name, size, a);
17032 										Trim(name);
17033 										ok = true;
17034 									}
17035 									else
17036 									{
17037 										ok = false;
17038 										break;
17039 									}
17040 								}
17041 							}
17042 						}
17043 					}
17044 				}
17045 			}
17046 		}
17047 	}
17048 
17049 	ReleaseSock(s);
17050 	return ok;
17051 }
17052 
17053 // Set the IP address
SetIP(IP * ip,UCHAR a1,UCHAR a2,UCHAR a3,UCHAR a4)17054 void SetIP(IP *ip, UCHAR a1, UCHAR a2, UCHAR a3, UCHAR a4)
17055 {
17056 	// Validate arguments
17057 	if (ip == NULL)
17058 	{
17059 		return;
17060 	}
17061 
17062 	Zero(ip, sizeof(IP));
17063 	ip->addr[0] = a1;
17064 	ip->addr[1] = a2;
17065 	ip->addr[2] = a3;
17066 	ip->addr[3] = a4;
17067 }
SetIP32(UCHAR a1,UCHAR a2,UCHAR a3,UCHAR a4)17068 UINT SetIP32(UCHAR a1, UCHAR a2, UCHAR a3, UCHAR a4)
17069 {
17070 	IP ip;
17071 
17072 	Zero(&ip, sizeof(ip));
17073 	SetIP(&ip, a1, a2, a3, a4);
17074 
17075 	return IPToUINT(&ip);
17076 }
17077 
17078 // Get either of v4 and v6 results with a DNS forward lookup (The IPv4 precedes in the case of both results)
GetIP46Any4(IP * ip,char * hostname)17079 bool GetIP46Any4(IP *ip, char *hostname)
17080 {
17081 	IP ip4, ip6;
17082 	bool b = false;
17083 	// Validate arguments
17084 	if (ip == NULL || hostname == NULL)
17085 	{
17086 		return false;
17087 	}
17088 
17089 	if (GetIP46(&ip4, &ip6, hostname) == false)
17090 	{
17091 		return false;
17092 	}
17093 
17094 	if (IsZeroIp(&ip6) == false)
17095 	{
17096 		Copy(ip, &ip6, sizeof(IP));
17097 
17098 		b = true;
17099 	}
17100 
17101 	if (IsZeroIp(&ip4) == false)
17102 	{
17103 		Copy(ip, &ip4, sizeof(IP));
17104 
17105 		b = true;
17106 	}
17107 
17108 	return b;
17109 }
17110 
17111 // Get either of v4 and v6 results with a DNS forward lookup (The IPv6 precedes in the case of both)
GetIP46Any6(IP * ip,char * hostname)17112 bool GetIP46Any6(IP *ip, char *hostname)
17113 {
17114 	IP ip4, ip6;
17115 	bool b = false;
17116 	// Validate arguments
17117 	if (ip == NULL || hostname == NULL)
17118 	{
17119 		return false;
17120 	}
17121 
17122 	if (GetIP46(&ip4, &ip6, hostname) == false)
17123 	{
17124 		return false;
17125 	}
17126 
17127 	if (IsZeroIp(&ip4) == false)
17128 	{
17129 		Copy(ip, &ip4, sizeof(IP));
17130 
17131 		b = true;
17132 	}
17133 
17134 	if (IsZeroIp(&ip6) == false)
17135 	{
17136 		Copy(ip, &ip6, sizeof(IP));
17137 
17138 		b = true;
17139 	}
17140 
17141 	return b;
17142 }
17143 
17144 // Obtain in both v4 and v6 results with a DNS forward lookup
GetIP46(IP * ip4,IP * ip6,char * hostname)17145 bool GetIP46(IP *ip4, IP *ip6, char *hostname)
17146 {
17147 	return GetIP46Ex(ip4, ip6, hostname, 0, NULL);
17148 }
GetIP46Ex(IP * ip4,IP * ip6,char * hostname,UINT timeout,bool * cancel)17149 bool GetIP46Ex(IP *ip4, IP *ip6, char *hostname, UINT timeout, bool *cancel)
17150 {
17151 	IP a, b;
17152 	bool ok_a, ok_b;
17153 	// Validate arguments
17154 	if (ip4 == NULL || ip6 == NULL || hostname == NULL)
17155 	{
17156 		return false;
17157 	}
17158 
17159 	ZeroIP4(ip4);
17160 	ZeroIP6(ip6);
17161 
17162 	ok_a = ok_b = false;
17163 
17164 	if (GetIP6Ex(&a, hostname, timeout, cancel))
17165 	{
17166 		ok_a = true;
17167 	}
17168 
17169 	if (GetIP4Ex(&b, hostname, timeout, cancel))
17170 	{
17171 		ok_b = true;
17172 	}
17173 
17174 	if (ok_a)
17175 	{
17176 		if (IsIP4(&a))
17177 		{
17178 			Copy(ip4, &a, sizeof(IP));
17179 		}
17180 	}
17181 	if (ok_b)
17182 	{
17183 		if (IsIP4(&b))
17184 		{
17185 			Copy(ip4, &b, sizeof(IP));
17186 		}
17187 
17188 		if (IsIP6(&b))
17189 		{
17190 			Copy(ip6, &b, sizeof(IP));
17191 		}
17192 	}
17193 	if (ok_a)
17194 	{
17195 		if (IsIP6(&a))
17196 		{
17197 			Copy(ip6, &a, sizeof(IP));
17198 		}
17199 	}
17200 
17201 	if (IsZeroIp(ip4) && IsZeroIp(ip6))
17202 	{
17203 		return false;
17204 	}
17205 
17206 	return true;
17207 }
17208 
17209 // Clean-up of the parameters for GetIP thread
CleanupGetIPThreadParam(GETIP_THREAD_PARAM * p)17210 void CleanupGetIPThreadParam(GETIP_THREAD_PARAM *p)
17211 {
17212 	// Validate arguments
17213 	if (p == NULL)
17214 	{
17215 		return;
17216 	}
17217 
17218 	Free(p);
17219 }
17220 
17221 // Release of the parameters of the GetIP for thread
ReleaseGetIPThreadParam(GETIP_THREAD_PARAM * p)17222 void ReleaseGetIPThreadParam(GETIP_THREAD_PARAM *p)
17223 {
17224 	// Validate arguments
17225 	if (p == NULL)
17226 	{
17227 		return;
17228 	}
17229 
17230 	if (Release(p->Ref) == 0)
17231 	{
17232 		CleanupGetIPThreadParam(p);
17233 	}
17234 }
17235 
17236 // Thread to perform to query the DNS forward lookup (with timeout)
GetIP4Ex6ExThread(THREAD * t,void * param)17237 void GetIP4Ex6ExThread(THREAD *t, void *param)
17238 {
17239 	GETIP_THREAD_PARAM *p;
17240 	// Validate arguments
17241 	if (t == NULL || param == NULL)
17242 	{
17243 		return;
17244 	}
17245 
17246 	p = (GETIP_THREAD_PARAM *)param;
17247 
17248 	AddRef(p->Ref);
17249 
17250 	NoticeThreadInit(t);
17251 
17252 	AddWaitThread(t);
17253 
17254 	// Execution of resolution
17255 	if (p->IPv6 == false)
17256 	{
17257 		// IPv4
17258 		p->Ok = GetIP4Inner(&p->Ip, p->HostName);
17259 	}
17260 	else
17261 	{
17262 		// IPv6
17263 		p->Ok = GetIP6Inner(&p->Ip, p->HostName);
17264 	}
17265 
17266 	ReleaseGetIPThreadParam(p);
17267 
17268 	DelWaitThread(t);
17269 
17270 	Dec(getip_thread_counter);
17271 }
17272 
17273 // Perform a forward DNS query (with timeout)
GetIP4Ex6Ex(IP * ip,char * hostname_arg,UINT timeout,bool ipv6,bool * cancel)17274 bool GetIP4Ex6Ex(IP *ip, char *hostname_arg, UINT timeout, bool ipv6, bool *cancel)
17275 {
17276 	return GetIP4Ex6Ex2(ip, hostname_arg, timeout, ipv6, cancel, false);
17277 }
GetIP4Ex6Ex2(IP * ip,char * hostname_arg,UINT timeout,bool ipv6,bool * cancel,bool only_direct_dns)17278 bool GetIP4Ex6Ex2(IP *ip, char *hostname_arg, UINT timeout, bool ipv6, bool *cancel, bool only_direct_dns)
17279 {
17280 	GETIP_THREAD_PARAM *p;
17281 	THREAD *t;
17282 	bool ret = false;
17283 	UINT64 start_tick = 0;
17284 	UINT64 end_tick = 0;
17285 	UINT64 spent_time = 0;
17286 	UINT64 now;
17287 	UINT n;
17288 	bool use_dns_proxy = false;
17289 	char hostname[260];
17290 	UINT i;
17291 	bool timed_out;
17292 	// Validate arguments
17293 	if (ip == NULL || hostname_arg == NULL)
17294 	{
17295 		return false;
17296 	}
17297 	if (timeout == 0)
17298 	{
17299 		timeout = TIMEOUT_GETIP;
17300 	}
17301 
17302 	Zero(hostname, sizeof(hostname));
17303 	StrCpy(hostname, sizeof(hostname), hostname_arg);
17304 
17305 	i = SearchStrEx(hostname, "/", 0, true);
17306 	if (i != INFINITE)
17307 	{
17308 		hostname[i] = 0;
17309 	}
17310 
17311 	if (ipv6 == false)
17312 	{
17313 		IP ip2;
17314 
17315 		if (StrToIP(&ip2, hostname) && IsZeroIp(&ip2) == false)
17316 		{
17317 			if (IsIP4(&ip2))
17318 			{
17319 				// IPv4 address direct specification
17320 				Copy(ip, &ip2, sizeof(IP));
17321 				return true;
17322 			}
17323 			else
17324 			{
17325 				// IPv6 address direct specification
17326 				return false;
17327 			}
17328 		}
17329 	}
17330 	else
17331 	{
17332 		IP ip2;
17333 
17334 		if (StrToIP(&ip2, hostname) && IsZeroIp(&ip2) == false)
17335 		{
17336 			if (IsIP6(&ip2))
17337 			{
17338 				// IPv6 address direct specification
17339 				Copy(ip, &ip2, sizeof(IP));
17340 				return true;
17341 			}
17342 			else
17343 			{
17344 				// IPv4 address direct specification
17345 				return false;
17346 			}
17347 		}
17348 	}
17349 
17350 	if (only_direct_dns == false)
17351 	{
17352 		if (ipv6 == false)
17353 		{
17354 			if (IsUseDnsProxy())
17355 			{
17356 				use_dns_proxy = true;
17357 			}
17358 		}
17359 	}
17360 
17361 
17362 	// check the quota
17363 	start_tick = Tick64();
17364 	end_tick = start_tick + (UINT64)timeout;
17365 
17366 	n = 0;
17367 
17368 	timed_out = false;
17369 
17370 	while (true)
17371 	{
17372 		UINT64 now = Tick64();
17373 		UINT64 remain;
17374 		UINT remain32;
17375 
17376 		if (GetGetIpThreadMaxNum() > GetCurrentGetIpThreadNum())
17377 		{
17378 			// below the quota
17379 			break;
17380 		}
17381 
17382 		if (now >= end_tick)
17383 		{
17384 			// timeouted
17385 			timed_out = true;
17386 			break;
17387 		}
17388 
17389 		if (cancel != NULL && (*cancel))
17390 		{
17391 			// cancelled
17392 			timed_out = true;
17393 			break;
17394 		}
17395 
17396 		remain = end_tick - now;
17397 		remain32 = MIN((UINT)remain, 100);
17398 
17399 		SleepThread(remain32);
17400 		n++;
17401 	}
17402 
17403 	now = Tick64();
17404 	spent_time = now - start_tick;
17405 
17406 	if (n == 0)
17407 	{
17408 		spent_time = 0;
17409 	}
17410 
17411 	if ((UINT)spent_time >= timeout)
17412 	{
17413 		timed_out = true;
17414 	}
17415 
17416 	if (timed_out)
17417 	{
17418 		IP ip2;
17419 
17420 		// timed out, cancelled
17421 		if (QueryDnsCache(&ip2, hostname))
17422 		{
17423 			ret = true;
17424 
17425 			Copy(ip, &ip2, sizeof(IP));
17426 		}
17427 
17428 		Debug("GetIP4Ex6Ex2: Worker thread quota exceeded: max=%u current=%u\n",
17429 			GetGetIpThreadMaxNum(), GetCurrentGetIpThreadNum());
17430 
17431 		return ret;
17432 	}
17433 
17434 	// Increment the counter
17435 	Inc(getip_thread_counter);
17436 
17437 	if (spent_time != 0)
17438 	{
17439 		Debug("GetIP4Ex6Ex2: Waited for %u msecs to create a worker thread.\n",
17440 			spent_time);
17441 	}
17442 
17443 	timeout -= (UINT)spent_time;
17444 
17445 	p = ZeroMalloc(sizeof(GETIP_THREAD_PARAM));
17446 	p->Ref = NewRef();
17447 	StrCpy(p->HostName, sizeof(p->HostName), hostname);
17448 	p->IPv6 = ipv6;
17449 	p->Timeout = timeout;
17450 	p->Ok = false;
17451 
17452 	t = NewThread(GetIP4Ex6ExThread, p);
17453 	WaitThreadInit(t);
17454 
17455 	if (cancel == NULL)
17456 	{
17457 		WaitThread(t, timeout);
17458 	}
17459 	else
17460 	{
17461 		start_tick = Tick64();
17462 		end_tick = start_tick + (UINT64)timeout;
17463 
17464 		while (true)
17465 		{
17466 			UINT64 now = Tick64();
17467 			UINT64 remain;
17468 			UINT remain32;
17469 
17470 			if (*cancel)
17471 			{
17472 				break;
17473 			}
17474 
17475 			if (now >= end_tick)
17476 			{
17477 				break;
17478 			}
17479 
17480 			remain = end_tick - now;
17481 			remain32 = MIN((UINT)remain, 100);
17482 
17483 			if (WaitThread(t, remain32))
17484 			{
17485 				break;
17486 			}
17487 		}
17488 	}
17489 
17490 	ReleaseThread(t);
17491 
17492 	if (p->Ok)
17493 	{
17494 		ret = true;
17495 		Copy(ip, &p->Ip, sizeof(IP));
17496 	}
17497 	else
17498 	{
17499 		IP ip2;
17500 
17501 #if	0
17502 		if (only_direct_dns == false)
17503 		{
17504 			if (ipv6)
17505 			{
17506 				UINT flets_type = DetectFletsType();
17507 
17508 				// if I'm in the FLETs of NTT East,
17509 				// try to get an IP address using the DNS proxy server
17510 				if ((flets_type & FLETS_DETECT_TYPE_EAST_BFLETS_PRIVATE) &&
17511 					GetIPViaDnsProxyForJapanFlets(ip, hostname, true, 0, cancel, NULL))
17512 				{
17513 					// B FLETs
17514 					ret = true;
17515 				}
17516 				else if ((flets_type & FLETS_DETECT_TYPE_EAST_NGN_PRIVATE) &&
17517 					GetIPViaDnsProxyForJapanFlets(ip, hostname, true, 0, cancel, FLETS_NGN_EAST_DNS_PROXY_HOSTNAME))
17518 				{
17519 					// FLET'S Hikar-Next (NTT East)
17520 					ret = true;
17521 				}
17522 				else if ((flets_type & FLETS_DETECT_TYPE_WEST_NGN_PRIVATE) &&
17523 					GetIPViaDnsProxyForJapanFlets(ip, hostname, true, 0, cancel, FLETS_NGN_WEST_DNS_PROXY_HOSTNAME))
17524 				{
17525 					// FLET'S Hikar-Next (NTT West)
17526 					ret = true;
17527 				}
17528 			}
17529 		}
17530 #endif
17531 
17532 		if (QueryDnsCache(&ip2, hostname))
17533 		{
17534 			ret = true;
17535 
17536 			Copy(ip, &ip2, sizeof(IP));
17537 		}
17538 	}
17539 
17540 
17541 	ReleaseGetIPThreadParam(p);
17542 
17543 	return ret;
17544 }
GetIP4Ex(IP * ip,char * hostname,UINT timeout,bool * cancel)17545 bool GetIP4Ex(IP *ip, char *hostname, UINT timeout, bool *cancel)
17546 {
17547 	return GetIP4Ex6Ex(ip, hostname, timeout, false, cancel);
17548 }
GetIP6Ex(IP * ip,char * hostname,UINT timeout,bool * cancel)17549 bool GetIP6Ex(IP *ip, char *hostname, UINT timeout, bool *cancel)
17550 {
17551 	return GetIP4Ex6Ex(ip, hostname, timeout, true, cancel);
17552 }
GetIP4(IP * ip,char * hostname)17553 bool GetIP4(IP *ip, char *hostname)
17554 {
17555 	return GetIP4Ex(ip, hostname, 0, NULL);
17556 }
GetIP6(IP * ip,char * hostname)17557 bool GetIP6(IP *ip, char *hostname)
17558 {
17559 	return GetIP6Ex(ip, hostname, 0, NULL);
17560 }
17561 
17562 // Perform a DNS forward lookup query
GetIP(IP * ip,char * hostname)17563 bool GetIP(IP *ip, char *hostname)
17564 {
17565 	return GetIPEx(ip, hostname, false);
17566 }
GetIPEx(IP * ip,char * hostname,bool ipv6)17567 bool GetIPEx(IP *ip, char *hostname, bool ipv6)
17568 {
17569 	if (ipv6 == false)
17570 	{
17571 		return GetIP4(ip, hostname);
17572 	}
17573 	else
17574 	{
17575 		return GetIP6(ip, hostname);
17576 	}
17577 }
GetIP6Inner(IP * ip,char * hostname)17578 bool GetIP6Inner(IP *ip, char *hostname)
17579 {
17580 	struct sockaddr_in6 in;
17581 	struct in6_addr addr;
17582 	struct addrinfo hint;
17583 	struct addrinfo *info;
17584 	// Validate arguments
17585 	if (ip == NULL || hostname == NULL)
17586 	{
17587 		return false;
17588 	}
17589 
17590 	if (IsEmptyStr(hostname))
17591 	{
17592 		return false;
17593 	}
17594 
17595 	if (StrCmpi(hostname, "localhost") == 0)
17596 	{
17597 		GetLocalHostIP6(ip);
17598 		return true;
17599 	}
17600 
17601 	if (StrToIP6(ip, hostname) == false && StrToIP(ip, hostname) == false)
17602 	{
17603 		// Forward resolution
17604 		Zero(&hint, sizeof(hint));
17605 		hint.ai_family = AF_INET6;
17606 		hint.ai_socktype = SOCK_STREAM;
17607 		hint.ai_protocol = IPPROTO_TCP;
17608 		info = NULL;
17609 
17610 		if (getaddrinfo(hostname, NULL, &hint, &info) != 0 ||
17611 			info->ai_family != AF_INET6)
17612 		{
17613 			if (info)
17614 			{
17615 				freeaddrinfo(info);
17616 			}
17617 			return QueryDnsCacheEx(ip, hostname, true);
17618 		}
17619 		// Forward resolution success
17620 		Copy(&in, info->ai_addr, sizeof(struct sockaddr_in6));
17621 		freeaddrinfo(info);
17622 
17623 		Copy(&addr, &in.sin6_addr, sizeof(addr));
17624 		InAddrToIP6(ip, &addr);
17625 	}
17626 
17627 	// Save Cache
17628 	NewDnsCache(hostname, ip);
17629 
17630 	return true;
17631 }
GetIP4Inner(IP * ip,char * hostname)17632 bool GetIP4Inner(IP *ip, char *hostname)
17633 {
17634 	struct sockaddr_in in;
17635 	struct in_addr addr;
17636 	struct addrinfo hint;
17637 	struct addrinfo *info;
17638 	// Validate arguments
17639 	if (ip == NULL || hostname == NULL)
17640 	{
17641 		return false;
17642 	}
17643 
17644 	if (IsEmptyStr(hostname))
17645 	{
17646 		return false;
17647 	}
17648 
17649 	if (StrCmpi(hostname, "localhost") == 0)
17650 	{
17651 		SetIP(ip, 127, 0, 0, 1);
17652 		return true;
17653 	}
17654 
17655 	if (StrToIP6(ip, hostname) == false && StrToIP(ip, hostname) == false)
17656 	{
17657 		// Forward resolution
17658 		Zero(&hint, sizeof(hint));
17659 		hint.ai_family = AF_INET;
17660 		hint.ai_socktype = SOCK_STREAM;
17661 		hint.ai_protocol = IPPROTO_TCP;
17662 		info = NULL;
17663 
17664 		if (getaddrinfo(hostname, NULL, &hint, &info) != 0 ||
17665 			info->ai_family != AF_INET)
17666 		{
17667 			if (info)
17668 			{
17669 				freeaddrinfo(info);
17670 			}
17671 			return QueryDnsCache(ip, hostname);
17672 		}
17673 		// Forward resolution success
17674 		Copy(&in, info->ai_addr, sizeof(struct sockaddr_in));
17675 		freeaddrinfo(info);
17676 		Copy(&addr, &in.sin_addr, sizeof(addr));
17677 		InAddrToIP(ip, &addr);
17678 	}
17679 
17680 	// Save Cache
17681 	NewDnsCache(hostname, ip);
17682 
17683 	return true;
17684 }
17685 
17686 // Search in the DNS cache
QueryDnsCache(IP * ip,char * hostname)17687 bool QueryDnsCache(IP *ip, char *hostname)
17688 {
17689 	return QueryDnsCacheEx(ip, hostname, false);
17690 }
QueryDnsCacheEx(IP * ip,char * hostname,bool ipv6)17691 bool QueryDnsCacheEx(IP *ip, char *hostname, bool ipv6)
17692 {
17693 	DNSCACHE *c;
17694 	char tmp[MAX_SIZE];
17695 	// Validate arguments
17696 	if (ip == NULL || hostname == NULL)
17697 	{
17698 		return false;
17699 	}
17700 
17701 	GenDnsCacheKeyName(tmp, sizeof(tmp), hostname, ipv6);
17702 
17703 	c = FindDnsCache(tmp);
17704 	if (c == NULL)
17705 	{
17706 		return false;
17707 	}
17708 
17709 	Copy(ip, &c->IpAddress, sizeof(IP));
17710 
17711 	return true;
17712 }
17713 
17714 // Convert the IP to a string
IPToUniStr(wchar_t * str,UINT size,IP * ip)17715 void IPToUniStr(wchar_t *str, UINT size, IP *ip)
17716 {
17717 	char tmp[128];
17718 
17719 	IPToStr(tmp, sizeof(tmp), ip);
17720 	StrToUni(str, size, tmp);
17721 }
17722 
17723 // Convert the IP to a string (32bit UINT)
IPToUniStr32(wchar_t * str,UINT size,UINT ip)17724 void IPToUniStr32(wchar_t *str, UINT size, UINT ip)
17725 {
17726 	char tmp[128];
17727 
17728 	IPToStr32(tmp, sizeof(tmp), ip);
17729 	StrToUni(str, size, tmp);
17730 }
17731 
17732 // Convert the IP to a string (128bit byte array)
IPToStr128(char * str,UINT size,UCHAR * ip_bytes)17733 void IPToStr128(char *str, UINT size, UCHAR *ip_bytes)
17734 {
17735 	IP ip_st;
17736 	// Validate arguments
17737 	if (str == NULL)
17738 	{
17739 		return;
17740 	}
17741 
17742 	SetIP6(&ip_st, ip_bytes);
17743 	IPToStr(str, size, &ip_st);
17744 }
17745 
17746 // Convert the IP to a string (32bit UINT)
IPToStr32(char * str,UINT size,UINT ip)17747 void IPToStr32(char *str, UINT size, UINT ip)
17748 {
17749 	IP ip_st;
17750 	// Validate arguments
17751 	if (str == NULL)
17752 	{
17753 		return;
17754 	}
17755 
17756 	UINTToIP(&ip_st, ip);
17757 	IPToStr(str, size, &ip_st);
17758 }
17759 
17760 // Convert IPv4 or IPv6 to a string
IPToStr4or6(char * str,UINT size,UINT ip_4_uint,UCHAR * ip_6_bytes)17761 void IPToStr4or6(char *str, UINT size, UINT ip_4_uint, UCHAR *ip_6_bytes)
17762 {
17763 	IP ip4;
17764 	IP ip6;
17765 	IP ip;
17766 	// Validate arguments
17767 	if (str == NULL)
17768 	{
17769 		return;
17770 	}
17771 
17772 	Zero(&ip, sizeof(ip));
17773 
17774 	UINTToIP(&ip4, ip_4_uint);
17775 	SetIP6(&ip6, ip_6_bytes);
17776 
17777 	if (IsIP6(&ip4) || (IsZeroIp(&ip4) && (IsZeroIp(&ip6) == false)))
17778 	{
17779 		Copy(&ip, &ip6, sizeof(IP));
17780 	}
17781 	else
17782 	{
17783 		Copy(&ip, &ip4, sizeof(IP));
17784 	}
17785 
17786 	IPToStr(str, size, &ip);
17787 }
17788 
17789 // Convert the IP to a string
IPToStr(char * str,UINT size,IP * ip)17790 void IPToStr(char *str, UINT size, IP *ip)
17791 {
17792 	// Validate arguments
17793 	if (str == NULL || ip == NULL)
17794 	{
17795 		return;
17796 	}
17797 
17798 	if (IsIP6(ip))
17799 	{
17800 		IPToStr6(str, size, ip);
17801 	}
17802 	else
17803 	{
17804 		IPToStr4(str, size, ip);
17805 	}
17806 }
17807 
17808 // Convert the IPv4 to a string
IPToStr4(char * str,UINT size,IP * ip)17809 void IPToStr4(char *str, UINT size, IP *ip)
17810 {
17811 	// Validate arguments
17812 	if (str == NULL || ip == NULL)
17813 	{
17814 		return;
17815 	}
17816 
17817 	// Conversion
17818 	snprintf(str, size != 0 ? size : 64, "%u.%u.%u.%u", ip->addr[0], ip->addr[1], ip->addr[2], ip->addr[3]);
17819 }
17820 
17821 // Convert the string to an IP
StrToIP(IP * ip,char * str)17822 bool StrToIP(IP *ip, char *str)
17823 {
17824 	TOKEN_LIST *token;
17825 	char *tmp;
17826 	UINT i;
17827 	// Validate arguments
17828 	if (ip == NULL || str == NULL)
17829 	{
17830 		return false;
17831 	}
17832 
17833 	if (StrToIP6(ip, str))
17834 	{
17835 		return true;
17836 	}
17837 
17838 	Zero(ip, sizeof(IP));
17839 
17840 	tmp = CopyStr(str);
17841 	Trim(tmp);
17842 	token = ParseToken(tmp, ".");
17843 	Free(tmp);
17844 
17845 	if (token->NumTokens != 4)
17846 	{
17847 		FreeToken(token);
17848 		return false;
17849 	}
17850 	for (i = 0;i < 4;i++)
17851 	{
17852 		char *s = token->Token[i];
17853 		if (s[0] < '0' || s[0] > '9' ||
17854 			(ToInt(s) >= 256))
17855 		{
17856 			FreeToken(token);
17857 			return false;
17858 		}
17859 	}
17860 	Zero(ip, sizeof(IP));
17861 	for (i = 0;i < 4;i++)
17862 	{
17863 		ip->addr[i] = (UCHAR)ToInt(token->Token[i]);
17864 	}
17865 
17866 	FreeToken(token);
17867 
17868 	return true;
17869 }
StrToIP32(char * str)17870 UINT StrToIP32(char *str)
17871 {
17872 	IP ip;
17873 	// Validate arguments
17874 	if (str == NULL)
17875 	{
17876 		return 0;
17877 	}
17878 
17879 	if (StrToIP(&ip, str) == false)
17880 	{
17881 		return 0;
17882 	}
17883 
17884 	return IPToUINT(&ip);
17885 }
UniStrToIP(IP * ip,wchar_t * str)17886 bool UniStrToIP(IP *ip, wchar_t *str)
17887 {
17888 	char *tmp;
17889 	bool ret;
17890 
17891 	tmp = CopyUniToStr(str);
17892 	ret = StrToIP(ip, tmp);
17893 	Free(tmp);
17894 
17895 	return ret;
17896 }
UniStrToIP32(wchar_t * str)17897 UINT UniStrToIP32(wchar_t *str)
17898 {
17899 	UINT ret;
17900 	char *tmp;
17901 
17902 	tmp = CopyUniToStr(str);
17903 	ret = StrToIP32(tmp);
17904 	Free(tmp);
17905 
17906 	return ret;
17907 }
17908 
17909 // Convert the IP to the in_addr
IPToInAddr(struct in_addr * addr,IP * ip)17910 void IPToInAddr(struct in_addr *addr, IP *ip)
17911 {
17912 	UINT i;
17913 	// Validate arguments
17914 	if (addr == NULL || ip == NULL)
17915 	{
17916 		return;
17917 	}
17918 
17919 	Zero(addr, sizeof(struct in_addr));
17920 
17921 	if (IsIP6(ip) == false)
17922 	{
17923 		for (i = 0;i < 4;i++)
17924 		{
17925 			((UCHAR *)addr)[i] = ip->addr[i];
17926 		}
17927 	}
17928 }
17929 
17930 // Convert the IP to the in6_addr
IPToInAddr6(struct in6_addr * addr,IP * ip)17931 void IPToInAddr6(struct in6_addr *addr, IP *ip)
17932 {
17933 	UINT i;
17934 	// Validate arguments
17935 	if (addr == NULL || ip == NULL)
17936 	{
17937 		return;
17938 	}
17939 
17940 	Zero(addr, sizeof(struct in6_addr));
17941 
17942 	if (IsIP6(ip))
17943 	{
17944 		for (i = 0;i < 16;i++)
17945 		{
17946 			((UCHAR *)addr)[i] = ip->ipv6_addr[i];
17947 		}
17948 	}
17949 }
17950 
17951 // Convert the in_addr to the IP
InAddrToIP(IP * ip,struct in_addr * addr)17952 void InAddrToIP(IP *ip, struct in_addr *addr)
17953 {
17954 	UINT i;
17955 	// Validate arguments
17956 	if (ip == NULL || addr == NULL)
17957 	{
17958 		return;
17959 	}
17960 
17961 	Zero(ip, sizeof(IP));
17962 
17963 	for (i = 0;i < 4;i++)
17964 	{
17965 		ip->addr[i] = ((UCHAR *)addr)[i];
17966 	}
17967 }
17968 
17969 // Convert the in6_addr to the IP
InAddrToIP6(IP * ip,struct in6_addr * addr)17970 void InAddrToIP6(IP *ip, struct in6_addr *addr)
17971 {
17972 	UINT i;
17973 	// Validate arguments
17974 	if (ip == NULL || addr == NULL)
17975 	{
17976 		return;
17977 	}
17978 
17979 	ZeroIP6(ip);
17980 	for (i = 0;i < 16;i++)
17981 	{
17982 		ip->ipv6_addr[i] = ((UCHAR *)addr)[i];
17983 	}
17984 }
17985 
17986 // Search in the DNS cache
FindDnsCache(char * hostname)17987 DNSCACHE *FindDnsCache(char *hostname)
17988 {
17989 	return FindDnsCacheEx(hostname, false);
17990 }
FindDnsCacheEx(char * hostname,bool ipv6)17991 DNSCACHE *FindDnsCacheEx(char *hostname, bool ipv6)
17992 {
17993 	DNSCACHE *c;
17994 	char tmp[MAX_SIZE];
17995 	if (hostname == NULL)
17996 	{
17997 		return NULL;
17998 	}
17999 
18000 	GenDnsCacheKeyName(tmp, sizeof(tmp), hostname, ipv6);
18001 
18002 	LockDnsCache();
18003 	{
18004 		DNSCACHE t;
18005 		t.HostName = tmp;
18006 		c = Search(DnsCache, &t);
18007 	}
18008 	UnlockDnsCache();
18009 
18010 	return c;
18011 }
18012 
18013 // Generate the IPv4 / IPv6 key name for the DNS cache
GenDnsCacheKeyName(char * dst,UINT size,char * src,bool ipv6)18014 void GenDnsCacheKeyName(char *dst, UINT size, char *src, bool ipv6)
18015 {
18016 	// Validate arguments
18017 	if (dst == NULL || src == NULL)
18018 	{
18019 		return;
18020 	}
18021 
18022 	if (ipv6 == false)
18023 	{
18024 		StrCpy(dst, size, src);
18025 	}
18026 	else
18027 	{
18028 		Format(dst, size, "%s@ipv6", src);
18029 	}
18030 }
18031 
18032 // Registration of the new DNS cache
NewDnsCache(char * hostname,IP * ip)18033 void NewDnsCache(char *hostname, IP *ip)
18034 {
18035 	NewDnsCacheEx(hostname, ip, IsIP6(ip));
18036 }
NewDnsCacheEx(char * hostname,IP * ip,bool ipv6)18037 void NewDnsCacheEx(char *hostname, IP *ip, bool ipv6)
18038 {
18039 	DNSCACHE *c;
18040 	char tmp[MAX_PATH];
18041 	// Validate arguments
18042 	if (hostname == NULL || ip == NULL)
18043 	{
18044 		return;
18045 	}
18046 
18047 	if (IsNetworkNameCacheEnabled() == false)
18048 	{
18049 		return;
18050 	}
18051 
18052 	GenDnsCacheKeyName(tmp, sizeof(tmp), hostname, ipv6);
18053 
18054 	LockDnsCache();
18055 	{
18056 		DNSCACHE t;
18057 
18058 		// Search for anything matches to the hostname first
18059 		t.HostName = tmp;
18060 		c = Search(DnsCache, &t);
18061 
18062 		if (c == NULL)
18063 		{
18064 			// Newly register
18065 			c = ZeroMalloc(sizeof(DNSCACHE));
18066 			c->HostName = CopyStr(tmp);
18067 
18068 			Copy(&c->IpAddress, ip, sizeof(IP));
18069 
18070 			Add(DnsCache, c);
18071 		}
18072 		else
18073 		{
18074 			// Update
18075 			Copy(&c->IpAddress, ip, sizeof(IP));
18076 		}
18077 	}
18078 	UnlockDnsCache();
18079 }
18080 
18081 // Name comparison of the DNS cache entries
CompareDnsCache(void * p1,void * p2)18082 int CompareDnsCache(void *p1, void *p2)
18083 {
18084 	DNSCACHE *c1, *c2;
18085 	if (p1 == NULL || p2 == NULL)
18086 	{
18087 		return 0;
18088 	}
18089 	c1 = *(DNSCACHE **)p1;
18090 	c2 = *(DNSCACHE **)p2;
18091 	if (c1 == NULL || c2 == NULL)
18092 	{
18093 		return 0;
18094 	}
18095 
18096 	return StrCmpi(c1->HostName, c2->HostName);
18097 }
18098 
18099 // Initialization of the DNS cache
InitDnsCache()18100 void InitDnsCache()
18101 {
18102 	// Creating a List
18103 	DnsCache = NewList(CompareDnsCache);
18104 }
18105 
18106 // Release of the DNS cache
FreeDnsCache()18107 void FreeDnsCache()
18108 {
18109 	LockDnsCache();
18110 	{
18111 		DNSCACHE *c;
18112 		UINT i;
18113 		for (i = 0;i < LIST_NUM(DnsCache);i++)
18114 		{
18115 			// Release the memory for the entry
18116 			c = LIST_DATA(DnsCache, i);
18117 			Free(c->HostName);
18118 			Free(c);
18119 		}
18120 	}
18121 	UnlockDnsCache();
18122 
18123 	// Release the list
18124 	ReleaseList(DnsCache);
18125 	DnsCache = NULL;
18126 }
18127 
18128 // Lock the DNS cache
LockDnsCache()18129 void LockDnsCache()
18130 {
18131 	LockList(DnsCache);
18132 }
18133 
18134 // Unlock the DNS cache
UnlockDnsCache()18135 void UnlockDnsCache()
18136 {
18137 	UnlockList(DnsCache);
18138 }
18139 
18140 // DH temp key callback
TmpDhCallback(SSL * ssl,int is_export,int keylength)18141 DH *TmpDhCallback(SSL *ssl, int is_export, int keylength)
18142 {
18143 	DH *ret = NULL;
18144 
18145 	if (dh_2048 != NULL)
18146 	{
18147 		ret = dh_2048->dh;
18148 	}
18149 
18150 	return ret;
18151 }
18152 
18153 // Create the SSL_CTX
NewSSLCtx(bool server_mode)18154 struct ssl_ctx_st *NewSSLCtx(bool server_mode)
18155 {
18156 	struct ssl_ctx_st *ctx = SSL_CTX_new(SSLv23_method());
18157 
18158 #ifdef	SSL_OP_NO_TICKET
18159 	SSL_CTX_set_options(ctx, SSL_OP_NO_TICKET);
18160 #endif	// SSL_OP_NO_TICKET
18161 
18162 #ifdef	SSL_OP_CIPHER_SERVER_PREFERENCE
18163 	if (server_mode)
18164 	{
18165 		SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
18166 	}
18167 #endif	// SSL_OP_CIPHER_SERVER_PREFERENCE
18168 
18169 	SSL_CTX_set_tmp_dh_callback(ctx, TmpDhCallback);
18170 
18171 #ifdef	SSL_CTX_set_ecdh_auto
18172 	SSL_CTX_set_ecdh_auto(ctx, 1);
18173 #endif	// SSL_CTX_set_ecdh_auto
18174 
18175 #if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(LIBRESSL_VERSION_NUMBER)
18176 	// For compatibility with VPN 3.0 or older
18177 	SSL_CTX_set_security_level(ctx, 0);
18178 #endif
18179 
18180 	return ctx;
18181 }
18182 
18183 // Release of the SSL_CTX
FreeSSLCtx(struct ssl_ctx_st * ctx)18184 void FreeSSLCtx(struct ssl_ctx_st *ctx)
18185 {
18186 	// Validate arguments
18187 	if (ctx == NULL)
18188 	{
18189 		return;
18190 	}
18191 
18192 	SSL_CTX_free(ctx);
18193 }
18194 
18195 // The number of get ip threads
SetGetIpThreadMaxNum(UINT num)18196 void SetGetIpThreadMaxNum(UINT num)
18197 {
18198 	max_getip_thread = num;
18199 }
GetGetIpThreadMaxNum()18200 UINT GetGetIpThreadMaxNum()
18201 {
18202 	UINT ret = max_getip_thread;
18203 
18204 	if (ret == 0)
18205 	{
18206 		ret = 0x7FFFFFFF;
18207 	}
18208 
18209 	return ret;
18210 }
GetCurrentGetIpThreadNum()18211 UINT GetCurrentGetIpThreadNum()
18212 {
18213 	return Count(getip_thread_counter);
18214 }
18215 
18216 // Initialize the network communication module
InitNetwork()18217 void InitNetwork()
18218 {
18219 	disable_gethostname_by_accept = false;
18220 
18221 
18222 	InitDynList();
18223 
18224 
18225 	host_ip_address_list_cache_lock = NewLock();
18226 	host_ip_address_list_cache_last = 0;
18227 
18228 	num_tcp_connections = NewCounter();
18229 
18230 	getip_thread_counter = NewCounter();
18231 
18232 	// Initialization of client list
18233 	InitIpClientList();
18234 
18235 	// Thread related initialization
18236 	InitWaitThread();
18237 
18238 	// Initialization of the host name cache
18239 	InitHostCache();
18240 
18241 #ifdef	OS_WIN32
18242 	// Initializing the socket library
18243 	Win32InitSocketLibrary();
18244 #else
18245 	UnixInitSocketLibrary();
18246 #endif	// OS_WIN32
18247 
18248 	// Initialization of the DNS cache
18249 	InitDnsCache();
18250 
18251 	// Locking initialization
18252 	machine_name_lock = NewLock();
18253 	disconnect_function_lock = NewLock();
18254 	aho = NewLock();
18255 	machine_ip_process_hash_lock = NewLock();
18256 	socket_library_lock = NewLock();
18257 	//ssl_connect_lock = NewLock();  //2012.9.28 Not required for recent OpenSSL
18258 //	ssl_accept_lock = NewLock();
18259 	dns_lock = NewLock();
18260 	unix_dns_server_addr_lock = NewLock();
18261 	Zero(&unix_dns_server, sizeof(unix_dns_server));
18262 	local_mac_list_lock = NewLock();
18263 
18264 	cipher_list_token = ParseToken(cipher_list, " ");
18265 
18266 	current_global_ip_lock = NewLock();
18267 	current_fqdn_lock = NewLock();
18268 	current_global_ip_set = false;
18269 
18270 	disable_cache = false;
18271 
18272 
18273 	dh_2048 = DhNew2048();
18274 
18275 	Zero(rand_port_numbers, sizeof(rand_port_numbers));
18276 
18277 	SetGetIpThreadMaxNum(DEFAULT_GETIP_THREAD_MAX_NUM);
18278 }
18279 
18280 // Enable the network name cache
EnableNetworkNameCache()18281 void EnableNetworkNameCache()
18282 {
18283 	disable_cache = false;
18284 }
18285 
18286 // Disable the network name cache
DisableNetworkNameCache()18287 void DisableNetworkNameCache()
18288 {
18289 	disable_cache = true;
18290 }
18291 
18292 // Get whether the network name cache is enabled
IsNetworkNameCacheEnabled()18293 bool IsNetworkNameCacheEnabled()
18294 {
18295 	return !disable_cache;
18296 }
18297 
18298 // Get the cipher algorithm list
GetCipherList()18299 TOKEN_LIST *GetCipherList()
18300 {
18301 	return cipher_list_token;
18302 }
18303 
18304 // Get the TCP connections counter
GetNumTcpConnectionsCounter()18305 COUNTER *GetNumTcpConnectionsCounter()
18306 {
18307 	return num_tcp_connections;
18308 }
18309 
18310 // Get the current global IP address
GetCurrentGlobalIP(IP * ip,bool ipv6)18311 bool GetCurrentGlobalIP(IP *ip, bool ipv6)
18312 {
18313 	bool ret = false;
18314 	// Validate arguments
18315 	if (ip == NULL)
18316 	{
18317 		return false;
18318 	}
18319 
18320 	Zero(ip, sizeof(IP));
18321 
18322 	Lock(current_global_ip_lock);
18323 	{
18324 		if (ipv6 == false)
18325 		{
18326 			Copy(ip, &current_glocal_ipv4, sizeof(IP));
18327 		}
18328 		else
18329 		{
18330 			Copy(ip, &current_glocal_ipv6, sizeof(IP));
18331 		}
18332 
18333 		ret = current_global_ip_set;
18334 	}
18335 	Unlock(current_global_ip_lock);
18336 
18337 	return ret;
18338 }
18339 
18340 // Check whether the specified IP address is assigned to the local host
IsIPMyHost(IP * ip)18341 bool IsIPMyHost(IP *ip)
18342 {
18343 	LIST *o;
18344 	UINT i;
18345 	bool ret = false;
18346 	// Validate arguments
18347 	if (ip == NULL)
18348 	{
18349 		return false;
18350 	}
18351 
18352 	if (IsZeroIp(ip))
18353 	{
18354 		return false;
18355 	}
18356 
18357 	// Search to check whether it matches to any of the IP of the local host
18358 	o = GetHostIPAddressList();
18359 
18360 	for (i = 0;i < LIST_NUM(o);i++)
18361 	{
18362 		IP *p = LIST_DATA(o, i);
18363 
18364 		if (CmpIpAddr(p, ip) == 0)
18365 		{
18366 			// Matched
18367 			ret = true;
18368 			break;
18369 		}
18370 	}
18371 
18372 	FreeHostIPAddressList(o);
18373 
18374 	if (ret == false)
18375 	{
18376 		if (IsLocalHostIP(ip))
18377 		{
18378 			// localhost IP addresses
18379 			ret = true;
18380 		}
18381 	}
18382 
18383 	return ret;
18384 }
18385 
18386 // Check whether the specified IP address is a private IP address
IsIPPrivate(IP * ip)18387 bool IsIPPrivate(IP *ip)
18388 {
18389 	// Validate arguments
18390 	if (ip == NULL)
18391 	{
18392 		return false;
18393 	}
18394 
18395 	if (ip->addr[0] == 10)
18396 	{
18397 		return true;
18398 	}
18399 
18400 	if (ip->addr[0] == 172)
18401 	{
18402 		if (ip->addr[1] >= 16 && ip->addr[1] <= 31)
18403 		{
18404 			return true;
18405 		}
18406 	}
18407 
18408 	if (ip->addr[0] == 192 && ip->addr[1] == 168)
18409 	{
18410 		return true;
18411 	}
18412 
18413 	if (ip->addr[0] == 169 && ip->addr[1] == 254)
18414 	{
18415 		return true;
18416 	}
18417 
18418 	if (ip->addr[0] == 100)
18419 	{
18420 		if (ip->addr[1] >= 64 && ip->addr[1] <= 127)
18421 		{
18422 			return true;
18423 		}
18424 	}
18425 
18426 	if (g_private_ip_list != NULL)
18427 	{
18428 		if (IsIP4(ip))
18429 		{
18430 			UINT ip4 = IPToUINT(ip);
18431 
18432 			return IsOnPrivateIPFile(ip4);
18433 		}
18434 	}
18435 
18436 	return false;
18437 }
18438 
18439 // Is the IP address either local or private?
IsIPLocalOrPrivate(IP * ip)18440 bool IsIPLocalOrPrivate(IP *ip)
18441 {
18442 	// Validate arguments
18443 	if (ip == NULL)
18444 	{
18445 		return false;
18446 	}
18447 
18448 	if (IsIPPrivate(ip))
18449 	{
18450 		return true;
18451 	}
18452 
18453 	if (IsLocalHostIP(ip))
18454 	{
18455 		return true;
18456 	}
18457 
18458 	if (IsIPMyHost(ip))
18459 	{
18460 		return true;
18461 	}
18462 
18463 	return false;
18464 }
18465 
18466 // Read a private IP list file
LoadPrivateIPFile()18467 void LoadPrivateIPFile()
18468 {
18469 	BUF *b = ReadDump(PRIVATE_IP_TXT_FILENAME);
18470 	LIST *o;
18471 	if (b == NULL)
18472 	{
18473 		return;
18474 	}
18475 
18476 	o = NewList(NULL);
18477 
18478 	while (true)
18479 	{
18480 		char *line = CfgReadNextLine(b);
18481 		if (line == NULL)
18482 		{
18483 			break;
18484 		}
18485 
18486 		Trim(line);
18487 
18488 		if (IsEmptyStr(line) == false)
18489 		{
18490 			UINT ip = 0, mask = 0;
18491 
18492 			if (ParseIpAndSubnetMask4(line, &ip, &mask))
18493 			{
18494 				PRIVATE_IP_SUBNET *p = ZeroMalloc(sizeof(PRIVATE_IP_SUBNET));
18495 
18496 				p->Ip = ip;
18497 				p->Mask = mask;
18498 				p->Ip2 = ip & mask;
18499 
18500 				Add(o, p);
18501 			}
18502 		}
18503 
18504 		Free(line);
18505 	}
18506 
18507 	g_private_ip_list = o;
18508 	g_use_privateip_file = true;
18509 
18510 	FreeBuf(b);
18511 }
18512 
18513 // Examine whether the specified IP address is in the private IP file
IsOnPrivateIPFile(UINT ip)18514 bool IsOnPrivateIPFile(UINT ip)
18515 {
18516 	bool ret = false;
18517 
18518 	if (g_private_ip_list != NULL)
18519 	{
18520 		LIST *o = g_private_ip_list;
18521 		UINT i;
18522 
18523 		for (i = 0;i < LIST_NUM(o);i++)
18524 		{
18525 			PRIVATE_IP_SUBNET *p = LIST_DATA(o, i);
18526 
18527 			if ((ip & p->Mask) == p->Ip2)
18528 			{
18529 				ret = true;
18530 			}
18531 		}
18532 	}
18533 
18534 	return ret;
18535 }
18536 
18537 // Free the private IP file
FreePrivateIPFile()18538 void FreePrivateIPFile()
18539 {
18540 	if (g_private_ip_list != NULL)
18541 	{
18542 		LIST *o = g_private_ip_list;
18543 		UINT i;
18544 
18545 		g_private_ip_list = NULL;
18546 
18547 		for (i = 0;i < LIST_NUM(o);i++)
18548 		{
18549 			PRIVATE_IP_SUBNET *p = LIST_DATA(o, i);
18550 
18551 			Free(p);
18552 		}
18553 
18554 		ReleaseList(o);
18555 	}
18556 
18557 	g_use_privateip_file = false;
18558 }
18559 
18560 // Check whether the specified IP address is in the same network to this computer
IsIPAddressInSameLocalNetwork(IP * a)18561 bool IsIPAddressInSameLocalNetwork(IP *a)
18562 {
18563 	bool ret = false;
18564 	LIST *o;
18565 	UINT i;
18566 	// Validate arguments
18567 	if (a == NULL)
18568 	{
18569 		return false;
18570 	}
18571 
18572 	o = GetHostIPAddressList();
18573 
18574 	if (o != NULL)
18575 	{
18576 		for (i = 0;i < LIST_NUM(o);i++)
18577 		{
18578 			IP *p = LIST_DATA(o, i);
18579 
18580 			if (IsIP4(p))
18581 			{
18582 				if (IsZeroIp(p) == false && p->addr[0] != 127)
18583 				{
18584 					if (IsInSameNetwork4Standard(p, a))
18585 					{
18586 						ret = true;
18587 						break;
18588 					}
18589 				}
18590 			}
18591 		}
18592 
18593 		FreeHostIPAddressList(o);
18594 	}
18595 
18596 	return ret;
18597 }
18598 
18599 // Guess the IPv4, IPv6 global address from the IP address list of the current interface
GetCurrentGlobalIPGuess(IP * ip,bool ipv6)18600 void GetCurrentGlobalIPGuess(IP *ip, bool ipv6)
18601 {
18602 	LIST *o;
18603 	UINT i;
18604 	// Validate arguments
18605 	if (ip == NULL)
18606 	{
18607 		return;
18608 	}
18609 
18610 	Zero(ip, sizeof(IP));
18611 
18612 	o = GetHostIPAddressList();
18613 
18614 	if (ipv6 == false)
18615 	{
18616 		// IPv4
18617 		for (i = 0;i < LIST_NUM(o);i++)
18618 		{
18619 			IP *p = LIST_DATA(o, i);
18620 
18621 			if (IsIP4(p))
18622 			{
18623 				if (IsZeroIp(p) == false && IsIPPrivate(p) == false && p->addr[0] != 127)
18624 				{
18625 					Copy(ip, p, sizeof(IP));
18626 				}
18627 			}
18628 		}
18629 
18630 		if (IsZeroIp(ip))
18631 		{
18632 			for (i = 0;i < LIST_NUM(o);i++)
18633 			{
18634 				IP *p = LIST_DATA(o, i);
18635 
18636 				if (IsIP4(p))
18637 				{
18638 					if (IsZeroIp(p) == false && IsIPPrivate(p) && p->addr[0] != 127)
18639 					{
18640 						Copy(ip, p, sizeof(IP));
18641 					}
18642 				}
18643 			}
18644 		}
18645 
18646 		if (IsZeroIp(ip))
18647 		{
18648 			SetIP(ip, 127, 0, 0, 1);
18649 		}
18650 	}
18651 	else
18652 	{
18653 		// IPv6
18654 		for (i = 0;i < LIST_NUM(o);i++)
18655 		{
18656 			IP *p = LIST_DATA(o, i);
18657 
18658 			if (IsIP6(p))
18659 			{
18660 				UINT type = GetIPAddrType6(p);
18661 
18662 				if ((type & IPV6_ADDR_GLOBAL_UNICAST) && ((type & IPV6_ADDR_ZERO) == 0) && ((type & IPV6_ADDR_LOOPBACK) == 0))
18663 				{
18664 					Copy(ip, p, sizeof(IP));
18665 				}
18666 			}
18667 		}
18668 	}
18669 
18670 	FreeHostIPAddressList(o);
18671 }
18672 
18673 // Record the current global IP address
SetCurrentGlobalIP(IP * ip,bool ipv6)18674 void SetCurrentGlobalIP(IP *ip, bool ipv6)
18675 {
18676 	// Validate arguments
18677 	if (ip == NULL)
18678 	{
18679 		return;
18680 	}
18681 
18682 	if (IsZeroIp(ip))
18683 	{
18684 		return;
18685 	}
18686 
18687 	Lock(current_global_ip_lock);
18688 	{
18689 		if (ipv6 == false)
18690 		{
18691 			Copy(&current_glocal_ipv4, ip, sizeof(IP));
18692 		}
18693 		else
18694 		{
18695 			Copy(&current_glocal_ipv6, ip, sizeof(IP));
18696 		}
18697 
18698 		current_global_ip_set = true;
18699 	}
18700 	Unlock(current_global_ip_lock);
18701 }
18702 
18703 // Release of the network communication module
FreeNetwork()18704 void FreeNetwork()
18705 {
18706 
18707 	if (dh_2048 != NULL)
18708 	{
18709 		DhFree(dh_2048);
18710 		dh_2048 = NULL;
18711 	}
18712 
18713 	// Release of thread-related
18714 	FreeWaitThread();
18715 
18716 	FreeToken(cipher_list_token);
18717 	cipher_list_token = NULL;
18718 
18719 	Zero(&unix_dns_server, sizeof(unix_dns_server));
18720 
18721 	// Release the locks
18722 	DeleteLock(unix_dns_server_addr_lock);
18723 	DeleteLock(dns_lock);
18724 	DeleteLock(ssl_accept_lock);
18725 	DeleteLock(machine_name_lock);
18726 	DeleteLock(disconnect_function_lock);
18727 	DeleteLock(aho);
18728 	DeleteLock(socket_library_lock);
18729 	DeleteLock(ssl_connect_lock);
18730 	DeleteLock(machine_ip_process_hash_lock);
18731 	machine_name_lock = NULL;
18732 	ssl_accept_lock = machine_name_lock = disconnect_function_lock =
18733 		aho = socket_library_lock = ssl_connect_lock = machine_ip_process_hash_lock = NULL;
18734 
18735 	// Release of the DNS cache
18736 	FreeDnsCache();
18737 
18738 	// Release of the host name cache
18739 	FreeHostCache();
18740 
18741 #ifdef	OS_WIN32
18742 	// Release of the socket library
18743 	Win32FreeSocketLibrary();
18744 #else
18745 	UnixFreeSocketLibrary();
18746 #endif	// OS_WIN32
18747 
18748 	DeleteCounter(num_tcp_connections);
18749 	num_tcp_connections = NULL;
18750 
18751 	// Release of client list
18752 	FreeIpClientList();
18753 
18754 	DeleteLock(current_global_ip_lock);
18755 	current_global_ip_lock = NULL;
18756 
18757 	DeleteLock(current_fqdn_lock);
18758 	current_fqdn_lock = NULL;
18759 
18760 	// Release of the local MAC list
18761 	if (local_mac_list != NULL)
18762 	{
18763 		FreeNicList(local_mac_list);
18764 		local_mac_list = NULL;
18765 	}
18766 
18767 	DeleteLock(local_mac_list_lock);
18768 	local_mac_list_lock = NULL;
18769 
18770 	DeleteLock(host_ip_address_list_cache_lock);
18771 	host_ip_address_list_cache_lock = NULL;
18772 
18773 	FreeHostIPAddressList(host_ip_address_cache);
18774 	host_ip_address_cache = NULL;
18775 
18776 
18777 	FreeDynList();
18778 
18779 	DeleteCounter(getip_thread_counter);
18780 	getip_thread_counter = NULL;
18781 
18782 }
18783 
18784 // Add a socket to socket list
AddSockList(SOCKLIST * sl,SOCK * s)18785 void AddSockList(SOCKLIST *sl, SOCK *s)
18786 {
18787 	// Validate arguments
18788 	if (sl == NULL || s == NULL)
18789 	{
18790 		return;
18791 	}
18792 
18793 	LockList(sl->SockList);
18794 	{
18795 		if (IsInList(sl->SockList, s) == false)
18796 		{
18797 			AddRef(s->ref);
18798 
18799 			Insert(sl->SockList, s);
18800 		}
18801 	}
18802 	UnlockList(sl->SockList);
18803 }
18804 
18805 // Remove the socket from socket list
DelSockList(SOCKLIST * sl,SOCK * s)18806 void DelSockList(SOCKLIST *sl, SOCK *s)
18807 {
18808 	// Validate arguments
18809 	if (sl == NULL || s == NULL)
18810 	{
18811 		return;
18812 	}
18813 
18814 	LockList(sl->SockList);
18815 	{
18816 		if (Delete(sl->SockList, s))
18817 		{
18818 			ReleaseSock(s);
18819 		}
18820 	}
18821 	UnlockList(sl->SockList);
18822 }
18823 
18824 // Stop all the sockets in the list and delete it
StopSockList(SOCKLIST * sl)18825 void StopSockList(SOCKLIST *sl)
18826 {
18827 	SOCK **ss;
18828 	UINT num, i;
18829 	// Validate arguments
18830 	if (sl == NULL)
18831 	{
18832 		return;
18833 	}
18834 
18835 	LockList(sl->SockList);
18836 	{
18837 		num = LIST_NUM(sl->SockList);
18838 		ss = ToArray(sl->SockList);
18839 
18840 		DeleteAll(sl->SockList);
18841 	}
18842 	UnlockList(sl->SockList);
18843 
18844 	for (i = 0;i < num;i++)
18845 	{
18846 		SOCK *s = ss[i];
18847 
18848 		Disconnect(s);
18849 		ReleaseSock(s);
18850 	}
18851 
18852 	Free(ss);
18853 }
18854 
18855 // Delete the socket list
FreeSockList(SOCKLIST * sl)18856 void FreeSockList(SOCKLIST *sl)
18857 {
18858 	// Validate arguments
18859 	if (sl == NULL)
18860 	{
18861 		return;
18862 	}
18863 
18864 	StopSockList(sl);
18865 
18866 	ReleaseList(sl->SockList);
18867 
18868 	Free(sl);
18869 }
18870 
18871 // Creating a socket list
NewSockList()18872 SOCKLIST *NewSockList()
18873 {
18874 	SOCKLIST *sl = ZeroMallocFast(sizeof(SOCKLIST));
18875 
18876 	sl->SockList = NewList(NULL);
18877 
18878 	return sl;
18879 }
18880 
18881 // Time-out thread of the socket on Solaris
SocketTimeoutThread(THREAD * t,void * param)18882 void SocketTimeoutThread(THREAD *t, void *param)
18883 {
18884 	SOCKET_TIMEOUT_PARAM *ttparam;
18885 	ttparam = (SOCKET_TIMEOUT_PARAM *)param;
18886 
18887 	// Wait for time-out period
18888 	Select(NULL, ttparam->sock->TimeOut, ttparam->cancel, NULL);
18889 
18890 	// Disconnect if it is blocked
18891 	if(! ttparam->unblocked)
18892 	{
18893 //		Debug("Socket timeouted\n");
18894 		closesocket(ttparam->sock->socket);
18895 	}
18896 	else
18897 	{
18898 //		Debug("Socket timeout cancelled\n");
18899 	}
18900 }
18901 
18902 // Initialize and start the thread for time-out
NewSocketTimeout(SOCK * sock)18903 SOCKET_TIMEOUT_PARAM *NewSocketTimeout(SOCK *sock)
18904 {
18905 	SOCKET_TIMEOUT_PARAM *ttp;
18906 	if(! sock->AsyncMode && sock->TimeOut != TIMEOUT_INFINITE)
18907 	{
18908 //		Debug("NewSockTimeout(%u)\n",sock->TimeOut);
18909 
18910 		ttp = (SOCKET_TIMEOUT_PARAM*)Malloc(sizeof(SOCKET_TIMEOUT_PARAM));
18911 
18912 		// Set the parameters of the time-out thread
18913 		ttp->cancel = NewCancel();
18914 		ttp->sock = sock;
18915 		ttp->unblocked = false;
18916 		ttp->thread = NewThread(SocketTimeoutThread, ttp);
18917 		return ttp;
18918 	}
18919 	return NULL;
18920 }
18921 
18922 // Stop and free the thread for timeout
FreeSocketTimeout(SOCKET_TIMEOUT_PARAM * ttp)18923 void FreeSocketTimeout(SOCKET_TIMEOUT_PARAM *ttp)
18924 {
18925 	if(ttp == NULL)
18926 	{
18927 		return;
18928 	}
18929 
18930 	ttp->unblocked = true;
18931 	Cancel(ttp->cancel);
18932 	WaitThread(ttp->thread, INFINITE);
18933 	ReleaseCancel(ttp->cancel);
18934 	ReleaseThread(ttp->thread);
18935 	Free(ttp);
18936 //	Debug("FreeSocketTimeout succeed\n");
18937 	return;
18938 }
18939 
18940 // Parse the IP address and subnet mask
ParseIpAndSubnetMask46(char * src,IP * ip,IP * mask)18941 bool ParseIpAndSubnetMask46(char *src, IP *ip, IP *mask)
18942 {
18943 	// Validate arguments
18944 	if (src == NULL || ip == NULL || mask == NULL)
18945 	{
18946 		return false;
18947 	}
18948 
18949 	if (ParseIpAndMask46(src, ip, mask) == false)
18950 	{
18951 		return false;
18952 	}
18953 
18954 	if (IsIP4(ip))
18955 	{
18956 		return IsSubnetMask4(mask);
18957 	}
18958 	else
18959 	{
18960 		return IsSubnetMask6(mask);
18961 	}
18962 }
ParseIpAndSubnetMask6(char * src,IP * ip,IP * mask)18963 bool ParseIpAndSubnetMask6(char *src, IP *ip, IP *mask)
18964 {
18965 	if (ParseIpAndSubnetMask46(src, ip, mask) == false)
18966 	{
18967 		return false;
18968 	}
18969 
18970 	if (IsIP6(ip) == false)
18971 	{
18972 		return false;
18973 	}
18974 
18975 	return true;
18976 }
ParseIpAndSubnetMask4(char * src,UINT * ip,UINT * mask)18977 bool ParseIpAndSubnetMask4(char *src, UINT *ip, UINT *mask)
18978 {
18979 	IP ip2, mask2;
18980 	// Validate arguments
18981 	if (src == NULL)
18982 	{
18983 		return false;
18984 	}
18985 
18986 	if (ParseIpAndSubnetMask46(src, &ip2, &mask2) == false)
18987 	{
18988 		return false;
18989 	}
18990 
18991 	if (IsIP4(&ip2) == false)
18992 	{
18993 		return false;
18994 	}
18995 
18996 	if (ip != NULL)
18997 	{
18998 		*ip = IPToUINT(&ip2);
18999 	}
19000 
19001 	if (mask != NULL)
19002 	{
19003 		*mask = IPToUINT(&mask2);
19004 	}
19005 
19006 	return true;
19007 }
19008 
19009 
19010 // Parse the IP address and the mask
ParseIpAndMask46(char * src,IP * ip,IP * mask)19011 bool ParseIpAndMask46(char *src, IP *ip, IP *mask)
19012 {
19013 	TOKEN_LIST *t;
19014 	char *ipstr;
19015 	char *subnetstr;
19016 	bool ret = false;
19017 	IP ip2;
19018 	IP mask2;
19019 	// Validate arguments
19020 	if (src == NULL || ip == NULL || mask == NULL)
19021 	{
19022 		return false;
19023 	}
19024 
19025 	Zero(&ip2, sizeof(IP));
19026 	Zero(&mask2, sizeof(IP));
19027 
19028 	t = ParseToken(src, "/");
19029 	if (t->NumTokens != 2)
19030 	{
19031 		FreeToken(t);
19032 		return false;
19033 	}
19034 
19035 	ipstr = t->Token[0];
19036 	subnetstr = t->Token[1];
19037 	Trim(ipstr);
19038 	Trim(subnetstr);
19039 
19040 	if (StrToIP(&ip2, ipstr))
19041 	{
19042 		if (StrToIP(&mask2, subnetstr))
19043 		{
19044 			// Compare the kind of the mask part and the IP address part to confirm same
19045 			if (IsIP6(&ip2) && IsIP6(&mask2))
19046 			{
19047 				// Both are IPv6
19048 				ret = true;
19049 				Copy(ip, &ip2, sizeof(IP));
19050 				Copy(mask, &mask2, sizeof(IP));
19051 			}
19052 			else if (IsIP4(&ip2) && IsIP4(&mask2))
19053 			{
19054 				// Both are IPv4
19055 				ret = true;
19056 				Copy(ip, &ip2, sizeof(IP));
19057 				Copy(mask, &mask2, sizeof(IP));
19058 			}
19059 		}
19060 		else
19061 		{
19062 			if (IsNum(subnetstr))
19063 			{
19064 				UINT i = ToInt(subnetstr);
19065 				// Mask part is a number
19066 				if (IsIP6(&ip2) && i <= 128)
19067 				{
19068 					ret = true;
19069 					Copy(ip, &ip2, sizeof(IP));
19070 					IntToSubnetMask6(mask, i);
19071 				}
19072 				else if (i <= 32)
19073 				{
19074 					ret = true;
19075 					Copy(ip, &ip2, sizeof(IP));
19076 					IntToSubnetMask4(mask, i);
19077 				}
19078 			}
19079 		}
19080 	}
19081 
19082 	FreeToken(t);
19083 
19084 	return ret;
19085 }
ParseIpAndMask4(char * src,UINT * ip,UINT * mask)19086 bool ParseIpAndMask4(char *src, UINT *ip, UINT *mask)
19087 {
19088 	IP ip_ip, ip_mask;
19089 	if (ParseIpAndMask46(src, &ip_ip, &ip_mask) == false)
19090 	{
19091 		return false;
19092 	}
19093 
19094 	if (IsIP4(&ip_ip) == false)
19095 	{
19096 		return false;
19097 	}
19098 
19099 	if (ip != NULL)
19100 	{
19101 		*ip = IPToUINT(&ip_ip);
19102 	}
19103 
19104 	if (mask != NULL)
19105 	{
19106 		*mask = IPToUINT(&ip_mask);
19107 	}
19108 
19109 	return true;
19110 }
ParseIpAndMask6(char * src,IP * ip,IP * mask)19111 bool ParseIpAndMask6(char *src, IP *ip, IP *mask)
19112 {
19113 	if (ParseIpAndMask46(src, ip, mask) == false)
19114 	{
19115 		return false;
19116 	}
19117 
19118 	if (IsIP6(ip) == false)
19119 	{
19120 		return false;
19121 	}
19122 
19123 	return true;
19124 }
19125 
19126 
19127 // Check whether the specification of the IPv4 address is correct
IsIpStr4(char * str)19128 bool IsIpStr4(char *str)
19129 {
19130 	// Validate arguments
19131 	if (str == NULL)
19132 	{
19133 		return false;
19134 	}
19135 
19136 	if (StrToIP32(str) == 0 && StrCmpi(str, "0.0.0.0") != 0)
19137 	{
19138 		return false;
19139 	}
19140 
19141 	return true;
19142 }
19143 
19144 // Check whether the specification of the IPv6 address is correct
IsIpStr6(char * str)19145 bool IsIpStr6(char *str)
19146 {
19147 	IP ip;
19148 	// Validate arguments
19149 	if (str == NULL)
19150 	{
19151 		return false;
19152 	}
19153 
19154 	if (StrToIP6(&ip, str) == false)
19155 	{
19156 		return false;
19157 	}
19158 
19159 	return true;
19160 }
19161 
19162 // Check whether the IP address specification is correct
IsIpStr46(char * str)19163 bool IsIpStr46(char *str)
19164 {
19165 	if (IsIpStr4(str) || IsIpStr6(str))
19166 	{
19167 		return true;
19168 	}
19169 
19170 	return false;
19171 }
19172 
19173 
19174 // Convert the string to an IPv4 mask
StrToMask4(IP * mask,char * str)19175 bool StrToMask4(IP *mask, char *str)
19176 {
19177 	// Validate arguments
19178 	if (mask == NULL || str == NULL)
19179 	{
19180 		return false;
19181 	}
19182 
19183 	if (str[0] == '/')
19184 	{
19185 		str++;
19186 	}
19187 
19188 	if (IsNum(str))
19189 	{
19190 		UINT n = ToInt(str);
19191 
19192 		if (n <= 32)
19193 		{
19194 			IntToSubnetMask4(mask, n);
19195 			return true;
19196 		}
19197 		else
19198 		{
19199 			return false;
19200 		}
19201 	}
19202 	else
19203 	{
19204 		if (StrToIP(mask, str) == false)
19205 		{
19206 			return false;
19207 		}
19208 		else
19209 		{
19210 			return IsIP4(mask);
19211 		}
19212 	}
19213 }
19214 
19215 // Convert the string to an IPv6 mask
StrToMask6(IP * mask,char * str)19216 bool StrToMask6(IP *mask, char *str)
19217 {
19218 	// Validate arguments
19219 	if (mask == NULL || str == NULL)
19220 	{
19221 		return false;
19222 	}
19223 
19224 	if (str[0] == '/')
19225 	{
19226 		str++;
19227 	}
19228 
19229 	if (IsNum(str))
19230 	{
19231 		UINT n = ToInt(str);
19232 
19233 		if (n <= 128)
19234 		{
19235 			IntToSubnetMask6(mask, n);
19236 			return true;
19237 		}
19238 		else
19239 		{
19240 			return false;
19241 		}
19242 	}
19243 	else
19244 	{
19245 		if (StrToIP(mask, str) == false)
19246 		{
19247 			return false;
19248 		}
19249 		else
19250 		{
19251 			return IsIP6(mask);
19252 		}
19253 	}
19254 }
StrToMask6Addr(IPV6_ADDR * mask,char * str)19255 bool StrToMask6Addr(IPV6_ADDR *mask, char *str)
19256 {
19257 	IP ip;
19258 
19259 	if (StrToMask6(&ip, str) == false)
19260 	{
19261 		return false;
19262 	}
19263 
19264 	if (IPToIPv6Addr(mask, &ip) == false)
19265 	{
19266 		return false;
19267 	}
19268 
19269 	return true;
19270 }
19271 
19272 // Convert the string to an IPv4 / IPv6 mask
StrToMask46(IP * mask,char * str,bool ipv6)19273 bool StrToMask46(IP *mask, char *str, bool ipv6)
19274 {
19275 	if (ipv6)
19276 	{
19277 		return StrToMask6(mask, str);
19278 	}
19279 	else
19280 	{
19281 		return StrToMask4(mask, str);
19282 	}
19283 }
19284 
19285 
19286 // Convert the IPv4 / IPv6 mask to a string
MaskToStr(char * str,UINT size,IP * mask)19287 void MaskToStr(char *str, UINT size, IP *mask)
19288 {
19289 	MaskToStrEx(str, size, mask, false);
19290 }
MaskToStrEx(char * str,UINT size,IP * mask,bool always_full_address)19291 void MaskToStrEx(char *str, UINT size, IP *mask, bool always_full_address)
19292 {
19293 	// Validate arguments
19294 	if (str == NULL || mask == NULL)
19295 	{
19296 		return;
19297 	}
19298 
19299 	if (always_full_address == false && IsSubnetMask(mask))
19300 	{
19301 		ToStr(str, SubnetMaskToInt(mask));
19302 	}
19303 	else
19304 	{
19305 		IPToStr(str, size, mask);
19306 	}
19307 }
MaskToStr32(char * str,UINT size,UINT mask)19308 void MaskToStr32(char *str, UINT size, UINT mask)
19309 {
19310 	MaskToStr32Ex(str, size, mask, false);
19311 }
MaskToStr32Ex(char * str,UINT size,UINT mask,bool always_full_address)19312 void MaskToStr32Ex(char *str, UINT size, UINT mask, bool always_full_address)
19313 {
19314 	IP ip;
19315 
19316 	UINTToIP(&ip, mask);
19317 
19318 	MaskToStrEx(str, size, &ip, always_full_address);
19319 }
Mask6AddrToStrEx(char * str,UINT size,IPV6_ADDR * mask,bool always_full_address)19320 void Mask6AddrToStrEx(char *str, UINT size, IPV6_ADDR *mask, bool always_full_address)
19321 {
19322 	IP ip;
19323 
19324 	// Validate arguments
19325 	if (str == NULL || mask == NULL)
19326 	{
19327 		StrCpy(str, size, "");
19328 		return;
19329 	}
19330 
19331 	IPv6AddrToIP(&ip, mask);
19332 
19333 	MaskToStrEx(str, size, &ip, always_full_address);
19334 }
Mask6AddrToStr(char * str,UINT size,IPV6_ADDR * mask)19335 void Mask6AddrToStr(char *str, UINT size, IPV6_ADDR *mask)
19336 {
19337 	Mask6AddrToStrEx(str, size, mask, false);
19338 }
19339 
19340 // Disconnecting of the tube
TubeDisconnect(TUBE * t)19341 void TubeDisconnect(TUBE *t)
19342 {
19343 	// Validate arguments
19344 	if (t == NULL)
19345 	{
19346 		return;
19347 	}
19348 
19349 	if (t->TubePairData == NULL)
19350 	{
19351 		return;
19352 	}
19353 
19354 	Lock(t->TubePairData->Lock);
19355 	{
19356 		t->TubePairData->IsDisconnected = true;
19357 
19358 		Set(t->TubePairData->Event1);
19359 		Set(t->TubePairData->Event2);
19360 		SetSockEvent(t->TubePairData->SockEvent1);
19361 		SetSockEvent(t->TubePairData->SockEvent2);
19362 	}
19363 	Unlock(t->TubePairData->Lock);
19364 }
19365 
19366 // Creating a tube pair
NewTubePair(TUBE ** t1,TUBE ** t2,UINT size_of_header)19367 void NewTubePair(TUBE **t1, TUBE **t2, UINT size_of_header)
19368 {
19369 	TUBEPAIR_DATA *d;
19370 	// Validate arguments
19371 	if (t1 == NULL || t2 == NULL)
19372 	{
19373 		return;
19374 	}
19375 
19376 	*t1 = NewTube(size_of_header);
19377 	*t2 = NewTube(size_of_header);
19378 
19379 	(*t1)->IndexInTubePair = 0;
19380 	(*t2)->IndexInTubePair = 1;
19381 
19382 	d = NewTubePairData();
19383 	AddRef(d->Ref);
19384 
19385 	(*t1)->TubePairData = d;
19386 	(*t2)->TubePairData = d;
19387 
19388 	d->Event1 = (*t1)->Event;
19389 	d->Event2 = (*t2)->Event;
19390 
19391 	AddRef(d->Event1->ref);
19392 	AddRef(d->Event2->ref);
19393 }
19394 
19395 // Creating a tube pair data
NewTubePairData()19396 TUBEPAIR_DATA *NewTubePairData()
19397 {
19398 	TUBEPAIR_DATA *d = ZeroMalloc(sizeof(TUBEPAIR_DATA));
19399 
19400 	d->Ref = NewRef();
19401 
19402 	d->Lock = NewLock();
19403 
19404 	return d;
19405 }
19406 
19407 // Set the SockEvent to the tube
SetTubeSockEvent(TUBE * t,SOCK_EVENT * e)19408 void SetTubeSockEvent(TUBE *t, SOCK_EVENT *e)
19409 {
19410 	// Validate arguments
19411 	if (t == NULL)
19412 	{
19413 		return;
19414 	}
19415 
19416 	Lock(t->Lock);
19417 	{
19418 		TUBEPAIR_DATA *d;
19419 
19420 		if (t->SockEvent != e)
19421 		{
19422 			if (t->SockEvent != NULL)
19423 			{
19424 				ReleaseSockEvent(t->SockEvent);
19425 			}
19426 
19427 			if (e != NULL)
19428 			{
19429 				AddRef(e->ref);
19430 			}
19431 
19432 			t->SockEvent = e;
19433 		}
19434 
19435 		d = t->TubePairData;
19436 
19437 		if (d != NULL)
19438 		{
19439 			Lock(d->Lock);
19440 			{
19441 				SOCK_EVENT **sep = (t->IndexInTubePair == 0 ? &d->SockEvent1 : &d->SockEvent2);
19442 
19443 				if (*sep != e)
19444 				{
19445 					if (*sep != NULL)
19446 					{
19447 						ReleaseSockEvent(*sep);
19448 					}
19449 
19450 					if (e != NULL)
19451 					{
19452 						AddRef(e->ref);
19453 					}
19454 
19455 					*sep = e;
19456 				}
19457 			}
19458 			Unlock(d->Lock);
19459 		}
19460 	}
19461 	Unlock(t->Lock);
19462 }
19463 
19464 // Release of the tube pair data
ReleaseTubePairData(TUBEPAIR_DATA * d)19465 void ReleaseTubePairData(TUBEPAIR_DATA *d)
19466 {
19467 	// Validate arguments
19468 	if (d == NULL)
19469 	{
19470 		return;
19471 	}
19472 
19473 	if (Release(d->Ref) == 0)
19474 	{
19475 		CleanupTubePairData(d);
19476 	}
19477 }
CleanupTubePairData(TUBEPAIR_DATA * d)19478 void CleanupTubePairData(TUBEPAIR_DATA *d)
19479 {
19480 	// Validate arguments
19481 	if (d == NULL)
19482 	{
19483 		return;
19484 	}
19485 
19486 	ReleaseEvent(d->Event1);
19487 	ReleaseEvent(d->Event2);
19488 
19489 	ReleaseSockEvent(d->SockEvent1);
19490 	ReleaseSockEvent(d->SockEvent2);
19491 
19492 	DeleteLock(d->Lock);
19493 
19494 	Free(d);
19495 }
19496 
19497 // Check whether the tube is connected to the opponent still
IsTubeConnected(TUBE * t)19498 bool IsTubeConnected(TUBE *t)
19499 {
19500 	// Validate arguments
19501 	if (t == NULL)
19502 	{
19503 		return false;
19504 	}
19505 
19506 	if (t->TubePairData == NULL)
19507 	{
19508 		return true;
19509 	}
19510 
19511 	if (t->TubePairData->IsDisconnected)
19512 	{
19513 		return false;
19514 	}
19515 
19516 	return true;
19517 }
19518 
19519 // Send the data to the tube
TubeSend(TUBE * t,void * data,UINT size,void * header)19520 bool TubeSend(TUBE *t, void *data, UINT size, void *header)
19521 {
19522 	return TubeSendEx(t, data, size, header, false);
19523 }
TubeSendEx(TUBE * t,void * data,UINT size,void * header,bool no_flush)19524 bool TubeSendEx(TUBE *t, void *data, UINT size, void *header, bool no_flush)
19525 {
19526 	return TubeSendEx2(t, data, size, header, no_flush, 0);
19527 }
TubeSendEx2(TUBE * t,void * data,UINT size,void * header,bool no_flush,UINT max_num_in_queue)19528 bool TubeSendEx2(TUBE *t, void *data, UINT size, void *header, bool no_flush, UINT max_num_in_queue)
19529 {
19530 	// Validate arguments
19531 	if (t == NULL || data == NULL || size == 0)
19532 	{
19533 		return false;
19534 	}
19535 
19536 	if (IsTubeConnected(t) == false)
19537 	{
19538 		return false;
19539 	}
19540 
19541 	LockQueue(t->Queue);
19542 	{
19543 		if (max_num_in_queue == 0 || (t->Queue->num_item <= max_num_in_queue))
19544 		{
19545 			InsertQueue(t->Queue, NewTubeData(data, size, header, t->SizeOfHeader));
19546 		}
19547 		else
19548 		{
19549 			no_flush = true;
19550 		}
19551 	}
19552 	UnlockQueue(t->Queue);
19553 
19554 	if (no_flush == false)
19555 	{
19556 		Set(t->Event);
19557 		SetSockEvent(t->SockEvent);
19558 	}
19559 
19560 	return true;
19561 }
19562 
19563 // Flush the tube
TubeFlush(TUBE * t)19564 void TubeFlush(TUBE *t)
19565 {
19566 	TubeFlushEx(t, false);
19567 }
TubeFlushEx(TUBE * t,bool force)19568 void TubeFlushEx(TUBE *t, bool force)
19569 {
19570 	// Validate arguments
19571 	if (t == NULL)
19572 	{
19573 		return;
19574 	}
19575 
19576 	if (IsTubeConnected(t) == false)
19577 	{
19578 		return;
19579 	}
19580 
19581 	if (force == false)
19582 	{
19583 		if (t->Queue->num_item == 0)
19584 		{
19585 			return;
19586 		}
19587 	}
19588 
19589 	Set(t->Event);
19590 	SetSockEvent(t->SockEvent);
19591 }
19592 
19593 // Receive the data from the tube (asynchronous)
TubeRecvAsync(TUBE * t)19594 TUBEDATA *TubeRecvAsync(TUBE *t)
19595 {
19596 	TUBEDATA *d;
19597 	// Validate arguments
19598 	if (t == NULL)
19599 	{
19600 		return NULL;
19601 	}
19602 
19603 	if (IsTubeConnected(t) == false)
19604 	{
19605 		return NULL;
19606 	}
19607 
19608 	LockQueue(t->Queue);
19609 	{
19610 		d = GetNext(t->Queue);
19611 	}
19612 	UnlockQueue(t->Queue);
19613 
19614 	return d;
19615 }
19616 
19617 // Get the SockEvent associated with the tube
GetTubeSockEvent(TUBE * t)19618 SOCK_EVENT *GetTubeSockEvent(TUBE *t)
19619 {
19620 	SOCK_EVENT *e = NULL;
19621 	// Validate arguments
19622 	if (t == NULL)
19623 	{
19624 		return NULL;
19625 	}
19626 
19627 	Lock(t->Lock);
19628 	{
19629 		if (t->SockEvent != NULL)
19630 		{
19631 			AddRef(t->SockEvent->ref);
19632 
19633 			e = t->SockEvent;
19634 		}
19635 	}
19636 	Unlock(t->Lock);
19637 
19638 	return e;
19639 }
19640 
19641 // Receive the data from the tube (synchronous)
TubeRecvSync(TUBE * t,UINT timeout)19642 TUBEDATA *TubeRecvSync(TUBE *t, UINT timeout)
19643 {
19644 	UINT64 start_tick, timeout_tick;
19645 	TUBEDATA *d = NULL;
19646 	// Validate arguments
19647 	if (t == NULL)
19648 	{
19649 		return NULL;
19650 	}
19651 
19652 	if (IsTubeConnected(t) == false)
19653 	{
19654 		return NULL;
19655 	}
19656 
19657 	start_tick = Tick64();
19658 	timeout_tick = start_tick + (UINT64)timeout;
19659 
19660 	while (true)
19661 	{
19662 		UINT64 now = Tick64();
19663 		UINT remain_time;
19664 		SOCK_EVENT *e;
19665 		UINT interval;
19666 
19667 		d = NULL;
19668 
19669 		if (IsTubeConnected(t) == false)
19670 		{
19671 			break;
19672 		}
19673 
19674 		LockQueue(t->Queue);
19675 		{
19676 			d = GetNext(t->Queue);
19677 		}
19678 		UnlockQueue(t->Queue);
19679 
19680 		if (d != NULL)
19681 		{
19682 			break;
19683 		}
19684 
19685 		if (timeout != INFINITE && now >= timeout_tick)
19686 		{
19687 			return NULL;
19688 		}
19689 
19690 		remain_time = (UINT)(timeout_tick - now);
19691 
19692 		e = GetTubeSockEvent(t);
19693 
19694 		interval = (timeout == INFINITE ? INFINITE : remain_time);
19695 
19696 		if (e == NULL)
19697 		{
19698 			Wait(t->Event, interval);
19699 		}
19700 		else
19701 		{
19702 			WaitSockEvent(e, interval);
19703 
19704 			ReleaseSockEvent(e);
19705 		}
19706 	}
19707 
19708 	return d;
19709 }
19710 
19711 // Creating a tube
NewTube(UINT size_of_header)19712 TUBE *NewTube(UINT size_of_header)
19713 {
19714 	TUBE *t = ZeroMalloc(sizeof(TUBE));
19715 
19716 	t->Event = NewEvent();
19717 	t->Queue = NewQueue();
19718 	t->Ref = NewRef();
19719 	t->Lock = NewLock();
19720 	t->SockEvent = NewSockEvent();
19721 
19722 	t->SizeOfHeader = size_of_header;
19723 
19724 	return t;
19725 }
19726 
19727 // Release of the tube
ReleaseTube(TUBE * t)19728 void ReleaseTube(TUBE *t)
19729 {
19730 	// Validate arguments
19731 	if (t == NULL)
19732 	{
19733 		return;
19734 	}
19735 
19736 	if (Release(t->Ref) == 0)
19737 	{
19738 		CleanupTube(t);
19739 	}
19740 }
CleanupTube(TUBE * t)19741 void CleanupTube(TUBE *t)
19742 {
19743 	// Validate arguments
19744 	if (t == NULL)
19745 	{
19746 		return;
19747 	}
19748 
19749 	while (true)
19750 	{
19751 		TUBEDATA *d = GetNext(t->Queue);
19752 		if (d == NULL)
19753 		{
19754 			break;
19755 		}
19756 
19757 		FreeTubeData(d);
19758 	}
19759 
19760 	ReleaseQueue(t->Queue);
19761 	ReleaseEvent(t->Event);
19762 	ReleaseSockEvent(t->SockEvent);
19763 
19764 	ReleaseTubePairData(t->TubePairData);
19765 
19766 	DeleteLock(t->Lock);
19767 
19768 	Free(t);
19769 }
19770 
19771 // Creating a tube data
NewTubeData(void * data,UINT size,void * header,UINT header_size)19772 TUBEDATA *NewTubeData(void *data, UINT size, void *header, UINT header_size)
19773 {
19774 	TUBEDATA *d;
19775 	// Validate arguments
19776 	if (size == 0 || data == NULL)
19777 	{
19778 		return NULL;
19779 	}
19780 
19781 	d = ZeroMalloc(sizeof(TUBEDATA));
19782 
19783 	d->Data = Clone(data, size);
19784 	d->DataSize = size;
19785 	if (header != NULL)
19786 	{
19787 		d->Header = Clone(header, header_size);
19788 		d->HeaderSize = header_size;
19789 	}
19790 	else
19791 	{
19792 		d->Header = ZeroMalloc(header_size);
19793 	}
19794 
19795 	return d;
19796 }
19797 
19798 // Release of the tube data
FreeTubeData(TUBEDATA * d)19799 void FreeTubeData(TUBEDATA *d)
19800 {
19801 	// Validate arguments
19802 	if (d == NULL)
19803 	{
19804 		return;
19805 	}
19806 
19807 	Free(d->Data);
19808 	Free(d->Header);
19809 
19810 	Free(d);
19811 }
19812 
19813 // Release of the IP address list of the host
FreeHostIPAddressList(LIST * o)19814 void FreeHostIPAddressList(LIST *o)
19815 {
19816 	UINT i;
19817 	// Validate arguments
19818 	if (o == NULL)
19819 	{
19820 		return;
19821 	}
19822 
19823 	for (i = 0;i < LIST_NUM(o);i++)
19824 	{
19825 		IP *ip = LIST_DATA(o, i);
19826 
19827 		Free(ip);
19828 	}
19829 
19830 	ReleaseList(o);
19831 }
19832 
19833 // Get whether the specified IP address is held by this host
IsMyIPAddress(IP * ip)19834 bool IsMyIPAddress(IP *ip)
19835 {
19836 	LIST *o;
19837 	UINT i;
19838 	bool ret = false;
19839 	// Validate arguments
19840 	if (ip == NULL)
19841 	{
19842 		return false;
19843 	}
19844 
19845 	o = GetHostIPAddressList();
19846 
19847 	for (i = 0;i < LIST_NUM(o);i++)
19848 	{
19849 		IP *a = LIST_DATA(o, i);
19850 
19851 		if (CmpIpAddr(ip, a) == 0)
19852 		{
19853 			ret = true;
19854 			break;
19855 		}
19856 	}
19857 
19858 	FreeHostIPAddressList(o);
19859 
19860 	return ret;
19861 }
19862 
19863 // Add the IP address to the list
AddHostIPAddressToList(LIST * o,IP * ip)19864 void AddHostIPAddressToList(LIST *o, IP *ip)
19865 {
19866 	IP *r;
19867 	// Validate arguments
19868 	if (o == NULL || ip == NULL)
19869 	{
19870 		return;
19871 	}
19872 
19873 	r = Search(o, ip);
19874 	if (r != NULL)
19875 	{
19876 		return;
19877 	}
19878 
19879 	Insert(o, Clone(ip, sizeof(IP)));
19880 }
19881 
19882 // Comparison of the IP address list items
CmpIpAddressList(void * p1,void * p2)19883 int CmpIpAddressList(void *p1, void *p2)
19884 {
19885 	IP *ip1, *ip2;
19886 	UINT r;
19887 	// Validate arguments
19888 	if (p1 == NULL || p2 == NULL)
19889 	{
19890 		return 0;
19891 	}
19892 	ip1 = *(IP **)p1;
19893 	ip2 = *(IP **)p2;
19894 	if (ip1 == NULL || ip2 == NULL)
19895 	{
19896 		return 0;
19897 	}
19898 
19899 	// IPv4 < IPv6
19900 	r = COMPARE_RET(IsIP6(ip1), IsIP6(ip2));
19901 	if (r != 0)
19902 	{
19903 		return r;
19904 	}
19905 
19906 	// any > specified IP
19907 	if (IsZeroIP(ip1) && IsZeroIP(ip2) == false)
19908 	{
19909 		return 1;
19910 	}
19911 	if (IsZeroIP(ip1) == false && IsZeroIP(ip2))
19912 	{
19913 		return -1;
19914 	}
19915 
19916 	// local > others
19917 	if (IsLocalHostIP(ip1) && IsLocalHostIP(ip2) == false)
19918 	{
19919 		return 1;
19920 	}
19921 	if (IsLocalHostIP(ip1) == false && IsLocalHostIP(ip2))
19922 	{
19923 		return -1;
19924 	}
19925 
19926 	// ip address
19927 	r = CmpIpAddr(ip1, ip2);
19928 	if (r != 0)
19929 	{
19930 		return r;
19931 	}
19932 
19933 	// interface index
19934 	if (IsIP6(ip1))
19935 	{
19936 		r = COMPARE_RET(ip1->ipv6_scope_id, ip2->ipv6_scope_id);
19937 	}
19938 	else
19939 	{
19940 		r = 0;
19941 	}
19942 
19943 	return r;
19944 }
19945 
19946 // Get the IP address list hash of the host
GetHostIPAddressListHash()19947 UINT64 GetHostIPAddressListHash()
19948 {
19949 	UINT i;
19950 	LIST *o;
19951 	BUF *buf = NewBuf();
19952 	UCHAR hash[SHA1_SIZE];
19953 	UINT64 ret = 0;
19954 
19955 	o = GetHostIPAddressList();
19956 
19957 	if (o != NULL)
19958 	{
19959 		for (i = 0;i < LIST_NUM(o);i++)
19960 		{
19961 			IP *ip = LIST_DATA(o, i);
19962 			char tmp[128];
19963 
19964 			Zero(tmp, sizeof(tmp));
19965 			IPToStr(tmp, sizeof(tmp), ip);
19966 
19967 			WriteBufStr(buf, tmp);
19968 		}
19969 
19970 		FreeHostIPAddressList(o);
19971 	}
19972 
19973 	WriteBufStr(buf, "test");
19974 
19975 	HashSha1(hash, buf->Buf, buf->Size);
19976 
19977 	FreeBuf(buf);
19978 
19979 	Copy(&ret, hash, sizeof(UINT64));
19980 
19981 	ret = Endian64(ret);
19982 
19983 	return ret;
19984 }
19985 
19986 // Get the IP address list of the host (using cache)
GetHostIPAddressList()19987 LIST *GetHostIPAddressList()
19988 {
19989 	LIST *o = NULL;
19990 	if (host_ip_address_list_cache_lock == NULL)
19991 	{
19992 		return GetHostIPAddressListInternal();
19993 	}
19994 
19995 	Lock(host_ip_address_list_cache_lock);
19996 	{
19997 		UINT64 now = Tick64();
19998 
19999 		if (host_ip_address_list_cache_last == 0 ||
20000 			((host_ip_address_list_cache_last + (UINT64)HOST_IP_ADDRESS_LIST_CACHE) < now) ||
20001 			host_ip_address_cache == NULL)
20002 		{
20003 			if (host_ip_address_cache != NULL)
20004 			{
20005 				FreeHostIPAddressList(host_ip_address_cache);
20006 			}
20007 
20008 			host_ip_address_cache = GetHostIPAddressListInternal();
20009 
20010 			host_ip_address_list_cache_last = now;
20011 		}
20012 
20013 		o = CloneIPAddressList(host_ip_address_cache);
20014 	}
20015 	Unlock(host_ip_address_list_cache_lock);
20016 
20017 	if (o == NULL)
20018 	{
20019 		o = GetHostIPAddressListInternal();
20020 	}
20021 
20022 	return o;
20023 }
20024 
20025 // Copy of the IP address list
CloneIPAddressList(LIST * o)20026 LIST *CloneIPAddressList(LIST *o)
20027 {
20028 	LIST *ret;
20029 	UINT i;
20030 	// Validate arguments
20031 	if (o == NULL)
20032 	{
20033 		return NULL;
20034 	}
20035 
20036 	ret = NewListFast(CmpIpAddressList);
20037 
20038 	for (i = 0;i < LIST_NUM(o);i++)
20039 	{
20040 		IP *ip = LIST_DATA(o, i);
20041 
20042 		if (ip != NULL)
20043 		{
20044 			ip = Clone(ip, sizeof(IP));
20045 
20046 			Add(ret, ip);
20047 		}
20048 	}
20049 
20050 	return ret;
20051 }
20052 
20053 // Get an IP address list of the host
GetHostIPAddressListInternal()20054 LIST *GetHostIPAddressListInternal()
20055 {
20056 	char hostname[MAX_SIZE];
20057 	LIST *o;
20058 	IP any6, any4;
20059 	IP local6, local4;
20060 	bool is_v6_supported = IsIPv6Supported();
20061 
20062 	GetLocalHostIP4(&local4);
20063 	GetLocalHostIP6(&local6);
20064 
20065 	ZeroIP4(&any4);
20066 	ZeroIP6(&any6);
20067 
20068 	Zero(hostname, sizeof(hostname));
20069 
20070 	gethostname(hostname, sizeof(hostname));
20071 
20072 	o = NewListFast(CmpIpAddressList);
20073 
20074 	// any
20075 	AddHostIPAddressToList(o, &any4);
20076 	if (is_v6_supported)
20077 	{
20078 		AddHostIPAddressToList(o, &any6);
20079 	}
20080 
20081 	// localhost
20082 	AddHostIPAddressToList(o, &local4);
20083 	if (is_v6_supported)
20084 	{
20085 		AddHostIPAddressToList(o, &local6);
20086 	}
20087 
20088 #ifndef	MAYAQUA_SUPPORTS_GETIFADDRS
20089 	// IPv4
20090 	if (true)
20091 	{
20092 		struct sockaddr_in in;
20093 		struct in_addr addr;
20094 		struct addrinfo hint;
20095 		struct addrinfo *info;
20096 
20097 //		Debug("***** GetHostIPAddressListInternal IPv4 Begin *****\n");
20098 
20099 		Zero(&hint, sizeof(hint));
20100 		hint.ai_family = AF_INET;
20101 		hint.ai_socktype = SOCK_DGRAM;
20102 		hint.ai_protocol = IPPROTO_UDP;
20103 		info = NULL;
20104 
20105 		if (getaddrinfo(hostname, NULL, &hint, &info) == 0)
20106 		{
20107 			if (info->ai_family == AF_INET)
20108 			{
20109 				struct addrinfo *current = info;
20110 				while (current != NULL)
20111 				{
20112 					IP ip;
20113 
20114 					Copy(&in, current->ai_addr, sizeof(in));
20115 					Copy(&addr, &in.sin_addr, sizeof(addr));
20116 
20117 					InAddrToIP(&ip, &addr);
20118 					AddHostIPAddressToList(o, &ip);
20119 
20120 //					Debug("%r\n", &ip);
20121 
20122 					current = current->ai_next;
20123 				}
20124 			}
20125 
20126 			freeaddrinfo(info);
20127 		}
20128 //		Debug("***** GetHostIPAddressListInternal IPv4 End *****\n");
20129 	}
20130 
20131 #ifndef	UNIX_LINUX
20132 	// IPv6
20133 	if (is_v6_supported)
20134 	{
20135 		struct sockaddr_in6 in;
20136 		struct in6_addr addr;
20137 		struct addrinfo hint;
20138 		struct addrinfo *info;
20139 
20140 		Zero(&hint, sizeof(hint));
20141 		hint.ai_family = AF_INET6;
20142 		hint.ai_socktype = SOCK_DGRAM;
20143 		hint.ai_protocol = IPPROTO_UDP;
20144 		info = NULL;
20145 
20146 //		Debug("***** GetHostIPAddressListInternal IPv6 Begin *****\n");
20147 
20148 		if (getaddrinfo(hostname, NULL, &hint, &info) == 0)
20149 		{
20150 			if (info->ai_family == AF_INET6)
20151 			{
20152 				struct addrinfo *current = info;
20153 				while (current != NULL)
20154 				{
20155 					IP ip;
20156 
20157 					Copy(&in, current->ai_addr, sizeof(in));
20158 					Copy(&addr, &in.sin6_addr, sizeof(addr));
20159 
20160 					InAddrToIP6(&ip, &addr);
20161 					ip.ipv6_scope_id = in.sin6_scope_id;
20162 
20163 					AddHostIPAddressToList(o, &ip);
20164 
20165 //					Debug("%r\n", &ip);
20166 
20167 					current = current->ai_next;
20168 				}
20169 			}
20170 
20171 			freeaddrinfo(info);
20172 		}
20173 //		Debug("***** GetHostIPAddressListInternal IPv6 End *****\n");
20174 	}
20175 #endif	// UNIX_LINUX
20176 #endif	// MAYAQUA_SUPPORTS_GETIFADDRS
20177 
20178 #ifdef	MAYAQUA_SUPPORTS_GETIFADDRS
20179 	// If the getifaddrs is available, use this
20180 	if (true)
20181 	{
20182 		struct ifaddrs *aa = NULL;
20183 
20184 		if (getifaddrs(&aa) == 0)
20185 		{
20186 			struct ifaddrs *a = aa;
20187 
20188 			while (a != NULL)
20189 			{
20190 				if (a->ifa_addr != NULL)
20191 				{
20192 					 struct sockaddr *addr = a->ifa_addr;
20193 
20194 					 if (addr->sa_family == AF_INET)
20195 					 {
20196 						 IP ip;
20197 						 struct sockaddr_in *d = (struct sockaddr_in *)addr;
20198 						 struct in_addr *addr = &d->sin_addr;
20199 
20200 						 InAddrToIP(&ip, addr);
20201 
20202 						 AddHostIPAddressToList(o, &ip);
20203 					 }
20204 					 else if (addr->sa_family == AF_INET6)
20205 					 {
20206 						 IP ip;
20207 						 struct sockaddr_in6 *d = (struct sockaddr_in6 *)addr;
20208 						 UINT scope_id = d->sin6_scope_id;
20209 						 struct in6_addr *addr = &d->sin6_addr;
20210 
20211 						 InAddrToIP6(&ip, addr);
20212 						 ip.ipv6_scope_id = scope_id;
20213 
20214 						 AddHostIPAddressToList(o, &ip);
20215 					 }
20216 				}
20217 
20218 				a = a->ifa_next;
20219 			}
20220 
20221 			freeifaddrs(aa);
20222 		}
20223 	}
20224 #endif	// MAYAQUA_SUPPORTS_GETIFADDRS
20225 
20226 	return o;
20227 }
20228 
20229 // Get whether the UDP listener opens the specified port
IsUdpPortOpened(UDPLISTENER * u,IP * server_ip,UINT port)20230 bool IsUdpPortOpened(UDPLISTENER *u, IP *server_ip, UINT port)
20231 {
20232 	UINT i;
20233 	// Validate arguments
20234 	if (u == NULL || port == 0)
20235 	{
20236 		return false;
20237 	}
20238 
20239 	if (server_ip != NULL)
20240 	{
20241 		for (i = 0;i < LIST_NUM(u->SockList);i++)
20242 		{
20243 			UDPLISTENER_SOCK *us = LIST_DATA(u->SockList, i);
20244 
20245 			if (us->Sock != NULL && us->HasError == false)
20246 			{
20247 				if (us->Port == port)
20248 				{
20249 					if (CmpIpAddr(server_ip, &us->IpAddress) == 0)
20250 					{
20251 						return true;
20252 					}
20253 				}
20254 			}
20255 		}
20256 	}
20257 
20258 	for (i = 0;i < LIST_NUM(u->SockList);i++)
20259 	{
20260 		UDPLISTENER_SOCK *us = LIST_DATA(u->SockList, i);
20261 
20262 		if (us->Sock != NULL && us->HasError == false)
20263 		{
20264 			if (us->Port == port)
20265 			{
20266 				if (IsZeroIP(&us->IpAddress))
20267 				{
20268 					return true;
20269 				}
20270 			}
20271 		}
20272 	}
20273 
20274 	return false;
20275 }
20276 
20277 // IP address acquisition thread
QueryIpThreadMain(THREAD * thread,void * param)20278 void QueryIpThreadMain(THREAD *thread, void *param)
20279 {
20280 	QUERYIPTHREAD *t = (QUERYIPTHREAD *)param;
20281 	// Validate arguments
20282 	if (thread == NULL || param == NULL)
20283 	{
20284 		return;
20285 	}
20286 
20287 	while (t->Halt == false)
20288 	{
20289 		UINT next_wait_time = 0;
20290 		IP ip;
20291 		bool ok = false;
20292 
20293 		if (GetIP4Ex(&ip, t->Hostname, 5000, &t->Halt))
20294 		{
20295 			if (IsZeroIP(&ip) == false)
20296 			{
20297 				Lock(t->Lock);
20298 				{
20299 					Copy(&t->Ip, &ip, sizeof(IP));
20300 				}
20301 				Unlock(t->Lock);
20302 
20303 				ok = true;
20304 			}
20305 		}
20306 
20307 		if (ok == false)
20308 		{
20309 			next_wait_time = t->IntervalLastNg;
20310 		}
20311 		else
20312 		{
20313 			next_wait_time = t->IntervalLastOk;
20314 		}
20315 
20316 		if (t->Halt)
20317 		{
20318 			break;
20319 		}
20320 
20321 		Wait(t->HaltEvent, next_wait_time);
20322 	}
20323 }
20324 
20325 // Creating an IP address acquisition thread
NewQueryIpThread(char * hostname,UINT interval_last_ok,UINT interval_last_ng)20326 QUERYIPTHREAD *NewQueryIpThread(char *hostname, UINT interval_last_ok, UINT interval_last_ng)
20327 {
20328 	QUERYIPTHREAD *t;
20329 
20330 	t = ZeroMalloc(sizeof(QUERYIPTHREAD));
20331 
20332 	t->HaltEvent = NewEvent();
20333 	t->Lock = NewLock();
20334 	StrCpy(t->Hostname, sizeof(t->Hostname), hostname);
20335 	t->IntervalLastOk = interval_last_ok;
20336 	t->IntervalLastNg = interval_last_ng;
20337 
20338 	t->Thread = NewThread(QueryIpThreadMain, t);
20339 
20340 	return t;
20341 }
20342 
20343 // Get the results of the IP address acquisition thread
GetQueryIpThreadResult(QUERYIPTHREAD * t,IP * ip)20344 bool GetQueryIpThreadResult(QUERYIPTHREAD *t, IP *ip)
20345 {
20346 	bool ret = false;
20347 	Zero(ip, sizeof(IP));
20348 	// Validate arguments
20349 	if (t == NULL || ip == NULL)
20350 	{
20351 		return false;
20352 	}
20353 
20354 	Lock(t->Lock);
20355 
20356 	if (IsZero(&t->Ip, sizeof(IP)))
20357 	{
20358 		ret = false;
20359 	}
20360 	else
20361 	{
20362 		Copy(ip, &t->Ip, sizeof(IP));
20363 	}
20364 
20365 	Unlock(t->Lock);
20366 
20367 	return ret;
20368 }
20369 
20370 // Release of the IP address acquisition thread
FreeQueryIpThread(QUERYIPTHREAD * t)20371 void FreeQueryIpThread(QUERYIPTHREAD *t)
20372 {
20373 	// Validate arguments
20374 	if (t == NULL)
20375 	{
20376 		return;
20377 	}
20378 
20379 	t->Halt = true;
20380 	Set(t->HaltEvent);
20381 
20382 	WaitThread(t->Thread, INFINITE);
20383 	ReleaseThread(t->Thread);
20384 
20385 	ReleaseEvent(t->HaltEvent);
20386 
20387 	DeleteLock(t->Lock);
20388 
20389 	Free(t);
20390 }
20391 
20392 // Get a public port list which is known by UDP listener
UdpListenerGetPublicPortList(UDPLISTENER * u,char * dst,UINT size)20393 void UdpListenerGetPublicPortList(UDPLISTENER *u, char *dst, UINT size)
20394 {
20395 	UINT k;
20396 	// Validate arguments
20397 	ClearStr(dst, size);
20398 	if (u == NULL || dst == NULL)
20399 	{
20400 		return;
20401 	}
20402 
20403 	LockList(u->PortList);
20404 	{
20405 		for (k = 0;k < LIST_NUM(u->SockList);k++)
20406 		{
20407 			UDPLISTENER_SOCK *us = LIST_DATA(u->SockList, k);
20408 
20409 			if (us->PublicPort != 0)
20410 			{
20411 				char tmp[64];
20412 				ToStr(tmp, us->PublicPort);
20413 				StrCat(dst, size, tmp);
20414 				StrCat(dst, size, " ");
20415 			}
20416 		}
20417 	}
20418 	UnlockList(u->PortList);
20419 
20420 	Trim(dst);
20421 }
20422 
20423 // UDP listener thread
UdpListenerThread(THREAD * thread,void * param)20424 void UdpListenerThread(THREAD *thread, void *param)
20425 {
20426 	UDPLISTENER *u = (UDPLISTENER *)param;
20427 	UINT i, j, k;
20428 	UINT buf_size = 65536;
20429 	void *buf;
20430 	bool cont_flag;
20431 	BUF *ip_list_buf = NewBuf();
20432 	// Validate arguments
20433 	if (thread == NULL || param == NULL)
20434 	{
20435 		return;
20436 	}
20437 
20438 	buf = Malloc(buf_size);
20439 
20440 	// Initializing the socket list
20441 	u->SockList = NewList(NULL);
20442 
20443 	u->LastCheckTick = 0;
20444 
20445 //	u->PollMyIpAndPort = true;
20446 
20447 	// Main loop
20448 	while (u->Halt == false)
20449 	{
20450 		LIST *recv_list;
20451 		UINT recv_list_total_size = 0;
20452 		UINT64 now = Tick64();
20453 		UINT interval;
20454 		bool stage_changed = false;
20455 		IP nat_t_ip;
20456 
20457 		Zero(&nat_t_ip, sizeof(nat_t_ip));
20458 
20459 
20460 		if (u->LastCheckTick == 0 || (now >= (u->LastCheckTick + UDPLISTENER_CHECK_INTERVAL)))
20461 		{
20462 			LIST *iplist;
20463 			LIST *del_us_list = NewListFast(NULL);
20464 			BUF *ip_list_buf_new = NewBuf();
20465 
20466 			u->LastCheckTick = now;
20467 
20468 			// Obtain an IP address list
20469 			iplist = GetHostIPAddressList();
20470 
20471 			LockList(u->PortList);
20472 			{
20473 				for (k = 0;k < LIST_NUM(u->SockList);k++)
20474 				{
20475 					UDPLISTENER_SOCK *us = LIST_DATA(u->SockList, k);
20476 
20477 					us->Mark = false;
20478 				}
20479 
20480 				// If the combination of the IP address and the port number doesn't exist in the list, add it to the list
20481 				for (i = 0;i < LIST_NUM(iplist);i++)
20482 				{
20483 					IP *ip = LIST_DATA(iplist, i);
20484 
20485 					WriteBuf(ip_list_buf_new, ip, sizeof(IP));
20486 
20487 					for (j = 0;j < LIST_NUM(u->PortList);j++)
20488 					{
20489 						UINT k;
20490 						UINT *port = LIST_DATA(u->PortList, j);
20491 						bool existing = false;
20492 
20493 						if (IsZeroIP(ip) && (IS_SPECIAL_PORT(*port)))
20494 						{
20495 							continue;
20496 						}
20497 
20498 
20499 						for (k = 0;k < LIST_NUM(u->SockList);k++)
20500 						{
20501 							UDPLISTENER_SOCK *us = LIST_DATA(u->SockList, k);
20502 
20503 							if (CmpIpAddr(&us->IpAddress, ip) == 0 && us->Port == *port)
20504 							{
20505 								existing = true;
20506 
20507 								us->Mark = true;
20508 
20509 								break;
20510 							}
20511 						}
20512 
20513 						if (existing == false)
20514 						{
20515 							UDPLISTENER_SOCK *us = ZeroMalloc(sizeof(UDPLISTENER_SOCK));
20516 
20517 							Copy(&us->IpAddress, ip, sizeof(IP));
20518 							us->Port = *port;
20519 
20520 							us->Mark = true;
20521 
20522 							Add(u->SockList, us);
20523 						}
20524 					}
20525 				}
20526 
20527 				// If any errors suspected or the combination of IP address and port number
20528 				// has been regarded to delete already, delete it
20529 				for (k = 0;k < LIST_NUM(u->SockList);k++)
20530 				{
20531 					UDPLISTENER_SOCK *us = LIST_DATA(u->SockList, k);
20532 
20533 					if (us->Mark == false || us->HasError)
20534 					{
20535 						Debug("mark=%u error=%u\n", us->Mark, us->HasError);
20536 						Add(del_us_list, us);
20537 					}
20538 				}
20539 
20540 				for (i = 0;i < LIST_NUM(del_us_list);i++)
20541 				{
20542 					UDPLISTENER_SOCK *us = LIST_DATA(del_us_list, i);
20543 
20544 					char ipstr[MAX_SIZE];
20545 
20546 					IPToStr(ipstr, sizeof(ipstr), &us->IpAddress);
20547 					Debug("Closed UDP Port %u at %s.\n", us->Port, ipstr);
20548 
20549 					Delete(u->SockList, us);
20550 
20551 					if (us->Sock != NULL)
20552 					{
20553 						Disconnect(us->Sock);
20554 						ReleaseSock(us->Sock);
20555 					}
20556 
20557 					Free(us);
20558 				}
20559 			}
20560 			UnlockList(u->PortList);
20561 
20562 			// Open the UDP sockets which is not opend yet
20563 			for (k = 0;k < LIST_NUM(u->SockList);k++)
20564 			{
20565 				UDPLISTENER_SOCK *us = LIST_DATA(u->SockList, k);
20566 
20567 				if (us->Sock == NULL)
20568 				{
20569 					char ipstr[MAX_SIZE];
20570 
20571 					IPToStr(ipstr, sizeof(ipstr), &us->IpAddress);
20572 
20573 					if (us->ErrorDebugDisplayed == false)
20574 					{
20575 						Debug("Opening UDP Port %u at %s ...", us->Port, ipstr);
20576 					}
20577 
20578 					us->Sock = NewUDPEx2(us->Port, IsIP6(&us->IpAddress), &us->IpAddress);
20579 
20580 					if (us->Sock != NULL)
20581 					{
20582 						if (us->ErrorDebugDisplayed == false)
20583 						{
20584 							Debug("Ok.\n");
20585 						}
20586 						else
20587 						{
20588 							Debug("Opening UDP Port %u at %s ...", us->Port, ipstr);
20589 							Debug("Ok.\n");
20590 						}
20591 						JoinSockToSockEvent(us->Sock, u->Event);
20592 
20593 						us->ErrorDebugDisplayed = false;
20594 					}
20595 					else
20596 					{
20597 						if (us->ErrorDebugDisplayed == false)
20598 						{
20599 							Debug("Error.\n");
20600 						}
20601 
20602 						us->ErrorDebugDisplayed = true;
20603 					}
20604 				}
20605 			}
20606 
20607 			FreeHostIPAddressList(iplist);
20608 
20609 			ReleaseList(del_us_list);
20610 
20611 			if (CompareBuf(ip_list_buf, ip_list_buf_new) == false)
20612 			{
20613 				u->HostIPAddressListChanged = true;
20614 			}
20615 
20616 			FreeBuf(ip_list_buf);
20617 			ip_list_buf = ip_list_buf_new;
20618 		}
20619 
20620 LABEL_RESTART:
20621 
20622 		stage_changed = false;
20623 
20624 		recv_list = NewListFast(NULL);
20625 		recv_list_total_size = 0;
20626 
20627 		if (u->PollMyIpAndPort)
20628 		{
20629 			{
20630 				// Create a thread to get a NAT-T IP address if necessary
20631 				if (u->GetNatTIpThread == NULL)
20632 				{
20633 					char natt_hostname[MAX_SIZE];
20634 
20635 					RUDPGetRegisterHostNameByIP(natt_hostname, sizeof(natt_hostname), NULL);
20636 
20637 					u->GetNatTIpThread = NewQueryIpThread(natt_hostname, QUERYIPTHREAD_INTERVAL_LAST_OK, QUERYIPTHREAD_INTERVAL_LAST_NG);
20638 				}
20639 
20640 				GetQueryIpThreadResult(u->GetNatTIpThread, &nat_t_ip);
20641 			}
20642 		}
20643 
20644 		// Receive the data that is arriving at the socket
20645 		for (k = 0;k < LIST_NUM(u->SockList);k++)
20646 		{
20647 			UDPLISTENER_SOCK *us = LIST_DATA(u->SockList, k);
20648 
20649 			if (us->Sock != NULL)
20650 			{
20651 				UINT num_ignore_errors = 0;
20652 
20653 				if (u->PollMyIpAndPort && IsIP4(&us->IpAddress))
20654 				{
20655 					if (us->NextMyIpAndPortPollTick == 0 || us->NextMyIpAndPortPollTick <= now)
20656 					{
20657 						// Examine the self IP address and the self port number by using NAT-T server
20658 						us->NextMyIpAndPortPollTick = now + (UINT64)GenRandInterval(UDP_NAT_T_NAT_STATUS_CHECK_INTERVAL_MIN, UDP_NAT_T_NAT_STATUS_CHECK_INTERVAL_MAX);
20659 
20660 						if (IsZeroIP(&nat_t_ip) == false
20661 							)
20662 						{
20663 							UCHAR c = 'A';
20664 
20665 							SendTo(us->Sock, &nat_t_ip, UDP_NAT_T_PORT, &c, 1);
20666 						}
20667 					}
20668 				}
20669 
20670 				while (true)
20671 				{
20672 					IP src_addr;
20673 					UINT src_port;
20674 					UDPPACKET *p;
20675 					UINT size;
20676 
20677 					if (u->RecvBufSize != 0 && recv_list_total_size >= u->RecvBufSize)
20678 					{
20679 						// No more receive packet since the buffer is full
20680 						break;
20681 					}
20682 
20683 					size = RecvFrom(us->Sock, &src_addr, &src_port, buf, buf_size);
20684 					if (size == 0)
20685 					{
20686 						// Socket failure
20687 						if (us->Sock->IgnoreRecvErr == false)
20688 						{
20689 LABEL_FATAL_ERROR:
20690 							Debug("RecvFrom has Error.\n");
20691 							us->HasError = true;
20692 						}
20693 						else
20694 						{
20695 							if ((num_ignore_errors++) >= MAX_NUM_IGNORE_ERRORS)
20696 							{
20697 								goto LABEL_FATAL_ERROR;
20698 							}
20699 						}
20700 						break;
20701 					}
20702 					else if (size == SOCK_LATER)
20703 					{
20704 						// No packet
20705 						break;
20706 					}
20707 					//Debug("UDP %u\n", size);
20708 
20709 					if (src_port == UDP_NAT_T_PORT && CmpIpAddr(&src_addr, &nat_t_ip) == 0)
20710 					{
20711 						// Receive a packet in which the IP address and the port number are written from the NAT-T server
20712 						if (size >= 8)
20713 						{
20714 							IP my_ip;
20715 							UINT my_port;
20716 
20717 							if (RUDPParseIPAndPortStr(buf, size, &my_ip, &my_port))
20718 							{
20719 								Copy(&us->PublicIpAddress, &my_ip, sizeof(IP));
20720 								us->PublicPort = my_port;
20721 							}
20722 						}
20723 					}
20724 					else
20725 					{
20726 						// Receive a regular packet
20727 						p = NewUdpPacket(&src_addr, src_port, &us->Sock->LocalIP, us->Sock->LocalPort,
20728 							Clone(buf, size), size);
20729 
20730 						if (p->SrcPort == MAKE_SPECIAL_PORT(52))
20731 						{
20732 							p->SrcPort = p->DestPort = MAKE_SPECIAL_PORT(50);
20733 						}
20734 
20735 						Add(recv_list, p);
20736 
20737 						recv_list_total_size += size;
20738 					}
20739 
20740 					stage_changed = true;
20741 				}
20742 			}
20743 		}
20744 
20745 		// Pass the received packet to the procedure
20746 		// Print("recv_list_total_size = %u\n", recv_list_total_size);
20747 		u->RecvProc(u, recv_list);
20748 
20749 		// Release the packet
20750 		for (i = 0;i < LIST_NUM(recv_list);i++)
20751 		{
20752 			UDPPACKET *p = LIST_DATA(recv_list, i);
20753 
20754 			FreeUdpPacket(p);
20755 		}
20756 
20757 		ReleaseList(recv_list);
20758 
20759 		cont_flag = true;
20760 
20761 		do
20762 		{
20763 			// When there are packets to be transmitted, transmit it
20764 			LockList(u->SendPacketList);
20765 			{
20766 				UDPLISTENER_SOCK *last_us = NULL;
20767 				IP last_src_ip;
20768 				UINT last_src_port;
20769 
20770 				Zero(&last_src_ip, sizeof(IP));
20771 				last_src_port = 0;
20772 
20773 				// Print("LIST_NUM(u->SendPacketList) = %u\n", LIST_NUM(u->SendPacketList));
20774 
20775 				for (i = 0;i < LIST_NUM(u->SendPacketList);i++)
20776 				{
20777 					UDPPACKET *p = LIST_DATA(u->SendPacketList, i);
20778 					UDPLISTENER_SOCK *us;
20779 
20780 					if (last_us != NULL && last_src_port == p->SrcPort && CmpIpAddr(&last_src_ip, &p->SrcIP) == 0)
20781 					{
20782 						us = last_us;
20783 					}
20784 					else
20785 					{
20786 						// Search for a good interface for the transmission
20787 						us = DetermineUdpSocketForSending(u, p);
20788 
20789 						if (us != NULL)
20790 						{
20791 							last_us = us;
20792 							last_src_port = p->SrcPort;
20793 							Copy(&last_src_ip, &p->SrcIP, sizeof(IP));
20794 						}
20795 					}
20796 
20797 					if (us != NULL)
20798 					{
20799 						// Send
20800 						UINT ret = SendTo(us->Sock, &p->DstIP, p->DestPort, p->Data, p->Size);
20801 
20802 						if (ret == 0)
20803 						{
20804 							if (us->Sock->IgnoreSendErr == false)
20805 							{
20806 								// Socket failure
20807 								Debug("SendTo has Error.\n");
20808 								us->HasError = true;
20809 								last_us = NULL;
20810 							}
20811 						}
20812 						else
20813 						{
20814 							if (ret != SOCK_LATER)
20815 							{
20816 								stage_changed = true;
20817 							}
20818 						}
20819 					}
20820 
20821 					FreeUdpPacket(p);
20822 				}
20823 				DeleteAll(u->SendPacketList);
20824 			}
20825 			UnlockList(u->SendPacketList);
20826 
20827 			if (LIST_NUM(u->SendPacketList) == 0)
20828 			{
20829 				cont_flag = false;
20830 			}
20831 		}
20832 		while (cont_flag);
20833 
20834 		if (stage_changed && u->Halt == false)
20835 		{
20836 			goto LABEL_RESTART;
20837 		}
20838 
20839 		// Timing adjustment
20840 		interval = GetNextIntervalForInterrupt(u->Interrupts);
20841 
20842 		if (interval == INFINITE)
20843 		{
20844 			interval = UDPLISTENER_WAIT_INTERVAL;
20845 		}
20846 		else
20847 		{
20848 			interval = MIN(UDPLISTENER_WAIT_INTERVAL, interval);
20849 		}
20850 
20851 		if (interval >= 1)
20852 		{
20853 			WaitSockEvent(u->Event, interval);
20854 		}
20855 	}
20856 
20857 	if (u->GetNatTIpThread != NULL)
20858 	{
20859 		FreeQueryIpThread(u->GetNatTIpThread);
20860 	}
20861 
20862 	// Release of the socket list
20863 	for (i = 0;i < LIST_NUM(u->SockList);i++)
20864 	{
20865 		UDPLISTENER_SOCK *us = (UDPLISTENER_SOCK *)LIST_DATA(u->SockList, i);
20866 
20867 		Disconnect(us->Sock);
20868 		ReleaseSock(us->Sock);
20869 
20870 		Free(us);
20871 	}
20872 	ReleaseList(u->SockList);
20873 
20874 	FreeBuf(ip_list_buf);
20875 
20876 	Free(buf);
20877 }
20878 
20879 // Select the best UDP socket to be used for transmission
DetermineUdpSocketForSending(UDPLISTENER * u,UDPPACKET * p)20880 UDPLISTENER_SOCK *DetermineUdpSocketForSending(UDPLISTENER *u, UDPPACKET *p)
20881 {
20882 	UINT i;
20883 	// Validate arguments
20884 	if (u == NULL || p == NULL)
20885 	{
20886 		return NULL;
20887 	}
20888 
20889 	for (i = 0;i < LIST_NUM(u->SockList);i++)
20890 	{
20891 		UDPLISTENER_SOCK *us = LIST_DATA(u->SockList, i);
20892 
20893 		if (us->Sock != NULL && us->HasError == false)
20894 		{
20895 			if (us->Port == p->SrcPort)
20896 			{
20897 				if (CmpIpAddr(&us->IpAddress, &p->SrcIP) == 0)
20898 				{
20899 					return us;
20900 				}
20901 			}
20902 		}
20903 	}
20904 
20905 	for (i = 0;i < LIST_NUM(u->SockList);i++)
20906 	{
20907 		UDPLISTENER_SOCK *us = LIST_DATA(u->SockList, i);
20908 
20909 		if (us->Sock != NULL && us->HasError == false)
20910 		{
20911 			if (us->Port == p->SrcPort)
20912 			{
20913 				if (IsZeroIP(&us->IpAddress))
20914 				{
20915 					if ((IsIP4(&p->DstIP) && IsIP4(&us->IpAddress)) ||
20916 						(IsIP6(&p->DstIP) && IsIP6(&us->IpAddress)))
20917 					{
20918 						return us;
20919 					}
20920 				}
20921 			}
20922 		}
20923 	}
20924 
20925 	return NULL;
20926 }
20927 
20928 // Release of the UDP packet
FreeUdpPacket(UDPPACKET * p)20929 void FreeUdpPacket(UDPPACKET *p)
20930 {
20931 	// Validate arguments
20932 	if (p == NULL)
20933 	{
20934 		return;
20935 	}
20936 
20937 	Free(p->Data);
20938 	Free(p);
20939 }
20940 
20941 // Create a new UDP packet
NewUdpPacket(IP * src_ip,UINT src_port,IP * dst_ip,UINT dst_port,void * data,UINT size)20942 UDPPACKET *NewUdpPacket(IP *src_ip, UINT src_port, IP *dst_ip, UINT dst_port, void *data, UINT size)
20943 {
20944 	UDPPACKET *p;
20945 	// Validate arguments
20946 	if (data == NULL || size == 0 || dst_ip == NULL || dst_port == 0)
20947 	{
20948 		return NULL;
20949 	}
20950 
20951 	p = ZeroMalloc(sizeof(UDPPACKET));
20952 
20953 	p->Data = data;
20954 	p->Size = size;
20955 
20956 	Copy(&p->SrcIP, src_ip, sizeof(IP));
20957 	p->SrcPort = src_port;
20958 
20959 	Copy(&p->DstIP, dst_ip, sizeof(IP));
20960 	p->DestPort = dst_port;
20961 
20962 	return p;
20963 }
20964 
20965 // Transmit the packets via UDP Listener
UdpListenerSendPackets(UDPLISTENER * u,LIST * packet_list)20966 void UdpListenerSendPackets(UDPLISTENER *u, LIST *packet_list)
20967 {
20968 	UINT num = 0;
20969 	// Validate arguments
20970 	if (u == NULL || packet_list == NULL)
20971 	{
20972 		return;
20973 	}
20974 
20975 	LockList(u->SendPacketList);
20976 	{
20977 		UINT i;
20978 
20979 		num = LIST_NUM(packet_list);
20980 
20981 		for (i = 0;i < LIST_NUM(packet_list);i++)
20982 		{
20983 			UDPPACKET *p = LIST_DATA(packet_list, i);
20984 
20985 			Add(u->SendPacketList, p);
20986 		}
20987 	}
20988 	UnlockList(u->SendPacketList);
20989 
20990 	if (num >= 1)
20991 	{
20992 		SetSockEvent(u->Event);
20993 	}
20994 }
UdpListenerSendPacket(UDPLISTENER * u,UDPPACKET * packet)20995 void UdpListenerSendPacket(UDPLISTENER *u, UDPPACKET *packet)
20996 {
20997 	LIST *o;
20998 	// Validate arguments
20999 	if (u == NULL || packet == NULL)
21000 	{
21001 		return;
21002 	}
21003 
21004 	o = NewListFast(NULL);
21005 	Add(o, packet);
21006 
21007 	UdpListenerSendPackets(u, o);
21008 
21009 	ReleaseList(o);
21010 }
21011 
21012 // Creating a UDP listener
NewUdpListener(UDPLISTENER_RECV_PROC * recv_proc,void * param)21013 UDPLISTENER *NewUdpListener(UDPLISTENER_RECV_PROC *recv_proc, void *param)
21014 {
21015 	UDPLISTENER *u;
21016 	// Validate arguments
21017 	if (recv_proc == NULL)
21018 	{
21019 		return NULL;
21020 	}
21021 
21022 	u = ZeroMalloc(sizeof(UDPLISTENER));
21023 
21024 	u->RecvBufSize = UDP_MAX_BUFFER_SIZE;
21025 
21026 	u->Param = param;
21027 
21028 	u->PortList = NewList(NULL);
21029 	u->Event = NewSockEvent();
21030 
21031 	u->RecvProc = recv_proc;
21032 	u->SendPacketList = NewList(NULL);
21033 
21034 	u->Interrupts = NewInterruptManager();
21035 
21036 	u->Thread = NewThread(UdpListenerThread, u);
21037 
21038 	return u;
21039 }
21040 
21041 // Release the UDP listener
FreeUdpListener(UDPLISTENER * u)21042 void FreeUdpListener(UDPLISTENER *u)
21043 {
21044 	UINT i;
21045 	// Validate arguments
21046 	if (u == NULL)
21047 	{
21048 		return;
21049 	}
21050 
21051 	u->Halt = true;
21052 	SetSockEvent(u->Event);
21053 
21054 	WaitThread(u->Thread, INFINITE);
21055 	ReleaseThread(u->Thread);
21056 	ReleaseSockEvent(u->Event);
21057 
21058 	ReleaseIntList(u->PortList);
21059 
21060 	for (i = 0;i < LIST_NUM(u->SendPacketList);i++)
21061 	{
21062 		UDPPACKET *p = LIST_DATA(u->SendPacketList, i);
21063 
21064 		FreeUdpPacket(p);
21065 	}
21066 
21067 	ReleaseList(u->SendPacketList);
21068 
21069 	FreeInterruptManager(u->Interrupts);
21070 
21071 	Free(u);
21072 }
21073 
21074 // Add the UDP port
AddPortToUdpListener(UDPLISTENER * u,UINT port)21075 void AddPortToUdpListener(UDPLISTENER *u, UINT port)
21076 {
21077 	// Validate arguments
21078 	if (u == NULL || port == 0)
21079 	{
21080 		return;
21081 	}
21082 
21083 	LockList(u->PortList);
21084 	{
21085 		AddIntDistinct(u->PortList, port);
21086 	}
21087 	UnlockList(u->PortList);
21088 
21089 	SetSockEvent(u->Event);
21090 }
21091 
21092 // Get the port list
GetUdpListenerPortList(UDPLISTENER * u,UINT ** port_list)21093 UINT GetUdpListenerPortList(UDPLISTENER *u, UINT **port_list)
21094 {
21095 	UINT num_ports;
21096 	// Validate arguments
21097 	if (u == NULL || port_list == NULL)
21098 	{
21099 		return 0;
21100 	}
21101 
21102 	LockList(u->PortList);
21103 	{
21104 		UINT *ports;
21105 		UINT i;
21106 
21107 		num_ports = LIST_NUM(u->PortList);
21108 		ports = ZeroMalloc(sizeof(UINT) * num_ports);
21109 
21110 		for (i = 0;i < num_ports;i++)
21111 		{
21112 			ports[i] = *((UINT *)(LIST_DATA(u->PortList, i)));
21113 		}
21114 
21115 		*port_list = ports;
21116 	}
21117 	UnlockList(u->PortList);
21118 
21119 	return num_ports;
21120 }
21121 
21122 // Dekete all the UDP ports
DeleteAllPortFromUdpListener(UDPLISTENER * u)21123 void DeleteAllPortFromUdpListener(UDPLISTENER *u)
21124 {
21125 	// Validate arguments
21126 	if (u == NULL)
21127 	{
21128 		return;
21129 	}
21130 
21131 	LockList(u->PortList);
21132 	{
21133 		UINT num_ports = LIST_NUM(u->PortList);
21134 		UINT *ports = ZeroMalloc(sizeof(UINT) * num_ports);
21135 		UINT i;
21136 
21137 		for (i = 0;i < num_ports;i++)
21138 		{
21139 			ports[i] = *((UINT *)(LIST_DATA(u->PortList, i)));
21140 		}
21141 
21142 		for (i = 0;i < num_ports;i++)
21143 		{
21144 			UINT port = ports[i];
21145 
21146 			DelInt(u->PortList, port);
21147 		}
21148 
21149 		Free(ports);
21150 	}
21151 	UnlockList(u->PortList);
21152 
21153 	SetSockEvent(u->Event);
21154 }
21155 
21156 // Delete the UDP port
DeletePortFromUdpListener(UDPLISTENER * u,UINT port)21157 void DeletePortFromUdpListener(UDPLISTENER *u, UINT port)
21158 {
21159 	// Validate arguments
21160 	if (u == NULL || port == 0)
21161 	{
21162 		return;
21163 	}
21164 
21165 	LockList(u->PortList);
21166 	{
21167 		DelInt(u->PortList, port);
21168 	}
21169 	UnlockList(u->PortList);
21170 
21171 	SetSockEvent(u->Event);
21172 }
21173 
21174 // Sort function of the interrupt management list
CmpInterruptManagerTickList(void * p1,void * p2)21175 int CmpInterruptManagerTickList(void *p1, void *p2)
21176 {
21177 	UINT64 *v1, *v2;
21178 	if (p1 == NULL || p2 == NULL)
21179 	{
21180 		return 0;
21181 	}
21182 
21183 	v1 = *(UINT64 **)p1;
21184 	v2 = *(UINT64 **)p2;
21185 	if (v1 == NULL || v2 == NULL)
21186 	{
21187 		return 0;
21188 	}
21189 
21190 	if (*v1 > *v2)
21191 	{
21192 		return 1;
21193 	}
21194 	else if (*v1 < *v2)
21195 	{
21196 		return -1;
21197 	}
21198 	else
21199 	{
21200 		return 0;
21201 	}
21202 }
21203 
21204 // Initialization of the interrupt management
NewInterruptManager()21205 INTERRUPT_MANAGER *NewInterruptManager()
21206 {
21207 	INTERRUPT_MANAGER *m = ZeroMalloc(sizeof(INTERRUPT_MANAGER));
21208 
21209 	m->TickList = NewList(CmpInterruptManagerTickList);
21210 
21211 	return m;
21212 }
21213 
21214 // Release of the interrupt management
FreeInterruptManager(INTERRUPT_MANAGER * m)21215 void FreeInterruptManager(INTERRUPT_MANAGER *m)
21216 {
21217 	UINT i;
21218 	// Validate arguments
21219 	if (m == NULL)
21220 	{
21221 		return;
21222 	}
21223 
21224 	for (i = 0;i < LIST_NUM(m->TickList);i++)
21225 	{
21226 		UINT64 *v = LIST_DATA(m->TickList, i);
21227 
21228 		Free(v);
21229 	}
21230 
21231 	ReleaseList(m->TickList);
21232 
21233 	Free(m);
21234 }
21235 
21236 // Add a number to the interrupt management
AddInterrupt(INTERRUPT_MANAGER * m,UINT64 tick)21237 void AddInterrupt(INTERRUPT_MANAGER *m, UINT64 tick)
21238 {
21239 	// Validate arguments
21240 	if (tick == 0)
21241 	{
21242 		return;
21243 	}
21244 
21245 	LockList(m->TickList);
21246 	{
21247 		if (Search(m->TickList, &tick) == NULL)
21248 		{
21249 			Insert(m->TickList, Clone(&tick, sizeof(UINT64)));
21250 		}
21251 	}
21252 	UnlockList(m->TickList);
21253 }
21254 
21255 // Get the interval to the next calling
GetNextIntervalForInterrupt(INTERRUPT_MANAGER * m)21256 UINT GetNextIntervalForInterrupt(INTERRUPT_MANAGER *m)
21257 {
21258 	UINT ret = INFINITE;
21259 	UINT i;
21260 	LIST *o = NULL;
21261 	UINT64 now = Tick64();
21262 	// Validate arguments
21263 	if (m == NULL)
21264 	{
21265 		return 0;
21266 	}
21267 
21268 	LockList(m->TickList);
21269 	{
21270 		// Remove entries older than now already
21271 		for (i = 0;i < LIST_NUM(m->TickList);i++)
21272 		{
21273 			UINT64 *v = LIST_DATA(m->TickList, i);
21274 
21275 			if (now >= *v)
21276 			{
21277 				ret = 0;
21278 
21279 				if (o == NULL)
21280 				{
21281 					o = NewListFast(NULL);
21282 				}
21283 
21284 				Add(o, v);
21285 			}
21286 			else
21287 			{
21288 				break;
21289 			}
21290 		}
21291 
21292 		for (i = 0;i < LIST_NUM(o);i++)
21293 		{
21294 			UINT64 *v = LIST_DATA(o, i);
21295 
21296 			Free(v);
21297 
21298 			Delete(m->TickList, v);
21299 		}
21300 
21301 		if (o != NULL)
21302 		{
21303 			ReleaseList(o);
21304 		}
21305 
21306 		if (ret == INFINITE)
21307 		{
21308 			if (LIST_NUM(m->TickList) >= 1)
21309 			{
21310 				UINT64 *v = LIST_DATA(m->TickList, 0);
21311 
21312 				ret = (UINT)(*v - now);
21313 			}
21314 		}
21315 	}
21316 	UnlockList(m->TickList);
21317 
21318 	return ret;
21319 }
21320 
21321 // Let that the listening socket for the reverse socket to accept the new socket
InjectNewReverseSocketToAccept(SOCK * listen_sock,SOCK * s,IP * client_ip,UINT client_port)21322 void InjectNewReverseSocketToAccept(SOCK *listen_sock, SOCK *s, IP *client_ip, UINT client_port)
21323 {
21324 	bool ok = false;
21325 	// Validate arguments
21326 	if (listen_sock == NULL || s == NULL)
21327 	{
21328 		return;
21329 	}
21330 
21331 	LockQueue(listen_sock->ReverseAcceptQueue);
21332 	{
21333 		if (listen_sock->CancelAccept == false && listen_sock->Disconnecting == false)
21334 		{
21335 			InsertQueue(listen_sock->ReverseAcceptQueue, s);
21336 
21337 			ok = true;
21338 
21339 			s->ServerMode = true;
21340 			s->IsReverseAcceptedSocket = true;
21341 
21342 			Copy(&s->RemoteIP, client_ip, sizeof(IP));
21343 			s->RemotePort = client_port;
21344 		}
21345 	}
21346 	UnlockQueue(listen_sock->ReverseAcceptQueue);
21347 
21348 	if (ok == false)
21349 	{
21350 		Disconnect(s);
21351 		ReleaseSock(s);
21352 	}
21353 	else
21354 	{
21355 		Set(listen_sock->ReverseAcceptEvent);
21356 	}
21357 }
21358 
21359 // Create a listening socket for the reverse socket
ListenReverse()21360 SOCK *ListenReverse()
21361 {
21362 	SOCK *s = NewSock();
21363 
21364 	s->Type = SOCK_REVERSE_LISTEN;
21365 	s->ListenMode = true;
21366 	s->ReverseAcceptQueue = NewQueue();
21367 	s->ReverseAcceptEvent = NewEvent();
21368 	s->Connected = true;
21369 
21370 	return s;
21371 }
21372 
21373 // Accept on the reverse socket
AcceptReverse(SOCK * s)21374 SOCK *AcceptReverse(SOCK *s)
21375 {
21376 	// Validate arguments
21377 	if (s == NULL || s->Type != SOCK_REVERSE_LISTEN || s->ListenMode == false)
21378 	{
21379 		return NULL;
21380 	}
21381 
21382 	while (true)
21383 	{
21384 		SOCK *ret;
21385 		if (s->Disconnecting || s->CancelAccept)
21386 		{
21387 			return NULL;
21388 		}
21389 
21390 		LockQueue(s->ReverseAcceptQueue);
21391 		{
21392 			ret = GetNext(s->ReverseAcceptQueue);
21393 		}
21394 		UnlockQueue(s->ReverseAcceptQueue);
21395 
21396 		if (ret != NULL)
21397 		{
21398 			StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_AZURE);
21399 
21400 			AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails), "VPNAzure");
21401 
21402 			return ret;
21403 		}
21404 
21405 		Wait(s->ReverseAcceptEvent, INFINITE);
21406 	}
21407 }
21408 
21409 // Start listening on the in-process socket
ListenInProc()21410 SOCK *ListenInProc()
21411 {
21412 	SOCK *s = NewSock();
21413 
21414 	s->Type = SOCK_INPROC;
21415 	s->ListenMode = true;
21416 	s->InProcAcceptQueue = NewQueue();
21417 	s->InProcAcceptEvent = NewEvent();
21418 	s->Connected = true;
21419 
21420 	return s;
21421 }
21422 
21423 // Accept at the in-process socket
AcceptInProc(SOCK * s)21424 SOCK *AcceptInProc(SOCK *s)
21425 {
21426 	// Validate arguments
21427 	if (s == NULL || s->Type != SOCK_INPROC || s->ListenMode == false)
21428 	{
21429 		return NULL;
21430 	}
21431 
21432 	while (true)
21433 	{
21434 		SOCK *ret;
21435 		if (s->Disconnecting || s->CancelAccept)
21436 		{
21437 			return NULL;
21438 		}
21439 
21440 		LockQueue(s->InProcAcceptQueue);
21441 		{
21442 			ret = GetNext(s->InProcAcceptQueue);
21443 		}
21444 		UnlockQueue(s->InProcAcceptQueue);
21445 
21446 		if (ret != NULL)
21447 		{
21448 			StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_INPROC);
21449 
21450 			AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails), "InProc");
21451 
21452 			return ret;
21453 		}
21454 
21455 		Wait(s->InProcAcceptEvent, INFINITE);
21456 	}
21457 }
21458 
21459 // Connect by the in-process socket
ConnectInProc(SOCK * listen_sock,IP * client_ip,UINT client_port,IP * server_ip,UINT server_port)21460 SOCK *ConnectInProc(SOCK *listen_sock, IP *client_ip, UINT client_port, IP *server_ip, UINT server_port)
21461 {
21462 	SOCK *ss, *sc;
21463 	bool ok = false;
21464 	// Validate arguments
21465 	if (listen_sock == NULL || listen_sock->Type != SOCK_INPROC || listen_sock->ListenMode == false)
21466 	{
21467 		return NULL;
21468 	}
21469 
21470 	NewSocketPair(&sc, &ss, client_ip, client_port, server_ip, server_port);
21471 
21472 	LockQueue(listen_sock->InProcAcceptQueue);
21473 	{
21474 		if (listen_sock->CancelAccept == false && listen_sock->Disconnecting == false)
21475 		{
21476 			InsertQueue(listen_sock->InProcAcceptQueue, ss);
21477 
21478 			ok = true;
21479 		}
21480 	}
21481 	UnlockQueue(listen_sock->InProcAcceptQueue);
21482 
21483 	if (ok == false)
21484 	{
21485 		ReleaseSock(ss);
21486 		ReleaseSock(sc);
21487 		return NULL;
21488 	}
21489 
21490 	Set(listen_sock->InProcAcceptEvent);
21491 
21492 	return sc;
21493 }
21494 
21495 // Creating a new socket pair
NewSocketPair(SOCK ** client,SOCK ** server,IP * client_ip,UINT client_port,IP * server_ip,UINT server_port)21496 void NewSocketPair(SOCK **client, SOCK **server, IP *client_ip, UINT client_port, IP *server_ip, UINT server_port)
21497 {
21498 	IP iptmp;
21499 	TUBE *t1, *t2;
21500 	SOCK *sc, *ss;
21501 	SOCK_EVENT *e1, *e2;
21502 	// Validate arguments
21503 	if (client == NULL || server == NULL)
21504 	{
21505 		return;
21506 	}
21507 
21508 	SetIP(&iptmp, 127, 0, 0, 1);
21509 	if (client_ip == NULL)
21510 	{
21511 		client_ip = &iptmp;
21512 	}
21513 	if (server_ip == NULL)
21514 	{
21515 		server_ip = &iptmp;
21516 	}
21517 
21518 	// Creating a tube
21519 	NewTubePair(&t1, &t2, 0);	// t1: C -> S,  t2: S -> C
21520 
21521 	// Creating a socket event
21522 	e1 = NewSockEvent();
21523 	e2 = NewSockEvent();
21524 
21525 	SetTubeSockEvent(t1, e1);
21526 	SetTubeSockEvent(t2, e2);
21527 
21528 	sc = NewInProcSocket(t1, t2);
21529 	ss = NewInProcSocket(t2, t1);
21530 
21531 	Copy(&sc->LocalIP, client_ip, sizeof(IP));
21532 	sc->LocalPort = client_port;
21533 	Copy(&sc->RemoteIP, server_ip, sizeof(IP));
21534 	sc->RemotePort = server_port;
21535 
21536 	Copy(&ss->LocalIP, server_ip, sizeof(IP));
21537 	ss->LocalPort = server_port;
21538 	Copy(&ss->RemoteIP, client_ip, sizeof(IP));
21539 	ss->RemotePort = client_port;
21540 
21541 	sc->Connected = true;
21542 	sc->ServerMode = false;
21543 
21544 	ss->Connected = true;
21545 	ss->ServerMode = true;
21546 
21547 	SetTimeout(sc, INFINITE);
21548 	SetTimeout(ss, INFINITE);
21549 
21550 	QuerySocketInformation(sc);
21551 	QuerySocketInformation(ss);
21552 
21553 	ReleaseSockEvent(e1);
21554 	ReleaseSockEvent(e2);
21555 
21556 	ReleaseTube(t1);
21557 	ReleaseTube(t2);
21558 
21559 	*client = sc;
21560 	*server = ss;
21561 }
21562 
21563 // Creating a new in-process socket
NewInProcSocket(TUBE * tube_send,TUBE * tube_recv)21564 SOCK *NewInProcSocket(TUBE *tube_send, TUBE *tube_recv)
21565 {
21566 	SOCK *s;
21567 	// Validate arguments
21568 	if (tube_recv == NULL || tube_send == NULL)
21569 	{
21570 		return NULL;
21571 	}
21572 
21573 	s = NewSock();
21574 
21575 	s->Type = SOCK_INPROC;
21576 
21577 	s->SendTube = tube_send;
21578 	s->RecvTube = tube_recv;
21579 
21580 	AddRef(tube_send->Ref);
21581 	AddRef(tube_recv->Ref);
21582 
21583 	s->InProcRecvFifo = NewFifo();
21584 
21585 	s->Connected = true;
21586 
21587 	return s;
21588 }
21589 
21590 // Transmission process for the in-process socket
SendInProc(SOCK * sock,void * data,UINT size)21591 UINT SendInProc(SOCK *sock, void *data, UINT size)
21592 {
21593 	if (sock == NULL || sock->Type != SOCK_INPROC || sock->Disconnecting || sock->Connected == false)
21594 	{
21595 		return 0;
21596 	}
21597 
21598 	if (IsTubeConnected(sock->SendTube) == false)
21599 	{
21600 		return 0;
21601 	}
21602 
21603 	if (TubeSend(sock->SendTube, data, size, NULL) == false)
21604 	{
21605 		return 0;
21606 	}
21607 
21608 	return size;
21609 }
21610 
21611 // Receiving process for the in-process socket
RecvInProc(SOCK * sock,void * data,UINT size)21612 UINT RecvInProc(SOCK *sock, void *data, UINT size)
21613 {
21614 	FIFO *f;
21615 	UINT ret;
21616 	UINT timeout;
21617 	UINT64 giveup_time;
21618 	TUBEDATA *d = NULL;
21619 	if (sock == NULL || sock->Type != SOCK_INPROC || sock->Disconnecting || sock->Connected == false)
21620 	{
21621 		return 0;
21622 	}
21623 
21624 	if (IsTubeConnected(sock->SendTube) == false)
21625 	{
21626 		return 0;
21627 	}
21628 
21629 	f = sock->InProcRecvFifo;
21630 	if (f == NULL)
21631 	{
21632 		return 0;
21633 	}
21634 
21635 	// If there is data in the FIFO, return it immediately
21636 	ret = ReadFifo(f, data, size);
21637 	if (ret != 0)
21638 	{
21639 		return ret;
21640 	}
21641 
21642 	timeout = GetTimeout(sock);
21643 
21644 	giveup_time = Tick64() + (UINT)timeout;
21645 
21646 	// When there is no data in the FIFO, read the next data from the tube
21647 	d = NULL;
21648 
21649 	while (true)
21650 	{
21651 		UINT64 now = 0;
21652 		UINT interval;
21653 
21654 		if (sock->AsyncMode == false)
21655 		{
21656 			now = Tick64();
21657 
21658 			if (now >= giveup_time)
21659 			{
21660 				break;
21661 			}
21662 		}
21663 
21664 		d = TubeRecvAsync(sock->RecvTube);
21665 
21666 		if (d != NULL)
21667 		{
21668 			break;
21669 		}
21670 
21671 		if (IsTubeConnected(sock->RecvTube) == false)
21672 		{
21673 			break;
21674 		}
21675 
21676 		if (sock->AsyncMode)
21677 		{
21678 			break;
21679 		}
21680 
21681 		interval = (UINT)(giveup_time - now);
21682 
21683 		Wait(sock->RecvTube->Event, interval);
21684 	}
21685 
21686 	if (d == NULL)
21687 	{
21688 		if (IsTubeConnected(sock->RecvTube) == false)
21689 		{
21690 			return 0;
21691 		}
21692 
21693 		if (sock->AsyncMode == false)
21694 		{
21695 			// If a timeout occurs in synchronous mode, disconnect ir
21696 			Disconnect(sock);
21697 
21698 			return 0;
21699 		}
21700 		else
21701 		{
21702 			// If a timeout occurs in asynchronous mode, returns the blocking error
21703 			return SOCK_LATER;
21704 		}
21705 	}
21706 	else
21707 	{
21708 		// If the received data is larger than the requested size, write the rest to FIFO
21709 		if (d->DataSize > size)
21710 		{
21711 			WriteFifo(f, ((UCHAR *)d->Data) + size, d->DataSize - size);
21712 			ret = size;
21713 		}
21714 		else
21715 		{
21716 			ret = d->DataSize;
21717 		}
21718 
21719 		Copy(data, d->Data, ret);
21720 
21721 		FreeTubeData(d);
21722 
21723 		return ret;
21724 	}
21725 }
21726 
21727 // Wait for the arrival of data on multiple tubes
WaitForTubes(TUBE ** tubes,UINT num,UINT timeout)21728 void WaitForTubes(TUBE **tubes, UINT num, UINT timeout)
21729 {
21730 	// Validate arguments
21731 	if (num != 0 && tubes == NULL)
21732 	{
21733 		return;
21734 	}
21735 	if (timeout == 0)
21736 	{
21737 		return;
21738 	}
21739 	if (num == 0)
21740 	{
21741 		SleepThread(timeout);
21742 		return;
21743 	}
21744 
21745 #ifdef	OS_WIN32
21746 	Win32WaitForTubes(tubes, num, timeout);
21747 #else	// OS_WIN32
21748 	UnixWaitForTubes(tubes, num, timeout);
21749 #endif	// OS_WIN32
21750 }
21751 
21752 #ifdef	OS_WIN32
Win32WaitForTubes(TUBE ** tubes,UINT num,UINT timeout)21753 void Win32WaitForTubes(TUBE **tubes, UINT num, UINT timeout)
21754 {
21755 	HANDLE array[MAXIMUM_WAIT_OBJECTS];
21756 	UINT i;
21757 
21758 	Zero(array, sizeof(array));
21759 
21760 	for (i = 0;i < num;i++)
21761 	{
21762 		TUBE *t = tubes[i];
21763 
21764 		array[i] = t->Event->pData;
21765 	}
21766 
21767 	if (num == 1)
21768 	{
21769 		WaitForSingleObject(array[0], timeout);
21770 	}
21771 	else
21772 	{
21773 		WaitForMultipleObjects(num, array, false, timeout);
21774 	}
21775 }
21776 #else	// OS_WIN32
UnixWaitForTubes(TUBE ** tubes,UINT num,UINT timeout)21777 void UnixWaitForTubes(TUBE **tubes, UINT num, UINT timeout)
21778 {
21779 	int *fds;
21780 	UINT i;
21781 	char tmp[MAX_SIZE];
21782 	bool any_of_tubes_are_readable = false;
21783 
21784 	fds = ZeroMalloc(sizeof(int) * num);
21785 
21786 	for (i = 0;i < num;i++)
21787 	{
21788 		fds[i] = tubes[i]->SockEvent->pipe_read;
21789 
21790 		if (tubes[i]->SockEvent->current_pipe_data != 0)
21791 		{
21792 			any_of_tubes_are_readable = true;
21793 		}
21794 	}
21795 
21796 	if (any_of_tubes_are_readable == false)
21797 	{
21798 		UnixSelectInner(num, fds, 0, NULL, timeout);
21799 	}
21800 
21801 	for (i = 0;i < num;i++)
21802 	{
21803 		int fd = fds[i];
21804 		int readret;
21805 
21806 		tubes[i]->SockEvent->current_pipe_data = 0;
21807 
21808 		do
21809 		{
21810 			readret = read(fd, tmp, sizeof(tmp));
21811 		}
21812 		while (readret >= 1);
21813 	}
21814 
21815 	Free(fds);
21816 }
21817 #endif	// OS_WIN32
21818 
21819 // Creating a Tube Flush List
NewTubeFlushList()21820 TUBE_FLUSH_LIST *NewTubeFlushList()
21821 {
21822 	TUBE_FLUSH_LIST *f = ZeroMalloc(sizeof(TUBE_FLUSH_LIST));
21823 
21824 	f->List = NewListFast(NULL);
21825 
21826 	return f;
21827 }
21828 
21829 // Release of the Tube Flush List
FreeTubeFlushList(TUBE_FLUSH_LIST * f)21830 void FreeTubeFlushList(TUBE_FLUSH_LIST *f)
21831 {
21832 	UINT i;
21833 	// Validate arguments
21834 	if (f == NULL)
21835 	{
21836 		return;
21837 	}
21838 
21839 	for (i = 0;i < LIST_NUM(f->List);i++)
21840 	{
21841 		TUBE *t = LIST_DATA(f->List, i);
21842 
21843 		ReleaseTube(t);
21844 	}
21845 
21846 	ReleaseList(f->List);
21847 
21848 	Free(f);
21849 }
21850 
21851 // Add a Tube to the Tube Flush List
AddTubeToFlushList(TUBE_FLUSH_LIST * f,TUBE * t)21852 void AddTubeToFlushList(TUBE_FLUSH_LIST *f, TUBE *t)
21853 {
21854 	// Validate arguments
21855 	if (f == NULL || t == NULL)
21856 	{
21857 		return;
21858 	}
21859 
21860 	if (t->IsInFlushList)
21861 	{
21862 		return;
21863 	}
21864 
21865 	if (IsInList(f->List, t) == false)
21866 	{
21867 		Add(f->List, t);
21868 
21869 		AddRef(t->Ref);
21870 
21871 		t->IsInFlushList = true;
21872 	}
21873 }
21874 
21875 // Flush the all tubes in the Tube Flush List
FlushTubeFlushList(TUBE_FLUSH_LIST * f)21876 void FlushTubeFlushList(TUBE_FLUSH_LIST *f)
21877 {
21878 	UINT i;
21879 	// Validate arguments
21880 	if (f == NULL)
21881 	{
21882 		return;
21883 	}
21884 
21885 	for (i = 0;i < LIST_NUM(f->List);i++)
21886 	{
21887 		TUBE *t = LIST_DATA(f->List, i);
21888 
21889 		TubeFlush(t);
21890 		t->IsInFlushList = false;
21891 
21892 		ReleaseTube(t);
21893 	}
21894 
21895 	DeleteAll(f->List);
21896 }
21897 
21898 // The server receives a PACK from the client
HttpServerRecv(SOCK * s)21899 PACK *HttpServerRecv(SOCK *s)
21900 {
21901 	return HttpServerRecvEx(s, 0);
21902 }
HttpServerRecvEx(SOCK * s,UINT max_data_size)21903 PACK *HttpServerRecvEx(SOCK *s, UINT max_data_size)
21904 {
21905 	BUF *b;
21906 	PACK *p;
21907 	HTTP_HEADER *h;
21908 	UINT size;
21909 	UCHAR *tmp;
21910 	HTTP_VALUE *v;
21911 	UINT num_noop = 0;
21912 	if (max_data_size == 0) max_data_size = HTTP_PACK_MAX_SIZE;
21913 	// Validate arguments
21914 	if (s == NULL)
21915 	{
21916 		return NULL;
21917 	}
21918 
21919 START:
21920 
21921 	h = RecvHttpHeader(s);
21922 	if (h == NULL)
21923 	{
21924 		goto BAD_REQUEST;
21925 	}
21926 
21927 	if (StrCmpi(h->Method, "POST") != 0 ||
21928 		StrCmpi(h->Target, HTTP_VPN_TARGET) != 0 ||
21929 		StrCmpi(h->Version, "HTTP/1.1") != 0)
21930 	{
21931 		FreeHttpHeader(h);
21932 		goto BAD_REQUEST;
21933 	}
21934 
21935 	v = GetHttpValue(h, "Content-Type");
21936 	if (v == NULL || StrCmpi(v->Data, HTTP_CONTENT_TYPE2) != 0)
21937 	{
21938 		FreeHttpHeader(h);
21939 		goto BAD_REQUEST;
21940 	}
21941 
21942 	size = GetContentLength(h);
21943 	if (size == 0 || (size > max_data_size))
21944 	{
21945 		FreeHttpHeader(h);
21946 		goto BAD_REQUEST;
21947 	}
21948 
21949 	tmp = MallocEx(size, true);
21950 	if (RecvAll(s, tmp, size, s->SecureMode) == false)
21951 	{
21952 		Free(tmp);
21953 		FreeHttpHeader(h);
21954 		return NULL;
21955 	}
21956 
21957 	b = NewBuf();
21958 	WriteBuf(b, tmp, size);
21959 	Free(tmp);
21960 	FreeHttpHeader(h);
21961 
21962 	SeekBuf(b, 0, 0);
21963 	p = BufToPack(b);
21964 	FreeBuf(b);
21965 
21966 	// Determine whether it's a NOOP
21967 	if (PackGetInt(p, "noop") != 0)
21968 	{
21969 		Debug("recv: noop\n");
21970 		FreePack(p);
21971 
21972 		p = PackError(0);
21973 		PackAddInt(p, "noop", 1);
21974 		if (HttpServerSend(s, p) == false)
21975 		{
21976 			FreePack(p);
21977 			return NULL;
21978 		}
21979 
21980 		FreePack(p);
21981 
21982 		num_noop++;
21983 
21984 		if (num_noop > MAX_NOOP_PER_SESSION)
21985 		{
21986 			return NULL;
21987 		}
21988 
21989 		goto START;
21990 	}
21991 
21992 	return p;
21993 
21994 BAD_REQUEST:
21995 	// Return an error
21996 
21997 
21998 	return NULL;
21999 }
22000 
22001 // Store the error value into PACK
PackError(UINT error)22002 PACK *PackError(UINT error)
22003 {
22004 	PACK *p;
22005 
22006 	p = NewPack();
22007 	PackAddInt(p, "error", error);
22008 
22009 	return p;
22010 }
22011 
22012 // Get the error value from PACK
GetErrorFromPack(PACK * p)22013 UINT GetErrorFromPack(PACK *p)
22014 {
22015 	// Validate arguments
22016 	if (p == NULL)
22017 	{
22018 		return 0;
22019 	}
22020 
22021 	return PackGetInt(p, "error");
22022 }
22023 
22024 // Client receives a PACK from the server
HttpClientRecv(SOCK * s)22025 PACK *HttpClientRecv(SOCK *s)
22026 {
22027 	BUF *b;
22028 	PACK *p;
22029 	HTTP_HEADER *h;
22030 	UINT size;
22031 	UCHAR *tmp;
22032 	HTTP_VALUE *v;
22033 	// Validate arguments
22034 	if (s == NULL)
22035 	{
22036 		return NULL;
22037 	}
22038 
22039 	h = RecvHttpHeader(s);
22040 	if (h == NULL)
22041 	{
22042 		return NULL;
22043 	}
22044 
22045 	if (StrCmpi(h->Method, "HTTP/1.1") != 0 ||
22046 		StrCmpi(h->Target, "200") != 0)
22047 	{
22048 		FreeHttpHeader(h);
22049 		return NULL;
22050 	}
22051 
22052 	v = GetHttpValue(h, "Content-Type");
22053 	if (v == NULL || StrCmpi(v->Data, HTTP_CONTENT_TYPE2) != 0)
22054 	{
22055 		FreeHttpHeader(h);
22056 		return NULL;
22057 	}
22058 
22059 	size = GetContentLength(h);
22060 	if (size == 0 || size > MAX_PACK_SIZE)
22061 	{
22062 		FreeHttpHeader(h);
22063 		return NULL;
22064 	}
22065 
22066 	tmp = MallocEx(size, true);
22067 	if (RecvAll(s, tmp, size, s->SecureMode) == false)
22068 	{
22069 		Free(tmp);
22070 		FreeHttpHeader(h);
22071 		return NULL;
22072 	}
22073 
22074 	b = NewBuf();
22075 	WriteBuf(b, tmp, size);
22076 	Free(tmp);
22077 	FreeHttpHeader(h);
22078 
22079 	SeekBuf(b, 0, 0);
22080 	p = BufToPack(b);
22081 	FreeBuf(b);
22082 
22083 	return p;
22084 }
22085 
22086 // Create an entry to PACK for the dummy
CreateDummyValue(PACK * p)22087 void CreateDummyValue(PACK *p)
22088 {
22089 	UINT size;
22090 	UCHAR *buf;
22091 	// Validate arguments
22092 	if (p == NULL)
22093 	{
22094 		return;
22095 	}
22096 
22097 	size = Rand32() % HTTP_PACK_RAND_SIZE_MAX;
22098 	buf = Malloc(size);
22099 	Rand(buf, size);
22100 
22101 	PackAddData(p, "pencore", buf, size);
22102 
22103 	Free(buf);
22104 }
22105 
22106 // Client sends a PACK to the server
HttpClientSend(SOCK * s,PACK * p)22107 bool HttpClientSend(SOCK *s, PACK *p)
22108 {
22109 	BUF *b;
22110 	bool ret;
22111 	HTTP_HEADER *h;
22112 	char date_str[MAX_SIZE];
22113 	char ip_str[MAX_SIZE];
22114 
22115 	// Validate arguments
22116 	if (s == NULL || p == NULL)
22117 	{
22118 		return false;
22119 	}
22120 
22121 	IPToStr(ip_str, sizeof(ip_str), &s->RemoteIP);
22122 
22123 	CreateDummyValue(p);
22124 
22125 	b = PackToBuf(p);
22126 	if (b == NULL)
22127 	{
22128 		return false;
22129 	}
22130 
22131 	h = NewHttpHeader("POST", HTTP_VPN_TARGET, "HTTP/1.1");
22132 
22133 	GetHttpDateStr(date_str, sizeof(date_str), SystemTime64());
22134 	AddHttpValue(h, NewHttpValue("Date", date_str));
22135 	AddHttpValue(h, NewHttpValue("Host", ip_str));
22136 	AddHttpValue(h, NewHttpValue("Keep-Alive", HTTP_KEEP_ALIVE));
22137 	AddHttpValue(h, NewHttpValue("Connection", "Keep-Alive"));
22138 	AddHttpValue(h, NewHttpValue("Content-Type", HTTP_CONTENT_TYPE2));
22139 
22140 	ret = PostHttp(s, h, b->Buf, b->Size);
22141 
22142 	FreeHttpHeader(h);
22143 	FreeBuf(b);
22144 
22145 	return ret;
22146 }
22147 
22148 // Server sends a PACK to the client
HttpServerSend(SOCK * s,PACK * p)22149 bool HttpServerSend(SOCK *s, PACK *p)
22150 {
22151 	BUF *b;
22152 	bool ret;
22153 	HTTP_HEADER *h;
22154 	char date_str[MAX_SIZE];
22155 	// Validate arguments
22156 	if (s == NULL || p == NULL)
22157 	{
22158 		return false;
22159 	}
22160 
22161 	CreateDummyValue(p);
22162 
22163 	b = PackToBuf(p);
22164 	if (b == NULL)
22165 	{
22166 		return false;
22167 	}
22168 
22169 	h = NewHttpHeader("HTTP/1.1", "200", "OK");
22170 
22171 	GetHttpDateStr(date_str, sizeof(date_str), SystemTime64());
22172 	AddHttpValue(h, NewHttpValue("Date", date_str));
22173 	AddHttpValue(h, NewHttpValue("Keep-Alive", HTTP_KEEP_ALIVE));
22174 	AddHttpValue(h, NewHttpValue("Connection", "Keep-Alive"));
22175 	AddHttpValue(h, NewHttpValue("Content-Type", HTTP_CONTENT_TYPE2));
22176 
22177 	ret = PostHttp(s, h, b->Buf, b->Size);
22178 
22179 	FreeHttpHeader(h);
22180 	FreeBuf(b);
22181 
22182 	return ret;
22183 }
22184 
22185 // Replace unsafe characters in target
ReplaceUnsafeCharInTarget(char * target)22186 void ReplaceUnsafeCharInTarget(char *target){
22187 	UINT i;
22188 	for(i = 0; target[i] ; i++) {
22189 		if(target[i] == '<')
22190 			target[i] = '(';
22191 		else if(target[i] == '>')
22192 			target[i] = ')';
22193 	}
22194 }
22195 
22196 // Sending the 400 Bad Request: Invalid Hostname
HttpSendInvalidHostname(SOCK * s,char * method)22197 bool HttpSendInvalidHostname(SOCK *s, char *method)
22198 {
22199 	HTTP_HEADER *h;
22200 	char date_str[MAX_SIZE];
22201 	char *str;
22202 	bool ret;
22203 	char host[MAX_SIZE];
22204 	UINT port;
22205 	// Validate arguments
22206 	if (s == NULL)
22207 	{
22208 		return false;
22209 	}
22210 
22211 	// Get the host name
22212 	//GetMachineName(host, MAX_SIZE);
22213 	Zero(host, sizeof(host));
22214 	IPToStr(host, sizeof(host), &s->LocalIP);
22215 	// Get the port number
22216 	port = s->LocalPort;
22217 
22218 	// Creating a header
22219 	GetHttpDateStr(date_str, sizeof(date_str), SystemTime64());
22220 
22221 	h = NewHttpHeader("HTTP/1.1", "400", "Bad Request");
22222 
22223 	AddHttpValue(h, NewHttpValue("Date", date_str));
22224 	AddHttpValue(h, NewHttpValue("Keep-Alive", HTTP_KEEP_ALIVE));
22225 	AddHttpValue(h, NewHttpValue("Connection", "Keep-Alive"));
22226 	AddHttpValue(h, NewHttpValue("Content-Type", HTTP_CONTENT_TYPE));
22227 
22228 	// Creating a Data
22229 	str = "<h1>Bad Request (Invalid Hostname)</h1>\n";
22230 
22231 	// Transmission
22232 	ret = PostHttp(s, h, str, StrLen(str));
22233 
22234 	FreeHttpHeader(h);
22235 
22236 	return ret;
22237 }
22238 
22239 // Sending the 501 Not Implemented error
HttpSendNotImplemented(SOCK * s,char * method,char * target,char * version)22240 bool HttpSendNotImplemented(SOCK *s, char *method, char *target, char *version)
22241 {
22242 	HTTP_HEADER *h;
22243 	char date_str[MAX_SIZE];
22244 	char *str;
22245 	UINT str_size;
22246 	char port_str[MAX_SIZE];
22247 	bool ret;
22248 	char host[MAX_SIZE];
22249 	UINT port;
22250 	// Validate arguments
22251 	if (s == NULL || target == NULL)
22252 	{
22253 		return false;
22254 	}
22255 
22256 	// Get the host name
22257 	//GetMachineName(host, MAX_SIZE);
22258 	Zero(host, sizeof(host));
22259 	IPToStr(host, sizeof(host), &s->LocalIP);
22260 	// Get the port number
22261 	port = s->LocalPort;
22262 
22263 	// Creating a header
22264 	GetHttpDateStr(date_str, sizeof(date_str), SystemTime64());
22265 
22266 	h = NewHttpHeader("HTTP/1.1", "501", "Method Not Implemented");
22267 
22268 	AddHttpValue(h, NewHttpValue("Date", date_str));
22269 	AddHttpValue(h, NewHttpValue("Keep-Alive", HTTP_KEEP_ALIVE));
22270 	AddHttpValue(h, NewHttpValue("Connection", "Keep-Alive"));
22271 	AddHttpValue(h, NewHttpValue("Content-Type", HTTP_CONTENT_TYPE));
22272 
22273 	// Creating a Data
22274 	str_size = sizeof(http_501_str) * 2 + StrLen(target) + StrLen(host) + StrLen(method) + StrLen(version);
22275 	str = Malloc(str_size);
22276 	StrCpy(str, str_size, http_501_str);
22277 
22278 	// TARGET
22279 	ReplaceUnsafeCharInTarget(target);
22280 	ReplaceStri(str, str_size, str, "$TARGET$", target);
22281 
22282 	// HOST
22283 	ReplaceStri(str, str_size, str, "$HOST$", host);
22284 
22285 	// PORT
22286 	ToStr(port_str, port);
22287 	ReplaceStri(str, str_size, str, "$PORT$", port_str);
22288 
22289 	// METHOD
22290 	ReplaceStri(str, str_size, str, "$METHOD$", method);
22291 
22292 	// VERSION
22293 	ReplaceStri(str, str_size, str, "$VERSION$", version);
22294 
22295 	// Transmission
22296 	ret = PostHttp(s, h, str, StrLen(str));
22297 
22298 	FreeHttpHeader(h);
22299 	Free(str);
22300 
22301 	return ret;
22302 }
22303 
22304 // Sending a HTTP body contents
HttpSendBody(SOCK * s,void * data,UINT size,char * contents_type)22305 bool HttpSendBody(SOCK *s, void *data, UINT size, char *contents_type)
22306 {
22307 	HTTP_HEADER *h;
22308 	char date_str[MAX_SIZE];
22309 	bool ret;
22310 	if (s == NULL || (size != 0 && data == NULL))
22311 	{
22312 		return false;
22313 	}
22314 	if (contents_type == NULL)
22315 	{
22316 		contents_type = "application/octet-stream";
22317 	}
22318 	// Creating a header
22319 	h = NewHttpHeader("HTTP/1.1", "200", "OK");
22320 
22321 	GetHttpDateStr(date_str, sizeof(date_str), SystemTime64());
22322 	AddHttpValue(h, NewHttpValue("Date", date_str));
22323 	AddHttpValue(h, NewHttpValue("Content-Type", contents_type));
22324 	AddHttpValue(h, NewHttpValue("Cache-Control", "no-cache"));
22325 
22326 	ret = PostHttp(s, h, data, size);
22327 
22328 	FreeHttpHeader(h);
22329 
22330 	return ret;
22331 }
22332 
22333 // Sending a 404 Not Found error
HttpSendNotFound(SOCK * s,char * target)22334 bool HttpSendNotFound(SOCK *s, char *target)
22335 {
22336 	HTTP_HEADER *h;
22337 	char date_str[MAX_SIZE];
22338 	char *str;
22339 	UINT str_size;
22340 	char port_str[MAX_SIZE];
22341 	bool ret;
22342 	char host[MAX_SIZE];
22343 	UINT port;
22344 	// Validate arguments
22345 	if (s == NULL || target == NULL)
22346 	{
22347 		return false;
22348 	}
22349 
22350 	// Get the host name
22351 	//GetMachineName(host, MAX_SIZE);
22352 	Zero(host, sizeof(host));
22353 	IPToStr(host, sizeof(host), &s->LocalIP);
22354 	// Get the port number
22355 	port = s->LocalPort;
22356 
22357 	// Creating a header
22358 	GetHttpDateStr(date_str, sizeof(date_str), SystemTime64());
22359 
22360 	h = NewHttpHeader("HTTP/1.1", "404", "Not Found");
22361 
22362 	AddHttpValue(h, NewHttpValue("Date", date_str));
22363 	AddHttpValue(h, NewHttpValue("Keep-Alive", HTTP_KEEP_ALIVE));
22364 	AddHttpValue(h, NewHttpValue("Connection", "Keep-Alive"));
22365 	AddHttpValue(h, NewHttpValue("Content-Type", HTTP_CONTENT_TYPE));
22366 
22367 	// Creating a Data
22368 	str_size = sizeof(http_404_str) * 2 + StrLen(target) + StrLen(host);
22369 	str = Malloc(str_size);
22370 	StrCpy(str, str_size, http_404_str);
22371 
22372 	// TARGET
22373 	ReplaceUnsafeCharInTarget(target);
22374 	ReplaceStri(str, str_size, str, "$TARGET$", target);
22375 
22376 	// HOST
22377 	ReplaceStri(str, str_size, str, "$HOST$", host);
22378 
22379 	// PORT
22380 	ToStr(port_str, port);
22381 	ReplaceStri(str, str_size, str, "$PORT$", port_str);
22382 
22383 	// Transmission
22384 	ret = PostHttp(s, h, str, StrLen(str));
22385 
22386 	FreeHttpHeader(h);
22387 	Free(str);
22388 
22389 	return ret;
22390 }
22391 
22392 // Sending a 500 Server Error
HttpSendServerError(SOCK * s,char * target)22393 bool HttpSendServerError(SOCK *s, char *target)
22394 {
22395 	HTTP_HEADER *h;
22396 	char date_str[MAX_SIZE];
22397 	char *str;
22398 	UINT str_size;
22399 	char port_str[MAX_SIZE];
22400 	bool ret;
22401 	char host[MAX_SIZE];
22402 	UINT port;
22403 	// Validate arguments
22404 	if (s == NULL || target == NULL)
22405 	{
22406 		return false;
22407 	}
22408 
22409 	// Get the host name
22410 	//GetMachineName(host, MAX_SIZE);
22411 	Zero(host, sizeof(host));
22412 	IPToStr(host, sizeof(host), &s->LocalIP);
22413 	// Get the port number
22414 	port = s->LocalPort;
22415 
22416 	// Creating a header
22417 	GetHttpDateStr(date_str, sizeof(date_str), SystemTime64());
22418 
22419 	h = NewHttpHeader("HTTP/1.1", "500", "Server Error");
22420 
22421 	AddHttpValue(h, NewHttpValue("Date", date_str));
22422 	AddHttpValue(h, NewHttpValue("Keep-Alive", HTTP_KEEP_ALIVE));
22423 	AddHttpValue(h, NewHttpValue("Connection", "Keep-Alive"));
22424 	AddHttpValue(h, NewHttpValue("Content-Type", HTTP_CONTENT_TYPE));
22425 
22426 	// Creating a Data
22427 	str_size = sizeof(http_500_str) * 2 + StrLen(target) + StrLen(host);
22428 	str = Malloc(str_size);
22429 	StrCpy(str, str_size, http_500_str);
22430 
22431 	// TARGET
22432 	ReplaceUnsafeCharInTarget(target);
22433 	ReplaceStri(str, str_size, str, "$TARGET$", target);
22434 
22435 	// HOST
22436 	ReplaceStri(str, str_size, str, "$HOST$", host);
22437 
22438 	// PORT
22439 	ToStr(port_str, port);
22440 	ReplaceStri(str, str_size, str, "$PORT$", port_str);
22441 
22442 	// Transmission
22443 	ret = PostHttp(s, h, str, StrLen(str));
22444 
22445 	FreeHttpHeader(h);
22446 	Free(str);
22447 
22448 	return ret;
22449 }
22450 
22451 // Sending a 403 Forbidden error
HttpSendForbidden(SOCK * s,char * target,char * server_id)22452 bool HttpSendForbidden(SOCK *s, char *target, char *server_id)
22453 {
22454 	HTTP_HEADER *h;
22455 	char date_str[MAX_SIZE];
22456 	char *str;
22457 	UINT str_size;
22458 	char port_str[MAX_SIZE];
22459 	bool ret;
22460 	char host[MAX_SIZE];
22461 	UINT port;
22462 	// Validate arguments
22463 	if (s == NULL || target == NULL)
22464 	{
22465 		return false;
22466 	}
22467 
22468 	// Get the host name
22469 	//GetMachineName(host, MAX_SIZE);
22470 	Zero(host, sizeof(host));
22471 	IPToStr(host, sizeof(host), &s->LocalIP);
22472 	// Get the port number
22473 	port = s->LocalPort;
22474 
22475 	// Creating a header
22476 	GetHttpDateStr(date_str, sizeof(date_str), SystemTime64());
22477 
22478 	h = NewHttpHeader("HTTP/1.1", "403", "Forbidden");
22479 
22480 	AddHttpValue(h, NewHttpValue("Date", date_str));
22481 	AddHttpValue(h, NewHttpValue("Keep-Alive", HTTP_KEEP_ALIVE));
22482 	AddHttpValue(h, NewHttpValue("Connection", "Keep-Alive"));
22483 	AddHttpValue(h, NewHttpValue("Content-Type", HTTP_CONTENT_TYPE));
22484 
22485 	// Creating a Data
22486 	str_size = sizeof(http_403_str) * 2 + StrLen(target) + StrLen(host);
22487 	str = Malloc(str_size);
22488 	StrCpy(str, str_size, http_403_str);
22489 
22490 	// TARGET
22491 	ReplaceUnsafeCharInTarget(target);
22492 	ReplaceStri(str, str_size, str, "$TARGET$", target);
22493 
22494 	// HOST
22495 	ReplaceStri(str, str_size, str, "$HOST$", host);
22496 
22497 	// PORT
22498 	ToStr(port_str, port);
22499 	ReplaceStri(str, str_size, str, "$PORT$", port_str);
22500 
22501 	// Transmission
22502 	ret = PostHttp(s, h, str, StrLen(str));
22503 
22504 	FreeHttpHeader(h);
22505 	Free(str);
22506 
22507 	return ret;
22508 }
22509 
22510 // Get the date and time string for the HTTP header
GetHttpDateStr(char * str,UINT size,UINT64 t)22511 void GetHttpDateStr(char *str, UINT size, UINT64 t)
22512 {
22513 	SYSTEMTIME s;
22514 	static char *wday[] =
22515 	{
22516 		"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
22517 	};
22518 	static char *month[] =
22519 	{
22520 		"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct",
22521 		"Nov", "Dec",
22522 	};
22523 	// Validate arguments
22524 	if (str == NULL)
22525 	{
22526 		return;
22527 	}
22528 	UINT64ToSystem(&s, t);
22529 
22530 	Format(str, size, "%s, %02u %s %04u %02u:%02u:%02u GMT",
22531 		wday[s.wDayOfWeek], s.wDay, month[s.wMonth - 1], s.wYear,
22532 		s.wHour, s.wMinute, s.wSecond);
22533 }
22534 
22535 // Get the Content-Length from the HTTP header
GetContentLength(HTTP_HEADER * header)22536 UINT GetContentLength(HTTP_HEADER *header)
22537 {
22538 	UINT ret;
22539 	HTTP_VALUE *v;
22540 	// Validate arguments
22541 	if (header == NULL)
22542 	{
22543 		return 0;
22544 	}
22545 
22546 	v = GetHttpValue(header, "Content-Length");
22547 	if (v == NULL)
22548 	{
22549 		return 0;
22550 	}
22551 
22552 	ret = ToInt(v->Data);
22553 
22554 	return ret;
22555 }
22556 
22557 // Send the data in the HTTP
PostHttp(SOCK * s,HTTP_HEADER * header,void * post_data,UINT post_size)22558 bool PostHttp(SOCK *s, HTTP_HEADER *header, void *post_data, UINT post_size)
22559 {
22560 	char *header_str;
22561 	BUF *b;
22562 	bool ret;
22563 	// Validate arguments
22564 	if (s == NULL || header == NULL || (post_size != 0 && post_data == NULL))
22565 	{
22566 		return false;
22567 	}
22568 
22569 	// Check whether the Content-Lentgh exists?
22570 	if (GetHttpValue(header, "Content-Length") == NULL)
22571 	{
22572 		char tmp[MAX_SIZE];
22573 		// Add because it does not exist
22574 		ToStr(tmp, post_size);
22575 		AddHttpValue(header, NewHttpValue("Content-Length", tmp));
22576 	}
22577 
22578 	// Convert the header to string
22579 	header_str = HttpHeaderToStr(header);
22580 	if (header_str == NULL)
22581 	{
22582 		return false;
22583 	}
22584 	b = NewBuf();
22585 	WriteBuf(b, header_str, StrLen(header_str));
22586 	Free(header_str);
22587 
22588 	// Append the data
22589 	WriteBuf(b, post_data, post_size);
22590 
22591 	// Send
22592 	ret = SendAll(s, b->Buf, b->Size, s->SecureMode);
22593 
22594 	FreeBuf(b);
22595 
22596 	return ret;
22597 }
22598 
22599 // Convert a HTTP header to a string
HttpHeaderToStr(HTTP_HEADER * header)22600 char *HttpHeaderToStr(HTTP_HEADER *header)
22601 {
22602 	BUF *b;
22603 	char *tmp;
22604 	UINT i;
22605 	char *s;
22606 	// Validate arguments
22607 	if (header == NULL)
22608 	{
22609 		return NULL;
22610 	}
22611 
22612 	tmp = Malloc(HTTP_HEADER_LINE_MAX_SIZE);
22613 	b = NewBuf();
22614 
22615 	// Header
22616 	Format(tmp, HTTP_HEADER_LINE_MAX_SIZE,
22617 		"%s %s %s\r\n", header->Method, header->Target, header->Version);
22618 	WriteBuf(b, tmp, StrLen(tmp));
22619 
22620 	// Value
22621 	for (i = 0;i < LIST_NUM(header->ValueList);i++)
22622 	{
22623 		HTTP_VALUE *v = (HTTP_VALUE *)LIST_DATA(header->ValueList, i);
22624 		Format(tmp, HTTP_HEADER_LINE_MAX_SIZE,
22625 			"%s: %s\r\n", v->Name, v->Data);
22626 		WriteBuf(b, tmp, StrLen(tmp));
22627 	}
22628 
22629 	// Trailing newline
22630 	WriteBuf(b, "\r\n", 2);
22631 	s = Malloc(b->Size + 1);
22632 	Copy(s, b->Buf, b->Size);
22633 	s[b->Size] = 0;
22634 
22635 	FreeBuf(b);
22636 	Free(tmp);
22637 
22638 	return s;
22639 }
22640 
22641 // Send the HTTP header
SendHttpHeader(SOCK * s,HTTP_HEADER * header)22642 bool SendHttpHeader(SOCK *s, HTTP_HEADER *header)
22643 {
22644 	char *str;
22645 	bool ret;
22646 	// Validate arguments
22647 	if (s == NULL || header == NULL)
22648 	{
22649 		return false;
22650 	}
22651 
22652 	// Convert to string
22653 	str = HttpHeaderToStr(header);
22654 
22655 	// Transmission
22656 	ret = SendAll(s, str, StrLen(str), s->SecureMode);
22657 
22658 	Free(str);
22659 
22660 	return ret;
22661 }
22662 
22663 // Receive an HTTP header
RecvHttpHeader(SOCK * s)22664 HTTP_HEADER *RecvHttpHeader(SOCK *s)
22665 {
22666 	TOKEN_LIST *token = NULL;
22667 	char *str = NULL;
22668 	HTTP_HEADER *header = NULL;
22669 	// Validate arguments
22670 	if (s == NULL)
22671 	{
22672 		return NULL;
22673 	}
22674 
22675 	// Get the first line
22676 	str = RecvLine(s, HTTP_HEADER_LINE_MAX_SIZE);
22677 	if (str == NULL)
22678 	{
22679 		goto LABEL_ERROR;
22680 	}
22681 
22682 	// Split into tokens
22683 	token = ParseToken(str, " ");
22684 	if (token->NumTokens < 3)
22685 	{
22686 		goto LABEL_ERROR;
22687 	}
22688 
22689 	Free(str);
22690 	str = NULL;
22691 
22692 	// Creating a header object
22693 	header = NewHttpHeader(token->Token[0], token->Token[1], token->Token[2]);
22694 
22695 	if (StrCmpi(header->Version, "HTTP/0.9") == 0)
22696 	{
22697 		// The header ends with this line
22698 		FreeToken(token);
22699 		return header;
22700 	}
22701 
22702 	// Get the subsequent lines
22703 	while (true)
22704 	{
22705 		UINT pos;
22706 		HTTP_VALUE *v;
22707 		char *value_name, *value_data;
22708 		str = RecvLine(s, HTTP_HEADER_LINE_MAX_SIZE);
22709 		if (str == NULL)
22710 		{
22711 			goto LABEL_ERROR;
22712 		}
22713 		Trim(str);
22714 
22715 		if (StrLen(str) == 0)
22716 		{
22717 			// End of header
22718 			Free(str);
22719 			str = NULL;
22720 			break;
22721 		}
22722 
22723 		// Get the position of the colon
22724 		pos = SearchStr(str, ":", 0);
22725 		if (pos == INFINITE)
22726 		{
22727 			// The colon does not exist
22728 			goto LABEL_ERROR;
22729 		}
22730 
22731 		// Divide into the name and the data
22732 		value_name = Malloc(pos + 1);
22733 		Copy(value_name, str, pos);
22734 		value_name[pos] = 0;
22735 		value_data = &str[pos + 1];
22736 
22737 		v = NewHttpValue(value_name, value_data);
22738 		if (v == NULL)
22739 		{
22740 			Free(value_name);
22741 			goto LABEL_ERROR;
22742 		}
22743 
22744 		Free(value_name);
22745 
22746 		AddHttpValue(header, v);
22747 		Free(str);
22748 	}
22749 
22750 	FreeToken(token);
22751 
22752 	return header;
22753 
22754 LABEL_ERROR:
22755 	// Memory release
22756 	if (token)
22757 	{
22758 		FreeToken(token);
22759 	}
22760 	if (str)
22761 	{
22762 		Free(str);
22763 	}
22764 	if (header)
22765 	{
22766 		FreeHttpHeader(header);
22767 	}
22768 	return NULL;
22769 }
22770 
22771 // Receive a line
RecvLine(SOCK * s,UINT max_size)22772 char *RecvLine(SOCK *s, UINT max_size)
22773 {
22774 	BUF *b;
22775 	char c;
22776 	char *str;
22777 	// Validate arguments
22778 	if (s == NULL || max_size == 0)
22779 	{
22780 		return NULL;
22781 	}
22782 
22783 	b = NewBuf();
22784 	while (true)
22785 	{
22786 		UCHAR *buf;
22787 		if (RecvAll(s, &c, sizeof(c), s->SecureMode) == false)
22788 		{
22789 			FreeBuf(b);
22790 			return NULL;
22791 		}
22792 		WriteBuf(b, &c, sizeof(c));
22793 		buf = (UCHAR *)b->Buf;
22794 		if (b->Size > max_size)
22795 		{
22796 			FreeBuf(b);
22797 			return NULL;
22798 		}
22799 		if (b->Size >= 1)
22800 		{
22801 			if (buf[b->Size - 1] == '\n')
22802 			{
22803 				b->Size--;
22804 				if (b->Size >= 1)
22805 				{
22806 					if (buf[b->Size - 1] == '\r')
22807 					{
22808 						b->Size--;
22809 					}
22810 				}
22811 				str = Malloc(b->Size + 1);
22812 				Copy(str, b->Buf, b->Size);
22813 				str[b->Size] = 0;
22814 				FreeBuf(b);
22815 
22816 				return str;
22817 			}
22818 		}
22819 	}
22820 }
22821 
22822 // Creating a new HTTP value
NewHttpValue(char * name,char * data)22823 HTTP_VALUE *NewHttpValue(char *name, char *data)
22824 {
22825 	HTTP_VALUE *v;
22826 	// Validate arguments
22827 	if (name == NULL || data == NULL)
22828 	{
22829 		return NULL;
22830 	}
22831 
22832 	v = ZeroMalloc(sizeof(HTTP_VALUE));
22833 
22834 	v->Name = CopyStr(name);
22835 	v->Data = CopyStr(data);
22836 
22837 	Trim(v->Name);
22838 	Trim(v->Data);
22839 
22840 	return v;
22841 }
22842 
22843 // Look for the HTTP value from the HTTP header
GetHttpValue(HTTP_HEADER * header,char * name)22844 HTTP_VALUE *GetHttpValue(HTTP_HEADER *header, char *name)
22845 {
22846 	HTTP_VALUE *v, t;
22847 	// Validate arguments
22848 	if (header == NULL || name == NULL)
22849 	{
22850 		return NULL;
22851 	}
22852 
22853 	t.Name = name;
22854 	v = Search(header->ValueList, &t);
22855 	if (v == NULL)
22856 	{
22857 		return NULL;
22858 	}
22859 
22860 	return v;
22861 }
22862 
22863 // Add a HTTP value to the HTTP header
AddHttpValue(HTTP_HEADER * header,HTTP_VALUE * value)22864 void AddHttpValue(HTTP_HEADER *header, HTTP_VALUE *value)
22865 {
22866 	// Validate arguments
22867 	if (header == NULL || value == NULL)
22868 	{
22869 		return;
22870 	}
22871 
22872 	if (LIST_NUM(header->ValueList) < HTTP_HEADER_MAX_LINES)
22873 	{
22874 		Insert(header->ValueList, value);
22875 	}
22876 	else
22877 	{
22878 		FreeHttpValue(value);
22879 	}
22880 }
22881 
22882 // Create an HTTP header
NewHttpHeader(char * method,char * target,char * version)22883 HTTP_HEADER *NewHttpHeader(char *method, char *target, char *version)
22884 {
22885 	return NewHttpHeaderEx(method, target, version, false);
22886 }
NewHttpHeaderEx(char * method,char * target,char * version,bool no_sort)22887 HTTP_HEADER *NewHttpHeaderEx(char *method, char *target, char *version, bool no_sort)
22888 {
22889 	HTTP_HEADER *header;
22890 	// Validate arguments
22891 	if (method == NULL || target == NULL || version == NULL)
22892 	{
22893 		return NULL;
22894 	}
22895 
22896 	header = ZeroMalloc(sizeof(HTTP_HEADER));
22897 
22898 	header->Method = CopyStr(method);
22899 	header->Target = CopyStr(target);
22900 	header->Version = CopyStr(version);
22901 	header->ValueList = NewListFast(no_sort ? NULL : CompareHttpValue);
22902 
22903 	return header;
22904 }
22905 
22906 // Comparison function of the HTTP value
CompareHttpValue(void * p1,void * p2)22907 int CompareHttpValue(void *p1, void *p2)
22908 {
22909 	HTTP_VALUE *v1, *v2;
22910 	if (p1 == NULL || p2 == NULL)
22911 	{
22912 		return 0;
22913 	}
22914 	v1 = *(HTTP_VALUE **)p1;
22915 	v2 = *(HTTP_VALUE **)p2;
22916 	if (v1 == NULL || v2 == NULL)
22917 	{
22918 		return 0;
22919 	}
22920 	return StrCmpi(v1->Name, v2->Name);
22921 }
22922 
22923 // Release the HTTP value
FreeHttpValue(HTTP_VALUE * value)22924 void FreeHttpValue(HTTP_VALUE *value)
22925 {
22926 	// Validate arguments
22927 	if (value == NULL)
22928 	{
22929 		return;
22930 	}
22931 
22932 	Free(value->Data);
22933 	Free(value->Name);
22934 
22935 	Free(value);
22936 }
22937 
22938 // Release the HTTP header
FreeHttpHeader(HTTP_HEADER * header)22939 void FreeHttpHeader(HTTP_HEADER *header)
22940 {
22941 	UINT i;
22942 	HTTP_VALUE **values;
22943 	// Validate arguments
22944 	if (header == NULL)
22945 	{
22946 		return;
22947 	}
22948 
22949 	Free(header->Method);
22950 	Free(header->Target);
22951 	Free(header->Version);
22952 
22953 	values = ToArray(header->ValueList);
22954 	for (i = 0;i < LIST_NUM(header->ValueList);i++)
22955 	{
22956 		FreeHttpValue(values[i]);
22957 	}
22958 	Free(values);
22959 
22960 	ReleaseList(header->ValueList);
22961 
22962 	Free(header);
22963 }
22964 
22965 // Receive a PACK
RecvPack(SOCK * s)22966 PACK *RecvPack(SOCK *s)
22967 {
22968 	PACK *p;
22969 	BUF *b;
22970 	void *data;
22971 	UINT sz;
22972 	// Validate arguments
22973 	if (s == NULL || s->Type != SOCK_TCP)
22974 	{
22975 		return false;
22976 	}
22977 
22978 	if (RecvAll(s, &sz, sizeof(UINT), s->SecureMode) == false)
22979 	{
22980 		return false;
22981 	}
22982 	sz = Endian32(sz);
22983 	if (sz > MAX_PACK_SIZE)
22984 	{
22985 		return false;
22986 	}
22987 	data = MallocEx(sz, true);
22988 	if (RecvAll(s, data, sz, s->SecureMode) == false)
22989 	{
22990 		Free(data);
22991 		return false;
22992 	}
22993 
22994 	b = NewBuf();
22995 	WriteBuf(b, data, sz);
22996 	SeekBuf(b, 0, 0);
22997 	p = BufToPack(b);
22998 	FreeBuf(b);
22999 	Free(data);
23000 
23001 	return p;
23002 }
23003 
23004 // Receive a PACK (with checking the hash)
RecvPackWithHash(SOCK * s)23005 PACK *RecvPackWithHash(SOCK *s)
23006 {
23007 	PACK *p;
23008 	BUF *b;
23009 	void *data;
23010 	UINT sz;
23011 	UCHAR hash1[SHA1_SIZE];
23012 	UCHAR hash2[SHA1_SIZE];
23013 	// Validate arguments
23014 	if (s == NULL || s->Type != SOCK_TCP)
23015 	{
23016 		return false;
23017 	}
23018 
23019 	if (RecvAll(s, &sz, sizeof(UINT), s->SecureMode) == false)
23020 	{
23021 		return false;
23022 	}
23023 	sz = Endian32(sz);
23024 	if (sz > MAX_PACK_SIZE)
23025 	{
23026 		return false;
23027 	}
23028 	data = MallocEx(sz, true);
23029 	if (RecvAll(s, data, sz, s->SecureMode) == false)
23030 	{
23031 		Free(data);
23032 		return false;
23033 	}
23034 
23035 	HashSha1(hash1, data, sz);
23036 	if (RecvAll(s, hash2, sizeof(hash2), s->SecureMode) == false)
23037 	{
23038 		Free(data);
23039 		return false;
23040 	}
23041 
23042 	if (Cmp(hash1, hash2, SHA1_SIZE) != 0)
23043 	{
23044 		Free(data);
23045 		return false;
23046 	}
23047 
23048 	b = NewBuf();
23049 	WriteBuf(b, data, sz);
23050 	SeekBuf(b, 0, 0);
23051 	p = BufToPack(b);
23052 	FreeBuf(b);
23053 	Free(data);
23054 
23055 	return p;
23056 }
23057 
23058 // Send a PACK
SendPack(SOCK * s,PACK * p)23059 bool SendPack(SOCK *s, PACK *p)
23060 {
23061 	BUF *b;
23062 	UINT sz;
23063 	// Validate arguments
23064 	if (s == NULL || p == NULL || s->Type != SOCK_TCP)
23065 	{
23066 		return false;
23067 	}
23068 
23069 	b = PackToBuf(p);
23070 	sz = Endian32(b->Size);
23071 
23072 	SendAdd(s, &sz, sizeof(UINT));
23073 	SendAdd(s, b->Buf, b->Size);
23074 	FreeBuf(b);
23075 
23076 	return SendNow(s, s->SecureMode);
23077 }
23078 
23079 // Send a Pack (with adding a hash)
SendPackWithHash(SOCK * s,PACK * p)23080 bool SendPackWithHash(SOCK *s, PACK *p)
23081 {
23082 	BUF *b;
23083 	UINT sz;
23084 	UCHAR hash[SHA1_SIZE];
23085 	// Validate arguments
23086 	if (s == NULL || p == NULL || s->Type != SOCK_TCP)
23087 	{
23088 		return false;
23089 	}
23090 
23091 	b = PackToBuf(p);
23092 	sz = Endian32(b->Size);
23093 
23094 	SendAdd(s, &sz, sizeof(UINT));
23095 	SendAdd(s, b->Buf, b->Size);
23096 	HashSha1(hash, b->Buf, b->Size);
23097 	SendAdd(s, hash, sizeof(hash));
23098 
23099 	FreeBuf(b);
23100 
23101 	return SendNow(s, s->SecureMode);
23102 }
23103 
23104 // Get SNI name from the data that has arrived to the TCP connection before accepting an SSL connection
GetSniNameFromPreSslConnection(SOCK * s,char * sni,UINT sni_size)23105 bool GetSniNameFromPreSslConnection(SOCK *s, char *sni, UINT sni_size)
23106 {
23107 	UCHAR tmp[1500];
23108 	UINT size;
23109 	// Validate arguments
23110 	if (s == NULL || sni == NULL)
23111 	{
23112 		return false;
23113 	}
23114 
23115 	size = Peek(s, tmp, sizeof(tmp));
23116 	if (size == 0)
23117 	{
23118 		return false;
23119 	}
23120 
23121 	return GetSniNameFromSslPacket(tmp, size, sni, sni_size);
23122 }
23123 
23124 // Get SNI name from the SSL packet
GetSniNameFromSslPacket(UCHAR * packet_buf,UINT packet_size,char * sni,UINT sni_size)23125 bool GetSniNameFromSslPacket(UCHAR *packet_buf, UINT packet_size, char *sni, UINT sni_size)
23126 {
23127 	BUF *buf;
23128 	bool ret = false;
23129 	UCHAR content_type;
23130 	USHORT version;
23131 	USHORT handshake_length;
23132 
23133 	// Validate arguments
23134 	if (packet_buf == NULL || packet_size <= 11)
23135 	{
23136 		return false;
23137 	}
23138 
23139 	if (!(packet_buf[0] == 0x16 && packet_buf[1] >= 0x03 &&
23140 		packet_buf[5] == 0x01 && packet_buf[6] == 0x00 &&
23141 		packet_buf[9] >= 0x03))
23142 	{
23143 		return false;
23144 	}
23145 
23146 	buf = NewBufFromMemory(packet_buf, packet_size);
23147 
23148 	if (ReadBuf(buf, &content_type, sizeof(UCHAR)) == sizeof(UCHAR) &&
23149 		ReadBuf(buf, &version, sizeof(USHORT)) == sizeof(USHORT) &&
23150 		ReadBuf(buf, &handshake_length, sizeof(USHORT)) == sizeof(USHORT))
23151 	{
23152 		version = Endian16(version);
23153 		handshake_length = Endian16(handshake_length);
23154 
23155 		if (content_type == 0x16 && version >= 0x0301)
23156 		{
23157 			UCHAR *handshake_data = Malloc(handshake_length);
23158 
23159 			if (ReadBuf(buf, handshake_data, handshake_length) == handshake_length)
23160 			{
23161 				BUF *buf2 = NewBufFromMemory(handshake_data, handshake_length);
23162 				USHORT handshake_type;
23163 				USHORT handshake_length_2;
23164 
23165 				if (ReadBuf(buf2, &handshake_type, sizeof(USHORT)) == sizeof(USHORT) &&
23166 					ReadBuf(buf2, &handshake_length_2, sizeof(USHORT)) == sizeof(USHORT))
23167 				{
23168 					handshake_type = Endian16(handshake_type);
23169 					handshake_length_2 = Endian16(handshake_length_2);
23170 
23171 					if (handshake_type == 0x0100 && handshake_length_2 <= (handshake_length - 4))
23172 					{
23173 						USHORT version2;
23174 
23175 						if (ReadBuf(buf2, &version2, sizeof(USHORT)) == sizeof(USHORT))
23176 						{
23177 							version2 = Endian16(version2);
23178 
23179 							if (version2 >= 0x0301)
23180 							{
23181 								UCHAR rand[32];
23182 
23183 								if (ReadBuf(buf2, rand, sizeof(rand)) == sizeof(rand))
23184 								{
23185 									UCHAR session_id_len;
23186 
23187 									if (ReadBuf(buf2, &session_id_len, sizeof(UCHAR)) == sizeof(UCHAR))
23188 									{
23189 										if (ReadBuf(buf2, NULL, session_id_len) == session_id_len)
23190 										{
23191 											USHORT cipher_len;
23192 
23193 											if (ReadBuf(buf2, &cipher_len, sizeof(USHORT)) == sizeof(USHORT))
23194 											{
23195 												cipher_len = Endian16(cipher_len);
23196 
23197 												if (ReadBuf(buf2, NULL, cipher_len) == cipher_len)
23198 												{
23199 													UCHAR comps_len;
23200 
23201 													if (ReadBuf(buf2, &comps_len, sizeof(UCHAR)) == sizeof(UCHAR))
23202 													{
23203 														if (ReadBuf(buf2, NULL, comps_len) == comps_len)
23204 														{
23205 															USHORT ext_length;
23206 
23207 															if (ReadBuf(buf2, &ext_length, sizeof(USHORT)) == sizeof(USHORT))
23208 															{
23209 																UCHAR *ext_buf;
23210 
23211 																ext_length = Endian16(ext_length);
23212 
23213 																ext_buf = Malloc(ext_length);
23214 
23215 																if (ReadBuf(buf2, ext_buf, ext_length) == ext_length)
23216 																{
23217 																	BUF *ebuf = NewBufFromMemory(ext_buf, ext_length);
23218 
23219 																	while (ret == false)
23220 																	{
23221 																		USHORT type;
23222 																		USHORT data_len;
23223 																		UCHAR *data;
23224 
23225 																		if (ReadBuf(ebuf, &type, sizeof(USHORT)) != sizeof(USHORT))
23226 																		{
23227 																			break;
23228 																		}
23229 
23230 																		if (ReadBuf(ebuf, &data_len, sizeof(USHORT)) != sizeof(USHORT))
23231 																		{
23232 																			break;
23233 																		}
23234 
23235 																		type = Endian16(type);
23236 																		data_len = Endian16(data_len);
23237 
23238 																		data = Malloc(data_len);
23239 
23240 																		if (ReadBuf(ebuf, data, data_len) != data_len)
23241 																		{
23242 																			Free(data);
23243 																			break;
23244 																		}
23245 
23246 																		if (type == 0x0000)
23247 																		{
23248 																			BUF *dbuf = NewBufFromMemory(data, data_len);
23249 
23250 																			USHORT total_len;
23251 
23252 																			if (ReadBuf(dbuf, &total_len, sizeof(USHORT)) == sizeof(USHORT))
23253 																			{
23254 																				UCHAR c;
23255 																				total_len = Endian16(total_len);
23256 
23257 																				if (ReadBuf(dbuf, &c, sizeof(UCHAR)) == sizeof(UCHAR))
23258 																				{
23259 																					if (c == 0)
23260 																					{
23261 																						USHORT name_len;
23262 
23263 																						if (ReadBuf(dbuf, &name_len, sizeof(USHORT)) == sizeof(USHORT))
23264 																						{
23265 																							char *name_buf;
23266 																							name_len = Endian16(name_len);
23267 
23268 																							name_buf = ZeroMalloc(name_len + 1);
23269 
23270 																							if (ReadBuf(dbuf, name_buf, name_len) == name_len)
23271 																							{
23272 																								if (StrLen(name_buf) >= 1)
23273 																								{
23274 																									ret = true;
23275 
23276 																									StrCpy(sni, sni_size, name_buf);
23277 																								}
23278 																							}
23279 
23280 																							Free(name_buf);
23281 																						}
23282 																					}
23283 																				}
23284 																			}
23285 
23286 																			FreeBuf(dbuf);
23287 																		}
23288 
23289 																		Free(data);
23290 																	}
23291 
23292 																	FreeBuf(ebuf);
23293 																}
23294 
23295 																Free(ext_buf);
23296 															}
23297 														}
23298 													}
23299 												}
23300 											}
23301 										}
23302 									}
23303 								}
23304 							}
23305 						}
23306 					}
23307 				}
23308 
23309 				FreeBuf(buf2);
23310 			}
23311 
23312 			Free(handshake_data);
23313 		}
23314 	}
23315 
23316 	FreeBuf(buf);
23317 
23318 	if (ret)
23319 	{
23320 		Trim(sni);
23321 
23322 		if (IsEmptyStr(sni))
23323 		{
23324 			ret = false;
23325 		}
23326 	}
23327 
23328 	return ret;
23329 }
23330