1 // SoftEther VPN Source Code - Developer Edition Master Branch
2 // Mayaqua Kernel
3 
4 
5 // Network.c
6 // Network communication module
7 
8 #include "Network.h"
9 
10 #include "Cfg.h"
11 #include "DNS.h"
12 #include "FileIO.h"
13 #include "HTTP.h"
14 #include "Internat.h"
15 #include "Memory.h"
16 #include "Microsoft.h"
17 #include "Object.h"
18 #include "Pack.h"
19 #include "Str.h"
20 #include "TcpIp.h"
21 #include "Tick64.h"
22 #include "Unix.h"
23 
24 #include <string.h>
25 
26 #include <openssl/err.h>
27 #include <openssl/ssl.h>
28 
29 #ifdef OS_UNIX
30 #include <fcntl.h>
31 #include <netdb.h>
32 #include <poll.h>
33 #include <signal.h>
34 
35 #include <netinet/tcp.h>
36 #include <sys/socket.h>
37 #include <sys/time.h>
38 #endif
39 
40 #ifdef UNIX_MACOS
41 #include <sys/event.h>
42 #endif
43 
44 #ifdef __DragonFly__
45 #include <sys/socket.h> /* for struct sockaddr */
46 #endif
47 
48 #ifdef UNIX
49 #ifdef UNIX_SOLARIS
50 #define USE_STATVFS
51 #include <sys/statvfs.h>
52 #else
53 #define MAYAQUA_SUPPORTS_GETIFADDRS
54 #include <ifaddrs.h>
55 #endif
56 #endif
57 
58 #ifdef OS_WIN32
59 #include <iphlpapi.h>
60 #include <WS2tcpip.h>
61 
62 #include <IcmpAPI.h>
63 
64 struct ROUTE_CHANGE_DATA
65 {
66 	OVERLAPPED Overlapped;
67 	HANDLE Handle;
68 	UINT NumCalled;
69 };
70 #endif
71 
72 // Whether the blocking occurs in SSL
73 #if	defined(UNIX_BSD) || defined(UNIX_MACOS)
74 #define	FIX_SSL_BLOCKING
75 #endif
76 
77 // HTTP constant
78 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 ";
79 static char http_detect_server_tag_future[] = "9C37197CA7C2428388C2E6E59B829B30";
80 
81 // Lock related
82 static LOCK *machine_name_lock = NULL;
83 static LOCK *disconnect_function_lock = NULL;
84 extern LOCK *openssl_lock;
85 static COUNTER *num_tcp_connections = NULL;
86 static LOCK *unix_dns_server_addr_lock = NULL;
87 static IP unix_dns_server;
88 static LIST *WaitThreadList = NULL;
89 static UCHAR machine_ip_process_hash[SHA1_SIZE];
90 static LOCK *machine_ip_process_hash_lock = NULL;
91 static LOCK *current_global_ip_lock = NULL;
92 static LOCK *current_fqdn_lock = NULL;
93 static bool current_global_ip_set = false;
94 static IP current_glocal_ipv4 = {0};
95 static IP current_glocal_ipv6 = {0};
96 static char current_fqdn[MAX_SIZE];
97 static bool g_no_rudp_server = false;
98 static bool g_no_rudp_register = false;
99 static bool g_natt_low_priority = false;
100 static LOCK *host_ip_address_list_cache_lock = NULL;
101 static UINT64 host_ip_address_list_cache_last = 0;
102 static LIST *host_ip_address_cache = NULL;
103 static bool disable_gethostname_by_accept = false;
104 
105 
106 static LIST *ip_clients = NULL;
107 
108 static LIST *local_mac_list = NULL;
109 static LOCK *local_mac_list_lock = NULL;
110 
111 static UINT rand_port_numbers[256] = {0};
112 
113 
114 static bool g_use_privateip_file = false;
115 static bool g_source_ip_validation_force_disable = false;
116 
117 static DH_CTX *dh_param = NULL;
118 
119 typedef struct PRIVATE_IP_SUBNET
120 {
121 	UINT Ip, Mask, Ip2;
122 } PRIVATE_IP_SUBNET;
123 
124 static LIST *g_private_ip_list = NULL;
125 
126 
127 static LIST *g_dyn_value_list = NULL;
128 
129 
130 
131 //#define	RUDP_DETAIL_LOG
132 
133 
134 
135 
136 // 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)137 UINT64 GetDynValueOrDefault(char *name, UINT64 default_value, UINT64 min_value, UINT64 max_value)
138 {
139 	UINT64 ret = GetDynValue(name);
140 
141 	if (ret == 0)
142 	{
143 		return default_value;
144 	}
145 
146 	if (ret < min_value)
147 	{
148 		ret = min_value;
149 	}
150 
151 	if (ret > max_value)
152 	{
153 		ret = max_value;
154 	}
155 
156 	return ret;
157 }
158 
159 // Get a value from a dynamic value list (Returns a default value if the value is not found)
160 // The value is limited to 1/5 to 50 times of the default value for safety
GetDynValueOrDefaultSafe(char * name,UINT64 default_value)161 UINT64 GetDynValueOrDefaultSafe(char *name, UINT64 default_value)
162 {
163 	return GetDynValueOrDefault(name, default_value, default_value / (UINT64)5, default_value * (UINT64)50);
164 }
165 
166 // Get a value from a dynamic value list
GetDynValue(char * name)167 UINT64 GetDynValue(char *name)
168 {
169 	UINT64 ret = 0;
170 	// Validate arguments
171 	if (name == NULL)
172 	{
173 		return 0;
174 	}
175 
176 	if (g_dyn_value_list == NULL)
177 	{
178 		return 0;
179 	}
180 
181 	LockList(g_dyn_value_list);
182 	{
183 		UINT i;
184 
185 		for (i = 0; i < LIST_NUM(g_dyn_value_list); i++)
186 		{
187 			DYN_VALUE *vv = LIST_DATA(g_dyn_value_list, i);
188 
189 			if (StrCmpi(vv->Name, name) == 0)
190 			{
191 				ret = vv->Value;
192 				break;
193 			}
194 		}
195 	}
196 	UnlockList(g_dyn_value_list);
197 
198 	return ret;
199 }
200 
201 // Set the value to the dynamic value list
SetDynListValue(char * name,UINT64 value)202 void SetDynListValue(char *name, UINT64 value)
203 {
204 	// Validate arguments
205 	if (name == NULL)
206 	{
207 		return;
208 	}
209 
210 	if (g_dyn_value_list == NULL)
211 	{
212 		return;
213 	}
214 
215 	LockList(g_dyn_value_list);
216 	{
217 		UINT i;
218 		DYN_VALUE *v = NULL;
219 
220 		for (i = 0; i < LIST_NUM(g_dyn_value_list); i++)
221 		{
222 			DYN_VALUE *vv = LIST_DATA(g_dyn_value_list, i);
223 
224 			if (StrCmpi(vv->Name, name) == 0)
225 			{
226 				v = vv;
227 				break;
228 			}
229 		}
230 
231 		if (v == NULL)
232 		{
233 			v = ZeroMalloc(sizeof(DYN_VALUE));
234 			StrCpy(v->Name, sizeof(v->Name), name);
235 
236 			Add(g_dyn_value_list, v);
237 		}
238 
239 		v->Value = value;
240 	}
241 	UnlockList(g_dyn_value_list);
242 }
243 
244 // Apply by extracting dynamic value list from the specified PACK
ExtractAndApplyDynList(PACK * p)245 void ExtractAndApplyDynList(PACK *p)
246 {
247 	BUF *b;
248 	// Validate arguments
249 	if (p == NULL)
250 	{
251 		return;
252 	}
253 
254 	b = PackGetBuf(p, "DynList");
255 	if (b == NULL)
256 	{
257 		return;
258 	}
259 
260 	AddDynList(b);
261 
262 	FreeBuf(b);
263 }
264 
265 // Insert the data to the dynamic value list
AddDynList(BUF * b)266 void AddDynList(BUF *b)
267 {
268 	PACK *p;
269 	TOKEN_LIST *t;
270 	// Validate arguments
271 	if (b == NULL)
272 	{
273 		return;
274 	}
275 
276 	SeekBufToBegin(b);
277 
278 	p = BufToPack(b);
279 	if (p == NULL)
280 	{
281 		return;
282 	}
283 
284 	t = GetPackElementNames(p);
285 	if (t != NULL)
286 	{
287 		UINT i;
288 
289 		for (i = 0; i < t->NumTokens; i++)
290 		{
291 			char *name = t->Token[i];
292 			UINT64 v = PackGetInt64(p, name);
293 
294 			SetDynListValue(name, v);
295 		}
296 
297 		FreeToken(t);
298 	}
299 
300 	FreePack(p);
301 }
302 
303 // Initialization of the dynamic value list
InitDynList()304 void InitDynList()
305 {
306 	g_dyn_value_list = NewList(NULL);
307 }
308 
309 // Solution of dynamic value list
FreeDynList()310 void FreeDynList()
311 {
312 	UINT i;
313 	if (g_dyn_value_list == NULL)
314 	{
315 		return;
316 	}
317 
318 	for (i = 0; i < LIST_NUM(g_dyn_value_list); i++)
319 	{
320 		DYN_VALUE *d = LIST_DATA(g_dyn_value_list, i);
321 
322 		Free(d);
323 	}
324 
325 	ReleaseList(g_dyn_value_list);
326 
327 	g_dyn_value_list = NULL;
328 }
329 
330 // Disable NAT-T function globally
DisableRDUPServerGlobally()331 void DisableRDUPServerGlobally()
332 {
333 	g_no_rudp_server = true;
334 }
335 
336 // Get the current time zone
GetCurrentTimezone()337 int GetCurrentTimezone()
338 {
339 	int ret = 0;
340 
341 #ifdef	OS_WIN32
342 	ret = GetCurrentTimezoneWin32();
343 #else	// OS_WIN32
344 	{
345 #if	defined(UNIX_MACOS) || defined(UNIX_BSD)
346 		struct timeval tv;
347 		struct timezone tz;
348 
349 		Zero(&tv, sizeof(tv));
350 		Zero(&tz, sizeof(tz));
351 
352 		gettimeofday(&tv, &tz);
353 
354 		ret = tz.tz_minuteswest;
355 
356 #else	// defined(UNIX_MACOS) || defined(UNIX_BSD)
357 		tzset();
358 
359 		ret = timezone / 60;
360 #endif	// defined(UNIX_MACOS) || defined(UNIX_BSD)
361 	}
362 #endif	// OS_WIN32
363 
364 	return ret;
365 }
366 
367 // Flag of whether to use an alternate host name
IsUseAlternativeHostname()368 bool IsUseAlternativeHostname()
369 {
370 
371 	return false;
372 }
373 
374 #ifdef	OS_WIN32
375 // Get the current time zone (Win32)
GetCurrentTimezoneWin32()376 int GetCurrentTimezoneWin32()
377 {
378 	TIME_ZONE_INFORMATION info;
379 	Zero(&info, sizeof(info));
380 
381 	if (GetTimeZoneInformation(&info) == TIME_ZONE_ID_INVALID)
382 	{
383 		return 0;
384 	}
385 
386 	return info.Bias;
387 }
388 #endif	// OS_WIN32
389 
390 
391 // Set the current FQDN of the DDNS
SetCurrentDDnsFqdn(char * name)392 void SetCurrentDDnsFqdn(char *name)
393 {
394 	// Validate arguments
395 	if (name == NULL)
396 	{
397 		return;
398 	}
399 
400 	Lock(current_fqdn_lock);
401 	{
402 		StrCpy(current_fqdn, sizeof(current_fqdn), name);
403 	}
404 	Unlock(current_fqdn_lock);
405 }
406 
407 // Get the current DDNS FQDN hash
GetCurrentDDnsFqdnHash()408 UINT GetCurrentDDnsFqdnHash()
409 {
410 	UINT ret;
411 	UCHAR hash[SHA1_SIZE];
412 	char name[MAX_SIZE];
413 
414 	ClearStr(name, sizeof(name));
415 	GetCurrentDDnsFqdn(name, sizeof(name));
416 
417 	Trim(name);
418 	StrUpper(name);
419 
420 	Sha1(hash, name, StrLen(name));
421 
422 	Copy(&ret, hash, sizeof(UINT));
423 
424 	return ret;
425 }
426 
427 // Get the current DDNS FQDN
GetCurrentDDnsFqdn(char * name,UINT size)428 void GetCurrentDDnsFqdn(char *name, UINT size)
429 {
430 	ClearStr(name, size);
431 	// Validate arguments
432 	if (name == NULL || size == 0)
433 	{
434 		return;
435 	}
436 
437 	Lock(current_fqdn_lock);
438 	{
439 		StrCpy(name, size, current_fqdn);
440 	}
441 	Unlock(current_fqdn_lock);
442 
443 	Trim(name);
444 }
445 
446 // Check whether the specified MAC address exists on the local host (high speed)
IsMacAddressLocalFast(void * addr)447 bool IsMacAddressLocalFast(void *addr)
448 {
449 	bool ret = false;
450 	// Validate arguments
451 	if (addr == NULL)
452 	{
453 		return false;
454 	}
455 
456 	Lock(local_mac_list_lock);
457 	{
458 		if (local_mac_list == NULL)
459 		{
460 			// First enumeration
461 			RefreshLocalMacAddressList();
462 		}
463 
464 		ret = IsMacAddressLocalInner(local_mac_list, addr);
465 	}
466 	Unlock(local_mac_list_lock);
467 
468 	return ret;
469 }
470 
471 // Update the local MAC address list
RefreshLocalMacAddressList()472 void RefreshLocalMacAddressList()
473 {
474 	Lock(local_mac_list_lock);
475 	{
476 		if (local_mac_list != NULL)
477 		{
478 			FreeNicList(local_mac_list);
479 		}
480 
481 		local_mac_list = GetNicList();
482 	}
483 	Unlock(local_mac_list_lock);
484 }
485 
486 // Check whether the specified MAC address exists on the local host
IsMacAddressLocalInner(LIST * o,void * addr)487 bool IsMacAddressLocalInner(LIST *o, void *addr)
488 {
489 	bool ret = false;
490 	UINT i;
491 	// Validate arguments
492 	if (o == NULL || addr == NULL)
493 	{
494 		return false;
495 	}
496 
497 	for (i = 0; i < LIST_NUM(o); i++)
498 	{
499 		NIC_ENTRY *e = LIST_DATA(o, i);
500 
501 		if (Cmp(e->MacAddress, addr, 6) == 0)
502 		{
503 			ret = true;
504 			break;
505 		}
506 	}
507 
508 	return ret;
509 }
510 
511 // Get a list of the NICs on the computer
GetNicList()512 LIST *GetNicList()
513 {
514 	LIST *o = NULL;
515 
516 #ifdef	OS_WIN32
517 	o = Win32GetNicList();
518 
519 	if (o != NULL)
520 	{
521 		return o;
522 	}
523 
524 #endif	// OS_WIN32
525 
526 	return NewListFast(NULL);
527 }
528 
529 #ifdef	OS_WIN32
Win32GetNicList()530 LIST *Win32GetNicList()
531 {
532 	UINT i;
533 	LIST *o = NewListFast(NULL);
534 	MS_ADAPTER_LIST *al = MsCreateAdapterList();
535 
536 	if (al == NULL)
537 	{
538 		return NULL;
539 	}
540 
541 	for (i = 0; i < al->Num; i++)
542 	{
543 		MS_ADAPTER *a = al->Adapters[i];
544 
545 		if (a->Type == 6 && a->AddressSize == 6)
546 		{
547 			NIC_ENTRY *e = ZeroMalloc(sizeof(NIC_ENTRY));
548 
549 			StrCpy(e->IfName, sizeof(e->IfName), a->Title);
550 			Copy(e->MacAddress, a->Address, 6);
551 
552 			Add(o, e);
553 		}
554 	}
555 
556 	MsFreeAdapterList(al);
557 
558 	return o;
559 }
560 #endif	// OS_WIN32
561 
562 // Release the NIC list
FreeNicList(LIST * o)563 void FreeNicList(LIST *o)
564 {
565 	UINT i;
566 	// Validate arguments
567 	if (o == NULL)
568 	{
569 		return;
570 	}
571 
572 	for (i = 0; i < LIST_NUM(o); i++)
573 	{
574 		NIC_ENTRY *e = LIST_DATA(o, i);
575 
576 		Free(e);
577 	}
578 
579 	ReleaseList(o);
580 }
581 
582 // If the computer is connected to the FLET'S line currently, detect the type of the line (obsolete)
DetectFletsType()583 UINT DetectFletsType()
584 {
585 	UINT ret = 0;
586 	//LIST *o = GetHostIPAddressList();
587 //	UINT i;
588 
589 	/*
590 		for (i = 0;i < LIST_NUM(o);i++)
591 		{
592 			IP *ip = LIST_DATA(o, i);
593 
594 			if (IsIP6(ip))
595 			{
596 				char ip_str[MAX_SIZE];
597 
598 				IPToStr(ip_str, sizeof(ip_str), ip);
599 
600 				if (IsInSameNetwork6ByStr(ip_str, "2001:c90::", "/32"))
601 				{
602 					// NTT East B-FLETs
603 					ret |= FLETS_DETECT_TYPE_EAST_BFLETS_PRIVATE;
604 				}
605 
606 				if (IsInSameNetwork6ByStr(ip_str, "2408:200::", "/23"))
607 				{
608 					// Wrapping in network of NTT East NGN
609 					ret |= FLETS_DETECT_TYPE_EAST_NGN_PRIVATE;
610 				}
611 
612 				if (IsInSameNetwork6ByStr(ip_str, "2001:a200::", "/23"))
613 				{
614 					// Wrapping in network of NTT West NGN
615 					ret |= FLETS_DETECT_TYPE_WEST_NGN_PRIVATE;
616 				}
617 			}
618 		}
619 
620 		FreeHostIPAddressList(o);
621 	*/
622 	return ret;
623 }
624 
625 // 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)626 bool GetIPViaDnsProxyForJapanFlets(IP *ip_ret, char *hostname, bool ipv6, UINT timeout, bool *cancel, char *dns_proxy_hostname)
627 {
628 	SOCK *s;
629 	char connect_hostname[MAX_SIZE];
630 	char connect_hostname2[MAX_SIZE];
631 	IP dns_proxy_ip;
632 	bool ret = false;
633 	bool dummy_flag = false;
634 	char request_str[512];
635 	// Validate arguments
636 	if (ip_ret == NULL || hostname == NULL)
637 	{
638 		return false;
639 	}
640 	if (timeout == 0)
641 	{
642 		timeout = BFLETS_DNS_PROXY_TIMEOUT_FOR_QUERY;
643 	}
644 	if (cancel == NULL)
645 	{
646 		cancel = &dummy_flag;
647 	}
648 
649 	// Get the IP address of the DNS proxy server
650 	if (IsEmptyStr(dns_proxy_hostname))
651 	{
652 		// B FLETs
653 		if (GetDnsProxyIPAddressForJapanBFlets(&dns_proxy_ip, BFLETS_DNS_PROXY_TIMEOUT_FOR_GET_F, cancel) == false)
654 		{
655 			return false;
656 		}
657 	}
658 	else
659 	{
660 		// FLET'S NEXT
661 		if (GetIP6Ex(&dns_proxy_ip, dns_proxy_hostname, FLETS_NGN_DNS_QUERY_TIMEOUT, cancel) == false)
662 		{
663 			return false;
664 		}
665 	}
666 
667 	if (*cancel)
668 	{
669 		return false;
670 	}
671 
672 	IPToStr(connect_hostname, sizeof(connect_hostname), &dns_proxy_ip);
673 
674 	/*{
675 		StrCpy(connect_hostname, sizeof(connect_hostname), "2409:250:62c0:100:6a05:caff:fe09:5158");
676 	}*/
677 
678 	StrCpy(connect_hostname2, sizeof(connect_hostname2), connect_hostname);
679 	if (IsIP6(&dns_proxy_ip))
680 	{
681 		Format(connect_hostname2, sizeof(connect_hostname2), "[%s]", connect_hostname);
682 	}
683 
684 	s = ConnectEx3(connect_hostname, BFLETS_DNS_PROXY_PORT, timeout, cancel, NULL, NULL, false, false);
685 
686 	if (s == NULL)
687 	{
688 		return false;
689 	}
690 
691 	if (*cancel)
692 	{
693 		Disconnect(s);
694 		ReleaseSock(s);
695 
696 		return false;
697 	}
698 
699 	SetTimeout(s, timeout);
700 
701 	// Start the SSL
702 	if (StartSSLEx(s, NULL, NULL, 0, NULL) && (*cancel == false))
703 	{
704 		UCHAR hash[SHA1_SIZE];
705 		BUF *hash2 = StrToBin(BFLETS_DNS_PROXY_CERT_HASH);
706 
707 		Zero(hash, sizeof(hash));
708 		GetXDigest(s->RemoteX, hash, true);
709 
710 		if (Cmp(hash, hash2->Buf, SHA1_SIZE) == 0)
711 		{
712 			// Send the HTTP Request
713 			Format(request_str, sizeof(request_str),
714 			       "GET " BFLETS_DNS_PROXY_PATH "?q=%s&ipv6=%u\r\n"
715 			       "\r\n",
716 			       hostname, ipv6, connect_hostname2);
717 
718 			if (SendAll(s, request_str, StrLen(request_str), true))
719 			{
720 				if (*cancel == false)
721 				{
722 					BUF *recv_buf = NewBuf();
723 					UINT port_ret;
724 
725 					while (true)
726 					{
727 						UCHAR tmp[MAX_SIZE];
728 						UINT r;
729 
730 						r = Recv(s, tmp, sizeof(tmp), true);
731 
732 						if (r == 0 || (recv_buf->Size > 65536))
733 						{
734 							break;
735 						}
736 						else
737 						{
738 							WriteBuf(recv_buf, tmp, r);
739 						}
740 					}
741 
742 					ret = RUDPParseIPAndPortStr(recv_buf->Buf, recv_buf->Size, ip_ret, &port_ret);
743 
744 					FreeBuf(recv_buf);
745 				}
746 			}
747 		}
748 
749 		FreeBuf(hash2);
750 	}
751 
752 	Disconnect(s);
753 	ReleaseSock(s);
754 
755 	if (ret)
756 	{
757 		DnsCacheUpdate(hostname, ipv6 ? ip_ret : NULL, ipv6 ? NULL : ip_ret);
758 	}
759 
760 	return ret;
761 }
762 
763 // 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)764 bool GetDnsProxyIPAddressForJapanBFlets(IP *ip_ret, UINT timeout, bool *cancel)
765 {
766 	BUF *b;
767 	LIST *o;
768 	bool ret = false;
769 	// Validate arguments
770 	if (ip_ret == NULL)
771 	{
772 		return false;
773 	}
774 	if (timeout == 0)
775 	{
776 		timeout = BFLETS_DNS_PROXY_TIMEOUT_FOR_GET_F;
777 	}
778 
779 	b = QueryFileByUdpForJapanBFlets(timeout, cancel);
780 
781 	if (b == NULL)
782 	{
783 		return false;
784 	}
785 
786 	o = ReadIni(b);
787 
788 	if (o != NULL)
789 	{
790 		INI_ENTRY *e = GetIniEntry(o, "DDnsServerForBFlets");
791 
792 		if (e != NULL)
793 		{
794 			char *s = e->Value;
795 
796 			if (IsEmptyStr(s) == false)
797 			{
798 				IP ip;
799 
800 				if (StrToIP(&ip, s))
801 				{
802 					if (IsZeroIp(&ip) == false)
803 					{
804 						Copy(ip_ret, &ip, sizeof(IP));
805 						ret = true;
806 					}
807 				}
808 			}
809 		}
810 	}
811 
812 	FreeIni(o);
813 	FreeBuf(b);
814 
815 	return ret;
816 }
817 
818 // Get a valid F.txt file in B-FLET'S service that is provided by NTT East of Japan
QueryFileByUdpForJapanBFlets(UINT timeout,bool * cancel)819 BUF *QueryFileByUdpForJapanBFlets(UINT timeout, bool *cancel)
820 {
821 	bool dummy_flag = false;
822 	BUF *txt_buf = NULL;
823 	BUF *ret = NULL;
824 	LIST *ip_list = NULL;
825 	UINT i;
826 	// Validate arguments
827 	if (cancel == NULL)
828 	{
829 		cancel = &dummy_flag;
830 	}
831 	if (timeout == 0)
832 	{
833 		timeout = BFLETS_DNS_PROXY_TIMEOUT_FOR_GET_F;
834 	}
835 
836 	txt_buf = ReadDump(UDP_FILE_QUERY_BFLETS_TXT_FILENAME);
837 	if (txt_buf == NULL)
838 	{
839 		return NULL;
840 	}
841 
842 	ip_list = NewListFast(NULL);
843 
844 	while (true)
845 	{
846 		char *line = CfgReadNextLine(txt_buf);
847 		if (line == NULL)
848 		{
849 			break;
850 		}
851 
852 		Trim(line);
853 
854 		if (IsEmptyStr(line) == false && StartWith(line, "#") == false)
855 		{
856 			IP ip;
857 
858 			if (StrToIP6(&ip, line))
859 			{
860 				if (IsZeroIp(&ip) == false)
861 				{
862 					if (IsIPv6LocalNetworkAddress(&ip) == false)
863 					{
864 						Add(ip_list, Clone(&ip, sizeof(IP)));
865 					}
866 				}
867 			}
868 		}
869 
870 		Free(line);
871 	}
872 
873 	FreeBuf(txt_buf);
874 
875 	ret = QueryFileByIPv6Udp(ip_list, timeout, cancel);
876 
877 	for (i = 0; i < LIST_NUM(ip_list); i++)
878 	{
879 		IP *ip = LIST_DATA(ip_list, i);
880 
881 		Free(ip);
882 	}
883 
884 	ReleaseList(ip_list);
885 
886 	return ret;
887 }
888 
889 // 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)890 BUF *QueryFileByIPv6Udp(LIST *ip_list, UINT timeout, bool *cancel)
891 {
892 	bool dummy_flag = false;
893 	UINT64 start_tick, giveup_tick;
894 	UINT64 next_send_tick;
895 	SOCK *s;
896 	INTERRUPT_MANAGER *interrupt;
897 	BUF *buf = NULL;
898 	SOCK_EVENT *se;
899 	UCHAR *tmp_buf;
900 	UINT tmp_buf_size = 65535;
901 	// Validate arguments
902 	if (cancel == NULL)
903 	{
904 		cancel = &dummy_flag;
905 	}
906 	if (ip_list == NULL)
907 	{
908 		return NULL;
909 	}
910 
911 	s = NewUDP6(0, NULL);
912 	if (s == NULL)
913 	{
914 		return NULL;
915 	}
916 
917 	tmp_buf = Malloc(tmp_buf_size);
918 
919 	start_tick = Tick64();
920 	giveup_tick = start_tick + (UINT64)timeout;
921 	next_send_tick = 0;
922 
923 	interrupt = NewInterruptManager();
924 
925 	AddInterrupt(interrupt, giveup_tick);
926 
927 	se = NewSockEvent();
928 	JoinSockToSockEvent(s, se);
929 
930 	while (true)
931 	{
932 		UINT64 now = Tick64();
933 
934 		if (now >= giveup_tick)
935 		{
936 			// Time-out
937 			break;
938 		}
939 
940 		if (*cancel)
941 		{
942 			// User canceled
943 			break;
944 		}
945 
946 		// Receive
947 		while (true)
948 		{
949 			IP src_ip;
950 			UINT src_port;
951 			UINT r;
952 
953 			r = RecvFrom(s, &src_ip, &src_port, tmp_buf, tmp_buf_size);
954 
955 			if (r == SOCK_LATER || r == 0)
956 			{
957 				break;
958 			}
959 
960 			if (src_port == UDP_FILE_QUERY_DST_PORT)
961 			{
962 				if (r >= 40)
963 				{
964 					if (Cmp(tmp_buf, UDP_FILE_QUERY_MAGIC_NUMBER, StrLen(UDP_FILE_QUERY_MAGIC_NUMBER)) == 0)
965 					{
966 						// Successful reception
967 						buf = NewBuf();
968 						WriteBuf(buf, tmp_buf, r);
969 						SeekBuf(buf, 0, 0);
970 						break;
971 					}
972 				}
973 			}
974 		}
975 
976 		if (buf != NULL)
977 		{
978 			// Successful reception
979 			break;
980 		}
981 
982 		if (next_send_tick == 0 || (now >= next_send_tick))
983 		{
984 			// Transmission
985 			UINT i;
986 			for (i = 0; i < LIST_NUM(ip_list); i++)
987 			{
988 				IP *ip = LIST_DATA(ip_list, i);
989 				UCHAR c = 'F';
990 
991 				SendTo(s, ip, UDP_FILE_QUERY_DST_PORT, &c, 1);
992 			}
993 
994 			next_send_tick = now + (UINT64)UDP_FILE_QUERY_RETRY_INTERVAL;
995 			AddInterrupt(interrupt, next_send_tick);
996 		}
997 
998 		WaitSockEvent(se, GetNextIntervalForInterrupt(interrupt));
999 	}
1000 
1001 	FreeInterruptManager(interrupt);
1002 
1003 	Disconnect(s);
1004 	ReleaseSock(s);
1005 
1006 	ReleaseSockEvent(se);
1007 
1008 	Free(tmp_buf);
1009 
1010 	return buf;
1011 }
1012 
1013 // 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)1014 void ParseNtUsername(char *src_username, char *dst_username, UINT dst_username_size, char *dst_domain, UINT dst_domain_size, bool do_not_parse_atmark)
1015 {
1016 	char tmp_username[MAX_SIZE];
1017 	char tmp_domain[MAX_SIZE];
1018 	TOKEN_LIST *t;
1019 
1020 	if (src_username != dst_username)
1021 	{
1022 		ClearStr(dst_username, dst_username_size);
1023 	}
1024 
1025 	ClearStr(dst_domain, dst_domain_size);
1026 	// Validate arguments
1027 	if (src_username == NULL || dst_username == NULL || dst_domain == NULL)
1028 	{
1029 		return;
1030 	}
1031 
1032 	StrCpy(tmp_username, sizeof(tmp_username), src_username);
1033 	ClearStr(tmp_domain, sizeof(tmp_domain));
1034 
1035 	// Analysis of username@domain.name format
1036 	if (do_not_parse_atmark == false)
1037 	{
1038 		t = ParseTokenWithNullStr(tmp_username, "@");
1039 		if (t->NumTokens >= 1)
1040 		{
1041 			StrCpy(tmp_username, sizeof(tmp_username), t->Token[0]);
1042 		}
1043 		if (t->NumTokens >= 2)
1044 		{
1045 			StrCpy(tmp_domain, sizeof(tmp_domain), t->Token[1]);
1046 		}
1047 		FreeToken(t);
1048 	}
1049 
1050 	// If the username part is in "domain\username" format, split it
1051 	t = ParseTokenWithNullStr(tmp_username, "\\");
1052 	if (t->NumTokens >= 2)
1053 	{
1054 		if (IsEmptyStr(tmp_domain))
1055 		{
1056 			StrCpy(tmp_domain, sizeof(tmp_domain), t->Token[0]);
1057 		}
1058 
1059 		StrCpy(tmp_username, sizeof(tmp_username), t->Token[1]);
1060 	}
1061 	FreeToken(t);
1062 
1063 	StrCpy(dst_username, dst_username_size, tmp_username);
1064 	StrCpy(dst_domain, dst_domain_size, tmp_domain);
1065 }
1066 
1067 // 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)1068 UINT RUDPCalcBestMssForBulk(RUDP_STACK *r, RUDP_SESSION *se)
1069 {
1070 	UINT ret;
1071 	// Validate arguments
1072 	if (r == NULL || se == NULL)
1073 	{
1074 		return 0;
1075 	}
1076 
1077 	ret = MTU_FOR_PPPOE;
1078 
1079 	// IPv4
1080 	if (IsIP6(&se->YourIp) == false)
1081 	{
1082 		ret -= 20;
1083 	}
1084 	else
1085 	{
1086 		ret -= 40;
1087 	}
1088 
1089 	if (r->Protocol == RUDP_PROTOCOL_ICMP)
1090 	{
1091 		// ICMP
1092 		ret -= 8;
1093 
1094 		ret -= SHA1_SIZE;
1095 	}
1096 	else if (r->Protocol == RUDP_PROTOCOL_DNS)
1097 	{
1098 		// UDP
1099 		ret -= 8;
1100 
1101 		// DNS
1102 		ret -= 42;
1103 	}
1104 
1105 	// IV
1106 	ret -= SHA1_SIZE;
1107 
1108 	// Sign
1109 	ret -= SHA1_SIZE;
1110 
1111 	// SEQ_NO
1112 	ret -= sizeof(UINT64);
1113 
1114 	// Padding Max
1115 	ret -= 31;
1116 
1117 	// Ethernet header (target packets of communication)
1118 	ret -= 14;
1119 
1120 	// IPv4 Header (target packet of communication)
1121 	ret -= 20;
1122 
1123 	// TCP header (target packet of communication)
1124 	ret -= 20;
1125 
1126 	// I don't know well, but subtract 24 bytes
1127 	ret -= 24;
1128 
1129 	return ret;
1130 }
1131 
1132 // Processing of the reply packet from the NAT-T server
RUDPProcess_NatT_Recv(RUDP_STACK * r,UDPPACKET * udp)1133 void RUDPProcess_NatT_Recv(RUDP_STACK *r, UDPPACKET *udp)
1134 {
1135 	BUF *b;
1136 	PACK *p;
1137 	// Validate arguments
1138 	if (r == NULL || udp == NULL)
1139 	{
1140 		return;
1141 	}
1142 
1143 	if (udp->Size >= 8)
1144 	{
1145 		char tmp[128];
1146 
1147 		Zero(tmp, sizeof(tmp));
1148 		Copy(tmp, udp->Data, MIN(udp->Size, sizeof(tmp) - 1));
1149 
1150 		if (StartWith(tmp, "IP="))
1151 		{
1152 			IP my_ip;
1153 			UINT my_port;
1154 
1155 			// There was a response to the packet to determine the NAT state
1156 			if (IsEmptyStr(r->NatT_Registered_IPAndPort) == false)
1157 			{
1158 				if (StrCmpi(r->NatT_Registered_IPAndPort, tmp) != 0)
1159 				{
1160 					// Redo getting the token and registration because the NAT state is changed
1161 					ClearStr(r->NatT_Registered_IPAndPort, sizeof(r->NatT_Registered_IPAndPort));
1162 
1163 					r->NatT_GetTokenNextTick = 0;
1164 					r->NatT_GetTokenFailNum = 0;
1165 					r->NatT_Token_Ok = false;
1166 					Zero(r->NatT_Token, sizeof(r->NatT_Token));
1167 
1168 					r->NatT_RegisterNextTick = 0;
1169 					r->NatT_RegisterFailNum = 0;
1170 					r->NatT_Register_Ok = false;
1171 				}
1172 			}
1173 
1174 			if (RUDPParseIPAndPortStr(udp->Data, udp->Size, &my_ip, &my_port))
1175 			{
1176 				if (r->NatTGlobalUdpPort != NULL)
1177 				{
1178 					*r->NatTGlobalUdpPort = my_port;
1179 				}
1180 			}
1181 
1182 			return;
1183 		}
1184 	}
1185 
1186 	// Interpret the UDP packet
1187 	b = NewBuf();
1188 	WriteBuf(b, udp->Data, udp->Size);
1189 	SeekBuf(b, 0, 0);
1190 
1191 	p = BufToPack(b);
1192 
1193 	if (p != NULL)
1194 	{
1195 		bool is_ok = PackGetBool(p, "ok");
1196 		UINT64 tran_id = PackGetInt64(p, "tran_id");
1197 
1198 		ExtractAndApplyDynList(p);
1199 
1200 		if (r->ServerMode)
1201 		{
1202 			if (PackCmpStr(p, "opcode", "get_token"))
1203 			{
1204 				// Get the Token
1205 				if (is_ok && (tran_id == r->NatT_TranId))
1206 				{
1207 					char tmp[MAX_SIZE];
1208 
1209 					if (PackGetStr(p, "token", tmp, sizeof(tmp)) && IsEmptyStr(tmp) == false)
1210 					{
1211 						char myip[MAX_SIZE];
1212 						// Acquisition success
1213 						StrCpy(r->NatT_Token, sizeof(r->NatT_Token), tmp);
1214 						r->NatT_Token_Ok = true;
1215 						r->NatT_GetTokenNextTick = r->Now + (UINT64)GenRandInterval(UDP_NAT_T_GET_TOKEN_INTERVAL_2_MIN, UDP_NAT_T_GET_TOKEN_INTERVAL_2_MAX);
1216 						r->NatT_GetTokenFailNum = 0;
1217 
1218 						// Since success to obtain the self global IPv4 address,
1219 						// re-obtain the destination NAT-T host from this IPv4 address
1220 						if (PackGetStr(p, "your_ip", myip, sizeof(myip)))
1221 						{
1222 							IP ip;
1223 							char new_hostname[MAX_SIZE];
1224 
1225 							StrToIP(&ip, myip);
1226 
1227 							SetCurrentGlobalIP(&ip, false);
1228 
1229 							RUDPGetRegisterHostNameByIP(new_hostname,
1230 							                            sizeof(new_hostname), &ip);
1231 
1232 							Lock(r->Lock);
1233 							{
1234 								if (StrCmpi(r->CurrentRegisterHostname, new_hostname) != 0)
1235 								{
1236 									r->NumChangedHostname++;
1237 
1238 									if (r->NumChangedHostname <= RUDP_NATT_MAX_CONT_CHANGE_HOSTNAME)
1239 									{
1240 										if (r->NumChangedHostnameValueResetTick == 0)
1241 										{
1242 											r->NumChangedHostnameValueResetTick = r->Now + (UINT64)RUDP_NATT_CONT_CHANGE_HOSTNAME_RESET_INTERVAL;
1243 										}
1244 
1245 										// Change the host name
1246 										Debug("CurrentRegisterHostname Changed: New=%s\n", new_hostname);
1247 										StrCpy(r->CurrentRegisterHostname, sizeof(r->CurrentRegisterHostname), new_hostname);
1248 
1249 										Zero(&r->NatT_IP, sizeof(r->NatT_IP));
1250 										//Zero(&r->NatT_IP_Safe, sizeof(r->NatT_IP_Safe));
1251 
1252 										Set(r->HaltEvent);
1253 									}
1254 									else
1255 									{
1256 										if (r->NumChangedHostnameValueResetTick == 0)
1257 										{
1258 											r->NumChangedHostnameValueResetTick = r->Now + (UINT64)RUDP_NATT_CONT_CHANGE_HOSTNAME_RESET_INTERVAL;
1259 										}
1260 
1261 										if (r->Now >= r->NumChangedHostnameValueResetTick)
1262 										{
1263 											r->NumChangedHostname = 0;
1264 											r->NumChangedHostnameValueResetTick = 0;
1265 										}
1266 									}
1267 								}
1268 								else
1269 								{
1270 									r->NumChangedHostname = 0;
1271 									r->NumChangedHostnameValueResetTick = 0;
1272 								}
1273 							}
1274 							Unlock(r->Lock);
1275 						}
1276 
1277 						AddInterrupt(r->Interrupt, r->NatT_GetTokenNextTick);
1278 					}
1279 				}
1280 			}
1281 			else if (PackCmpStr(p, "opcode", "nat_t_register"))
1282 			{
1283 				// NAT-T server registration result
1284 				if (is_ok && (tran_id == r->NatT_TranId))
1285 				{
1286 					UINT my_global_port;
1287 					// Successful registration
1288 					r->NatT_Register_Ok = true;
1289 					r->NatT_RegisterNextTick = r->Now + (UINT64)GenRandInterval(UDP_NAT_T_REGISTER_INTERVAL_MIN, UDP_NAT_T_REGISTER_INTERVAL_MAX);
1290 					r->NatT_RegisterFailNum = 0;
1291 
1292 					Debug("NAT-T Registered.\n");
1293 
1294 					// Save the IP address and port number at the time of registration
1295 					PackGetStr(p, "your_ip_and_port", r->NatT_Registered_IPAndPort, sizeof(r->NatT_Registered_IPAndPort));
1296 
1297 					if (g_source_ip_validation_force_disable == false)
1298 					{
1299 						// Enable the source IP address validation mechanism
1300 						r->NatT_EnableSourceIpValidation = PackGetBool(p, "enable_source_ip_validation");
1301 
1302 					}
1303 					else
1304 					{
1305 						// Force disable the source IP address validation mechanism
1306 						r->NatT_EnableSourceIpValidation = false;
1307 					}
1308 
1309 					// Global port of itself
1310 					my_global_port = PackGetInt(p, "your_port");
1311 
1312 					if (my_global_port != 0)
1313 					{
1314 						if (r->NatTGlobalUdpPort != NULL)
1315 						{
1316 							*r->NatTGlobalUdpPort = my_global_port;
1317 						}
1318 					}
1319 
1320 					AddInterrupt(r->Interrupt, r->NatT_RegisterNextTick);
1321 				}
1322 			}
1323 			else if (PackCmpStr(p, "opcode", "nat_t_connect_relay"))
1324 			{
1325 				// Connection request from the client via the NAT-T server
1326 				if (is_ok && (PackGetInt64(p, "session_key") == r->NatT_SessionKey))
1327 				{
1328 					char client_ip_str[MAX_SIZE];
1329 					UINT client_port;
1330 					IP client_ip;
1331 
1332 					PackGetStr(p, "client_ip", client_ip_str, sizeof(client_ip_str));
1333 					client_port = PackGetInt(p, "client_port");
1334 					StrToIP(&client_ip, client_ip_str);
1335 
1336 					if (IsZeroIp(&client_ip) == false && client_port != 0)
1337 					{
1338 						UCHAR *rand_data;
1339 						UINT rand_size;
1340 
1341 						if (r->NatT_EnableSourceIpValidation)
1342 						{
1343 							RUDPAddIpToValidateList(r, &client_ip);
1344 						}
1345 
1346 						rand_size = Rand32() % 19;
1347 						rand_data = Malloc(rand_size);
1348 
1349 						Rand(rand_data, rand_size);
1350 
1351 						RUDPSendPacket(r, &client_ip, client_port, rand_data, rand_size, 0);
1352 
1353 						Free(rand_data);
1354 					}
1355 				}
1356 			}
1357 		}
1358 
1359 		FreePack(p);
1360 	}
1361 
1362 	FreeBuf(b);
1363 }
1364 
1365 // Process such as packet transmission for NAT-T server
RUDPDo_NatT_Interrupt(RUDP_STACK * r)1366 void RUDPDo_NatT_Interrupt(RUDP_STACK *r)
1367 {
1368 	// Validate arguments
1369 	if (r == NULL)
1370 	{
1371 		return;
1372 	}
1373 
1374 	if (r->ServerMode)
1375 	{
1376 
1377 		if (g_no_rudp_register == false && IsZeroIp(&r->NatT_IP_Safe) == false)
1378 		{
1379 			if (r->NatT_GetTokenNextTick == 0 || r->Now >= r->NatT_GetTokenNextTick)
1380 			{
1381 				// Try to get a token from the NAT-T server periodically
1382 				PACK *p = NewPack();
1383 				BUF *b;
1384 
1385 				PackAddStr(p, "opcode", "get_token");
1386 				PackAddInt64(p, "tran_id", r->NatT_TranId);
1387 				PackAddInt(p, "nat_traversal_version", UDP_NAT_TRAVERSAL_VERSION);
1388 
1389 				b = PackToBuf(p);
1390 				FreePack(p);
1391 
1392 				RUDPSendPacket(r, &r->NatT_IP_Safe, UDP_NAT_T_PORT, b->Buf, b->Size, 0);
1393 
1394 				FreeBuf(b);
1395 
1396 				// Determine the next acquisition time
1397 				r->NatT_GetTokenFailNum++;
1398 				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));
1399 				AddInterrupt(r->Interrupt, r->NatT_GetTokenNextTick);
1400 				r->NatT_Token_Ok = false;
1401 			}
1402 		}
1403 
1404 		{
1405 			if (IsZeroIp(&r->NatT_IP_Safe) == false)
1406 			{
1407 				// Normal servers: Send request packets to the NAT-T server
1408 				if (r->NatT_NextNatStatusCheckTick == 0 || r->Now >= r->NatT_NextNatStatusCheckTick)
1409 				{
1410 					UCHAR a = 'A';
1411 					UINT ddns_hash;
1412 					// Check of the NAT state
1413 					RUDPSendPacket(r, &r->NatT_IP_Safe, UDP_NAT_T_PORT, &a, 1, 0);
1414 
1415 					// Execution time of the next
1416 					r->NatT_NextNatStatusCheckTick = r->Now + (UINT64)GenRandInterval(UDP_NAT_T_NAT_STATUS_CHECK_INTERVAL_MIN, UDP_NAT_T_NAT_STATUS_CHECK_INTERVAL_MAX);
1417 					AddInterrupt(r->Interrupt, r->NatT_NextNatStatusCheckTick);
1418 
1419 					// Check whether the DDNS host name changing have not occurred
1420 					ddns_hash = GetCurrentDDnsFqdnHash();
1421 
1422 					if (r->LastDDnsFqdnHash != ddns_hash)
1423 					{
1424 						r->LastDDnsFqdnHash = ddns_hash;
1425 						// Do the Register immediately if there is a change in the DDNS host name
1426 						r->NatT_RegisterNextTick = 0;
1427 					}
1428 				}
1429 			}
1430 		}
1431 
1432 		if (r->NatT_Token_Ok && g_no_rudp_register == false && IsZeroIp(&r->NatT_IP_Safe) == false)
1433 		{
1434 			if (r->NatT_RegisterNextTick == 0 || r->Now >= r->NatT_RegisterNextTick)
1435 			{
1436 				// Try to register itself periodically for NAT-T server
1437 				PACK *p = NewPack();
1438 				BUF *b;
1439 				char private_ip_str[MAX_SIZE];
1440 				char machine_key[MAX_SIZE];
1441 				char machine_name[MAX_SIZE];
1442 				UCHAR hash[SHA1_SIZE];
1443 				char ddns_fqdn[MAX_SIZE];
1444 
1445 				Debug("NAT-T Registering...\n");
1446 
1447 				GetCurrentDDnsFqdn(ddns_fqdn, sizeof(ddns_fqdn));
1448 
1449 				PackAddStr(p, "opcode", "nat_t_register");
1450 				PackAddInt64(p, "tran_id", r->NatT_TranId);
1451 				PackAddStr(p, "token", r->NatT_Token);
1452 				PackAddStr(p, "svc_name", r->SvcName);
1453 				PackAddStr(p, "product_str", "SoftEther OSS");
1454 				PackAddInt64(p, "session_key", r->NatT_SessionKey);
1455 				PackAddInt(p, "nat_traversal_version", UDP_NAT_TRAVERSAL_VERSION);
1456 
1457 
1458 				if (g_natt_low_priority)
1459 				{
1460 					PackAddBool(p, "low_priority", g_natt_low_priority);
1461 				}
1462 
1463 				Zero(private_ip_str, sizeof(private_ip_str));
1464 				if (IsZeroIp(&r->My_Private_IP_Safe) == false)
1465 				{
1466 					IPToStr(private_ip_str, sizeof(private_ip_str), &r->My_Private_IP_Safe);
1467 					PackAddStr(p, "private_ip", private_ip_str);
1468 				}
1469 
1470 				PackAddInt(p, "private_port", r->UdpSock->LocalPort);
1471 
1472 				Zero(hash, sizeof(hash));
1473 				GetCurrentMachineIpProcessHash(hash);
1474 				BinToStr(machine_key, sizeof(machine_key), hash, sizeof(hash));
1475 				PackAddStr(p, "machine_key", machine_key);
1476 
1477 				Zero(machine_name, sizeof(machine_name));
1478 				GetMachineName(machine_name, sizeof(machine_name));
1479 				PackAddStr(p, "host_name", machine_name);
1480 				PackAddStr(p, "ddns_fqdn", ddns_fqdn);
1481 
1482 				b = PackToBuf(p);
1483 				FreePack(p);
1484 
1485 				RUDPSendPacket(r, &r->NatT_IP_Safe, UDP_NAT_T_PORT, b->Buf, b->Size, 0);
1486 				//RUDPSendPacket(r, &r->NatT_IP_Safe, UDP_NAT_T_PORT, "a", 1);
1487 
1488 				FreeBuf(b);
1489 
1490 				// Determine the next acquisition time
1491 				r->NatT_RegisterFailNum++;
1492 				r->NatT_RegisterNextTick = r->Now + (UINT64)UDP_NAT_T_REGISTER_INTERVAL_INITIAL * (UINT64)MIN(r->NatT_RegisterFailNum, UDP_NAT_T_REGISTER_INTERVAL_FAIL_MAX);
1493 				AddInterrupt(r->Interrupt, r->NatT_RegisterNextTick);
1494 				r->NatT_Register_Ok = false;
1495 			}
1496 		}
1497 	}
1498 }
1499 
1500 // R-UDP packet reception procedure
RUDPRecvProc(RUDP_STACK * r,UDPPACKET * p)1501 void RUDPRecvProc(RUDP_STACK *r, UDPPACKET *p)
1502 {
1503 	RUDP_SESSION *se = NULL;
1504 	// Validate arguments
1505 	if (r == NULL || p == NULL)
1506 	{
1507 		return;
1508 	}
1509 
1510 	if (r->ServerMode)
1511 	{
1512 		if (g_no_rudp_server)
1513 		{
1514 			return;
1515 		}
1516 	}
1517 
1518 	if (r->ServerMode && r->NoNatTRegister == false)
1519 	{
1520 
1521 		if (p->SrcPort == UDP_NAT_T_PORT && CmpIpAddr(&p->SrcIP, &r->NatT_IP_Safe) == 0)
1522 		{
1523 			// There was a response from the NAT-T server
1524 			RUDPProcess_NatT_Recv(r, p);
1525 			return;
1526 		}
1527 	}
1528 
1529 	if (r->ServerMode)
1530 	{
1531 		if (r->ProcRpcRecv != NULL)
1532 		{
1533 			if (r->ProcRpcRecv(r, p))
1534 			{
1535 				return;
1536 			}
1537 		}
1538 	}
1539 
1540 	if (r->ServerMode)
1541 	{
1542 		// Search the session by the end-point information if in the server mode
1543 		se = RUDPSearchSession(r, &p->DstIP, p->DestPort, &p->SrcIP, p->SrcPort);
1544 	}
1545 	else
1546 	{
1547 		// Session should exist only one in the case of client mode
1548 		if (LIST_NUM(r->SessionList) >= 1)
1549 		{
1550 			se = LIST_DATA(r->SessionList, 0);
1551 		}
1552 		else
1553 		{
1554 			se = NULL;
1555 		}
1556 	}
1557 
1558 	if (p->Size < 20)
1559 	{
1560 		// The received packet is too small
1561 		if (r->ServerMode == false)
1562 		{
1563 			if (se != NULL && se->Status == RUDP_SESSION_STATUS_CONNECT_SENT)
1564 			{
1565 				if (CmpIpAddr(&se->YourIp, &p->SrcIP) == 0)
1566 				{
1567 					// If the connection initialization packet which is shorter than 20 bytes
1568 					// has been received from the server side, overwrite the source port number
1569 					// of the packet to the client-side session information (for some NAT)
1570 					se->YourPort = p->SrcPort;
1571 				}
1572 			}
1573 		}
1574 		return;
1575 	}
1576 
1577 	if (se == NULL && r->ServerMode && p->Size >= 40)
1578 	{
1579 		// Corresponding to a sudden change of port number on the client side.
1580 		// The target session is a session which matches the client side IP address
1581 		// and the key and the signature is verified
1582 		UINT i;
1583 		for (i = 0; i < LIST_NUM(r->SessionList); i++)
1584 		{
1585 			RUDP_SESSION *s = LIST_DATA(r->SessionList, i);
1586 
1587 			if (CmpIpAddr(&s->YourIp, &p->SrcIP) == 0)
1588 			{
1589 				if (RUDPCheckSignOfRecvPacket(r, s, p->Data, p->Size))
1590 				{
1591 					// Signature matched
1592 					se = s;
1593 					break;
1594 				}
1595 			}
1596 		}
1597 	}
1598 
1599 	if (se == NULL)
1600 	{
1601 		// There is no session
1602 		if (r->ServerMode)
1603 		{
1604 			if (p->Size < 40)
1605 			{
1606 				bool ok = true;
1607 				UCHAR ctoken_hash[SHA1_SIZE];
1608 
1609 				Zero(ctoken_hash, sizeof(ctoken_hash));
1610 
1611 				// Examine the quota of new session creation
1612 				if (LIST_NUM(r->SessionList) >= RUDP_QUOTA_MAX_NUM_SESSIONS)
1613 				{
1614 					// Entire number of sessions exceeds the limit
1615 					ok = false;
1616 				}
1617 				else if (r->NatT_EnableSourceIpValidation && RUDPIsIpInValidateList(r, &p->SrcIP) == false)
1618 				{
1619 					// Invalid source IP address, which is not registered on the validated source IP address list
1620 					ok = false;
1621 				}
1622 				else
1623 				{
1624 					UINT i;
1625 					// Check the number of sessions per IP address
1626 					UINT num = 0;
1627 
1628 					for (i = 0; i < LIST_NUM(r->SessionList); i++)
1629 					{
1630 						RUDP_SESSION *se = LIST_DATA(r->SessionList, i);
1631 
1632 						if (CmpIpAddr(&se->YourIp, &p->SrcIP) == 0)
1633 						{
1634 							num++;
1635 						}
1636 					}
1637 
1638 					if (num >= RUDP_QUOTA_MAX_NUM_SESSIONS_PER_IP)
1639 					{
1640 						// Limit exceeded the number of sessions per IP address
1641 						ok = false;
1642 					}
1643 				}
1644 
1645 
1646 				if (ok)
1647 				{
1648 					char ip_str[64];
1649 
1650 					// Create a session since a new session creation request packet was received
1651 					se = RUDPNewSession(true, &p->DstIP, p->DestPort, &p->SrcIP, p->SrcPort, p->Data);
1652 					se->Status = RUDP_SESSION_STATUS_ESTABLISHED;
1653 					Insert(r->SessionList, se);
1654 
1655 					IPToStr(ip_str, sizeof(ip_str), &p->SrcIP);
1656 					Debug("RUDPNewSession %X %s:%u\n", se, ip_str, p->SrcPort);
1657 
1658 					if (r->Protocol == RUDP_PROTOCOL_ICMP)
1659 					{
1660 						// In case of ICMP, save the ICMP TYPE number to use
1661 						se->Icmp_Type = (p->Type == ICMP_TYPE_INFORMATION_REQUEST ? ICMP_TYPE_INFORMATION_REPLY : p->Type);
1662 					}
1663 					else if (r->Protocol == RUDP_PROTOCOL_DNS)
1664 					{
1665 						// Save the Tran ID to be used if it's a DNS
1666 						se->Dns_TranId = (USHORT)p->Type;
1667 					}
1668 				}
1669 			}
1670 		}
1671 	}
1672 	else
1673 	{
1674 		if (p->Size < 40)
1675 		{
1676 			if (r->ServerMode)
1677 			{
1678 				if (Cmp(se->Key_Init, p->Data, SHA1_SIZE) == 0)
1679 				{
1680 					// New session creation request packet have received more than once. reply an ACK immediately for second and subsequent
1681 					se->LastSentTick = 0;
1682 
1683 					// Update the endpoint information
1684 					Copy(&se->YourIp, &p->SrcIP, sizeof(IP));
1685 					se->YourPort = p->SrcPort;
1686 
1687 					if (r->Protocol == RUDP_PROTOCOL_ICMP)
1688 					{
1689 						// In case of ICMP, save the ICMP TYPE number to use
1690 						se->Icmp_Type = (p->Type == ICMP_TYPE_INFORMATION_REQUEST ? ICMP_TYPE_INFORMATION_REPLY : p->Type);
1691 					}
1692 					else if (r->Protocol == RUDP_PROTOCOL_DNS)
1693 					{
1694 						// Save the Tran ID to be used if it's a DNS
1695 						se->Dns_TranId = (USHORT)p->Type;
1696 					}
1697 				}
1698 				else
1699 				{
1700 					// Since the different session creation request packet have been received from the same end point, ignore it
1701 				}
1702 			}
1703 		}
1704 		else
1705 		{
1706 			// Process the received packet
1707 			if (RUDPProcessRecvPacket(r, se, p->Data, p->Size) || RUDPProcessBulkRecvPacket(r, se, p->Data, p->Size))
1708 			{
1709 				// Update endpoint information (only the port number)
1710 				//Copy(&se->YourIp, &p->SrcIP, sizeof(IP));
1711 				se->YourPort = p->SrcPort;
1712 
1713 				if (r->Protocol == RUDP_PROTOCOL_ICMP)
1714 				{
1715 					// In case of ICMP, save the ICMP TYPE number to use
1716 					if (r->ServerMode)
1717 					{
1718 						se->Icmp_Type = (p->Type == ICMP_TYPE_INFORMATION_REQUEST ? ICMP_TYPE_INFORMATION_REPLY : p->Type);
1719 					}
1720 					else
1721 					{
1722 						se->Icmp_Type = (p->Type == ICMP_TYPE_INFORMATION_REPLY ? ICMP_TYPE_INFORMATION_REQUEST : p->Type);
1723 					}
1724 				}
1725 				else if (r->Protocol == RUDP_PROTOCOL_DNS)
1726 				{
1727 					if (r->ServerMode)
1728 					{
1729 						// Save the Tran ID to be used if it's a DNS
1730 						se->Dns_TranId = (USHORT)p->Type;
1731 					}
1732 				}
1733 			}
1734 		}
1735 	}
1736 }
1737 
1738 // Check whether the specificed IP address is in the validated source IP address list
RUDPIsIpInValidateList(RUDP_STACK * r,IP * ip)1739 bool RUDPIsIpInValidateList(RUDP_STACK *r, IP *ip)
1740 {
1741 	UINT i;
1742 	UINT64 now = Tick64();
1743 	LIST *o = NULL;
1744 	bool ret = false;
1745 	// Validate arguments
1746 	if (r == NULL || ip == NULL)
1747 	{
1748 		return false;
1749 	}
1750 
1751 	// Always allow private IP addresses
1752 	if (IsIPPrivate(ip))
1753 	{
1754 		return true;
1755 	}
1756 
1757 	if (IsIPAddressInSameLocalNetwork(ip))
1758 	{
1759 		return true;
1760 	}
1761 
1762 	for (i = 0; i < LIST_NUM(r->NatT_SourceIpList); i++)
1763 	{
1764 		RUDP_SOURCE_IP *s = (RUDP_SOURCE_IP *)LIST_DATA(r->NatT_SourceIpList, i);
1765 
1766 		if (s->ExpiresTick <= now)
1767 		{
1768 			if (o == NULL)
1769 			{
1770 				o = NewListFast(NULL);
1771 			}
1772 
1773 			Add(o, s);
1774 		}
1775 	}
1776 
1777 	if (o != NULL)
1778 	{
1779 		for (i = 0; i < LIST_NUM(o); i++)
1780 		{
1781 			RUDP_SOURCE_IP *s = (RUDP_SOURCE_IP *)LIST_DATA(o, i);
1782 
1783 			Delete(r->NatT_SourceIpList, s);
1784 
1785 			Free(s);
1786 		}
1787 
1788 		ReleaseList(o);
1789 	}
1790 
1791 	for (i = 0; i < LIST_NUM(r->NatT_SourceIpList); i++)
1792 	{
1793 		RUDP_SOURCE_IP *s = (RUDP_SOURCE_IP *)LIST_DATA(r->NatT_SourceIpList, i);
1794 
1795 		if (CmpIpAddr(&s->ClientIP, ip) == 0)
1796 		{
1797 			ret = true;
1798 			break;
1799 		}
1800 	}
1801 
1802 	Debug("RUDP: NAT-T: Validate IP: %r, ret=%u (current list len = %u)\n", ip, ret, LIST_NUM(r->NatT_SourceIpList));
1803 
1804 	return ret;
1805 }
1806 
1807 // Add an IP address to the validated source IP address list
RUDPAddIpToValidateList(RUDP_STACK * r,IP * ip)1808 void RUDPAddIpToValidateList(RUDP_STACK *r, IP *ip)
1809 {
1810 	UINT i;
1811 	RUDP_SOURCE_IP *sip;
1812 	UINT64 now = Tick64();
1813 	LIST *o = NULL;
1814 	// Validate arguments
1815 	if (r == NULL || ip == NULL)
1816 	{
1817 		return;
1818 	}
1819 
1820 	if (LIST_NUM(r->NatT_SourceIpList) >= RUDP_MAX_VALIDATED_SOURCE_IP_ADDRESSES)
1821 	{
1822 		return;
1823 	}
1824 
1825 	for (i = 0; i < LIST_NUM(r->NatT_SourceIpList); i++)
1826 	{
1827 		RUDP_SOURCE_IP *s = (RUDP_SOURCE_IP *)LIST_DATA(r->NatT_SourceIpList, i);
1828 
1829 		if (s->ExpiresTick <= now)
1830 		{
1831 			if (o == NULL)
1832 			{
1833 				o = NewListFast(NULL);
1834 			}
1835 
1836 			Add(o, s);
1837 		}
1838 	}
1839 
1840 	if (o != NULL)
1841 	{
1842 		for (i = 0; i < LIST_NUM(o); i++)
1843 		{
1844 			RUDP_SOURCE_IP *s = (RUDP_SOURCE_IP *)LIST_DATA(o, i);
1845 
1846 			Delete(r->NatT_SourceIpList, s);
1847 
1848 			Free(s);
1849 		}
1850 
1851 		ReleaseList(o);
1852 	}
1853 
1854 	sip = NULL;
1855 
1856 	for (i = 0; i < LIST_NUM(r->NatT_SourceIpList); i++)
1857 	{
1858 		RUDP_SOURCE_IP *s = (RUDP_SOURCE_IP *)LIST_DATA(r->NatT_SourceIpList, i);
1859 
1860 		if (CmpIpAddr(&s->ClientIP, ip) == 0)
1861 		{
1862 			sip = s;
1863 			break;
1864 		}
1865 	}
1866 
1867 	if (sip == NULL)
1868 	{
1869 		sip = ZeroMalloc(sizeof(RUDP_SOURCE_IP));
1870 
1871 		Copy(&sip->ClientIP, ip, sizeof(IP));
1872 
1873 		Add(r->NatT_SourceIpList, sip);
1874 	}
1875 
1876 	sip->ExpiresTick = now + (UINT64)RUDP_VALIDATED_SOURCE_IP_ADDRESS_EXPIRES;
1877 
1878 	Debug("RUDP: NAT-T: Src IP added: %r (current list len = %u)\n", ip, LIST_NUM(r->NatT_SourceIpList));
1879 }
1880 
1881 // R-UDP interrupt processing procedure
RUDPInterruptProc(RUDP_STACK * r)1882 void RUDPInterruptProc(RUDP_STACK *r)
1883 {
1884 	UINT i;
1885 	LIST *o;
1886 	// Validate arguments
1887 	if (r == NULL)
1888 	{
1889 		return;
1890 	}
1891 
1892 	// Packet transmission and other process for NAT-T server
1893 	if (r->NoNatTRegister == false)
1894 	{
1895 		RUDPDo_NatT_Interrupt(r);
1896 	}
1897 
1898 	if (r->ServerMode == false)
1899 	{
1900 		if (r->ClientInitiated == false)
1901 		{
1902 			bool client_target_inited = false;
1903 			Lock(r->Lock);
1904 			{
1905 				client_target_inited = r->TargetIpAndPortInited;
1906 			}
1907 			Unlock(r->Lock);
1908 
1909 			if (client_target_inited)
1910 			{
1911 				// Start a connection when there is the end point information of the destination server to connect as a client
1912 				RUDP_SESSION *se;
1913 				UCHAR init_key[SHA1_SIZE];
1914 				char ip_str[128];
1915 				UINT64 ui;
1916 
1917 				Rand(init_key, SHA1_SIZE);
1918 
1919 				se = RUDPNewSession(false, &r->UdpSock->LocalIP, r->UdpSock->LocalPort,
1920 				                    &r->TargetIp, r->TargetPort, init_key);
1921 
1922 				IPToStr(ip_str, sizeof(ip_str), &r->TargetIp);
1923 				Debug("RUDPNewSession %X %s:%u\n", se, ip_str, r->TargetPort);
1924 
1925 				Insert(r->SessionList, se);
1926 
1927 				ui = Endian64(se->Magic_Disconnect);
1928 				WriteFifo(se->SendFifo, &ui, sizeof(UINT64));
1929 
1930 				r->ClientInitiated = true;
1931 			}
1932 		}
1933 	}
1934 
1935 	// Process for all the sessions
1936 	for (i = 0; i < LIST_NUM(r->SessionList); i++)
1937 	{
1938 		RUDP_SESSION *se = LIST_DATA(r->SessionList, i);
1939 
1940 		if (r->Halt)
1941 		{
1942 			// Disconnect all the sessions if the R-UDP stack stopped
1943 			RUDPDisconnectSession(r, se, false);
1944 		}
1945 
1946 		if (se->FlushBulkSendTube)
1947 		{
1948 			if (se->TcpSock != NULL && se->TcpSock->BulkSendTube != NULL)
1949 			{
1950 				TubeFlush(se->TcpSock->BulkSendTube);
1951 			}
1952 
1953 			se->FlushBulkSendTube = false;
1954 		}
1955 
1956 		if (se->Status == RUDP_SESSION_STATUS_ESTABLISHED)
1957 		{
1958 			// Process for all of the sessions which is established a connection
1959 			UINT j;
1960 
1961 			if (r->Now >= (se->LatestRecvMyTick + (UINT64)RUDP_TIMEOUT))
1962 			{
1963 				// Disconnect the session because the fully communication failure is detected for a while
1964 				Debug("R-UDP Session %X Timed Out.\n", se);
1965 
1966 				RUDPDisconnectSession(r, se, false);
1967 			}
1968 
1969 			// If there are received segments, read to the part that has arrived in succession
1970 			if (FifoSize(se->RecvFifo) <= RUDP_MAX_FIFO_SIZE)
1971 			{
1972 				LIST *o;
1973 				UINT64 current_seq_no;
1974 
1975 				o = NULL;
1976 				current_seq_no = se->LastRecvCompleteSeqNo;
1977 				for (j = 0; j < LIST_NUM(se->RecvSegmentList); j++)
1978 				{
1979 					RUDP_SEGMENT *s;
1980 
1981 					current_seq_no++;
1982 
1983 					s = LIST_DATA(se->RecvSegmentList, j);
1984 
1985 					if (s->SeqNo == current_seq_no)
1986 					{
1987 #ifdef	RUDP_DETAIL_LOG
1988 						Debug("%X s->SeqNo = %I64u, current_seq_no = %I64u\n", se, s->SeqNo, current_seq_no);
1989 #endif	// RUDP_DETAIL_LOG
1990 
1991 						if (s->Size == sizeof(se->Magic_KeepAliveRequest) && Cmp(s->Data, se->Magic_KeepAliveRequest, sizeof(se->Magic_KeepAliveRequest)) == 0)
1992 						{
1993 							// Receive the KeepAlive Request
1994 #ifdef	RUDP_DETAIL_LOG
1995 							Debug("Recv KeepAlive Request\n");
1996 #endif	// RUDP_DETAIL_LOG
1997 
1998 							// Send a KeepAlive Response if the transmisson queue is empty
1999 							if (LIST_NUM(se->SendSegmentList) == 0)
2000 							{
2001 #ifdef	RUDP_DETAIL_LOG
2002 								Debug("Send KeepAlive Response\n");
2003 #endif	// RUDP_DETAIL_LOG
2004 
2005 								RUDPSendSegment(r, se, se->Magic_KeepAliveResponse, sizeof(se->Magic_KeepAliveResponse));
2006 							}
2007 						}
2008 						else if (s->Size == sizeof(se->Magic_KeepAliveResponse) && Cmp(s->Data, se->Magic_KeepAliveResponse, sizeof(se->Magic_KeepAliveResponse)) == 0)
2009 						{
2010 							// Receive the KeepAlive Response
2011 #ifdef	RUDP_DETAIL_LOG
2012 							Debug("Recv KeepAlive Response\n");
2013 #endif	// RUDP_DETAIL_LOG
2014 						}
2015 						else
2016 						{
2017 							// Write to the receive FIFO
2018 							WriteFifo(se->RecvFifo, s->Data, s->Size);
2019 						}
2020 						r->TotalLogicalReceived += s->Size;
2021 
2022 						// Advance the SEQ NO which has been received completely
2023 						se->LastRecvCompleteSeqNo = s->SeqNo;
2024 
2025 						// Add to the Delete list
2026 						if (o == NULL)
2027 						{
2028 							o = NewListFast(NULL);
2029 						}
2030 						Add(o, s);
2031 					}
2032 					else
2033 					{
2034 						// Continuous reading is interrupted
2035 #ifdef	RUDP_DETAIL_LOG
2036 						Debug("%X s->SeqNo = %I64u, current_seq_no = %I64u\n", se, s->SeqNo, current_seq_no);
2037 						WHERE;
2038 #endif	// RUDP_DETAIL_LOG
2039 						break;
2040 					}
2041 				}
2042 
2043 				// Delete the segment which has been received completely
2044 				if (o != NULL)
2045 				{
2046 					for (j = 0; j < LIST_NUM(o); j++)
2047 					{
2048 						RUDP_SEGMENT *s = LIST_DATA(o, j);
2049 
2050 						Delete(se->RecvSegmentList, s);
2051 						Free(s);
2052 					}
2053 					ReleaseList(o);
2054 				}
2055 			}
2056 
2057 			if (r->ServerMode && se->Magic_Disconnect == 0)
2058 			{
2059 				if (FifoSize(se->RecvFifo) >= sizeof(UINT64))
2060 				{
2061 					UINT64 ui;
2062 
2063 					if (ReadFifo(se->RecvFifo, &ui, sizeof(UINT64)) == sizeof(UINT64))
2064 					{
2065 						ui = Endian64(ui);
2066 
2067 						if ((ui & 0xffffffff00000000ULL) != 0ULL)
2068 						{
2069 							se->Magic_Disconnect = ui;
2070 						}
2071 					}
2072 				}
2073 			}
2074 
2075 			// If the data remains in FIFO, write it to the TCP socket as possible
2076 			if (r->ServerMode == false || se->Magic_Disconnect != 0)
2077 			{
2078 				while (FifoSize(se->RecvFifo) >= 1)
2079 				{
2080 					UINT ret;
2081 
2082 					RUDPInitSock(r, se);
2083 
2084 					ret = Send(se->TcpSock, FifoPtr(se->RecvFifo), FifoSize(se->RecvFifo), false);
2085 
2086 					if (ret == SOCK_LATER)
2087 					{
2088 						// Can not write any more
2089 						break;
2090 					}
2091 					else if (ret == 0)
2092 					{
2093 						// Disconnected
2094 						Disconnect(se->TcpSock);
2095 						RUDPDisconnectSession(r, se, false);
2096 						break;
2097 					}
2098 					else
2099 					{
2100 						// Writing success
2101 						ReadFifo(se->RecvFifo, NULL, ret);
2102 					}
2103 				}
2104 			}
2105 
2106 			// Read the data as much as possible from the TCP socket and store it to FIFO
2107 			if (se->TcpSock != NULL)
2108 			{
2109 				SetNoNeedToRead(se->TcpSock);
2110 
2111 				while (FifoSize(se->SendFifo) <= RUDP_MAX_FIFO_SIZE)
2112 				{
2113 					UINT ret = Recv(se->TcpSock, r->TmpBuf, sizeof(r->TmpBuf), false);
2114 
2115 					if (ret == SOCK_LATER)
2116 					{
2117 						// Can not read any more
2118 						break;
2119 					}
2120 					else if (ret == 0)
2121 					{
2122 						// Disconnected
2123 						Disconnect(se->TcpSock);
2124 						RUDPDisconnectSession(r, se, false);
2125 						break;
2126 					}
2127 					else
2128 					{
2129 						// Reading success
2130 						WriteFifo(se->SendFifo, r->TmpBuf, ret);
2131 					}
2132 				}
2133 			}
2134 
2135 			// Attempt to send a divided segment
2136 			while (true)
2137 			{
2138 				UINT64 seq_no_min, seq_no_max;
2139 
2140 				seq_no_min = RUDPGetCurrentSendingMinSeqNo(se);
2141 				seq_no_max = RUDPGetCurrentSendingMaxSeqNo(se);
2142 
2143 #ifdef	RUDP_DETAIL_LOG
2144 				Debug("min=%I64u max=%I64u\n", seq_no_min, seq_no_max);
2145 #endif	// RUDP_DETAIL_LOG
2146 
2147 				if (seq_no_min == 0 || ((seq_no_min + RUDP_MAX_NUM_ACK - 1) >= se->NextSendSeqNo))
2148 				{
2149 					// Because there is a room to send a new segment, send a segment
2150 					UINT size = MIN(FifoSize(se->SendFifo), RUDP_MAX_SEGMENT_SIZE);
2151 
2152 					if (size == 0)
2153 					{
2154 						// There is no more data to send in FIFO
2155 						break;
2156 					}
2157 
2158 					// Transmission
2159 					RUDPSendSegment(r, se, FifoPtr(se->SendFifo), size);
2160 
2161 					r->TotalLogicalSent += size;
2162 
2163 					// Advance the FIFO
2164 					ReadFifo(se->SendFifo, NULL, size);
2165 				}
2166 				else
2167 				{
2168 					// There is no room to send a new segment further
2169 					break;
2170 				}
2171 			}
2172 
2173 			if (se->DisconnectFlag == false)
2174 			{
2175 				UINT64 seq_no_min;
2176 
2177 				if (se->LastSentTick == 0 || (r->Now >= (se->LastSentTick + (UINT64)se->NextKeepAliveInterval)))
2178 				{
2179 					if (LIST_NUM(se->SendSegmentList) == 0)
2180 					{
2181 						// Send a Keep-Alive if no data was sent for a while and the transmission queue is empty
2182 						RUDPSendSegment(r, se, se->Magic_KeepAliveRequest, sizeof(se->Magic_KeepAliveRequest));
2183 
2184 #ifdef	RUDP_DETAIL_LOG
2185 						Debug("Sent KeepAlive Request\n");
2186 #endif	// RUDP_DETAIL_LOG
2187 					}
2188 
2189 					se->NextKeepAliveInterval = RUDP_KEEPALIVE_INTERVAL_MIN + (Rand32() % (RUDP_KEEPALIVE_INTERVAL_MAX - RUDP_KEEPALIVE_INTERVAL_MIN));
2190 
2191 					AddInterrupt(r->Interrupt, r->Now + se->NextKeepAliveInterval);
2192 				}
2193 
2194 				seq_no_min = RUDPGetCurrentSendingMinSeqNo(se);
2195 				for (j = 0; j < LIST_NUM(se->SendSegmentList); j++)
2196 				{
2197 					RUDP_SEGMENT *s = LIST_DATA(se->SendSegmentList, j);
2198 
2199 					if (s->SeqNo <= (seq_no_min + RUDP_MAX_NUM_ACK - 1))
2200 					{
2201 						if (s->NextSendTick == 0 || r->Now >= s->NextSendTick)
2202 						{
2203 							UINT next_interval;
2204 							// Transmits a segment which has not been sent even once yet, or whose retransmission time has arrived
2205 							RUDPSendSegmentNow(r, se, s->SeqNo, s->Data, s->Size);
2206 
2207 							if (se->CurrentRtt != 0)
2208 							{
2209 								next_interval = (se->CurrentRtt * 120 / 100) * Power(2, MIN(s->NumSent, 10));
2210 							}
2211 							else
2212 							{
2213 								next_interval = RUDP_RESEND_TIMER * Power(2, MIN(s->NumSent, 10));
2214 							}
2215 
2216 							next_interval = MIN(next_interval, RUDP_RESEND_TIMER_MAX);
2217 
2218 							s->NumSent++;
2219 
2220 							s->NextSendTick = r->Now + next_interval;
2221 
2222 							AddInterrupt(r->Interrupt, s->NextSendTick);
2223 						}
2224 					}
2225 				}
2226 
2227 				while (LIST_NUM(se->ReplyAckList) >= 1)
2228 				{
2229 					// If there are ACKs which is not responded yet in the list, send all of them
2230 					RUDPSendSegmentNow(r, se, se->NextSendSeqNo, NULL, 0);
2231 				}
2232 
2233 				// Send all if there are bulk transfer data
2234 				if (se->TcpSock != NULL)
2235 				{
2236 					SOCK *s = se->TcpSock;
2237 
2238 					if (s->BulkRecvTube != NULL)
2239 					{
2240 						TUBE *t = s->BulkRecvTube;
2241 
2242 						while (true)
2243 						{
2244 							TUBEDATA *d = TubeRecvAsync(t);
2245 
2246 							if (d == NULL)
2247 							{
2248 								break;
2249 							}
2250 
2251 							if (d->Header != NULL && d->HeaderSize == sizeof(TCP_PAIR_HEADER))
2252 							{
2253 								TCP_PAIR_HEADER *h = d->Header;
2254 
2255 								if (h->EnableHMac)
2256 								{
2257 									se->UseHMac = true;
2258 								}
2259 							}
2260 
2261 							RUDPBulkSend(r, se, d->Data, d->DataSize);
2262 
2263 							FreeTubeData(d);
2264 						}
2265 					}
2266 				}
2267 			}
2268 		}
2269 
2270 		if (r->ServerMode == false)
2271 		{
2272 			if (se->Status == RUDP_SESSION_STATUS_CONNECT_SENT)
2273 			{
2274 				// Send a connection request periodically from the client side
2275 				if (se->LastSentTick == 0 || ((se->LastSentTick + (UINT64)RUDP_RESEND_TIMER) <= r->Now))
2276 				{
2277 					UCHAR tmp[40];
2278 					UINT size_of_padding = 19;
2279 					UINT size = size_of_padding + SHA1_SIZE;
2280 
2281 					se->LastSentTick = r->Now;
2282 
2283 					Copy(tmp, se->Key_Init, SHA1_SIZE);
2284 					Rand(tmp + SHA1_SIZE, size_of_padding);
2285 
2286 					if (r->Protocol == RUDP_PROTOCOL_ICMP)
2287 					{
2288 						// ICMP packet
2289 						UCHAR *rand_data;
2290 						UINT rand_size;
2291 
2292 						rand_size = Rand32() % 64 + 64;
2293 						rand_data = Malloc(rand_size);
2294 						Rand(rand_data, rand_size);
2295 
2296 						RUDPSendPacket(r, &se->YourIp, se->YourPort, rand_data, rand_size, ICMP_TYPE_ECHO_REQUEST);
2297 						Free(rand_data);
2298 
2299 						se->Client_Icmp_NextSendEchoRequest = r->Now + GenRandInterval(RUDP_CLIENT_ECHO_REQUEST_SEND_INTERVAL_MIN, RUDP_CLIENT_ECHO_REQUEST_SEND_INTERVAL_MAX);
2300 						AddInterrupt(r->Interrupt, se->Client_Icmp_NextSendEchoRequest);
2301 
2302 						// Try in both INFORMATION_REQUEST and ECHO_RESPONSE from the client side first
2303 						RUDPSendPacket(r, &se->YourIp, se->YourPort, tmp, size, ICMP_TYPE_ECHO_RESPONSE);
2304 						RUDPSendPacket(r, &se->YourIp, se->YourPort, tmp, size, ICMP_TYPE_INFORMATION_REQUEST);
2305 					}
2306 					else if (r->Protocol == RUDP_PROTOCOL_DNS)
2307 					{
2308 						// DNS
2309 						RUDPSendPacket(r, &se->YourIp, se->YourPort, tmp, size, se->Dns_TranId);
2310 					}
2311 					else
2312 					{
2313 						// Normal UDP
2314 						RUDPSendPacket(r, &se->YourIp, se->YourPort, tmp, size, 0);
2315 					}
2316 
2317 					AddInterrupt(r->Interrupt, r->Now + (UINT64)RUDP_RESEND_TIMER);
2318 				}
2319 			}
2320 
2321 			if (r->Protocol == RUDP_PROTOCOL_ICMP)
2322 			{
2323 				if (se->Client_Icmp_NextSendEchoRequest == 0 || (r->Now >= se->Client_Icmp_NextSendEchoRequest))
2324 				{
2325 					// Periodic ICMP Echo transmission from the client side when R-UDP used in ICMP mode
2326 					// (To maintain the mapping table of the NAT)
2327 					UCHAR *rand_data;
2328 					UINT rand_size;
2329 
2330 					rand_size = Rand32() % 64 + 64;
2331 					rand_data = Malloc(rand_size);
2332 					Rand(rand_data, rand_size);
2333 
2334 					RUDPSendPacket(r, &se->YourIp, se->YourPort, rand_data, rand_size, ICMP_TYPE_ECHO_REQUEST);
2335 					Free(rand_data);
2336 
2337 					se->Client_Icmp_NextSendEchoRequest = r->Now + GenRandInterval(RUDP_CLIENT_ECHO_REQUEST_SEND_INTERVAL_MIN, RUDP_CLIENT_ECHO_REQUEST_SEND_INTERVAL_MAX);
2338 					AddInterrupt(r->Interrupt, se->Client_Icmp_NextSendEchoRequest);
2339 				}
2340 			}
2341 		}
2342 	}
2343 
2344 	// Release the disconnected sessions
2345 	o = NULL;
2346 	for (i = 0; i < LIST_NUM(r->SessionList); i++)
2347 	{
2348 		RUDP_SESSION *se = LIST_DATA(r->SessionList, i);
2349 
2350 		if (se->DisconnectFlag)
2351 		{
2352 			if (o == NULL)
2353 			{
2354 				o = NewListFast(NULL);
2355 			}
2356 
2357 			Add(o, se);
2358 		}
2359 	}
2360 	if (o != NULL)
2361 	{
2362 		for (i = 0; i < LIST_NUM(o); i++)
2363 		{
2364 			RUDP_SESSION *se = LIST_DATA(o, i);
2365 
2366 			Delete(r->SessionList, se);
2367 
2368 			RUDPFreeSession(se);
2369 		}
2370 
2371 		ReleaseList(o);
2372 	}
2373 }
2374 
2375 // Do the bulk send
RUDPBulkSend(RUDP_STACK * r,RUDP_SESSION * se,void * data,UINT data_size)2376 void RUDPBulkSend(RUDP_STACK *r, RUDP_SESSION *se, void *data, UINT data_size)
2377 {
2378 	UCHAR *buf;
2379 	UINT i, icmp_type, buf_size, padding_size;
2380 	icmp_type = 0;
2381 	// Validate arguments
2382 	if (r == NULL || se == NULL || (data == NULL && data_size != 0))
2383 	{
2384 		return;
2385 	}
2386 
2387 	if (se->BulkSendKey->Size == RUDP_BULK_KEY_SIZE_V2)
2388 	{
2389 		UCHAR *tmp, iv[RUDP_BULK_IV_SIZE_V2];
2390 		UINT size;
2391 		CIPHER *c;
2392 
2393 		padding_size = Rand32() % 31 + 1;
2394 
2395 		size = sizeof(UINT64) + data_size + padding_size;
2396 
2397 		// Packet: IV + Encrypted(SEQ_NO + Data + padding) + MAC
2398 		buf_size = RUDP_BULK_IV_SIZE_V2 + sizeof(UINT64) + data_size + padding_size + RUDP_BULK_MAC_SIZE_V2;
2399 		buf = Malloc(buf_size);
2400 
2401 		// IV
2402 		Copy(iv, se->BulkNextIv_V2, RUDP_BULK_IV_SIZE_V2);
2403 		Copy(buf, iv, RUDP_BULK_IV_SIZE_V2);
2404 
2405 		// SEQ NO
2406 		WRITE_UINT64(buf + RUDP_BULK_IV_SIZE_V2, se->BulkNextSeqNo);
2407 		se->BulkNextSeqNo++;
2408 
2409 		// Data
2410 		Copy(buf + RUDP_BULK_IV_SIZE_V2 + sizeof(UINT64), data, data_size);
2411 
2412 		// Padding
2413 		for (i = 0; i < padding_size; i++)
2414 		{
2415 			buf[RUDP_BULK_IV_SIZE_V2 + sizeof(UINT64) + data_size + i] = (UCHAR)padding_size;
2416 		}
2417 
2418 		size = sizeof(UINT64) + data_size + padding_size;
2419 		tmp = buf + RUDP_BULK_IV_SIZE_V2;
2420 
2421 		// Encryption
2422 		c = NewCipher("ChaCha20-Poly1305");
2423 		SetCipherKey(c, se->BulkSendKey->Data, true);
2424 		CipherProcessAead(c, iv, tmp + size, RUDP_BULK_MAC_SIZE_V2, tmp, tmp, size - RUDP_BULK_MAC_SIZE_V2, NULL, 0);
2425 		FreeCipher(c);
2426 
2427 		// Next IV
2428 		Copy(se->BulkNextIv_V2, buf + sizeof(UINT64) + data_size + padding_size, RUDP_BULK_IV_SIZE_V2);
2429 	}
2430 	else
2431 	{
2432 		UCHAR crypt_key_src[SHA1_SIZE * 2];
2433 		UCHAR crypt_key[SHA1_SIZE];
2434 		UCHAR sign[SHA1_SIZE];
2435 		UCHAR iv[SHA1_SIZE];
2436 		CRYPT *c;
2437 
2438 		padding_size = Rand32() % 31 + 1;
2439 
2440 		buf_size = SHA1_SIZE + SHA1_SIZE + sizeof(UINT64) + data_size + padding_size;
2441 		buf = Malloc(buf_size);
2442 
2443 		// SEQ NO
2444 		WRITE_UINT64(buf + SHA1_SIZE + SHA1_SIZE, se->BulkNextSeqNo);
2445 		se->BulkNextSeqNo++;
2446 
2447 		// Data
2448 		Copy(buf + SHA1_SIZE + SHA1_SIZE + sizeof(UINT64), data, data_size);
2449 
2450 		// Padding
2451 		for (i = 0; i < padding_size; i++)
2452 		{
2453 			buf[SHA1_SIZE + SHA1_SIZE + sizeof(UINT64) + data_size + i] = (UCHAR)padding_size;
2454 		}
2455 
2456 		// Encryption
2457 		Copy(iv, se->BulkNextIv, SHA1_SIZE);
2458 		Copy(crypt_key_src + 0, se->BulkSendKey->Data, SHA1_SIZE);
2459 		Copy(crypt_key_src + SHA1_SIZE, iv, SHA1_SIZE);
2460 		Sha1(crypt_key, crypt_key_src, SHA1_SIZE * 2);
2461 		c = NewCrypt(crypt_key, sizeof(crypt_key));
2462 		Encrypt(c, buf + SHA1_SIZE + SHA1_SIZE, buf + SHA1_SIZE + SHA1_SIZE, sizeof(UINT64) + data_size + padding_size);
2463 		FreeCrypt(c);
2464 
2465 		// IV
2466 		Copy(buf + SHA1_SIZE, iv, SHA1_SIZE);
2467 
2468 		// Sign
2469 		if (se->UseHMac == false)
2470 		{
2471 			Copy(buf + 0, se->BulkSendKey->Data, SHA1_SIZE);
2472 			Sha1(sign, buf, SHA1_SIZE + SHA1_SIZE + sizeof(UINT64) + data_size + padding_size);
2473 			Copy(buf + 0, sign, SHA1_SIZE);
2474 		}
2475 		else
2476 		{
2477 			HMacSha1(buf + 0, se->BulkSendKey->Data, SHA1_SIZE, buf + SHA1_SIZE, SHA1_SIZE + sizeof(UINT64) + data_size + padding_size);
2478 		}
2479 
2480 		// Next IV
2481 		Copy(se->BulkNextIv, buf + buf_size - SHA1_SIZE, SHA1_SIZE);
2482 	}
2483 
2484 	if (r->Protocol == RUDP_PROTOCOL_ICMP)
2485 	{
2486 		icmp_type = se->Icmp_Type;
2487 	}
2488 	else if (r->Protocol == RUDP_PROTOCOL_DNS)
2489 	{
2490 		icmp_type = se->Dns_TranId;
2491 	}
2492 
2493 	RUDPSendPacket(r, &se->YourIp, se->YourPort, buf, buf_size, icmp_type);
2494 
2495 	Free(buf);
2496 }
2497 
2498 // 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)2499 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)
2500 {
2501 	return ListenRUDPEx(svc_name, proc_interrupts, proc_rpc_recv, param, port, no_natt_register, over_dns_mode, NULL, 0, NULL);
2502 }
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,IP * listen_ip)2503 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,
2504                    volatile UINT *natt_global_udp_port, UCHAR rand_port_id, IP *listen_ip)
2505 {
2506 	SOCK *s;
2507 	RUDP_STACK *r;
2508 
2509 	// Creating a R-UDP stack
2510 	r = NewRUDPServer(svc_name, proc_interrupts, proc_rpc_recv, param, port, no_natt_register, over_dns_mode, natt_global_udp_port, rand_port_id, listen_ip);
2511 	if (r == NULL)
2512 	{
2513 		return NULL;
2514 	}
2515 
2516 	s = NewSock();
2517 
2518 	s->Type = SOCK_RUDP_LISTEN;
2519 	s->ListenMode = true;
2520 	s->Connected = true;
2521 
2522 	s->LocalPort = r->UdpSock->LocalPort;
2523 
2524 	s->R_UDP_Stack = r;
2525 
2526 	return s;
2527 }
2528 
2529 // Accept on the R-UDP socket
AcceptRUDP(SOCK * s)2530 SOCK *AcceptRUDP(SOCK *s)
2531 {
2532 	// Validate arguments
2533 	if (s == NULL || s->Type != SOCK_RUDP_LISTEN || s->ListenMode == false)
2534 	{
2535 		return NULL;
2536 	}
2537 
2538 	while (true)
2539 	{
2540 		RUDP_STACK *r = s->R_UDP_Stack;
2541 		SOCK *ret;
2542 
2543 		if (s->Disconnecting || s->CancelAccept)
2544 		{
2545 			return NULL;
2546 		}
2547 
2548 		ret = GetNextWithLock(r->NewSockQueue);
2549 
2550 		if (ret != NULL)
2551 		{
2552 			switch (r->Protocol)
2553 			{
2554 			case RUDP_PROTOCOL_UDP:
2555 				StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_NAT_T);
2556 				AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails), "RUDP/UDP");
2557 				break;
2558 
2559 			case RUDP_PROTOCOL_DNS:
2560 				StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_DNS);
2561 				AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails), "RUDP/DNS");
2562 				break;
2563 
2564 			case RUDP_PROTOCOL_ICMP:
2565 				StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_ICMP);
2566 				AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails), "RUDP/ICMP");
2567 				break;
2568 			}
2569 
2570 			return ret;
2571 		}
2572 
2573 		Wait(r->NewSockConnectEvent, INFINITE);
2574 	}
2575 }
2576 
2577 // Verify the signature of the received packet
RUDPCheckSignOfRecvPacket(RUDP_STACK * r,RUDP_SESSION * se,void * recv_data,UINT recv_size)2578 bool RUDPCheckSignOfRecvPacket(RUDP_STACK *r, RUDP_SESSION *se, void *recv_data, UINT recv_size)
2579 {
2580 	UCHAR sign[SHA1_SIZE];
2581 	UCHAR sign2[SHA1_SIZE];
2582 	UCHAR *p;
2583 	UINT size;
2584 	// Validate arguments
2585 	if (r == NULL || se == NULL || recv_data == NULL || recv_size == 0)
2586 	{
2587 		return false;
2588 	}
2589 
2590 	p = (UCHAR *)recv_data;
2591 	size = recv_size;
2592 	if (size < SHA1_SIZE)
2593 	{
2594 		return false;
2595 	}
2596 
2597 	// Verification the signature (segment packet)
2598 	Copy(sign, p, SHA1_SIZE);
2599 	Copy(p, se->Key_Recv, SHA1_SIZE);
2600 	Sha1(sign2, p, recv_size);
2601 
2602 	if (r->Protocol == RUDP_PROTOCOL_DNS || r->Protocol == RUDP_PROTOCOL_ICMP)
2603 	{
2604 		XorData(sign2, sign2, r->SvcNameHash, SHA1_SIZE);
2605 	}
2606 
2607 	Copy(p, sign, SHA1_SIZE);
2608 	if (Cmp(sign, sign2, SHA1_SIZE) == 0)
2609 	{
2610 		return true;
2611 	}
2612 
2613 	if (se->BulkRecvKey == NULL)
2614 	{
2615 		return false;
2616 	}
2617 
2618 	// Verification signature (bulk packet)
2619 	if (se->BulkRecvKey->Size == RUDP_BULK_KEY_SIZE_V2)
2620 	{
2621 		UCHAR *iv = p;
2622 		CIPHER *c;
2623 
2624 		// Packet: IV + Encrypted(SEQ_NO + Data + padding) + MAC
2625 		// IV
2626 		if (size < RUDP_BULK_IV_SIZE_V2)
2627 		{
2628 			return false;
2629 		}
2630 		iv = p;
2631 		p += RUDP_BULK_IV_SIZE_V2;
2632 		size -= RUDP_BULK_IV_SIZE_V2;
2633 
2634 		// Decrypt
2635 		if (size < (RUDP_BULK_MAC_SIZE_V2 + 1))
2636 		{
2637 			return false;
2638 		}
2639 
2640 		c = NewCipher("ChaCha20-Poly1305");
2641 		SetCipherKey(c, se->BulkRecvKey->Data, false);
2642 		size = CipherProcessAead(c, iv, p + size, RUDP_BULK_MAC_SIZE_V2, r->TmpBuf, p, size - RUDP_BULK_MAC_SIZE_V2, NULL, 0);
2643 		FreeCipher(c);
2644 
2645 		if (size == 0)
2646 		{
2647 			return false;
2648 		}
2649 
2650 		return true;
2651 	}
2652 	else
2653 	{
2654 		if (se->UseHMac == false)
2655 		{
2656 			Copy(sign, p, SHA1_SIZE);
2657 			Copy(p, se->BulkRecvKey->Data, SHA1_SIZE);
2658 			Sha1(sign2, p, recv_size);
2659 			Copy(p, sign, SHA1_SIZE);
2660 
2661 			if (Cmp(sign, sign2, SHA1_SIZE) == 0)
2662 			{
2663 				return true;
2664 			}
2665 		}
2666 
2667 		HMacSha1(sign2, se->BulkRecvKey->Data, SHA1_SIZE, p + SHA1_SIZE, size - SHA1_SIZE);
2668 		if (Cmp(p, sign2, SHA1_SIZE) == 0)
2669 		{
2670 			se->UseHMac = true;
2671 			return true;
2672 		}
2673 	}
2674 
2675 	return false;
2676 }
2677 
2678 // Process the received packet (bulk)
RUDPProcessBulkRecvPacket(RUDP_STACK * r,RUDP_SESSION * se,void * recv_data,UINT recv_size)2679 bool RUDPProcessBulkRecvPacket(RUDP_STACK *r, RUDP_SESSION *se, void *recv_data, UINT recv_size)
2680 {
2681 	UCHAR *p;
2682 	UCHAR *iv;
2683 	UINT size;
2684 	UCHAR padlen;
2685 	UINT64 seq_no;
2686 	UCHAR *payload;
2687 	UINT payload_size;
2688 	// Validate arguments
2689 	if (r == NULL || se == NULL || recv_data == NULL || recv_size == 0 || se->BulkRecvKey == NULL)
2690 	{
2691 		return false;
2692 	}
2693 
2694 	p = (UCHAR *)recv_data;
2695 	size = recv_size;
2696 	if (size < SHA1_SIZE)
2697 	{
2698 		return false;
2699 	}
2700 
2701 	if (se->BulkRecvKey->Size == RUDP_BULK_KEY_SIZE_V2)
2702 	{
2703 		UINT ret;
2704 		CIPHER *c;
2705 
2706 		// Packet: IV + Encrypted(SEQ_NO + Data + padding) + MAC
2707 		// IV
2708 		if (size < RUDP_BULK_IV_SIZE_V2)
2709 		{
2710 			WHERE;
2711 			return false;
2712 		}
2713 		iv = p;
2714 		p += RUDP_BULK_IV_SIZE_V2;
2715 		size -= RUDP_BULK_IV_SIZE_V2;
2716 
2717 		// Decrypt
2718 		if (size < (RUDP_BULK_MAC_SIZE_V2 + 1))
2719 		{
2720 			WHERE;
2721 			return false;
2722 		}
2723 
2724 		c = NewCipher("ChaCha20-Poly1305");
2725 		SetCipherKey(c, se->BulkRecvKey->Data, false);
2726 		ret = CipherProcessAead(c, iv, p + size, RUDP_BULK_MAC_SIZE_V2, p, p, size - RUDP_BULK_MAC_SIZE_V2, NULL, 0);
2727 		FreeCipher(c);
2728 
2729 		if (ret == 0)
2730 		{
2731 			WHERE;
2732 			return false;
2733 		}
2734 
2735 		size -= RUDP_BULK_MAC_SIZE_V2;
2736 
2737 		// padlen
2738 		padlen = p[size - 1];
2739 		if (padlen == 0)
2740 		{
2741 			WHERE;
2742 			return false;
2743 		}
2744 		if (size < padlen)
2745 		{
2746 			WHERE;
2747 			return false;
2748 		}
2749 		size -= padlen;
2750 	}
2751 	else
2752 	{
2753 		CRYPT *c;
2754 		UCHAR sign[SHA1_SIZE], sign2[SHA1_SIZE];
2755 		UCHAR key[SHA1_SIZE], keygen[SHA1_SIZE * 2];
2756 
2757 		// Validate the signature
2758 		if (se->UseHMac == false)
2759 		{
2760 			Copy(sign, p, SHA1_SIZE);
2761 			Copy(p, se->BulkRecvKey->Data, SHA1_SIZE);
2762 			Sha1(sign2, p, recv_size);
2763 			Copy(p, sign, SHA1_SIZE);
2764 
2765 			if (Cmp(sign, sign2, SHA1_SIZE) != 0)
2766 			{
2767 				HMacSha1(sign2, se->BulkRecvKey->Data, SHA1_SIZE, p + SHA1_SIZE, recv_size - SHA1_SIZE);
2768 
2769 				if (Cmp(p, sign2, SHA1_SIZE) != 0)
2770 				{
2771 					return false;
2772 				}
2773 				else
2774 				{
2775 					se->UseHMac = true;
2776 				}
2777 			}
2778 		}
2779 		else
2780 		{
2781 			HMacSha1(sign2, se->BulkRecvKey->Data, SHA1_SIZE, p + SHA1_SIZE, recv_size - SHA1_SIZE);
2782 
2783 			if (Cmp(p, sign2, SHA1_SIZE) != 0)
2784 			{
2785 				return false;
2786 			}
2787 		}
2788 
2789 		p += SHA1_SIZE;
2790 		size -= SHA1_SIZE;
2791 
2792 		// IV
2793 		if (size < SHA1_SIZE)
2794 		{
2795 			return false;
2796 		}
2797 		iv = p;
2798 		p += SHA1_SIZE;
2799 		size -= SHA1_SIZE;
2800 
2801 		// Decrypt
2802 		if (size < 1)
2803 		{
2804 			return false;
2805 		}
2806 		Copy(keygen + 0, se->BulkRecvKey->Data, SHA1_SIZE);
2807 		Copy(keygen + SHA1_SIZE, iv, SHA1_SIZE);
2808 		Sha1(key, keygen, sizeof(keygen));
2809 
2810 		c = NewCrypt(key, sizeof(key));
2811 		Encrypt(c, p, p, size);
2812 		FreeCrypt(c);
2813 
2814 		// padlen
2815 		padlen = p[size - 1];
2816 		if (padlen == 0)
2817 		{
2818 			return false;
2819 		}
2820 		if (size < padlen)
2821 		{
2822 			return false;
2823 		}
2824 		size -= padlen;
2825 	}
2826 
2827 	// SEQ NO
2828 	seq_no = READ_UINT64(p);
2829 	p += sizeof(UINT64);
2830 	size -= sizeof(UINT64);
2831 
2832 	if (seq_no == 0 || seq_no >= (0xF000000000000000ULL))
2833 	{
2834 		// Sequence number is invalid
2835 		return false;
2836 	}
2837 
2838 	if ((seq_no + RUDP_BULK_SEQ_NO_RANGE) < se->BulkRecvSeqNoMax)
2839 	{
2840 		// Sequence number is too small
2841 		return false;
2842 	}
2843 
2844 	se->LastRecvTick = r->Now;
2845 
2846 	payload = p;
2847 	payload_size = size;
2848 
2849 	se->BulkRecvSeqNoMax = MAX(seq_no, se->BulkRecvSeqNoMax);
2850 
2851 	// Send the received bulk packet to the Tube of the socket
2852 	RUDPInitSock(r, se);
2853 
2854 	if (se->TcpSock != NULL)
2855 	{
2856 		SOCK *s = se->TcpSock;
2857 		TUBE *t = s->BulkSendTube;
2858 
2859 		if (t != NULL)
2860 		{
2861 			TubeSendEx2(t, payload, payload_size, NULL, true, RUDP_BULK_MAX_RECV_PKTS_IN_QUEUE);
2862 
2863 			se->FlushBulkSendTube = true;
2864 		}
2865 	}
2866 
2867 	return true;
2868 }
2869 
2870 // Process the received packet (segment)
RUDPProcessRecvPacket(RUDP_STACK * r,RUDP_SESSION * se,void * recv_data,UINT recv_size)2871 bool RUDPProcessRecvPacket(RUDP_STACK *r, RUDP_SESSION *se, void *recv_data, UINT recv_size)
2872 {
2873 	UCHAR sign[SHA1_SIZE];
2874 	UCHAR sign2[SHA1_SIZE];
2875 	UCHAR *p;
2876 	UCHAR *iv;
2877 	UINT size;
2878 	UCHAR keygen[SHA1_SIZE * 2];
2879 	UCHAR key[SHA1_SIZE];
2880 	CRYPT *c;
2881 	UCHAR padlen;
2882 	UINT num_ack;
2883 	UINT i;
2884 	UINT64 seq_no;
2885 	UCHAR *payload;
2886 	UINT payload_size;
2887 	UINT64 max_ack;
2888 	UINT64 my_tick, your_tick;
2889 	// Validate arguments
2890 	if (r == NULL || se == NULL || recv_data == NULL || recv_size == 0)
2891 	{
2892 		return false;
2893 	}
2894 
2895 	p = (UCHAR *)recv_data;
2896 	size = recv_size;
2897 	if (size < SHA1_SIZE)
2898 	{
2899 		return false;
2900 	}
2901 
2902 	// Validate the signature
2903 	Copy(sign, p, SHA1_SIZE);
2904 	Copy(p, se->Key_Recv, SHA1_SIZE);
2905 	Sha1(sign2, p, recv_size);
2906 	Copy(p, sign, SHA1_SIZE);
2907 
2908 	if (r->Protocol == RUDP_PROTOCOL_DNS || r->Protocol == RUDP_PROTOCOL_ICMP)
2909 	{
2910 		XorData(sign2, sign2, r->SvcNameHash, SHA1_SIZE);
2911 	}
2912 
2913 	if (Cmp(sign, sign2, SHA1_SIZE) != 0)
2914 	{
2915 		//WHERE;
2916 		return false;
2917 	}
2918 	p += SHA1_SIZE;
2919 	size -= SHA1_SIZE;
2920 
2921 	// IV
2922 	if (size < SHA1_SIZE)
2923 	{
2924 		return false;
2925 	}
2926 	iv = p;
2927 	p += SHA1_SIZE;
2928 	size -= SHA1_SIZE;
2929 
2930 	// Decrypt
2931 	if (size < 1)
2932 	{
2933 		return false;
2934 	}
2935 	Copy(keygen + 0, iv, SHA1_SIZE);
2936 	Copy(keygen + SHA1_SIZE, se->Key_Recv, SHA1_SIZE);
2937 	Sha1(key, keygen, sizeof(keygen));
2938 
2939 	c = NewCrypt(key, sizeof(key));
2940 	Encrypt(c, p, p, size);
2941 	FreeCrypt(c);
2942 
2943 	// padlen
2944 	padlen = p[size - 1];
2945 	if (padlen == 0)
2946 	{
2947 		return false;
2948 	}
2949 	if (size < padlen)
2950 	{
2951 		return false;
2952 	}
2953 	size -= padlen;
2954 
2955 	// MyTick
2956 	if (size < sizeof(UINT64))
2957 	{
2958 		return false;
2959 	}
2960 	my_tick = READ_UINT64(p);
2961 	p += sizeof(UINT64);
2962 	size -= sizeof(UINT64);
2963 
2964 	// YourTick
2965 	if (size < sizeof(UINT64))
2966 	{
2967 		return false;
2968 	}
2969 	your_tick = READ_UINT64(p);
2970 	p += sizeof(UINT64);
2971 	size -= sizeof(UINT64);
2972 
2973 	if (your_tick > r->Now)
2974 	{
2975 		return false;
2976 	}
2977 
2978 	// MAX_ACK
2979 	if (size < sizeof(UINT64))
2980 	{
2981 		return false;
2982 	}
2983 	max_ack = READ_UINT64(p);
2984 	p += sizeof(UINT64);
2985 	size -= sizeof(UINT64);
2986 
2987 	// num_ack
2988 	if (size < sizeof(UINT))
2989 	{
2990 		return false;
2991 	}
2992 
2993 	num_ack = READ_UINT(p);
2994 	if (num_ack > RUDP_MAX_NUM_ACK)
2995 	{
2996 		return false;
2997 	}
2998 	p += sizeof(UINT);
2999 	size -= sizeof(UINT);
3000 
3001 	// ACKs
3002 	if (size < (sizeof(UINT64) * num_ack + sizeof(UINT64)))
3003 	{
3004 		return false;
3005 	}
3006 
3007 	if (max_ack >= 1)
3008 	{
3009 		RUDPProcessAck2(r, se, max_ack);
3010 	}
3011 
3012 	for (i = 0; i < num_ack; i++)
3013 	{
3014 		UINT64 seq = READ_UINT64(p);
3015 
3016 		RUDPProcessAck(r, se, seq);
3017 
3018 		p += sizeof(UINT64);
3019 		size -= sizeof(UINT64);
3020 	}
3021 
3022 	// Processing of the Tick (Calculation of RTT)
3023 	if (my_tick >= 2)
3024 	{
3025 		my_tick--;
3026 	}
3027 	se->YourTick = MAX(se->YourTick, my_tick);
3028 
3029 	se->LatestRecvMyTick = MAX(se->LatestRecvMyTick, your_tick);
3030 
3031 	if (se->LatestRecvMyTick2 != se->LatestRecvMyTick)
3032 	{
3033 		se->LatestRecvMyTick2 = se->LatestRecvMyTick;
3034 		se->CurrentRtt = (UINT)(r->Now - se->LatestRecvMyTick);
3035 
3036 #ifdef	RUDP_DETAIL_LOG
3037 		Debug("CurrentRTT = %u\n", se->CurrentRtt);
3038 #endif	// RUDP_DETAIL_LOG
3039 	}
3040 
3041 	// SEQ NO
3042 	seq_no = READ_UINT64(p);
3043 	p += sizeof(UINT64);
3044 	size -= sizeof(UINT64);
3045 
3046 	if (seq_no == 0)
3047 	{
3048 		// Sequence number of 0 is a invalid packet
3049 		return true;
3050 	}
3051 
3052 	if (seq_no == se->Magic_Disconnect)
3053 	{
3054 		// Disconnected from opponent
3055 		RUDPDisconnectSession(r, se, true);
3056 		return true;
3057 	}
3058 
3059 	// Update the last reception date and time
3060 	se->LastRecvTick = r->Now;
3061 
3062 	payload = p;
3063 	payload_size = size;
3064 
3065 #ifdef	RUDP_DETAIL_LOG
3066 	Debug("RUDP %X Segment Recv: %I64u (num_ack=%u, size=%u)\n", se, seq_no, num_ack, size);
3067 #endif	// RUDP_DETAIL_LOG
3068 
3069 	if (payload_size >= 1 && payload_size <= RUDP_MAX_SEGMENT_SIZE)
3070 	{
3071 		// Received one or more bytes of data
3072 
3073 #ifdef	RUDP_DETAIL_LOG
3074 		Debug("Recv Size: %X %I64u %u %u\n", se, seq_no, payload_size, recv_size);
3075 #endif	// RUDP_DETAIL_LOG
3076 
3077 		RUDPProcessRecvPayload(r, se, seq_no, payload, payload_size);
3078 	}
3079 
3080 	if (r->ServerMode == false)
3081 	{
3082 		if (se->Status == RUDP_SESSION_STATUS_CONNECT_SENT)
3083 		{
3084 			// Shift to the established state if the connection is not yet in established state
3085 			se->Status = RUDP_SESSION_STATUS_ESTABLISHED;
3086 
3087 			RUDPInitSock(r, se);
3088 		}
3089 	}
3090 
3091 	return true;
3092 }
3093 
3094 // Disconnect the session
RUDPDisconnectSession(RUDP_STACK * r,RUDP_SESSION * se,bool disconnected_by_you)3095 void RUDPDisconnectSession(RUDP_STACK *r, RUDP_SESSION *se, bool disconnected_by_you)
3096 {
3097 	// Validate arguments
3098 	if (r == NULL || se == NULL)
3099 	{
3100 		return;
3101 	}
3102 
3103 	if (se->DisconnectFlag == false)
3104 	{
3105 		UINT i;
3106 
3107 		se->DisconnectFlag = true;
3108 		se->DisconnectedByYou = disconnected_by_you;
3109 
3110 		Debug("R-UDP Session %X Disconnected. by you flag: %u\n", se, disconnected_by_you);
3111 
3112 		if (se->TcpSock != NULL)
3113 		{
3114 			// Disconnect a TCP socket
3115 			Disconnect(se->TcpSock);
3116 			ReleaseSock(se->TcpSock);
3117 
3118 			se->TcpSock = NULL;
3119 		}
3120 
3121 		// Send 5 disconnect signals serially if to disconnect from here
3122 		if (disconnected_by_you == false)
3123 		{
3124 			for (i = 0; i < 5; i++)
3125 			{
3126 				RUDPSendSegmentNow(r, se, se->Magic_Disconnect, NULL, 0);
3127 			}
3128 		}
3129 	}
3130 }
3131 
3132 // Initialize the TCP socket for the session
RUDPInitSock(RUDP_STACK * r,RUDP_SESSION * se)3133 void RUDPInitSock(RUDP_STACK *r, RUDP_SESSION *se)
3134 {
3135 	SOCK *s1, *s2;
3136 	UINT mss;
3137 	// Validate arguments
3138 	if (r == NULL || se == NULL || se->DisconnectFlag)
3139 	{
3140 		return;
3141 	}
3142 
3143 	if (se->TcpSock != NULL)
3144 	{
3145 		// It has already been created
3146 		return;
3147 	}
3148 
3149 	// Creating a TCP socket pair
3150 	if (NewTcpPair(&s1, &s2) == false)
3151 	{
3152 		// Failed to create. Disconnect the session
3153 		RUDPDisconnectSession(r, se, false);
3154 		return;
3155 	}
3156 
3157 	// Calculate the optimal MSS
3158 	mss = RUDPCalcBestMssForBulk(r, se);
3159 
3160 	if (r->ServerMode)
3161 	{
3162 		// Server mode
3163 		se->TcpSock = s2;
3164 
3165 		JoinSockToSockEvent(s2, r->SockEvent);
3166 
3167 		// Update the end point information of the socket s1
3168 		ZeroIP4(&s1->LocalIP);
3169 		s1->LocalPort = se->MyPort;
3170 		Copy(&s1->RemoteIP, &se->YourIp, sizeof(IP));
3171 		s1->RemotePort = se->YourPort;
3172 		if (IsLocalHostIP(&s1->RemoteIP) == false)
3173 		{
3174 			AddIpClient(&s1->RemoteIP);
3175 			s1->IpClientAdded = true;
3176 		}
3177 		s1->IsRUDPSocket = true;
3178 
3179 		s1->BulkSendKey = se->BulkSendKey;
3180 		s1->BulkRecvKey = se->BulkRecvKey;
3181 
3182 		AddRef(s1->BulkSendKey->Ref);
3183 		AddRef(s1->BulkRecvKey->Ref);
3184 
3185 		s1->RUDP_OptimizedMss = mss;
3186 
3187 		// Enqueue the newly created socket, and set the event
3188 		InsertQueueWithLock(r->NewSockQueue, s1);
3189 		Set(r->NewSockConnectEvent);
3190 	}
3191 	else
3192 	{
3193 		// Client mode
3194 		Lock(r->Lock);
3195 		{
3196 			if (r->TargetConnectedSock == NULL && r->DoNotSetTargetConnectedSock == false)
3197 			{
3198 				// Update the end point information of the socket s2
3199 				Copy(&s2->LocalIP, &r->UdpSock->LocalIP, sizeof(IP));
3200 				s2->LocalPort = se->MyPort;
3201 				Copy(&s2->RemoteIP, &se->YourIp, sizeof(IP));
3202 				s2->RemotePort = se->YourPort;
3203 				if (IsLocalHostIP(&s2->RemoteIP) == false)
3204 				{
3205 					AddIpClient(&s2->RemoteIP);
3206 					s2->IpClientAdded = true;
3207 				}
3208 				s2->IsRUDPSocket = true;
3209 
3210 				s2->BulkSendKey = se->BulkSendKey;
3211 				s2->BulkRecvKey = se->BulkRecvKey;
3212 
3213 				AddRef(s2->BulkSendKey->Ref);
3214 				AddRef(s2->BulkRecvKey->Ref);
3215 
3216 				s2->RUDP_OptimizedMss = mss;
3217 
3218 				// Register the socket to the RUDP stack
3219 				r->TargetConnectedSock = s2;
3220 				s2->R_UDP_Stack = r;
3221 				se->TcpSock = s1;
3222 
3223 				JoinSockToSockEvent(s1, r->SockEvent);
3224 
3225 				// Set the event to be set when the connection is successful
3226 				Set(r->TargetConnectedEvent);
3227 			}
3228 			else
3229 			{
3230 				Disconnect(s1);
3231 				Disconnect(s2);
3232 				ReleaseSock(s1);
3233 				ReleaseSock(s2);
3234 			}
3235 		}
3236 		Unlock(r->Lock);
3237 	}
3238 }
3239 
3240 // Process the received payload
RUDPProcessRecvPayload(RUDP_STACK * r,RUDP_SESSION * se,UINT64 seq,void * payload_data,UINT payload_size)3241 void RUDPProcessRecvPayload(RUDP_STACK *r, RUDP_SESSION *se, UINT64 seq, void *payload_data, UINT payload_size)
3242 {
3243 	RUDP_SEGMENT t;
3244 	RUDP_SEGMENT *s;
3245 	// Validate arguments
3246 	if (r == NULL || se == NULL || seq == 0 || payload_data == NULL || payload_size == 0 || payload_size > RUDP_MAX_SEGMENT_SIZE)
3247 	{
3248 		return;
3249 	}
3250 
3251 	if (seq > (se->LastRecvCompleteSeqNo + RUDP_MAX_NUM_ACK))
3252 	{
3253 		// Ignore the segment which have sequence number beyond the window size, and also not to reply an ACK
3254 		return;
3255 	}
3256 
3257 	if (seq <= se->LastRecvCompleteSeqNo)
3258 	{
3259 		// Do not receive the segment which have the sequence number that has been already received. However, reply an ACK for it
3260 		AddInt64Distinct(se->ReplyAckList, seq);
3261 		return;
3262 	}
3263 
3264 	Zero(&t, sizeof(t));
3265 	t.SeqNo = seq;
3266 
3267 	s = Search(se->RecvSegmentList, &t);
3268 	if (s != NULL)
3269 	{
3270 		// Do not receive the segment which have the sequence number that has been already received. However, reply an ACK for it
3271 		AddInt64Distinct(se->ReplyAckList, seq);
3272 		return;
3273 	}
3274 
3275 	// Received a segment of the new sequence number
3276 	s = ZeroMalloc(sizeof(RUDP_SEGMENT));
3277 	s->SeqNo = seq;
3278 	Copy(s->Data, payload_data, payload_size);
3279 	s->Size = payload_size;
3280 	Insert(se->RecvSegmentList, s);
3281 
3282 	// Reply an ACK
3283 	AddInt64Distinct(se->ReplyAckList, seq);
3284 
3285 	// Create a socket for session if it have not been created yet
3286 	//RUDPInitSock(r, se);
3287 }
3288 
3289 // Process the incoming ACK
RUDPProcessAck(RUDP_STACK * r,RUDP_SESSION * se,UINT64 seq)3290 void RUDPProcessAck(RUDP_STACK *r, RUDP_SESSION *se, UINT64 seq)
3291 {
3292 	RUDP_SEGMENT t;
3293 	RUDP_SEGMENT *s;
3294 	// Validate arguments
3295 	if (r == NULL || se == NULL || seq == 0)
3296 	{
3297 		return;
3298 	}
3299 
3300 	Zero(&t, sizeof(t));
3301 	t.SeqNo = seq;
3302 
3303 	s = Search(se->SendSegmentList, &t);
3304 	if (s == NULL)
3305 	{
3306 		return;
3307 	}
3308 
3309 	Delete(se->SendSegmentList, s);
3310 	Free(s);
3311 }
3312 
3313 // Remove all segments which are preceding max_seq as already delivered
RUDPProcessAck2(RUDP_STACK * r,RUDP_SESSION * se,UINT64 max_seq)3314 void RUDPProcessAck2(RUDP_STACK *r, RUDP_SESSION *se, UINT64 max_seq)
3315 {
3316 	LIST *o;
3317 	UINT i;
3318 	// Validate arguments
3319 	if (r == NULL || se == NULL || max_seq == 0)
3320 	{
3321 		return;
3322 	}
3323 
3324 	o = NULL;
3325 
3326 	for (i = 0; i < LIST_NUM(se->SendSegmentList); i++)
3327 	{
3328 		RUDP_SEGMENT *s = LIST_DATA(se->SendSegmentList, i);
3329 
3330 		if (s->SeqNo <= max_seq)
3331 		{
3332 			if (o == NULL)
3333 			{
3334 				o = NewListFast(NULL);
3335 			}
3336 
3337 			Add(o, s);
3338 		}
3339 	}
3340 
3341 	if (o != NULL)
3342 	{
3343 		for (i = 0; i < LIST_NUM(o); i++)
3344 		{
3345 			RUDP_SEGMENT *s = LIST_DATA(o, i);
3346 
3347 			Delete(se->SendSegmentList, s);
3348 
3349 			Free(s);
3350 		}
3351 
3352 		ReleaseList(o);
3353 	}
3354 }
3355 
3356 // Get the minimum sequence number which is trying to send
RUDPGetCurrentSendingMinSeqNo(RUDP_SESSION * se)3357 UINT64 RUDPGetCurrentSendingMinSeqNo(RUDP_SESSION *se)
3358 {
3359 	RUDP_SEGMENT *s;
3360 	// Validate arguments
3361 	if (se == NULL)
3362 	{
3363 		return 0;
3364 	}
3365 
3366 	if (LIST_NUM(se->SendSegmentList) == 0)
3367 	{
3368 		return 0;
3369 	}
3370 
3371 	s = LIST_DATA(se->SendSegmentList, 0);
3372 
3373 	return s->SeqNo;
3374 }
3375 
3376 // Get the maximum sequence number which is trying to send
RUDPGetCurrentSendingMaxSeqNo(RUDP_SESSION * se)3377 UINT64 RUDPGetCurrentSendingMaxSeqNo(RUDP_SESSION *se)
3378 {
3379 	RUDP_SEGMENT *s;
3380 	// Validate arguments
3381 	if (se == NULL)
3382 	{
3383 		return 0;
3384 	}
3385 
3386 	if (LIST_NUM(se->SendSegmentList) == 0)
3387 	{
3388 		return 0;
3389 	}
3390 
3391 	s = LIST_DATA(se->SendSegmentList, (LIST_NUM(se->SendSegmentList) - 1));
3392 
3393 	return s->SeqNo;
3394 }
3395 
3396 // R-UDP segment transmission
RUDPSendSegmentNow(RUDP_STACK * r,RUDP_SESSION * se,UINT64 seq_no,void * data,UINT size)3397 void RUDPSendSegmentNow(RUDP_STACK *r, RUDP_SESSION *se, UINT64 seq_no, void *data, UINT size)
3398 {
3399 	UCHAR dst[RUDP_MAX_PACKET_SIZE];
3400 	UCHAR *p;
3401 	UCHAR *iv;
3402 	LIST *o = NULL;
3403 	UINT i;
3404 	UCHAR padlen;
3405 	UINT current_size;
3406 	UCHAR sign[SHA1_SIZE];
3407 	UCHAR key[SHA1_SIZE];
3408 	UCHAR keygen[SHA1_SIZE * 2];
3409 	CRYPT *c;
3410 	UINT next_iv_pos;
3411 	UINT num_ack;
3412 	UINT icmp_type = 0;
3413 	// Validate arguments
3414 	if (r == NULL || se == NULL || (size != 0 && data == NULL) || (size > RUDP_MAX_SEGMENT_SIZE))
3415 	{
3416 		return;
3417 	}
3418 
3419 	Zero(dst, sizeof(dst));
3420 	p = dst;
3421 
3422 	// SIGN
3423 	Copy(p, se->Key_Send, SHA1_SIZE);
3424 	p += SHA1_SIZE;
3425 
3426 	// IV
3427 	iv = p;
3428 	Copy(iv, se->NextIv, SHA1_SIZE);
3429 	p += SHA1_SIZE;
3430 
3431 	for (i = 0; i < MIN(LIST_NUM(se->ReplyAckList), RUDP_MAX_NUM_ACK); i++)
3432 	{
3433 		UINT64 *seq = LIST_DATA(se->ReplyAckList, i);
3434 
3435 		if (o == NULL)
3436 		{
3437 			o = NewListFast(NULL);
3438 		}
3439 
3440 		Add(o, seq);
3441 	}
3442 
3443 	// MyTick
3444 	WRITE_UINT64(p, r->Now);
3445 	p += sizeof(UINT64);
3446 
3447 	// YourTick
3448 	WRITE_UINT64(p, se->YourTick);
3449 	p += sizeof(UINT64);
3450 
3451 	// MAX_ACK
3452 	WRITE_UINT64(p, se->LastRecvCompleteSeqNo);
3453 	p += sizeof(UINT64);
3454 
3455 	// NUM_ACK
3456 	num_ack = LIST_NUM(o);
3457 	WRITE_UINT(p, num_ack);
3458 	p += sizeof(UINT);
3459 
3460 	if (o != NULL)
3461 	{
3462 		// ACK body
3463 		for (i = 0; i < LIST_NUM(o); i++)
3464 		{
3465 			UINT64 *seq = LIST_DATA(o, i);
3466 
3467 			WRITE_UINT64(p, *seq);
3468 			p += sizeof(UINT64);
3469 
3470 			Delete(se->ReplyAckList, seq);
3471 
3472 			Free(seq);
3473 		}
3474 		ReleaseList(o);
3475 	}
3476 
3477 	// SEQ
3478 	WRITE_UINT64(p, seq_no);
3479 	p += sizeof(UINT64);
3480 
3481 	// data
3482 	Copy(p, data, size);
3483 	p += size;
3484 
3485 	// padding
3486 	padlen = Rand8();
3487 	padlen = MAX(padlen, 1);
3488 
3489 	for (i = 0; i < padlen; i++)
3490 	{
3491 		*p = padlen;
3492 		p++;
3493 	}
3494 
3495 	current_size = (UINT)(p - dst);
3496 
3497 	// Encrypt
3498 	Copy(keygen + 0, iv, SHA1_SIZE);
3499 	Copy(keygen + SHA1_SIZE, se->Key_Send, SHA1_SIZE);
3500 	Sha1(key, keygen, sizeof(keygen));
3501 	c = NewCrypt(key, sizeof(key));
3502 	Encrypt(c, dst + SHA1_SIZE * 2, dst + SHA1_SIZE * 2, current_size - (SHA1_SIZE * 2));
3503 	FreeCrypt(c);
3504 
3505 	// Sign
3506 	Sha1(sign, dst, current_size);
3507 	if (r->Protocol == RUDP_PROTOCOL_DNS || r->Protocol == RUDP_PROTOCOL_ICMP)
3508 	{
3509 		XorData(sign, sign, r->SvcNameHash, SHA1_SIZE);
3510 	}
3511 	Copy(dst, sign, SHA1_SIZE);
3512 
3513 	if (r->Protocol == RUDP_PROTOCOL_ICMP)
3514 	{
3515 		icmp_type = se->Icmp_Type;
3516 	}
3517 	else if (r->Protocol == RUDP_PROTOCOL_DNS)
3518 	{
3519 		icmp_type = se->Dns_TranId;
3520 	}
3521 	RUDPSendPacket(r, &se->YourIp, se->YourPort, dst, current_size, icmp_type);
3522 
3523 	if (size >= 1)
3524 	{
3525 		se->LastSentTick = r->Now;
3526 	}
3527 
3528 	// Next IV
3529 	next_iv_pos = Rand32() % (current_size - SHA1_SIZE);
3530 	Copy(se->NextIv, dst + next_iv_pos, SHA1_SIZE);
3531 
3532 #ifdef	RUDP_DETAIL_LOG
3533 	Debug("RUDP %X Segment Sent: %I64u (num_ack=%u, size=%u)\n", se, seq_no, num_ack, size);
3534 #endif	// RUDP_DETAIL_LOG
3535 
3536 	if (size >= 1)
3537 	{
3538 #ifdef	RUDP_DETAIL_LOG
3539 		Debug("Send Size: %X %I64u %u %u\n", se, seq_no, size, current_size);
3540 #endif	// RUDP_DETAIL_LOG
3541 	}
3542 }
3543 
3544 // R-UDP segment transmission (only put into the queue)
RUDPSendSegment(RUDP_STACK * r,RUDP_SESSION * se,void * data,UINT size)3545 void RUDPSendSegment(RUDP_STACK *r, RUDP_SESSION *se, void *data, UINT size)
3546 {
3547 	RUDP_SEGMENT *s;
3548 	// Validate arguments
3549 	if (r == NULL || se == NULL || (size != 0 && data == NULL) || (size > RUDP_MAX_SEGMENT_SIZE))
3550 	{
3551 		return;
3552 	}
3553 
3554 	s = ZeroMalloc(sizeof(RUDP_SEGMENT));
3555 
3556 	Copy(s->Data, data, size);
3557 	s->Size = size;
3558 
3559 	s->SeqNo = se->NextSendSeqNo++;
3560 
3561 	Insert(se->SendSegmentList, s);
3562 }
3563 
3564 // Search for a session
RUDPSearchSession(RUDP_STACK * r,IP * my_ip,UINT my_port,IP * your_ip,UINT your_port)3565 RUDP_SESSION *RUDPSearchSession(RUDP_STACK *r, IP *my_ip, UINT my_port, IP *your_ip, UINT your_port)
3566 {
3567 	RUDP_SESSION t;
3568 	RUDP_SESSION *se;
3569 	// Validate arguments
3570 	if (r == NULL || my_ip == NULL || your_ip == NULL)
3571 	{
3572 		return NULL;
3573 	}
3574 
3575 	Copy(&t.MyIp, my_ip, sizeof(IP));
3576 	t.MyPort = my_port;
3577 	Copy(&t.YourIp, your_ip, sizeof(IP));
3578 	t.YourPort = your_port;
3579 
3580 	se = Search(r->SessionList, &t);
3581 
3582 	return se;
3583 }
3584 
3585 // Release of the session
RUDPFreeSession(RUDP_SESSION * se)3586 void RUDPFreeSession(RUDP_SESSION *se)
3587 {
3588 	UINT i;
3589 	// Validate arguments
3590 	if (se == NULL)
3591 	{
3592 		return;
3593 	}
3594 
3595 	Debug("RUDPFreeSession %X\n", se);
3596 
3597 	for (i = 0; i < LIST_NUM(se->SendSegmentList); i++)
3598 	{
3599 		RUDP_SEGMENT *s = LIST_DATA(se->SendSegmentList, i);
3600 
3601 		Free(s);
3602 	}
3603 
3604 	ReleaseList(se->SendSegmentList);
3605 
3606 	for (i = 0; i < LIST_NUM(se->RecvSegmentList); i++)
3607 	{
3608 		RUDP_SEGMENT *s = LIST_DATA(se->RecvSegmentList, i);
3609 
3610 		Free(s);
3611 	}
3612 
3613 	ReleaseList(se->RecvSegmentList);
3614 
3615 	if (se->TcpSock != NULL)
3616 	{
3617 		Disconnect(se->TcpSock);
3618 		ReleaseSock(se->TcpSock);
3619 	}
3620 
3621 	ReleaseInt64List(se->ReplyAckList);
3622 
3623 	ReleaseFifo(se->RecvFifo);
3624 	ReleaseFifo(se->SendFifo);
3625 
3626 	ReleaseSharedBuffer(se->BulkSendKey);
3627 	ReleaseSharedBuffer(se->BulkRecvKey);
3628 
3629 	Free(se);
3630 }
3631 
3632 // Create a new session
RUDPNewSession(bool server_mode,IP * my_ip,UINT my_port,IP * your_ip,UINT your_port,UCHAR * init_key)3633 RUDP_SESSION *RUDPNewSession(bool server_mode, IP *my_ip, UINT my_port, IP *your_ip, UINT your_port, UCHAR *init_key)
3634 {
3635 	RUDP_SESSION *se;
3636 	UCHAR key1[SHA1_SIZE];
3637 	UCHAR key2[SHA1_SIZE];
3638 	UCHAR bulk_send_key[RUDP_BULK_KEY_SIZE_MAX];
3639 	UCHAR bulk_recv_key[RUDP_BULK_KEY_SIZE_MAX];
3640 	BUF *b;
3641 
3642 	se = ZeroMalloc(sizeof(RUDP_SESSION));
3643 
3644 	Copy(&se->MyIp, my_ip, sizeof(IP));
3645 	se->MyPort = my_port;
3646 
3647 	Copy(&se->YourIp, your_ip, sizeof(IP));
3648 	se->YourPort = your_port;
3649 
3650 	Copy(se->Key_Init, init_key, SHA1_SIZE);
3651 	se->LastSentTick = 0;
3652 	se->LastRecvTick = Tick64();
3653 	se->LatestRecvMyTick = Tick64();
3654 
3655 	se->NextSendSeqNo = 1;
3656 
3657 	se->ServerMode = server_mode;
3658 
3659 	se->SendSegmentList = NewList(RUDPCompareSegmentList);
3660 	se->RecvSegmentList = NewList(RUDPCompareSegmentList);
3661 
3662 	// Generate the two keys
3663 	b = NewBuf();
3664 	WriteBuf(b, init_key, SHA1_SIZE);
3665 	WriteBufStr(b, "zurukko");
3666 	Sha1(key1, b->Buf, b->Size);
3667 	FreeBuf(b);
3668 
3669 	b = NewBuf();
3670 	WriteBuf(b, init_key, SHA1_SIZE);
3671 	WriteBuf(b, key1, SHA1_SIZE);
3672 	WriteBufStr(b, "yasushineko");
3673 	Sha1(key2, b->Buf, b->Size);
3674 	FreeBuf(b);
3675 
3676 	// Generate the magic number for the KeepAlive
3677 	b = NewBuf();
3678 	WriteBuf(b, init_key, SHA1_SIZE);
3679 	WriteBufStr(b, "Magic_KeepAliveRequest");
3680 	Sha1(se->Magic_KeepAliveRequest, b->Buf, b->Size);
3681 	FreeBuf(b);
3682 	b = NewBuf();
3683 	WriteBuf(b, init_key, SHA1_SIZE);
3684 	WriteBufStr(b, "Magic_KeepAliveResponse");
3685 	Sha1(se->Magic_KeepAliveResponse, b->Buf, b->Size);
3686 	FreeBuf(b);
3687 
3688 	if (server_mode == false)
3689 	{
3690 		se->Magic_Disconnect = 0xffffffff00000000ULL | (UINT64)(Rand32());
3691 	}
3692 
3693 	Copy(se->Key_Init, init_key, SHA1_SIZE);
3694 
3695 	if (se->ServerMode)
3696 	{
3697 		Copy(se->Key_Send, key1, SHA1_SIZE);
3698 		Copy(se->Key_Recv, key2, SHA1_SIZE);
3699 	}
3700 	else
3701 	{
3702 		Copy(se->Key_Send, key2, SHA1_SIZE);
3703 		Copy(se->Key_Recv, key1, SHA1_SIZE);
3704 	}
3705 
3706 	Rand(se->NextIv, sizeof(se->NextIv));
3707 
3708 	se->ReplyAckList = NewInt64List(true);
3709 
3710 	se->NextKeepAliveInterval = RUDP_KEEPALIVE_INTERVAL_MIN + (Rand32() % (RUDP_KEEPALIVE_INTERVAL_MAX - RUDP_KEEPALIVE_INTERVAL_MIN));
3711 
3712 	se->RecvFifo = NewFifo();
3713 	se->SendFifo = NewFifo();
3714 
3715 	se->Dns_TranId = Rand16() % 65535 + 1;
3716 
3717 	// Generate the bulk transfer key
3718 	Rand(bulk_send_key, sizeof(bulk_send_key));
3719 	Rand(bulk_recv_key, sizeof(bulk_recv_key));
3720 
3721 	se->BulkSendKey = NewSharedBuffer(bulk_send_key, sizeof(bulk_send_key));
3722 	se->BulkRecvKey = NewSharedBuffer(bulk_recv_key, sizeof(bulk_recv_key));
3723 
3724 	Rand(se->BulkNextIv, sizeof(se->BulkNextIv));
3725 	Rand(se->BulkNextIv_V2, sizeof(se->BulkNextIv_V2));
3726 
3727 	se->BulkNextSeqNo = 1;
3728 
3729 	return se;
3730 }
3731 
3732 // Comparison function of the segment list items
RUDPCompareSegmentList(void * p1,void * p2)3733 int RUDPCompareSegmentList(void *p1, void *p2)
3734 {
3735 	RUDP_SEGMENT *s1, *s2;
3736 	UINT r;
3737 	// Validate arguments
3738 	if (p1 == NULL || p2 == NULL)
3739 	{
3740 		return 0;
3741 	}
3742 	s1 = *((RUDP_SEGMENT **)p1);
3743 	s2 = *((RUDP_SEGMENT **)p2);
3744 	if (s1 == NULL || s2 == NULL)
3745 	{
3746 		return 0;
3747 	}
3748 
3749 	r = COMPARE_RET(s1->SeqNo, s2->SeqNo);
3750 
3751 	return r;
3752 }
3753 
3754 // Send a UDP packet
RUDPSendPacket(RUDP_STACK * r,IP * dest_ip,UINT dest_port,void * data,UINT size,UINT icmp_type)3755 void RUDPSendPacket(RUDP_STACK *r, IP *dest_ip, UINT dest_port, void *data, UINT size, UINT icmp_type)
3756 {
3757 	UDPPACKET *p;
3758 	// Validate arguments
3759 	if (r == NULL || dest_ip == NULL || dest_port == 0 || data == NULL || size == 0)
3760 	{
3761 		return;
3762 	}
3763 
3764 	p = NewUdpPacket(&r->UdpSock->LocalIP, r->UdpSock->LocalPort,
3765 	                 dest_ip, dest_port,
3766 	                 Clone(data, size), size);
3767 
3768 	if (r->Protocol == RUDP_PROTOCOL_ICMP || r->Protocol == RUDP_PROTOCOL_DNS)
3769 	{
3770 		// ICMP Type / DNS Tran ID
3771 		p->Type = icmp_type;
3772 	}
3773 
3774 	Add(r->SendPacketList, p);
3775 }
3776 
3777 // R-UDP main thread
RUDPMainThread(THREAD * thread,void * param)3778 void RUDPMainThread(THREAD *thread, void *param)
3779 {
3780 	RUDP_STACK *r;
3781 	bool halt_flag = false;
3782 	// Validate arguments
3783 	if (thread == NULL || param == NULL)
3784 	{
3785 		return;
3786 	}
3787 
3788 	r = (RUDP_STACK *)param;
3789 
3790 	AddWaitThread(thread);
3791 	NoticeThreadInit(thread);
3792 
3793 	while (true)
3794 	{
3795 		UINT wait_interval;
3796 		UINT i;
3797 		UINT min_wait_interval;
3798 		UINT num_ignore_errors = 0;
3799 
3800 		r->Now = Tick64();
3801 
3802 		Lock(r->Lock);
3803 		{
3804 			Copy(&r->NatT_IP_Safe, &r->NatT_IP, sizeof(IP));
3805 			Copy(&r->My_Private_IP_Safe, &r->My_Private_IP, sizeof(IP));
3806 		}
3807 		Unlock(r->Lock);
3808 
3809 		// Receive the data from the UDP socket
3810 		while (true)
3811 		{
3812 			UINT ret;
3813 			IP ip_src;
3814 			UINT port_src;
3815 
3816 			ret = RecvFrom(r->UdpSock, &ip_src, &port_src, r->TmpBuf, sizeof(r->TmpBuf));
3817 
3818 			if (ret == SOCK_LATER)
3819 			{
3820 				// There is no packet more
3821 				break;
3822 			}
3823 			else if (ret != 0)
3824 			{
3825 				// Receive a Packet
3826 				bool ok = false;
3827 				UDPPACKET *p = NewUdpPacket(&ip_src, port_src,
3828 				                            &r->UdpSock->LocalIP, r->UdpSock->LocalPort,
3829 				                            Clone(r->TmpBuf, ret), ret);
3830 
3831 				if (r->Protocol == RUDP_PROTOCOL_ICMP)
3832 				{
3833 					// Analyse the incoming ICMP packet
3834 					UINT ip_header_size = GetIpHeaderSize(p->Data, p->Size);
3835 
3836 					if (ip_header_size >= sizeof(IPV4_HEADER))
3837 					{
3838 						if (p->Size >= (ip_header_size + sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO) + SHA1_SIZE))
3839 						{
3840 							ICMP_HEADER *icmp_header = (ICMP_HEADER *)(((UCHAR *)p->Data) + ip_header_size);
3841 							ICMP_ECHO *echo_header = (ICMP_ECHO *)(((UCHAR *)p->Data) + ip_header_size + sizeof(ICMP_HEADER));
3842 
3843 							if (icmp_header->Type == ICMP_TYPE_ECHO_RESPONSE ||
3844 							        icmp_header->Type == (r->ServerMode ? ICMP_TYPE_INFORMATION_REQUEST : ICMP_TYPE_INFORMATION_REPLY))
3845 							{
3846 								UCHAR hash[SHA1_SIZE];
3847 
3848 								Sha1(hash, ((UCHAR *)p->Data) + ip_header_size + sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO) + SHA1_SIZE,
3849 								     p->Size - (ip_header_size + sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO) + SHA1_SIZE));
3850 
3851 								if (Cmp(hash, ((UCHAR *)p->Data) + ip_header_size + sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO), SHA1_SIZE) == 0)
3852 								{
3853 									UCHAR *new_data;
3854 									UINT new_data_size;
3855 									if (r->ServerMode)
3856 									{
3857 										// On the server side, the ICMP ID and the SEQ NO of received messages are treated as a source port number
3858 										Copy(&p->SrcPort, echo_header, sizeof(UINT));
3859 									}
3860 
3861 									// Record the Type
3862 									p->Type = icmp_header->Type;
3863 
3864 									// Erase the header part
3865 									new_data_size = p->Size - (ip_header_size + sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO) + SHA1_SIZE);
3866 									new_data = Clone(((UCHAR *)p->Data) + ip_header_size + sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO) + SHA1_SIZE, new_data_size);
3867 									Free(p->Data);
3868 									p->Data = new_data;
3869 									p->Size = new_data_size;
3870 
3871 									ok = true;
3872 								}
3873 							}
3874 						}
3875 					}
3876 				}
3877 				else if (r->Protocol == RUDP_PROTOCOL_DNS)
3878 				{
3879 					// Analyse the incoming DNS packet
3880 					UINT offset;
3881 
3882 					if (r->ServerMode == false)
3883 					{
3884 						offset = 42;
3885 					}
3886 					else
3887 					{
3888 						offset = 37;
3889 					}
3890 
3891 					if (p->Size > offset)
3892 					{
3893 						UCHAR *new_data;
3894 						UINT new_size = p->Size - offset;
3895 
3896 						p->Type = *((USHORT *)p->Data);
3897 
3898 						new_data = Clone(((UCHAR *)p->Data) + offset, new_size);
3899 
3900 						Free(p->Data);
3901 						p->Data = new_data;
3902 						p->Size = new_size;
3903 
3904 						ok = true;
3905 					}
3906 				}
3907 				else
3908 				{
3909 					// Don't do anything for ordinary UDP packet
3910 					ok = true;
3911 				}
3912 
3913 				if (ok)
3914 				{
3915 					// Process the received packet
3916 					RUDPRecvProc(r, p);
3917 
3918 					r->TotalPhysicalReceived += ret;
3919 				}
3920 
3921 				FreeUdpPacket(p);
3922 			}
3923 			else
3924 			{
3925 				if (r->UdpSock->IgnoreRecvErr)
3926 				{
3927 					// An ignorable reception error occurs
3928 					if ((num_ignore_errors++) >= MAX_NUM_IGNORE_ERRORS)
3929 					{
3930 						break;
3931 					}
3932 				}
3933 				else
3934 				{
3935 					// A non-ignorable reception error occurs
3936 					break;
3937 				}
3938 			}
3939 		}
3940 
3941 		// Call the interrupt notification callback function
3942 		if (r->ProcInterrupts != NULL)
3943 		{
3944 			r->ProcInterrupts(r);
3945 		}
3946 
3947 		RUDPInterruptProc(r);
3948 
3949 		// Send all packets in the transmission packet list
3950 		for (i = 0; i < LIST_NUM(r->SendPacketList); i++)
3951 		{
3952 			UDPPACKET *p = LIST_DATA(r->SendPacketList, i);
3953 
3954 			if (r->Protocol == RUDP_PROTOCOL_ICMP)
3955 			{
3956 				// In case of the ICMP protocol, assemble an ICMP header
3957 				UINT dst_size = sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO) + SHA1_SIZE + p->Size;
3958 				UCHAR *dst_data = ZeroMalloc(dst_size);
3959 
3960 				ICMP_HEADER *icmp_header = (ICMP_HEADER *)dst_data;
3961 				ICMP_ECHO *icmp_echo = (ICMP_ECHO *)(dst_data + sizeof(ICMP_HEADER));
3962 				UCHAR *hash = dst_data + sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO);
3963 				UCHAR *icmp_data = dst_data + sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO) + SHA1_SIZE;
3964 
3965 				// Header
3966 				icmp_header->Type = (UCHAR)p->Type;
3967 				icmp_header->Code = 0;
3968 				icmp_header->Checksum = 0;
3969 
3970 				if (r->ServerMode)
3971 				{
3972 					// On the server side, use the port number in the opponent internal data as ICMP ID and SEQ NO
3973 					Copy(icmp_echo, &p->DestPort, 4);
3974 				}
3975 				else
3976 				{
3977 					// Use the fixed ICMP ID and SEQ NO on the client side
3978 					icmp_echo->Identifier = Endian16(r->Client_IcmpId);
3979 					icmp_echo->SeqNo = Endian16(r->Client_IcmpSeqNo);
3980 				}
3981 
3982 				// Data body
3983 				Copy(icmp_data, p->Data, p->Size);
3984 
3985 				// Hash
3986 				Sha1(hash, icmp_data, p->Size);
3987 
3988 				// Checksum calculation
3989 				icmp_header->Checksum = IpChecksum(dst_data, dst_size);
3990 
3991 				// Replacement
3992 				Free(p->Data);
3993 				p->Data = dst_data;
3994 				p->Size = dst_size;
3995 			}
3996 			else if (r->Protocol == RUDP_PROTOCOL_DNS)
3997 			{
3998 				BUF *b = NewBuf();
3999 				// In case of over DNS protocol, assemble a header that conforms to the DNS protocol
4000 				if (r->ServerMode == false)
4001 				{
4002 					// DNS query header
4003 					USHORT us = Rand16() % 65535 + 1;
4004 					static UCHAR dns_query_header_1[] =
4005 					{
4006 						0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08,
4007 					};
4008 					static UCHAR dns_query_header_2[] =
4009 					{
4010 						0x00, 0x00, 0x30, 0x00, 0x01, 0x00, 0x00, 0x29, 0x10,
4011 						0x00, 0x00, 0x00, 0x80, 0x00,
4012 					};
4013 					UCHAR rand_data[4];
4014 					char rand_str[MAX_SIZE];
4015 
4016 					Rand(rand_data, sizeof(rand_data));
4017 					BinToStr(rand_str, sizeof(rand_str), rand_data, sizeof(rand_data));
4018 					StrLower(rand_str);
4019 
4020 					WriteBuf(b, &us, sizeof(USHORT));
4021 					WriteBuf(b, dns_query_header_1, sizeof(dns_query_header_1));
4022 					WriteBuf(b, rand_str, 8);
4023 					WriteBuf(b, dns_query_header_2, sizeof(dns_query_header_2));
4024 					us = Endian16((USHORT)p->Size);
4025 					WriteBuf(b, &us, sizeof(USHORT));
4026 					WriteBuf(b, p->Data, p->Size);
4027 				}
4028 				else
4029 				{
4030 					// DNS response header
4031 					USHORT us = p->Type;
4032 					UINT ui;
4033 					static UCHAR dns_response_header_1[] =
4034 					{
4035 						0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00,
4036 						0x00, 0x00, 0x08,
4037 					};
4038 					static UCHAR dns_response_header_2[] =
4039 					{
4040 						0x00, 0x00, 0x30, 0x00, 0x01,
4041 						0xc0, 0x0c, 0x00, 0x30, 0x00, 0x01, 0x00, 0x00, 0xa4, 0x5b,
4042 					};
4043 					static UCHAR dns_response_header_3[] =
4044 					{
4045 						0x01, 0x00, 0x03, 0x08,
4046 					};
4047 					UCHAR rand_data[4];
4048 					char rand_str[MAX_SIZE];
4049 
4050 					Rand(rand_data, sizeof(rand_data));
4051 					BinToStr(rand_str, sizeof(rand_str), rand_data, sizeof(rand_data));
4052 					StrLower(rand_str);
4053 
4054 					WriteBuf(b, &us, sizeof(USHORT));
4055 					WriteBuf(b, dns_response_header_1, sizeof(dns_response_header_1));
4056 					WriteBuf(b, rand_str, 8);
4057 					WriteBuf(b, dns_response_header_2, sizeof(dns_response_header_2));
4058 					us = Endian16((USHORT)(p->Size + 4));
4059 					WriteBuf(b, &us, sizeof(USHORT));
4060 					WriteBuf(b, dns_response_header_3, sizeof(dns_response_header_3));
4061 					WriteBuf(b, p->Data, p->Size);
4062 
4063 					ui = Rand16() % (60 * 60 * 12) + (60 * 60 * 12);
4064 					WRITE_UINT(((UCHAR *)b->Buf) + 0x20, ui);
4065 				}
4066 				Free(p->Data);
4067 				p->Data = b->Buf;
4068 				p->Size = b->Size;
4069 				Free(b);
4070 			}
4071 
4072 			SendTo(r->UdpSock, &p->DstIP, p->DestPort, p->Data, p->Size);
4073 
4074 			r->TotalPhysicalSent += p->Size;
4075 
4076 			FreeUdpPacket(p);
4077 		}
4078 		DeleteAll(r->SendPacketList);
4079 
4080 		if (r->Halt)
4081 		{
4082 			// If it is necessary to stop, stop it after cycling through a loop
4083 			if (halt_flag == false)
4084 			{
4085 				halt_flag = true;
4086 				continue;
4087 			}
4088 			else
4089 			{
4090 				break;
4091 			}
4092 		}
4093 
4094 		// Rest the CPU until the next event
4095 		wait_interval = GetNextIntervalForInterrupt(r->Interrupt);
4096 		if (r->ServerMode)
4097 		{
4098 			min_wait_interval = RUDP_LOOP_WAIT_INTERVAL_S;
4099 		}
4100 		else
4101 		{
4102 			min_wait_interval = RUDP_LOOP_WAIT_INTERVAL_C;
4103 		}
4104 
4105 		if (wait_interval == INFINITE)
4106 		{
4107 			wait_interval = min_wait_interval;
4108 		}
4109 		else
4110 		{
4111 			wait_interval = MIN(min_wait_interval, wait_interval);
4112 		}
4113 
4114 #ifdef	RUDP_DETAIL_LOG
4115 		Debug("wait_interval = %u\n", wait_interval);
4116 #endif	// RUDP_DETAIL_LOG
4117 
4118 		if (wait_interval >= 1)
4119 		{
4120 			WaitSockEvent(r->SockEvent, wait_interval);
4121 		}
4122 
4123 #ifdef	RUDP_DETAIL_LOG
4124 		if (r->ServerMode)
4125 		{
4126 			char str1[MAX_SIZE];
4127 			char str2[MAX_SIZE];
4128 			double rate = 0.0;
4129 
4130 			ToStr64(str1, r->TotalPhysicalReceived);
4131 			ToStr64(str2, r->TotalLogicalReceived);
4132 
4133 			if (r->TotalPhysicalReceived >= 1)
4134 			{
4135 				rate = (double)r->TotalLogicalReceived / (double)r->TotalPhysicalReceived;
4136 			}
4137 
4138 			Debug("%s / %s %.4f\n", str1, str2, rate);
4139 		}
4140 #endif	// RUDP_DETAIL_LOG
4141 	}
4142 
4143 	Disconnect(r->UdpSock);
4144 
4145 	DelWaitThread(thread);
4146 }
4147 
4148 // Generate a appropriate register host name from the IP address
RUDPGetRegisterHostNameByIP(char * dst,UINT size,IP * ip)4149 void RUDPGetRegisterHostNameByIP(char *dst, UINT size, IP *ip)
4150 {
4151 	char tmp[16];
4152 	// Validate arguments
4153 	if (dst == NULL)
4154 	{
4155 		return;
4156 	}
4157 
4158 	if (ip != NULL && IsIP4(ip))
4159 	{
4160 		UCHAR hash[SHA1_SIZE];
4161 
4162 		Sha1(hash, IPV4(ip->address), IPV4_SIZE);
4163 		BinToStr(tmp, sizeof(tmp), hash, 2);
4164 	}
4165 	else
4166 	{
4167 		UCHAR rand[2];
4168 		Rand(rand, 2);
4169 		BinToStr(tmp, sizeof(tmp), rand, 2);
4170 	}
4171 
4172 	StrLower(tmp);
4173 	Format(dst, size,
4174 	       (IsUseAlternativeHostname() ? UDP_NAT_T_SERVER_TAG_ALT : UDP_NAT_T_SERVER_TAG),
4175 	       tmp[2], tmp[3]);
4176 
4177 
4178 	if (false)
4179 	{
4180 		Debug("Hash Src IP: %r\n"
4181 		      "Hash Dst HN: %s\n",
4182 		      ip,
4183 		      dst);
4184 	}
4185 }
4186 
4187 // Analyze the IP address and port number from the string
RUDPParseIPAndPortStr(void * data,UINT data_size,IP * ip,UINT * port)4188 bool RUDPParseIPAndPortStr(void *data, UINT data_size, IP *ip, UINT *port)
4189 {
4190 	char tmp[MAX_SIZE];
4191 	UINT i;
4192 	char ipstr[MAX_SIZE];
4193 	char *portstr;
4194 	// Validate arguments
4195 	if (data == NULL || ip == NULL || port == NULL)
4196 	{
4197 		return false;
4198 	}
4199 
4200 	Zero(tmp, sizeof(tmp));
4201 
4202 	Copy(tmp, data, MIN(data_size, sizeof(tmp) - 1));
4203 
4204 	if (StartWith(tmp, "IP=") == false)
4205 	{
4206 		return false;
4207 	}
4208 
4209 	i = SearchStrEx(tmp, "#", 0, true);
4210 	if (i != INFINITE)
4211 	{
4212 		tmp[i] = 0;
4213 	}
4214 
4215 	StrCpy(ipstr, sizeof(ipstr), tmp + 3);
4216 
4217 	i = SearchStrEx(ipstr, ",PORT=", 0, true);
4218 	if (i == INFINITE)
4219 	{
4220 		return false;
4221 	}
4222 
4223 	ipstr[i] = 0;
4224 	portstr = ipstr + i + 6;
4225 
4226 	StrToIP(ip, ipstr);
4227 	*port = ToInt(portstr);
4228 
4229 	return true;
4230 }
4231 
4232 // R-UDP NAT-T IP address acquisition thread
RUDPIpQueryThread(THREAD * thread,void * param)4233 void RUDPIpQueryThread(THREAD *thread, void *param)
4234 {
4235 	RUDP_STACK *r;
4236 	UINT64 next_getip_tick = 0;
4237 	UINT64 next_getprivate_ip_tick = 0;
4238 	UINT last_ip_hash = 0;
4239 	void *route_change_poller = NULL;
4240 	char current_hostname[MAX_SIZE];
4241 	bool last_time_ip_changed = false;
4242 	UINT num_retry = 0;
4243 	// Validate arguments
4244 	if (thread == NULL || param == NULL)
4245 	{
4246 		return;
4247 	}
4248 
4249 	r = (RUDP_STACK *)param;
4250 
4251 	last_ip_hash = GetHostIPAddressHash32();
4252 
4253 	route_change_poller = NewRouteChange();
4254 	IsRouteChanged(route_change_poller);
4255 
4256 	Zero(current_hostname, sizeof(current_hostname));
4257 
4258 	while (r->Halt == false)
4259 	{
4260 		UINT ip_hash = GetHostIPAddressHash32();
4261 		UINT64 now = Tick64();
4262 		bool ip_changed = false;
4263 
4264 		if (ip_hash != last_ip_hash)
4265 		{
4266 			last_time_ip_changed = false;
4267 		}
4268 
4269 		if ((ip_hash != last_ip_hash) || (IsRouteChanged(route_change_poller)))
4270 		{
4271 			if (last_time_ip_changed == false)
4272 			{
4273 				// Call all getting functions from the beginning
4274 				// if the routing table or the IP address of this host has changed
4275 				next_getip_tick = 0;
4276 				next_getprivate_ip_tick = 0;
4277 				ip_changed = true;
4278 
4279 				last_ip_hash = ip_hash;
4280 
4281 				last_time_ip_changed = true;
4282 			}
4283 		}
4284 		else
4285 		{
4286 			last_time_ip_changed = false;
4287 		}
4288 
4289 		Lock(r->Lock);
4290 		{
4291 			if (StrCmpi(current_hostname, r->CurrentRegisterHostname) != 0)
4292 			{
4293 				// The target host name has changed
4294 				next_getip_tick = 0;
4295 				StrCpy(current_hostname, sizeof(current_hostname), r->CurrentRegisterHostname);
4296 			}
4297 		}
4298 		Unlock(r->Lock);
4299 
4300 		// Get the IP address of the NAT-T server with DNS
4301 		if (next_getip_tick == 0 || now >= next_getip_tick)
4302 		{
4303 			IP ip;
4304 
4305 			if (GetIP4(&ip, current_hostname) && IsZeroIp(&ip) == false)
4306 			{
4307 				Lock(r->Lock);
4308 				{
4309 //					Debug("%r  %r\n",&r->NatT_IP, &ip);
4310 					if (CmpIpAddr(&r->NatT_IP, &ip) != 0)
4311 					{
4312 //						WHERE;
4313 						ip_changed = true;
4314 						Copy(&r->NatT_IP, &ip, sizeof(IP));
4315 					}
4316 				}
4317 				Unlock(r->Lock);
4318 			}
4319 
4320 			if (IsZeroIp(&r->NatT_IP))
4321 			{
4322 				num_retry++;
4323 
4324 				next_getip_tick = now + MIN((UINT64)UDP_NAT_T_GET_IP_INTERVAL * (UINT64)num_retry, (UINT64)UDP_NAT_T_GET_IP_INTERVAL_MAX);
4325 			}
4326 			else
4327 			{
4328 				next_getip_tick = now + (UINT64)UDP_NAT_T_GET_IP_INTERVAL_AFTER;
4329 			}
4330 
4331 			if (ip_changed)
4332 			{
4333 				Debug("NAT-T: NAT-T Server IP (%s): %r\n", current_hostname, &r->NatT_IP);
4334 
4335 				r->NatT_GetTokenNextTick = 0;
4336 				r->NatT_RegisterNextTick = 0;
4337 				r->NatT_GetTokenFailNum = 0;
4338 				r->NatT_RegisterFailNum = 0;
4339 
4340 				r->NatT_TranId = Rand64();
4341 
4342 				SetSockEvent(r->SockEvent);
4343 			}
4344 		}
4345 
4346 		// Get a private IP address of this host using TCP
4347 		if (next_getprivate_ip_tick == 0 || now >= next_getprivate_ip_tick)
4348 		{
4349 			IP ip;
4350 
4351 			if (GetMyPrivateIP(&ip, false))
4352 			{
4353 				Lock(r->Lock);
4354 				{
4355 					Copy(&r->My_Private_IP, &ip, sizeof(IP));
4356 				}
4357 				Unlock(r->Lock);
4358 			}
4359 
4360 			if (IsZeroIp(&r->My_Private_IP))
4361 			{
4362 				next_getprivate_ip_tick = now + (UINT64)UDP_NAT_T_GET_PRIVATE_IP_INTERVAL;
4363 			}
4364 			else
4365 			{
4366 				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);
4367 			}
4368 
4369 			Debug("NAT-T: My Private IP: %r\n", &r->My_Private_IP);
4370 		}
4371 
4372 		if (r->Halt)
4373 		{
4374 			break;
4375 		}
4376 
4377 		Wait(r->HaltEvent, RUDP_LOOP_WAIT_INTERVAL_S);
4378 	}
4379 
4380 	FreeRouteChange(route_change_poller);
4381 }
4382 
4383 // Generate a random intervals
GenRandInterval(UINT min,UINT max)4384 UINT GenRandInterval(UINT min, UINT max)
4385 {
4386 	UINT a, b;
4387 
4388 	a = MIN(min, max);
4389 	b = MAX(min, max);
4390 
4391 	if (a == b)
4392 	{
4393 		return a;
4394 	}
4395 
4396 	return (Rand32() % (b - a)) + a;
4397 }
4398 
4399 // Identify the private IP of the interface which is used to connect to the Internet currently
GetMyPrivateIP(IP * ip,bool from_vg)4400 bool GetMyPrivateIP(IP *ip, bool from_vg)
4401 {
4402 	SOCK *s;
4403 	IP t;
4404 	char *hostname = UDP_NAT_T_GET_PRIVATE_IP_TCP_SERVER;
4405 	// Validate arguments
4406 	if (ip == NULL)
4407 	{
4408 		return false;
4409 	}
4410 
4411 	s = ConnectEx(hostname, UDP_NAT_T_PORT_FOR_TCP_1, UDP_NAT_T_GET_PRIVATE_IP_CONNECT_TIMEOUT);
4412 
4413 	if (s == NULL)
4414 	{
4415 		s = ConnectEx(hostname, UDP_NAT_T_PORT_FOR_TCP_2, UDP_NAT_T_GET_PRIVATE_IP_CONNECT_TIMEOUT);
4416 
4417 		if (s == NULL)
4418 		{
4419 			s = ConnectEx(GetRandHostNameForGetMyPrivateIP(), UDP_NAT_T_PORT_FOR_TCP_1, UDP_NAT_T_GET_PRIVATE_IP_CONNECT_TIMEOUT);
4420 
4421 			if (s == NULL)
4422 			{
4423 				return false;
4424 			}
4425 		}
4426 	}
4427 
4428 	Copy(&t, &s->LocalIP, sizeof(IP));
4429 
4430 	Disconnect(s);
4431 	ReleaseSock(s);
4432 
4433 	if (IsZeroIp(&t))
4434 	{
4435 		return false;
4436 	}
4437 
4438 	Copy(ip, &t, sizeof(IP));
4439 
4440 	return true;
4441 }
GetRandHostNameForGetMyPrivateIP()4442 char *GetRandHostNameForGetMyPrivateIP()
4443 {
4444 	char *hosts[] =
4445 	{
4446 		"www.microsoft.com",
4447 		"www.yahoo.com",
4448 		"www.bing.com",
4449 	};
4450 	UINT num_hosts = 3;
4451 
4452 	return hosts[Rand32() % num_hosts];
4453 }
4454 
4455 // 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)4456 void WaitUntilHostIPAddressChanged(void *p, EVENT *event, UINT timeout, UINT ip_check_interval)
4457 {
4458 	UINT64 start, end;
4459 	UINT last_hash;
4460 	// Validate arguments
4461 	if (timeout == 0x7FFFFFFF)
4462 	{
4463 		timeout = 0xFFFFFFFF;
4464 	}
4465 	if (ip_check_interval == 0)
4466 	{
4467 		ip_check_interval = 0xFFFFFFFF;
4468 	}
4469 	if (event == NULL || timeout == 0)
4470 	{
4471 		return;
4472 	}
4473 
4474 	start = Tick64();
4475 	end = start + (UINT64)timeout;
4476 	last_hash = GetHostIPAddressHash32();
4477 
4478 	while (true)
4479 	{
4480 		UINT64 now = Tick64();
4481 		UINT next_interval;
4482 
4483 		if (now >= end)
4484 		{
4485 			break;
4486 		}
4487 
4488 		if (p != NULL)
4489 		{
4490 			if (IsRouteChanged(p))
4491 			{
4492 				break;
4493 			}
4494 		}
4495 
4496 		if (last_hash != GetHostIPAddressHash32())
4497 		{
4498 			break;
4499 		}
4500 
4501 		next_interval = (UINT)(end - now);
4502 		next_interval = MIN(next_interval, ip_check_interval);
4503 
4504 		if (Wait(event, next_interval))
4505 		{
4506 			break;
4507 		}
4508 	}
4509 }
InitWaitUntilHostIPAddressChanged()4510 void *InitWaitUntilHostIPAddressChanged()
4511 {
4512 	void *p = NewRouteChange();
4513 
4514 	if (p != NULL)
4515 	{
4516 		IsRouteChanged(p);
4517 	}
4518 
4519 	return p;
4520 }
FreeWaitUntilHostIPAddressChanged(void * p)4521 void FreeWaitUntilHostIPAddressChanged(void *p)
4522 {
4523 	FreeRouteChange(p);
4524 }
4525 
4526 // Get whether the specified IPv6 address is on the local network
IsIPv6LocalNetworkAddress(IP * ip)4527 bool IsIPv6LocalNetworkAddress(IP *ip)
4528 {
4529 	UINT type;
4530 	LIST *o;
4531 	UINT i;
4532 	bool ret = false;
4533 	IP mask64;
4534 	// Validate arguments
4535 	if (ip == NULL)
4536 	{
4537 		return false;
4538 	}
4539 	if (IsIP6(ip) == false)
4540 	{
4541 		return false;
4542 	}
4543 	if (IsZeroIp(ip))
4544 	{
4545 		return false;
4546 	}
4547 
4548 	type = GetIPAddrType6(ip);
4549 
4550 	if (type & IPV6_ADDR_LOCAL_UNICAST)
4551 	{
4552 		return true;
4553 	}
4554 
4555 	if ((type & IPV6_ADDR_GLOBAL_UNICAST) == 0)
4556 	{
4557 		return false;
4558 	}
4559 
4560 	IntToSubnetMask6(&mask64, 64);
4561 
4562 	o = GetHostIPAddressList();
4563 
4564 	ret = false;
4565 
4566 	for (i = 0; i < LIST_NUM(o); i++)
4567 	{
4568 		IP *p = LIST_DATA(o, i);
4569 
4570 		if (IsIP6(p))
4571 		{
4572 			if (IsZeroIp(p) == false)
4573 			{
4574 				if (IsLocalHostIP6(p) == false)
4575 				{
4576 					if (IsInSameNetwork6(p, ip, &mask64))
4577 					{
4578 						ret = true;
4579 					}
4580 				}
4581 			}
4582 		}
4583 	}
4584 
4585 	FreeHostIPAddressList(o);
4586 
4587 	return ret;
4588 }
4589 
4590 // Check whether the specified IP address is localhost or the IP address of the local interface of itself
IsIPLocalHostOrMySelf(IP * ip)4591 bool IsIPLocalHostOrMySelf(IP *ip)
4592 {
4593 	LIST *o;
4594 	bool ret = false;
4595 	UINT i;
4596 	// Validate arguments
4597 	if (ip == NULL)
4598 	{
4599 		return false;
4600 	}
4601 
4602 	o = GetHostIPAddressList();
4603 	if (o == NULL)
4604 	{
4605 		return false;
4606 	}
4607 
4608 	for (i = 0; i < LIST_NUM(o); i++)
4609 	{
4610 		IP *p = LIST_DATA(o, i);
4611 
4612 		if (CmpIpAddr(p, ip) == 0)
4613 		{
4614 			ret = true;
4615 
4616 			break;
4617 		}
4618 	}
4619 
4620 	FreeHostIPAddressList(o);
4621 
4622 	if (IsLocalHostIP4(ip) || IsLocalHostIP6(ip))
4623 	{
4624 		ret = true;
4625 	}
4626 
4627 	return ret;
4628 }
4629 
4630 // Obtain the hash value of combining all of the IP address assigned to the host
GetHostIPAddressHash32()4631 UINT GetHostIPAddressHash32()
4632 {
4633 	BUF *b;
4634 	UINT i;
4635 	UCHAR hash[SHA1_SIZE];
4636 	UINT ret;
4637 	LIST *o = GetHostIPAddressList();
4638 
4639 	if (o == NULL)
4640 	{
4641 		return 0;
4642 	}
4643 
4644 	b = NewBuf();
4645 	for (i = 0; i < LIST_NUM(o); i++)
4646 	{
4647 		IP *ip = LIST_DATA(o, i);
4648 
4649 		WriteBuf(b, ip, sizeof(IP));
4650 
4651 		WriteBufStr(b, ":-) yas (-:");
4652 	}
4653 	FreeHostIPAddressList(o);
4654 
4655 	WriteBuf(b, rand_port_numbers, sizeof(rand_port_numbers));
4656 
4657 	Sha1(hash, b->Buf, b->Size);
4658 
4659 	FreeBuf(b);
4660 
4661 	Copy(&ret, hash, sizeof(UINT));
4662 
4663 	return ret;
4664 }
4665 
4666 // Create an IPv4 UDP socket destined for a particular target
NewUDP4ForSpecificIp(IP * target_ip,UINT port)4667 SOCK *NewUDP4ForSpecificIp(IP *target_ip, UINT port)
4668 {
4669 	SOCK *s;
4670 	IP local_ip;
4671 	// Validate arguments
4672 	if (target_ip == NULL || IsZeroIP(target_ip) || IsIP4(target_ip) == false)
4673 	{
4674 		target_ip = NULL;
4675 	}
4676 
4677 	Zero(&local_ip, sizeof(local_ip));
4678 	GetBestLocalIpForTarget(&local_ip, target_ip);
4679 
4680 	s = NewUDP4(port, &local_ip);
4681 
4682 	if (s == NULL)
4683 	{
4684 		s = NewUDP4(port, NULL);
4685 	}
4686 
4687 	return s;
4688 }
4689 
4690 // Get the best self IPv4 address to connect to the target IPv4 address
GetBestLocalIpForTarget(IP * local_ip,IP * target_ip)4691 bool GetBestLocalIpForTarget(IP *local_ip, IP *target_ip)
4692 {
4693 	bool ret = false;
4694 	ROUTE_ENTRY *e;
4695 	IP ip2;
4696 	UINT n = 0;
4697 	IP zero_ip;
4698 	// Validate arguments
4699 	Zero(local_ip, sizeof(IP));
4700 	ZeroIP4(&zero_ip);
4701 	if (target_ip == NULL)
4702 	{
4703 		target_ip = &zero_ip;
4704 	}
4705 	if (local_ip == NULL || IsIP4(target_ip) == false)
4706 	{
4707 		return false;
4708 	}
4709 
4710 	Copy(&ip2, target_ip, sizeof(IP));
4711 
4712 	while (true)
4713 	{
4714 		n++;
4715 		if (n >= 64)
4716 		{
4717 			break;
4718 		}
4719 
4720 		e = GetBestRouteEntry(&ip2);
4721 		if (e != NULL)
4722 		{
4723 			if (IsZeroIp(&e->GatewayIP))
4724 			{
4725 				Free(e);
4726 				break;
4727 			}
4728 
4729 			if (e->LocalRouting)
4730 			{
4731 				ret = true;
4732 				Copy(local_ip, &e->GatewayIP, sizeof(IP));
4733 				Free(e);
4734 				break;
4735 			}
4736 			else
4737 			{
4738 				Copy(&ip2, &e->GatewayIP, sizeof(IP));
4739 			}
4740 
4741 			Free(e);
4742 		}
4743 	}
4744 
4745 	if (ret == false)
4746 	{
4747 		if (IsLocalHostIP4(target_ip))
4748 		{
4749 			GetLocalHostIP4(local_ip);
4750 			ret = true;
4751 		}
4752 	}
4753 
4754 	return ret;
4755 }
4756 
4757 // 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)4758 SOCK *NewRUDPClientNatT(char *svc_name, IP *ip, UINT *error_code, UINT timeout, bool *cancel, char *hint_str, char *target_hostname)
4759 {
4760 	IP nat_t_ip;
4761 	UINT dummy_int = 0;
4762 	UINT64 giveup_tick;
4763 	bool dummy_bool = false;
4764 	SOCK_EVENT *sock_event;
4765 	SOCK *sock;
4766 	bool same_lan = false;
4767 	char hostname[MAX_SIZE];
4768 
4769 
4770 
4771 	if (timeout == 0)
4772 	{
4773 		timeout = RUDP_TIMEOUT;
4774 	}
4775 	if (error_code == NULL)
4776 	{
4777 		error_code = &dummy_int;
4778 	}
4779 	if (cancel == NULL)
4780 	{
4781 		cancel = &dummy_bool;
4782 	}
4783 	*error_code = RUDP_ERROR_UNKNOWN;
4784 	if (svc_name == NULL || ip == NULL)
4785 	{
4786 		return NULL;
4787 	}
4788 
4789 	ListenTcpForPopupFirewallDialog();
4790 
4791 	giveup_tick = Tick64() + (UINT64)timeout;
4792 
4793 	// Get the IP address of the NAT-T server
4794 	RUDPGetRegisterHostNameByIP(hostname, sizeof(hostname), ip);
4795 	if (GetIP4Ex(&nat_t_ip, hostname, 0, cancel) == false)
4796 	{
4797 		*error_code = RUDP_ERROR_NAT_T_NO_RESPONSE;
4798 		return NULL;
4799 	}
4800 
4801 	if (Tick64() >= giveup_tick)
4802 	{
4803 		*error_code = RUDP_ERROR_TIMEOUT;
4804 		return NULL;
4805 	}
4806 	if (*cancel)
4807 	{
4808 		*error_code = RUDP_ERROR_USER_CANCELED;
4809 		return NULL;
4810 	}
4811 
4812 	sock = NewUDP4ForSpecificIp(&nat_t_ip, 0);
4813 	if (sock == NULL)
4814 	{
4815 		*error_code = RUDP_ERROR_UNKNOWN;
4816 		return NULL;
4817 	}
4818 	else
4819 	{
4820 		UINT64 next_send_request_tick = 0;
4821 		INTERRUPT_MANAGER *interrupt = NewInterruptManager();
4822 		UINT64 tran_id = Rand64();
4823 		UINT tmp_size = 65536;
4824 		UCHAR *tmp = Malloc(tmp_size);
4825 		char result_ip_str[MAX_SIZE];
4826 		IP result_ip;
4827 		UINT result_port;
4828 		SOCK *ret = NULL;
4829 		UINT num_tries = 0;
4830 		UINT64 current_cookie = 0;
4831 
4832 		AddInterrupt(interrupt, giveup_tick);
4833 
4834 		sock_event = NewSockEvent();
4835 		JoinSockToSockEvent(sock, sock_event);
4836 
4837 		// Communication with the NAT-T server
4838 		while (true)
4839 		{
4840 			UINT64 now = Tick64();
4841 			UINT interval;
4842 			UINT r;
4843 			IP src_ip;
4844 			UINT src_port;
4845 			UINT err;
4846 			UINT num_ignore_errors = 0;
4847 
4848 			if (now >= giveup_tick)
4849 			{
4850 				// Time-out
4851 LABEL_TIMEOUT:
4852 				*error_code = RUDP_ERROR_NAT_T_NO_RESPONSE;
4853 				break;
4854 			}
4855 
4856 			if (*cancel)
4857 			{
4858 				// User canceled
4859 				*error_code = RUDP_ERROR_USER_CANCELED;
4860 				break;
4861 			}
4862 
4863 			err = INFINITE;
4864 
4865 			// Receive a response packet from the NAT-T server
4866 			while (err == INFINITE)
4867 			{
4868 				r = RecvFrom(sock, &src_ip, &src_port, tmp, tmp_size);
4869 				if (r == SOCK_LATER)
4870 				{
4871 					// No packet
4872 					break;
4873 				}
4874 				else if (r == 0)
4875 				{
4876 					if (sock->IgnoreRecvErr == false)
4877 					{
4878 						// Communication error
4879 						goto LABEL_TIMEOUT;
4880 					}
4881 					else
4882 					{
4883 						if ((num_ignore_errors++) >= MAX_NUM_IGNORE_ERRORS)
4884 						{
4885 							goto LABEL_TIMEOUT;
4886 						}
4887 					}
4888 				}
4889 				else
4890 				{
4891 					// Check the source IP address and the port number
4892 					if (CmpIpAddr(&src_ip, &nat_t_ip) == 0 && src_port == UDP_NAT_T_PORT)
4893 					{
4894 						BUF *b = NewBuf();
4895 						PACK *p;
4896 
4897 						WriteBuf(b, tmp, r);
4898 						SeekBuf(b, 0, 0);
4899 
4900 
4901 						p = BufToPack(b);
4902 
4903 						if (p != NULL)
4904 						{
4905 							UINT64 cookie = PackGetInt64(p, "cookie");
4906 							if (cookie != 0)
4907 							{
4908 								current_cookie = cookie;
4909 							}
4910 
4911 							// Compare tran_id
4912 							if (PackGetInt64(p, "tran_id") == tran_id)
4913 							{
4914 								// Compare opcode
4915 								if (PackCmpStr(p, "opcode", "nat_t_connect_request"))
4916 								{
4917 									bool ok = PackGetBool(p, "ok");
4918 									bool multi_candidate = PackGetBool(p, "multi_candidates");
4919 
4920 									if (ok)
4921 									{
4922 										// Success
4923 										PackGetStr(p, "result_ip", result_ip_str, sizeof(result_ip_str));
4924 										StrToIP(&result_ip, result_ip_str);
4925 
4926 										result_port = PackGetInt(p, "result_port");
4927 
4928 										same_lan = PackGetBool(p, "same_lan");
4929 
4930 										if (result_port != 0)
4931 										{
4932 											if (IsZeroIp(&result_ip) == false)
4933 											{
4934 												if ((sock->IPv6 == false && IsIP4(&result_ip)) ||
4935 												        (sock->IPv6 && IsIP6(&result_ip)))
4936 												{
4937 													err = RUDP_ERROR_OK;
4938 												}
4939 											}
4940 										}
4941 									}
4942 									else if (multi_candidate)
4943 									{
4944 										// There are two or more computers behind the specified IP address
4945 										err = RUDP_ERROR_NAT_T_TWO_OR_MORE;
4946 									}
4947 									else
4948 									{
4949 										// Failure
4950 										err = RUDP_ERROR_NAT_T_NOT_FOUND;
4951 									}
4952 								}
4953 							}
4954 
4955 							FreePack(p);
4956 						}
4957 
4958 						FreeBuf(b);
4959 					}
4960 				}
4961 			}
4962 
4963 			if (err != INFINITE)
4964 			{
4965 				*error_code = err;
4966 				break;
4967 			}
4968 
4969 			if (next_send_request_tick == 0 || now >= next_send_request_tick)
4970 			{
4971 				// Send a connection request to the NAT-T server
4972 				BUF *b;
4973 				char ip_str[MAX_SIZE];
4974 				PACK *p = NewPack();
4975 
4976 				PackAddStr(p, "opcode", "nat_t_connect_request");
4977 				PackAddInt64(p, "tran_id", tran_id);
4978 				IPToStr(ip_str, sizeof(ip_str), ip);
4979 				PackAddStr(p, "dest_ip", ip_str);
4980 				PackAddInt64(p, "cookie", current_cookie);
4981 				if (IsEmptyStr(hint_str) == false)
4982 				{
4983 					PackAddStr(p, "hint", hint_str);
4984 				}
4985 				if (IsEmptyStr(target_hostname) == false)
4986 				{
4987 					PackAddStr(p, "target_hostname", target_hostname);
4988 				}
4989 				PackAddStr(p, "svc_name", svc_name);
4990 
4991 				PackAddInt(p, "nat_traversal_version", UDP_NAT_TRAVERSAL_VERSION);
4992 
4993 				b = PackToBuf(p);
4994 				FreePack(p);
4995 
4996 				SendTo(sock, &nat_t_ip, UDP_NAT_T_PORT, b->Buf, b->Size);
4997 				FreeBuf(b);
4998 
4999 				// Determine the next transmission time
5000 				next_send_request_tick = now + (UINT64)UDP_NAT_T_CONNECT_INTERVAL * (UINT64)(Power(2, MAX(num_tries, 6)));
5001 				num_tries++;
5002 				AddInterrupt(interrupt, next_send_request_tick);
5003 			}
5004 
5005 			interval = GetNextIntervalForInterrupt(interrupt);
5006 			interval = MIN(interval, 50);
5007 
5008 			WaitSockEvent(sock_event, interval);
5009 		}
5010 
5011 		Free(tmp);
5012 		FreeInterruptManager(interrupt);
5013 
5014 		if (*error_code == RUDP_ERROR_OK)
5015 		{
5016 			UINT remain_timeout;
5017 			UINT64 now = Tick64();
5018 			// Success to get the IP address and the port number of the target
5019 
5020 			// Get the rest timeout tolerance
5021 			if (now <= giveup_tick)
5022 			{
5023 				remain_timeout = (UINT)(giveup_tick - now);
5024 			}
5025 			else
5026 			{
5027 				remain_timeout = 0;
5028 			}
5029 
5030 			remain_timeout = MAX(remain_timeout, 2000);
5031 
5032 			if (same_lan)
5033 			{
5034 				// Discard current UDP socket and create a new UDP socket in NewRUDPClientDirect().
5035 				// Because using a UDP socket which used for communication with the NAT-T server
5036 				// can cause trouble when the client and the server exists in the same LAN.
5037 				ReleaseSockEvent(sock_event);
5038 				ReleaseSock(sock);
5039 
5040 				sock = NULL;
5041 				sock_event = NULL;
5042 			}
5043 
5044 			ret = NewRUDPClientDirect(svc_name, &result_ip, result_port, error_code, remain_timeout, cancel,
5045 			                          sock, sock_event, 0, false);
5046 		}
5047 
5048 		if (sock_event != NULL)
5049 		{
5050 			ReleaseSockEvent(sock_event);
5051 		}
5052 
5053 		if (sock != NULL)
5054 		{
5055 			if (ret == NULL)
5056 			{
5057 				Disconnect(sock);
5058 			}
5059 
5060 			ReleaseSock(sock);
5061 		}
5062 
5063 		return ret;
5064 	}
5065 }
5066 
5067 // Listen to the TCP for a moment to show the firewall dialog
ListenTcpForPopupFirewallDialog()5068 void ListenTcpForPopupFirewallDialog()
5069 {
5070 #ifdef	OS_WIN32
5071 	static bool tried = false;
5072 
5073 	if (tried == false)
5074 	{
5075 		SOCK *s;
5076 		tried = true;
5077 		s = ListenAnyPortEx2(false, true);
5078 
5079 		if (s != NULL)
5080 		{
5081 			Disconnect(s);
5082 			ReleaseSock(s);
5083 		}
5084 	}
5085 #endif	// OS_WIN32
5086 }
5087 
5088 // 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)5089 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)
5090 {
5091 	RUDP_STACK *r;
5092 	UINT dummy_int = 0;
5093 	SOCK *ret = NULL;
5094 	// Validate arguments
5095 	if (error_code == NULL)
5096 	{
5097 		error_code = &dummy_int;
5098 	}
5099 	if (timeout == 0)
5100 	{
5101 		timeout = RUDP_TIMEOUT;
5102 	}
5103 	*error_code = RUDP_ERROR_UNKNOWN;
5104 	if (svc_name == NULL || ip == NULL || port == 0)
5105 	{
5106 		return NULL;
5107 	}
5108 
5109 	r = NewRUDP(false, svc_name, NULL, NULL, NULL, local_port, sock, sock_event, false, over_dns_mode, ip, NULL, 0, NULL);
5110 	if (r == NULL)
5111 	{
5112 		*error_code = RUDP_ERROR_UNKNOWN;
5113 		return NULL;
5114 	}
5115 
5116 	// Set the port number and the target IP address
5117 	Lock(r->Lock);
5118 	{
5119 		Copy(&r->TargetIp, ip, sizeof(IP));
5120 		r->TargetPort = port;
5121 		r->TargetIpAndPortInited = true;
5122 	}
5123 	Unlock(r->Lock);
5124 	SetSockEvent(r->SockEvent);
5125 
5126 	// Wait for a connection success/failure to the target IP address
5127 	WaitEx(r->TargetConnectedEvent, timeout, cancel);
5128 	Lock(r->Lock);
5129 	{
5130 		if (r->TargetConnectedSock != NULL)
5131 		{
5132 			// The connection succeeded
5133 			ret = r->TargetConnectedSock;
5134 			r->TargetConnectedSock = NULL;
5135 		}
5136 		else
5137 		{
5138 			r->DoNotSetTargetConnectedSock = true;
5139 		}
5140 	}
5141 	Unlock(r->Lock);
5142 
5143 	if (ret == NULL)
5144 	{
5145 		// Stop the R-UDP stack if the connection has failed
5146 		*error_code = RUDP_ERROR_TIMEOUT;
5147 		FreeRUDP(r);
5148 	}
5149 	else if (cancel != NULL && (*cancel))
5150 	{
5151 		// User canceled
5152 		*error_code = RUDP_ERROR_USER_CANCELED;
5153 
5154 		Disconnect(ret);
5155 		ReleaseSock(ret);
5156 
5157 		ret = NULL;
5158 	}
5159 	else
5160 	{
5161 		*error_code = RUDP_ERROR_OK;
5162 	}
5163 
5164 	return ret;
5165 }
5166 
5167 // 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,IP * listen_ip)5168 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, IP *listen_ip)
5169 {
5170 	RUDP_STACK *r;
5171 	// Validate arguments
5172 	if (IsEmptyStr(svc_name))
5173 	{
5174 		return NULL;
5175 	}
5176 
5177 	if (g_no_rudp_server)
5178 	{
5179 		return NULL;
5180 	}
5181 
5182 	ListenTcpForPopupFirewallDialog();
5183 
5184 	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, listen_ip);
5185 
5186 	if (r == NULL)
5187 	{
5188 		return NULL;
5189 	}
5190 
5191 	return r;
5192 }
5193 
5194 // 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,IP * listen_ip)5195 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, IP *listen_ip)
5196 {
5197 	RUDP_STACK *r;
5198 	char tmp[MAX_SIZE];
5199 	UCHAR pid_hash[SHA1_SIZE];
5200 	UINT pid;
5201 	USHORT pid_us;
5202 
5203 	// Validate arguments
5204 	if (IsEmptyStr(svc_name))
5205 	{
5206 		return NULL;
5207 	}
5208 
5209 	ListenTcpForPopupFirewallDialog();
5210 
5211 	if (sock == NULL)
5212 	{
5213 		if (server_mode == false && client_target_ip != NULL)
5214 		{
5215 			sock = NewUDP4ForSpecificIp(client_target_ip, port);
5216 		}
5217 		else
5218 		{
5219 			if (rand_port_id == 0)
5220 			{
5221 				sock = NewUDPEx2(port, false, listen_ip);
5222 			}
5223 			else
5224 			{
5225 				sock = NewUDPEx2RandMachineAndExePath(false, listen_ip, 0, rand_port_id);
5226 			}
5227 		}
5228 
5229 		if (sock == NULL)
5230 		{
5231 			return NULL;
5232 		}
5233 	}
5234 	else
5235 	{
5236 		AddRef(sock->ref);
5237 	}
5238 
5239 	if (port == 0)
5240 	{
5241 		port = sock->LocalPort;
5242 	}
5243 
5244 	if (rand_port_id != 0)
5245 	{
5246 		rand_port_numbers[rand_port_id] = port;
5247 	}
5248 
5249 	if (sock_event == NULL)
5250 	{
5251 		sock_event = NewSockEvent();
5252 	}
5253 	else
5254 	{
5255 		AddRef(sock_event->ref);
5256 	}
5257 
5258 	r = ZeroMalloc(sizeof(RUDP_STACK));
5259 
5260 	r->NatT_SessionKey = Rand64();
5261 
5262 	StrCpy(r->SvcName, sizeof(r->SvcName), svc_name);
5263 	r->RandPortId = rand_port_id;
5264 	r->NatTGlobalUdpPort = natt_global_udp_port;
5265 	r->ServerMode = server_mode;
5266 	r->Interrupt = NewInterruptManager();
5267 	r->SessionList = NewList(RUDPCompareSessionList);
5268 	r->UdpSock = sock;
5269 	r->Port = port;
5270 	r->SockEvent = sock_event;
5271 	r->HaltEvent = NewEvent();
5272 	r->Now = Tick64();
5273 	r->Lock = NewLock();
5274 	r->Param = param;
5275 	r->TargetConnectedEvent = NewEvent();
5276 	r->SendPacketList = NewList(NULL);
5277 	r->NewSockConnectEvent = NewEvent();
5278 	r->NewSockQueue = NewQueue();
5279 	r->NatT_TranId = Rand64();
5280 
5281 	r->NatT_SourceIpList = NewListFast(NULL);
5282 
5283 	StrCpy(tmp, sizeof(tmp), r->SvcName);
5284 	Trim(tmp);
5285 	StrLower(tmp);
5286 
5287 	Sha1(r->SvcNameHash, tmp, StrLen(tmp));
5288 
5289 	r->Client_IcmpId = (USHORT)(Rand32() % 65534 + 1);
5290 	r->Client_IcmpSeqNo = (USHORT)(Rand32() % 65534 + 1);
5291 
5292 	// Determination of the type of the protocol
5293 	r->Protocol = RUDP_PROTOCOL_UDP;
5294 	if (r->Port == MAKE_SPECIAL_PORT(IP_PROTO_ICMPV4))
5295 	{
5296 		r->Protocol = RUDP_PROTOCOL_ICMP;
5297 
5298 		// Generate the ICMP ID based on the process ID
5299 #ifdef	OS_WIN32
5300 		pid = (UINT)MsGetProcessId();
5301 #else	// OS_WIN32
5302 		pid = (UINT)getpid();
5303 #endif	// OS_WIN32
5304 
5305 		pid = Endian32(pid);
5306 		Sha1(pid_hash, &pid, sizeof(UINT));
5307 
5308 		pid_us = READ_USHORT(pid_hash);
5309 		if (pid_us == 0 || pid_us == 0xFFFF)
5310 		{
5311 			pid_us = 1;
5312 		}
5313 
5314 		r->Client_IcmpId = pid_us;
5315 	}
5316 	else if (over_dns_mode)
5317 	{
5318 		r->Protocol = RUDP_PROTOCOL_DNS;
5319 	}
5320 
5321 	if (r->ServerMode)
5322 	{
5323 		r->NoNatTRegister = server_no_natt_register;
5324 
5325 		if (r->Protocol == RUDP_PROTOCOL_ICMP || r->Protocol == RUDP_PROTOCOL_DNS)
5326 		{
5327 			// Never register to the NAT-T server in case of using the DNS or the ICMP
5328 			r->NoNatTRegister = true;
5329 		}
5330 	}
5331 
5332 	if (true
5333 	   )
5334 	{
5335 		RUDPGetRegisterHostNameByIP(r->CurrentRegisterHostname, sizeof(r->CurrentRegisterHostname), NULL);
5336 	}
5337 
5338 	if (r->ServerMode)
5339 	{
5340 		r->ProcInterrupts = proc_interrupts;
5341 		r->ProcRpcRecv = proc_rpc_recv;
5342 	}
5343 
5344 	if (r->ServerMode && r->NoNatTRegister == false
5345 	   )
5346 	{
5347 		r->IpQueryThread = NewThread(RUDPIpQueryThread, r);
5348 	}
5349 
5350 	JoinSockToSockEvent(r->UdpSock, r->SockEvent);
5351 
5352 	r->Thread = NewThread(RUDPMainThread, r);
5353 	WaitThreadInit(r->Thread);
5354 
5355 	return r;
5356 }
5357 
5358 // R-UDP session comparison function
RUDPCompareSessionList(void * p1,void * p2)5359 int RUDPCompareSessionList(void *p1, void *p2)
5360 {
5361 	RUDP_SESSION *s1, *s2;
5362 	UINT r;
5363 	// Validate arguments
5364 	if (p1 == NULL || p2 == NULL)
5365 	{
5366 		return 0;
5367 	}
5368 	s1 = *((RUDP_SESSION **)p1);
5369 	s2 = *((RUDP_SESSION **)p2);
5370 	if (s1 == NULL || s2 == NULL)
5371 	{
5372 		return 0;
5373 	}
5374 
5375 	r = CmpIpAddr(&s1->YourIp, &s2->YourIp);
5376 	if (r != 0)
5377 	{
5378 		return r;
5379 	}
5380 
5381 	r = COMPARE_RET(s1->YourPort, s2->YourPort);
5382 	if (r != 0)
5383 	{
5384 		return r;
5385 	}
5386 
5387 	r = CmpIpAddr(&s1->MyIp, &s2->MyIp);
5388 	if (r != 0)
5389 	{
5390 		return r;
5391 	}
5392 
5393 	r = COMPARE_RET(s1->MyPort, s2->MyPort);
5394 	if (r != 0)
5395 	{
5396 		return r;
5397 	}
5398 
5399 	return 0;
5400 }
5401 
5402 // Release of the R-UDP
FreeRUDP(RUDP_STACK * r)5403 void FreeRUDP(RUDP_STACK *r)
5404 {
5405 	UINT i;
5406 	// Validate arguments
5407 	if (r == NULL)
5408 	{
5409 		return;
5410 	}
5411 
5412 	r->Halt = true;
5413 	Set(r->HaltEvent);
5414 	SetSockEvent(r->SockEvent);
5415 
5416 	if (r->ServerMode && r->NoNatTRegister == false)
5417 	{
5418 		if (r->IpQueryThread != NULL)
5419 		{
5420 			WaitThread(r->IpQueryThread, INFINITE);
5421 			ReleaseThread(r->IpQueryThread);
5422 		}
5423 	}
5424 
5425 	WaitThread(r->Thread, INFINITE);
5426 	ReleaseThread(r->Thread);
5427 
5428 	for (i = 0; i < LIST_NUM(r->SessionList); i++)
5429 	{
5430 		RUDP_SESSION *se = LIST_DATA(r->SessionList, i);
5431 
5432 		RUDPFreeSession(se);
5433 	}
5434 
5435 	ReleaseList(r->SessionList);
5436 
5437 	for (i = 0; i < LIST_NUM(r->SendPacketList); i++)
5438 	{
5439 		UDPPACKET *p = LIST_DATA(r->SendPacketList, i);
5440 
5441 		FreeUdpPacket(p);
5442 	}
5443 
5444 	while (true)
5445 	{
5446 		SOCK *s = GetNext(r->NewSockQueue);
5447 		if (s == NULL)
5448 		{
5449 			break;
5450 		}
5451 
5452 		Disconnect(s);
5453 		ReleaseSock(s);
5454 	}
5455 
5456 	for (i = 0; i < LIST_NUM(r->NatT_SourceIpList); i++)
5457 	{
5458 		RUDP_SOURCE_IP *sip = (RUDP_SOURCE_IP *)LIST_DATA(r->NatT_SourceIpList, i);
5459 
5460 		Free(sip);
5461 	}
5462 
5463 	ReleaseList(r->NatT_SourceIpList);
5464 
5465 	ReleaseQueue(r->NewSockQueue);
5466 
5467 	ReleaseList(r->SendPacketList);
5468 
5469 	FreeInterruptManager(r->Interrupt);
5470 
5471 	Disconnect(r->UdpSock);
5472 	ReleaseSock(r->UdpSock);
5473 	ReleaseSockEvent(r->SockEvent);
5474 	ReleaseEvent(r->HaltEvent);
5475 	ReleaseEvent(r->TargetConnectedEvent);
5476 
5477 	ReleaseEvent(r->NewSockConnectEvent);
5478 
5479 	Disconnect(r->TargetConnectedSock);
5480 	ReleaseSock(r->TargetConnectedSock);
5481 
5482 	DeleteLock(r->Lock);
5483 
5484 	if (r->RandPortId != 0)
5485 	{
5486 		rand_port_numbers[r->RandPortId] = 0;
5487 	}
5488 
5489 	Free(r);
5490 }
5491 
5492 // Generate a hash from the current computer name and the process name
GetCurrentMachineIpProcessHash(void * hash)5493 void GetCurrentMachineIpProcessHash(void *hash)
5494 {
5495 	// Validate arguments
5496 	if (hash == NULL)
5497 	{
5498 		return;
5499 	}
5500 
5501 	Lock(machine_ip_process_hash_lock);
5502 	{
5503 		if (IsZero(machine_ip_process_hash, SHA1_SIZE))
5504 		{
5505 			GetCurrentMachineIpProcessHashInternal(machine_ip_process_hash);
5506 		}
5507 
5508 		Copy(hash, machine_ip_process_hash, SHA1_SIZE);
5509 	}
5510 	Unlock(machine_ip_process_hash_lock);
5511 }
GetCurrentMachineIpProcessHashInternal(void * hash)5512 void GetCurrentMachineIpProcessHashInternal(void *hash)
5513 {
5514 	BUF *b;
5515 	LIST *ip_list;
5516 	char machine_name[MAX_SIZE];
5517 	wchar_t exe_path[MAX_PATH];
5518 	char *product_id = NULL;
5519 	// Validate arguments
5520 	if (hash == NULL)
5521 	{
5522 		return;
5523 	}
5524 
5525 #ifdef	OS_WIN32
5526 	product_id = MsRegReadStr(REG_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "ProductId");
5527 	if (product_id == NULL)
5528 	{
5529 		product_id = MsRegReadStr(REG_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion", "ProductId");
5530 	}
5531 #endif	// OS_WIN32
5532 
5533 	b = NewBuf();
5534 
5535 	GetMachineHostName(machine_name, sizeof(machine_name));
5536 	Trim(machine_name);
5537 	StrUpper(machine_name);
5538 
5539 	GetExeNameW(exe_path, sizeof(exe_path));
5540 	UniTrim(exe_path);
5541 	UniStrUpper(exe_path);
5542 
5543 	WriteBuf(b, machine_name, StrSize(machine_name));
5544 	WriteBuf(b, exe_path, UniStrSize(exe_path));
5545 	WriteBuf(b, product_id, StrSize(product_id));
5546 
5547 	ip_list = GetHostIPAddressList();
5548 	if (ip_list != NULL)
5549 	{
5550 		UINT i;
5551 		for (i = 0; i < LIST_NUM(ip_list); i++)
5552 		{
5553 			IP *ip = LIST_DATA(ip_list, i);
5554 
5555 			WriteBuf(b, ip, sizeof(IP));
5556 		}
5557 	}
5558 	FreeHostIPAddressList(ip_list);
5559 
5560 	Sha1(hash, b->Buf, b->Size);
5561 
5562 	FreeBuf(b);
5563 
5564 	Free(product_id);
5565 }
5566 
5567 // Create a pair of pre-bound TCP sockets
NewTcpPair(SOCK ** s1,SOCK ** s2)5568 bool NewTcpPair(SOCK **s1, SOCK **s2)
5569 {
5570 	SOCK *a;
5571 	SOCK *s, *c;
5572 	TUBE *t1, *t2;
5573 	SOCK_EVENT *e1, *e2;
5574 	// Validate arguments
5575 	if (s1 == NULL || s2 == NULL)
5576 	{
5577 		return false;
5578 	}
5579 
5580 	a = ListenAnyPortEx2(true, true);
5581 	if (a == NULL)
5582 	{
5583 		return false;
5584 	}
5585 
5586 	c = Connect("127.0.0.1", a->LocalPort);
5587 	if (c == NULL)
5588 	{
5589 		ReleaseSock(a);
5590 		return false;
5591 	}
5592 
5593 	s = Accept(a);
5594 	if (s == NULL)
5595 	{
5596 		ReleaseSock(c);
5597 		ReleaseSock(a);
5598 		return false;
5599 	}
5600 
5601 	ReleaseSock(a);
5602 
5603 	if ((s->LocalPort != c->RemotePort) || (s->RemotePort != c->LocalPort))
5604 	{
5605 		ReleaseSock(s);
5606 		ReleaseSock(c);
5607 		return false;
5608 	}
5609 
5610 	NewTubePair(&t1, &t2, sizeof(TCP_PAIR_HEADER));
5611 
5612 	// Creating a socket event
5613 	e1 = NewSockEvent();
5614 	e2 = NewSockEvent();
5615 
5616 	SetTubeSockEvent(t1, e1);
5617 	SetTubeSockEvent(t2, e2);
5618 
5619 	AddRef(t1->Ref);
5620 	AddRef(t2->Ref);
5621 	s->BulkRecvTube = c->BulkSendTube = t1;
5622 	s->BulkSendTube = c->BulkRecvTube = t2;
5623 
5624 	ReleaseSockEvent(e1);
5625 	ReleaseSockEvent(e2);
5626 
5627 	*s1 = s;
5628 	*s2 = c;
5629 
5630 	return true;
5631 }
5632 
5633 // Listen in any available port
ListenAnyPortEx2(bool local_only,bool disable_ca)5634 SOCK *ListenAnyPortEx2(bool local_only, bool disable_ca)
5635 {
5636 	UINT i;
5637 	SOCK *s;
5638 	for (i = 40000; i < 65536; i++)
5639 	{
5640 		s = ListenEx(i, local_only);
5641 		if (s != NULL)
5642 		{
5643 			return s;
5644 		}
5645 	}
5646 
5647 	return NULL;
5648 }
5649 
5650 
5651 #if OPENSSL_VERSION_NUMBER < 0x10100000L
5652 #define X509_STORE_CTX_get0_cert(o) ((o)->cert)
5653 #endif
5654 
5655 // Verify client SSL certificate during TLS handshake.
5656 //
5657 // (actually, only save the certificate for later authentication in Protocol.c)
SslCertVerifyCallback(int preverify_ok,X509_STORE_CTX * ctx)5658 int SslCertVerifyCallback(int preverify_ok, X509_STORE_CTX *ctx)
5659 {
5660 	SSL *ssl;
5661 	struct SslClientCertInfo *clientcert;
5662 	X509 *cert;
5663 
5664 	ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
5665 	clientcert = SSL_get_ex_data(ssl, GetSslClientCertIndex());
5666 
5667 	if (clientcert != NULL)
5668 	{
5669 		clientcert->PreverifyErr = X509_STORE_CTX_get_error(ctx);
5670 		clientcert->PreverifyErrMessage[0] = '\0';
5671 		if (!preverify_ok)
5672 		{
5673 			const char *msg = X509_verify_cert_error_string(clientcert->PreverifyErr);
5674 			StrCpy(clientcert->PreverifyErrMessage, PREVERIFY_ERR_MESSAGE_SIZE, (char *)msg);
5675 			Debug("SslCertVerifyCallback preverify error: '%s'\n", msg);
5676 		}
5677 		else
5678 		{
5679 			cert = X509_STORE_CTX_get0_cert(ctx);
5680 			if (cert != NULL)
5681 			{
5682 				X *tmpX = X509ToX(cert); // this only wraps cert, but we need to make a copy
5683 				if (!CompareX(tmpX, clientcert->X))
5684 				{
5685 					X *copyX = CloneX(tmpX);
5686 					if (clientcert->X != NULL)
5687 					{
5688 						FreeX(clientcert->X);
5689 					}
5690 					clientcert->X = copyX;
5691 				}
5692 				tmpX->do_not_free = true; // do not release inner X509 object
5693 				FreeX(tmpX);
5694 			}
5695 		}
5696 	}
5697 
5698 	return 1; /* allow the verification process to continue */
5699 }
5700 
5701 // Create a new SSL pipe
NewSslPipe(bool server_mode,X * x,K * k,DH_CTX * dh)5702 SSL_PIPE *NewSslPipe(bool server_mode, X *x, K *k, DH_CTX *dh)
5703 {
5704 	return NewSslPipeEx(server_mode, x, k, dh, false, NULL);
5705 }
5706 
5707 // 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)5708 SSL_PIPE *NewSslPipeEx(bool server_mode, X *x, K *k, DH_CTX *dh, bool verify_peer, struct SslClientCertInfo *clientcert)
5709 {
5710 	SSL_PIPE *s;
5711 	SSL *ssl;
5712 	SSL_CTX *ssl_ctx = NewSSLCtx(server_mode);
5713 
5714 	Lock(openssl_lock);
5715 	{
5716 		if (server_mode)
5717 		{
5718 #ifdef SSL_OP_NO_TLSv1_3
5719 			SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TLSv1_3); // For some reason pppd under linux doesn't like it
5720 #endif
5721 
5722 			AddChainSslCertOnDirectory(ssl_ctx);
5723 
5724 			if (dh != NULL)
5725 			{
5726 				SSL_CTX_set_tmp_dh(ssl_ctx, dh->dh);
5727 			}
5728 
5729 #if 0
5730 			// Cannot get config
5731 #ifdef SSL_SECOP_VERSION
5732 			if (sock->SslAcceptSettings.Override_Security_Level)
5733 			{
5734 				SSL_CTX_set_security_level(ssl_ctx, sock->SslAcceptSettings.Override_Security_Level_Value);
5735 			}
5736 #endif
5737 #endif
5738 		}
5739 
5740 		if (verify_peer)
5741 		{
5742 			SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, SslCertVerifyCallback);
5743 		}
5744 
5745 		if (dh != NULL)
5746 		{
5747 			SSL_CTX_set_options(ssl_ctx, SSL_OP_SINGLE_DH_USE);
5748 		}
5749 
5750 		if (server_mode == false)
5751 		{
5752 			SSL_CTX_set_options(ssl_ctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
5753 		}
5754 
5755 		ssl = SSL_new(ssl_ctx);
5756 
5757 		SSL_set_ex_data(ssl, GetSslClientCertIndex(), clientcert);
5758 	}
5759 	Unlock(openssl_lock);
5760 
5761 	s = ZeroMalloc(sizeof(SSL_PIPE));
5762 
5763 	s->ssl = ssl;
5764 	s->ssl_ctx = ssl_ctx;
5765 	s->ServerMode = server_mode;
5766 
5767 	s->SslInOut = NewSslBioSsl();
5768 	s->RawIn = NewSslBioMem();
5769 	s->RawOut = NewSslBioMem();
5770 
5771 	if (x != NULL && k != NULL)
5772 	{
5773 		Lock(openssl_lock);
5774 		{
5775 			SSL_use_certificate(s->ssl, x->x509);
5776 			SSL_use_PrivateKey(s->ssl, k->pkey);
5777 		}
5778 		Unlock(openssl_lock);
5779 	}
5780 
5781 	if (s->ServerMode == false)
5782 	{
5783 		SSL_set_connect_state(s->ssl);
5784 	}
5785 	else
5786 	{
5787 		SSL_set_accept_state(s->ssl);
5788 	}
5789 
5790 	SSL_set_bio(s->ssl, s->RawIn->bio, s->RawOut->bio);
5791 	BIO_set_ssl(s->SslInOut->bio, s->ssl, BIO_NOCLOSE);
5792 
5793 	//s->RawIn->NoFree = true;
5794 	s->RawOut->NoFree = true;
5795 
5796 	return s;
5797 }
5798 
5799 // Synchronization of the SSL pipe
SyncSslPipe(SSL_PIPE * s)5800 bool SyncSslPipe(SSL_PIPE *s)
5801 {
5802 	UINT i;
5803 	// Validate arguments
5804 	if (s == NULL || s->IsDisconnected)
5805 	{
5806 		return false;
5807 	}
5808 
5809 	for (i = 0; i < 2; i++)
5810 	{
5811 		if (SslBioSync(s->RawIn, true, false) == false)
5812 		{
5813 			s->IsDisconnected = true;
5814 			Debug("SyncSslPipe: s->RawIn error.\n");
5815 			return false;
5816 		}
5817 
5818 		if (SslBioSync(s->RawOut, false, true) == false)
5819 		{
5820 			s->IsDisconnected = true;
5821 			Debug("SyncSslPipe: s->RawOut error.\n");
5822 			return false;
5823 		}
5824 
5825 		if (SslBioSync(s->SslInOut, true, true) == false)
5826 		{
5827 			s->IsDisconnected = true;
5828 			Debug("SyncSslPipe: s->SslInOut error.\n");
5829 			return false;
5830 		}
5831 	}
5832 
5833 	return true;
5834 }
5835 
5836 // Release of the SSL pipe
FreeSslPipe(SSL_PIPE * s)5837 void FreeSslPipe(SSL_PIPE *s)
5838 {
5839 	// Validate arguments
5840 	if (s == NULL)
5841 	{
5842 		return;
5843 	}
5844 
5845 	FreeSslBio(s->SslInOut);
5846 	FreeSslBio(s->RawIn);
5847 	FreeSslBio(s->RawOut);
5848 
5849 	SSL_free(s->ssl);
5850 	SSL_CTX_free(s->ssl_ctx);
5851 
5852 	Free(s);
5853 }
5854 
5855 // Release of the SSL BIO
FreeSslBio(SSL_BIO * b)5856 void FreeSslBio(SSL_BIO *b)
5857 {
5858 	// Validate arguments
5859 	if (b == NULL)
5860 	{
5861 		return;
5862 	}
5863 
5864 	if (b->NoFree == false)
5865 	{
5866 		BIO_free(b->bio);
5867 	}
5868 
5869 	ReleaseFifo(b->RecvFifo);
5870 	ReleaseFifo(b->SendFifo);
5871 
5872 	Free(b);
5873 }
5874 
5875 // Create a new SSL BIO (SSL)
NewSslBioSsl()5876 SSL_BIO *NewSslBioSsl()
5877 {
5878 	SSL_BIO *b = ZeroMalloc(sizeof(SSL_BIO));
5879 
5880 	b->bio = BIO_new(BIO_f_ssl());
5881 
5882 	b->RecvFifo = NewFifo();
5883 	b->SendFifo = NewFifo();
5884 
5885 	return b;
5886 }
5887 
5888 // Create a new SSL BIO (memory)
NewSslBioMem()5889 SSL_BIO *NewSslBioMem()
5890 {
5891 	SSL_BIO *b = ZeroMalloc(sizeof(SSL_BIO));
5892 
5893 	b->bio = BIO_new(BIO_s_mem());
5894 
5895 	b->RecvFifo = NewFifo();
5896 	b->SendFifo = NewFifo();
5897 
5898 	return b;
5899 }
5900 
5901 // Synchronize memory contents of the SSL BIO with the FIFO
SslBioSync(SSL_BIO * b,bool sync_send,bool sync_recv)5902 bool SslBioSync(SSL_BIO *b, bool sync_send, bool sync_recv)
5903 {
5904 	// Validate arguments
5905 	if (b == NULL)
5906 	{
5907 		return false;
5908 	}
5909 
5910 	if (b->IsDisconnected)
5911 	{
5912 		return false;
5913 	}
5914 
5915 	// Write the contents of the SendFifo to the BIO
5916 	if (sync_send)
5917 	{
5918 		while (b->SendFifo->size >= 1)
5919 		{
5920 			int r = BIO_write(b->bio, GetFifoPointer(b->SendFifo), FifoSize(b->SendFifo));
5921 
5922 			if (r == 0)
5923 			{
5924 				b->IsDisconnected = true;
5925 				WHERE;
5926 				return false;
5927 			}
5928 			else
5929 			{
5930 				if (r < 0)
5931 				{
5932 					if (BIO_should_retry(b->bio))
5933 					{
5934 						break;
5935 					}
5936 					else
5937 					{
5938 						b->IsDisconnected = true;
5939 						WHERE;
5940 						return false;
5941 					}
5942 				}
5943 				else
5944 				{
5945 					ReadFifo(b->SendFifo, NULL, (UINT)r);
5946 				}
5947 			}
5948 		}
5949 	}
5950 
5951 	// Save to the RecvFifo by reading from the BIO
5952 	if (sync_recv)
5953 	{
5954 		while (true)
5955 		{
5956 			UCHAR tmp[4096];
5957 			int r;
5958 
5959 			r = BIO_read(b->bio, tmp, sizeof(tmp));
5960 
5961 			if (r == 0)
5962 			{
5963 				b->IsDisconnected = true;
5964 				WHERE;
5965 				return false;
5966 			}
5967 			else
5968 			{
5969 				if (r < 0)
5970 				{
5971 					if (BIO_should_retry(b->bio))
5972 					{
5973 						break;
5974 					}
5975 					else
5976 					{
5977 						b->IsDisconnected = true;
5978 						WHERE;
5979 						Debug("OpenSSL Error: %s\n", ERR_error_string(ERR_peek_last_error(), NULL));
5980 						return false;
5981 					}
5982 				}
5983 				else
5984 				{
5985 					WriteFifo(b->RecvFifo, tmp, (UINT)r);
5986 				}
5987 			}
5988 		}
5989 	}
5990 
5991 	return true;
5992 }
5993 
5994 // Release the memory for the return value of the ICMP API
IcmpApiFreeResult(ICMP_RESULT * ret)5995 void IcmpApiFreeResult(ICMP_RESULT *ret)
5996 {
5997 	// Validate arguments
5998 	if (ret == NULL)
5999 	{
6000 		return;
6001 	}
6002 
6003 	if (ret->Data != NULL)
6004 	{
6005 		Free(ret->Data);
6006 	}
6007 
6008 	Free(ret);
6009 }
6010 
6011 // Send an ICMP Echo using ICMP API
IcmpApiEchoSend(IP * dest_ip,UCHAR ttl,UCHAR * data,UINT size,UINT timeout)6012 ICMP_RESULT *IcmpApiEchoSend(IP *dest_ip, UCHAR ttl, UCHAR *data, UINT size, UINT timeout)
6013 {
6014 #ifdef OS_WIN32
6015 	// Validate arguments
6016 	if (dest_ip == NULL || IsIP4(dest_ip) == false || (size != 0 && data == NULL))
6017 	{
6018 		return NULL;
6019 	}
6020 	if (ttl == 0)
6021 	{
6022 		ttl = 127;
6023 	}
6024 
6025 	if (true)
6026 	{
6027 		HANDLE h;
6028 		DWORD dw;
6029 		IPAddr dest_addr;
6030 		UINT reply_size;
6031 		ICMP_ECHO_REPLY *reply;
6032 		ICMP_RESULT *ret = NULL;
6033 		IP_OPTION_INFORMATION opt;
6034 
6035 		h = IcmpCreateFile();
6036 
6037 		if (h == INVALID_HANDLE_VALUE)
6038 		{
6039 			return NULL;
6040 		}
6041 
6042 		Zero(&opt, sizeof(opt));
6043 		opt.Ttl = ttl;
6044 
6045 		IPToInAddr((struct in_addr *)&dest_addr, dest_ip);
6046 
6047 		reply_size = sizeof(*reply) + size + 64;
6048 		reply = ZeroMalloc(reply_size);
6049 
6050 		dw = IcmpSendEcho(h, dest_addr, data, size, &opt, reply, reply_size, timeout);
6051 
6052 		ret = ZeroMalloc(sizeof(ICMP_RESULT));
6053 
6054 		if (dw >= 1 && reply->Status == IP_SUCCESS)
6055 		{
6056 			ret->Ok = true;
6057 		}
6058 		else
6059 		{
6060 			switch (reply->Status)
6061 			{
6062 			case IP_DEST_NET_UNREACHABLE:
6063 				ret->Type = ICMP_TYPE_DESTINATION_UNREACHABLE;
6064 				ret->Code = ICMP_CODE_NET_UNREACHABLE;
6065 				break;
6066 
6067 			case IP_DEST_HOST_UNREACHABLE:
6068 				ret->Type = ICMP_TYPE_DESTINATION_UNREACHABLE;
6069 				ret->Code = ICMP_CODE_HOST_UNREACHABLE;
6070 				break;
6071 
6072 			case IP_DEST_PROT_UNREACHABLE:
6073 				ret->Type = ICMP_TYPE_DESTINATION_UNREACHABLE;
6074 				ret->Code = ICMP_CODE_PROTOCOL_UNREACHABLE;
6075 				break;
6076 
6077 			case IP_DEST_PORT_UNREACHABLE:
6078 				ret->Type = ICMP_TYPE_DESTINATION_UNREACHABLE;
6079 				ret->Code = ICMP_CODE_PORT_UNREACHABLE;
6080 				break;
6081 
6082 			case IP_TTL_EXPIRED_TRANSIT:
6083 				ret->Type = ICMP_TYPE_TIME_EXCEEDED;
6084 				ret->Code = ICMP_CODE_TTL_EXCEEDED_IN_TRANSIT;
6085 				break;
6086 
6087 			case IP_TTL_EXPIRED_REASSEM:
6088 				ret->Type = ICMP_TYPE_TIME_EXCEEDED;
6089 				ret->Code = ICMP_CODE_FRAGMENT_REASSEMBLY_TIME_EXCEEDED;
6090 				break;
6091 
6092 			default:
6093 				ret->Timeout = true;
6094 				break;
6095 			}
6096 		}
6097 
6098 		if (ret->Timeout == false)
6099 		{
6100 			ret->Ttl = reply->Options.Ttl;
6101 			ret->Rtt = reply->RoundTripTime;
6102 			InAddrToIP(&ret->IpAddress, (struct in_addr *)&reply->Address);
6103 
6104 			if (reply->DataSize >= 1 && reply->Data != NULL)
6105 			{
6106 				ret->DataSize = reply->DataSize;
6107 				ret->Data = Clone(reply->Data, reply->DataSize);
6108 			}
6109 		}
6110 
6111 		Free(reply);
6112 
6113 		IcmpCloseHandle(h);
6114 
6115 		return ret;
6116 	}
6117 	else
6118 	{
6119 		return NULL;
6120 	}
6121 
6122 #else	// OS_WIN32
6123 	return NULL;
6124 #endif	// OS_WIN32
6125 }
6126 
6127 // Initialize the routing table change detector
NewRouteChange()6128 ROUTE_CHANGE *NewRouteChange()
6129 {
6130 #ifdef	OS_WIN32
6131 	return Win32NewRouteChange();
6132 #else	// OS_WIN32
6133 	return NULL;
6134 #endif	// OS_WIN32
6135 }
6136 
6137 // Release the routing table change detector
FreeRouteChange(ROUTE_CHANGE * r)6138 void FreeRouteChange(ROUTE_CHANGE *r)
6139 {
6140 #ifdef	OS_WIN32
6141 	Win32FreeRouteChange(r);
6142 #endif	// OS_WIN32
6143 }
6144 
6145 // Get whether the routing table has been changed
IsRouteChanged(ROUTE_CHANGE * r)6146 bool IsRouteChanged(ROUTE_CHANGE *r)
6147 {
6148 #ifdef	OS_WIN32
6149 	return Win32IsRouteChanged(r);
6150 #else	// OS_WIN32
6151 	return false;
6152 #endif	// OS_WIN32
6153 }
6154 
6155 // Routing table change detector function (Win32)
6156 #ifdef	OS_WIN32
Win32NewRouteChange()6157 ROUTE_CHANGE *Win32NewRouteChange()
6158 {
6159 	ROUTE_CHANGE *r;
6160 	BOOL ret;
6161 
6162 	r = ZeroMalloc(sizeof(ROUTE_CHANGE));
6163 
6164 	r->Data = ZeroMalloc(sizeof(ROUTE_CHANGE_DATA));
6165 
6166 	r->Data->Overlapped.hEvent = CreateEventA(NULL, false, true, NULL);
6167 
6168 	ret = NotifyRouteChange(&r->Data->Handle, &r->Data->Overlapped);
6169 	if (!(ret == NO_ERROR || ret == WSA_IO_PENDING || WSAGetLastError() == WSA_IO_PENDING))
6170 	{
6171 		Free(r->Data);
6172 		Free(r);
6173 
6174 		return NULL;
6175 	}
6176 
6177 	return r;
6178 }
6179 
Win32FreeRouteChange(ROUTE_CHANGE * r)6180 void Win32FreeRouteChange(ROUTE_CHANGE *r)
6181 {
6182 	// Validate arguments
6183 	if (r == NULL)
6184 	{
6185 		return;
6186 	}
6187 
6188 	CancelIPChangeNotify(&r->Data->Overlapped);
6189 	CloseHandle(r->Data->Overlapped.hEvent);
6190 
6191 	Free(r->Data);
6192 	Free(r);
6193 }
6194 
Win32IsRouteChanged(ROUTE_CHANGE * r)6195 bool Win32IsRouteChanged(ROUTE_CHANGE *r)
6196 {
6197 	// Validate arguments
6198 	if (r == NULL)
6199 	{
6200 		return false;
6201 	}
6202 
6203 	if ((r->Data->NumCalled++) == 0)
6204 	{
6205 		return true;
6206 	}
6207 
6208 	if (WaitForSingleObject(r->Data->Overlapped.hEvent, 0) == WAIT_OBJECT_0)
6209 	{
6210 		NotifyRouteChange(&r->Data->Handle, &r->Data->Overlapped);
6211 		return true;
6212 	}
6213 
6214 	return false;
6215 }
6216 
6217 typedef struct WIN32_ACCEPT_CHECK_DATA
6218 {
6219 	bool IsIPv6;
6220 	bool Rejected;
6221 } WIN32_ACCEPT_CHECK_DATA;
6222 
Win32AcceptCheckCallback(LPWSABUF lpCallerId,LPWSABUF lpCallerData,LPQOS pQos,LPQOS lpGQOS,LPWSABUF lpCalleeId,LPWSABUF lpCalleeData,GROUP FAR * g,DWORD_PTR dwCallbackData)6223 int CALLBACK Win32AcceptCheckCallback(LPWSABUF lpCallerId, LPWSABUF lpCallerData, LPQOS pQos,
6224                                       LPQOS lpGQOS, LPWSABUF lpCalleeId, LPWSABUF lpCalleeData,
6225                                       GROUP FAR *g, DWORD_PTR dwCallbackData)
6226 {
6227 	return CF_ACCEPT;
6228 }
6229 
6230 // Accept function for Win32
Win32Accept(SOCK * sock,SOCKET s,struct sockaddr * addr,int * addrlen,bool ipv6)6231 SOCKET Win32Accept(SOCK *sock, SOCKET s, struct sockaddr *addr, int *addrlen, bool ipv6)
6232 {
6233 	SOCKET ret;
6234 	WIN32_ACCEPT_CHECK_DATA d;
6235 	UINT err;
6236 	int initial_addrlen = *addrlen;
6237 	UINT num_error = 0;
6238 	UINT zero = 0;
6239 	UINT tmp = 0;
6240 	DWORD ret_size = 0;
6241 	// Validate arguments
6242 	if (sock == NULL || s == INVALID_SOCKET)
6243 	{
6244 		return INVALID_SOCKET;
6245 	}
6246 
6247 	if (sock->hAcceptEvent == NULL)
6248 	{
6249 		sock->hAcceptEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
6250 
6251 		WSAEventSelect(s, sock->hAcceptEvent, FD_ACCEPT | FD_CLOSE);
6252 	}
6253 
6254 L_LOOP:
6255 
6256 	if (sock->CancelAccept)
6257 	{
6258 		return INVALID_SOCKET;
6259 	}
6260 
6261 	Zero(&d, sizeof(d));
6262 
6263 	d.IsIPv6 = ipv6;
6264 
6265 	*addrlen = initial_addrlen;
6266 	Zero(addr, initial_addrlen);
6267 	ret = WSAAccept(s, addr, addrlen, Win32AcceptCheckCallback, (DWORD_PTR)&d);
6268 
6269 	if (ret == INVALID_SOCKET)
6270 	{
6271 		err = WSAGetLastError();
6272 
6273 		if (err == WSAEWOULDBLOCK)
6274 		{
6275 			//Debug("!!! WSAAccept: WSAEWOULDBLOCK\n");
6276 			UINT wait_ret = WaitForSingleObject(sock->hAcceptEvent, 1234);
6277 
6278 			if (wait_ret == WAIT_OBJECT_0 || wait_ret == WAIT_TIMEOUT)
6279 			{
6280 				goto L_LOOP;
6281 			}
6282 
6283 			Debug("!!! WaitForSingleObject Error. ret=%u GetLastError=%u\n", wait_ret, GetLastError());
6284 		}
6285 
6286 		num_error++;
6287 
6288 		Debug("!!! WSAAccept Error: %u  rej=%u  num=%u  tick=%I64u\n", err, d.Rejected, num_error, Tick64());
6289 
6290 		if (d.Rejected && err == WSAECONNREFUSED)
6291 		{
6292 			goto L_LOOP;
6293 		}
6294 
6295 		if (err == WSAETIMEDOUT)
6296 		{
6297 			goto L_LOOP;
6298 		}
6299 	}
6300 	else
6301 	{
6302 		// Remove a new socket from the event
6303 		WSAEventSelect(ret, sock->hAcceptEvent, 0);
6304 
6305 		// Restore the new socket to synchronized
6306 		WSAIoctl(ret, FIONBIO, &zero, sizeof(zero), &tmp, sizeof(tmp), &ret_size, NULL, NULL);
6307 	}
6308 
6309 	return ret;
6310 }
6311 
6312 #endif	// OS_WIN32
6313 
6314 #define	USE_OLD_GETIP
6315 
6316 // Set the arp_filter in Linux
SetLinuxArpFilter()6317 void SetLinuxArpFilter()
6318 {
6319 	char *filename = "/proc/sys/net/ipv4/conf/all/arp_filter";
6320 	char *data = "1\n";
6321 	IO *o;
6322 
6323 	o = FileCreate(filename);
6324 	if (o == NULL)
6325 	{
6326 		return;
6327 	}
6328 
6329 	FileWrite(o, data, StrLen(data));
6330 	FileFlush(o);
6331 
6332 	FileClose(o);
6333 }
6334 
6335 // Determine whether the string is a IPv6 mask
IsIpMask6(char * str)6336 bool IsIpMask6(char *str)
6337 {
6338 	IP mask;
6339 	// Validate arguments
6340 	if (str == NULL)
6341 	{
6342 		return false;
6343 	}
6344 
6345 	return StrToMask6(&mask, str);
6346 }
6347 
6348 // Determine whether the string is a IPv6 address
IsStrIPv6Address(char * str)6349 bool IsStrIPv6Address(char *str)
6350 {
6351 	IP ip;
6352 	// Validate arguments
6353 	if (str == NULL)
6354 	{
6355 		return false;
6356 	}
6357 
6358 	if (StrToIP6(&ip, str) == false)
6359 	{
6360 		return false;
6361 	}
6362 
6363 	return true;
6364 }
6365 
6366 // Convert the subnet mask to an integer
SubnetMaskToInt6(IP * a)6367 UINT SubnetMaskToInt6(IP *a)
6368 {
6369 	UINT i;
6370 	// Validate arguments
6371 	if (IsIP6(a) == false)
6372 	{
6373 		return 0;
6374 	}
6375 
6376 	for (i = 0; i <= 128; i++)
6377 	{
6378 		IP tmp;
6379 
6380 		IntToSubnetMask6(&tmp, i);
6381 
6382 		if (CmpIpAddr(a, &tmp) == 0)
6383 		{
6384 			return i;
6385 		}
6386 	}
6387 
6388 	return 0;
6389 }
SubnetMaskToInt4(IP * a)6390 UINT SubnetMaskToInt4(IP *a)
6391 {
6392 	UINT i;
6393 	// Validate arguments
6394 	if (IsIP4(a) == false)
6395 	{
6396 		return 0;
6397 	}
6398 
6399 	for (i = 0; i <= 32; i++)
6400 	{
6401 		IP tmp;
6402 
6403 		IntToSubnetMask4(&tmp, i);
6404 
6405 		if (CmpIpAddr(a, &tmp) == 0)
6406 		{
6407 			return i;
6408 		}
6409 	}
6410 
6411 	return 0;
6412 }
SubnetMaskToInt(IP * a)6413 UINT SubnetMaskToInt(IP *a)
6414 {
6415 	if (IsIP6(a))
6416 	{
6417 		return SubnetMaskToInt6(a);
6418 	}
6419 	else
6420 	{
6421 		return SubnetMaskToInt4(a);
6422 	}
6423 }
6424 
6425 // Determine whether the specified IP address is a subnet mask
IsSubnetMask6(IP * a)6426 bool IsSubnetMask6(IP *a)
6427 {
6428 	UINT i;
6429 	// Validate arguments
6430 	if (IsIP6(a) == false)
6431 	{
6432 		return false;
6433 	}
6434 
6435 	for (i = 0; i <= 128; i++)
6436 	{
6437 		IP tmp;
6438 
6439 		IntToSubnetMask6(&tmp, i);
6440 
6441 		if (CmpIpAddr(a, &tmp) == 0)
6442 		{
6443 			return true;
6444 		}
6445 	}
6446 
6447 	return false;
6448 }
6449 
6450 // Generate a local address from the MAC address
GenerateEui64LocalAddress(IP * a,UCHAR * mac)6451 void GenerateEui64LocalAddress(IP *a, UCHAR *mac)
6452 {
6453 	// Validate arguments
6454 	if (a == NULL || mac == NULL)
6455 	{
6456 		return;
6457 	}
6458 
6459 	Zero(a, sizeof(IP));
6460 
6461 	UCHAR tmp[8];
6462 	GenerateEui64Address6(tmp, mac);
6463 
6464 	a->address[0] = 0xfe;
6465 	a->address[1] = 0x80;
6466 
6467 	Copy(&a->address[8], tmp, sizeof(tmp));
6468 }
6469 
6470 // Generate the EUI-64 address from the MAC address
GenerateEui64Address6(UCHAR * dst,UCHAR * mac)6471 void GenerateEui64Address6(UCHAR *dst, UCHAR *mac)
6472 {
6473 	// Validate arguments
6474 	if (dst == NULL || mac == NULL)
6475 	{
6476 		return;
6477 	}
6478 
6479 	Copy(dst, mac, 3);
6480 	Copy(dst + 5, mac, 3);
6481 
6482 	dst[3] = 0xff;
6483 	dst[4] = 0xfe;
6484 	dst[0] = ((~(dst[0] & 0x02)) & 0x02) | (dst[0] & 0xfd);
6485 }
6486 
6487 // Examine whether two IP addresses are in the same network
IsInSameNetwork6ByStr(char * ip1,char * ip2,char * subnet)6488 bool IsInSameNetwork6ByStr(char *ip1, char *ip2, char *subnet)
6489 {
6490 	IP p1, p2, s;
6491 
6492 	if (StrToIP6(&p1, ip1) == false)
6493 	{
6494 		return false;
6495 	}
6496 
6497 	if (StrToIP6(&p2, ip2) == false)
6498 	{
6499 		return false;
6500 	}
6501 
6502 	if (StrToMask6(&s, subnet) == false)
6503 	{
6504 		return false;
6505 	}
6506 
6507 	return IsInSameNetwork6(&p1, &p2, &s);
6508 }
IsInSameNetwork6(IP * a1,IP * a2,IP * subnet)6509 bool IsInSameNetwork6(IP *a1, IP *a2, IP *subnet)
6510 {
6511 	IP prefix1, prefix2;
6512 	// Validate arguments
6513 	if (IsIP6(a1) == false || IsIP6(a2) == false || IsIP6(subnet) == false)
6514 	{
6515 		return false;
6516 	}
6517 
6518 	if (a1->ipv6_scope_id != a2->ipv6_scope_id)
6519 	{
6520 		return false;
6521 	}
6522 
6523 	GetPrefixAddress6(&prefix1, a1, subnet);
6524 	GetPrefixAddress6(&prefix2, a2, subnet);
6525 
6526 	if (CmpIpAddr(&prefix1, &prefix2) == 0)
6527 	{
6528 		return true;
6529 	}
6530 
6531 	return false;
6532 }
IsInSameNetwork4(IP * a1,IP * a2,IP * subnet)6533 bool IsInSameNetwork4(IP *a1, IP *a2, IP *subnet)
6534 {
6535 	IP net1, net2;
6536 	// Validate arguments
6537 	if (IsIP4(a1) == false || IsIP4(a2) == false || IsIP4(subnet) == false)
6538 	{
6539 		return false;
6540 	}
6541 
6542 	IPAnd4(&net1, a1, subnet);
6543 	IPAnd4(&net2, a2, subnet);
6544 
6545 	if (CmpIpAddr(&net1, &net2) == 0)
6546 	{
6547 		return true;
6548 	}
6549 
6550 	return false;
6551 }
IsInSameNetwork4Standard(IP * a1,IP * a2)6552 bool IsInSameNetwork4Standard(IP *a1, IP *a2)
6553 {
6554 	IP subnet;
6555 
6556 	SetIP(&subnet, 255, 255, 0, 0);
6557 
6558 	return IsInSameNetwork4(a1, a2, &subnet);
6559 }
6560 
6561 // Get the prefix address
GetPrefixAddress6(IP * dst,IP * ip,IP * subnet)6562 void GetPrefixAddress6(IP *dst, IP *ip, IP *subnet)
6563 {
6564 	// Validate arguments
6565 	if (dst == NULL || ip == NULL || subnet == NULL)
6566 	{
6567 		return;
6568 	}
6569 
6570 	IPAnd6(dst, ip, subnet);
6571 
6572 	dst->ipv6_scope_id = ip->ipv6_scope_id;
6573 }
6574 
6575 // Get the type of the IPv6 address
GetIPv6AddrType(IPV6_ADDR * addr)6576 UINT GetIPv6AddrType(IPV6_ADDR *addr)
6577 {
6578 	IP ip;
6579 	// Validate arguments
6580 	if (addr == NULL)
6581 	{
6582 		return 0;
6583 	}
6584 
6585 	IPv6AddrToIP(&ip, addr);
6586 
6587 	return GetIPAddrType6(&ip);
6588 }
GetIPAddrType6(IP * ip)6589 UINT GetIPAddrType6(IP *ip)
6590 {
6591 	UINT ret = 0;
6592 	// Validate arguments
6593 	if (IsIP6(ip) == false)
6594 	{
6595 		return 0;
6596 	}
6597 
6598 	if (ip->address[0] == 0xff)
6599 	{
6600 		IP all_node, all_router;
6601 
6602 		GetAllNodeMulticaseAddress6(&all_node);
6603 
6604 		GetAllRouterMulticastAddress6(&all_router);
6605 
6606 		ret |= IPV6_ADDR_MULTICAST;
6607 
6608 		if (CmpIpAddr(ip, &all_node) == 0)
6609 		{
6610 			ret |= IPV6_ADDR_ALL_NODE_MULTICAST;
6611 		}
6612 		else if (CmpIpAddr(ip, &all_router) == 0)
6613 		{
6614 			ret |= IPV6_ADDR_ALL_ROUTER_MULTICAST;
6615 		}
6616 		else
6617 		{
6618 			if (ip->address[1] == 0x02 && ip->address[2] == 0 && ip->address[3] == 0 &&
6619 			        ip->address[4] == 0 && ip->address[5] == 0 && ip->address[6] == 0 &&
6620 			        ip->address[7] == 0 && ip->address[8] == 0 && ip->address[9] == 0 &&
6621 			        ip->address[10] == 0 && ip->address[11] == 0x01 && ip->address[12] == 0xff)
6622 			{
6623 				ret |= IPV6_ADDR_SOLICIATION_MULTICAST;
6624 			}
6625 		}
6626 	}
6627 	else
6628 	{
6629 		ret |= IPV6_ADDR_UNICAST;
6630 
6631 		if (ip->address[0] == 0xfe && (ip->address[1] & 0xc0) == 0x80)
6632 		{
6633 			ret |= IPV6_ADDR_LOCAL_UNICAST;
6634 		}
6635 		else
6636 		{
6637 			ret |= IPV6_ADDR_GLOBAL_UNICAST;
6638 
6639 			if (IsZero(&ip->address, sizeof(ip->address)))
6640 			{
6641 				ret |= IPV6_ADDR_ZERO;
6642 			}
6643 			else
6644 			{
6645 				IP loopback;
6646 
6647 				GetLoopbackAddress6(&loopback);
6648 
6649 				if (Cmp(ip->address, loopback.address, sizeof(ip->address)) == 0)
6650 				{
6651 					ret |= IPV6_ADDR_LOOPBACK;
6652 				}
6653 			}
6654 		}
6655 	}
6656 
6657 	return ret;
6658 }
6659 
6660 // Loopback address
GetLoopbackAddress6(IP * ip)6661 void GetLoopbackAddress6(IP *ip)
6662 {
6663 	// Validate arguments
6664 	if (ip == NULL)
6665 	{
6666 		return;
6667 	}
6668 
6669 	Zero(ip, sizeof(IP));
6670 
6671 	ip->address[15] = 0x01;
6672 }
6673 
6674 // All-nodes multicast address
GetAllNodeMulticaseAddress6(IP * ip)6675 void GetAllNodeMulticaseAddress6(IP *ip)
6676 {
6677 	// Validate arguments
6678 	if (ip == NULL)
6679 	{
6680 		return;
6681 	}
6682 
6683 	Zero(ip, sizeof(IP));
6684 
6685 	ip->address[0] = 0xff;
6686 	ip->address[1] = 0x02;
6687 	ip->address[15] = 0x01;
6688 }
6689 
6690 // All-routers multicast address
GetAllRouterMulticastAddress6(IP * ip)6691 void GetAllRouterMulticastAddress6(IP *ip)
6692 {
6693 	// Validate arguments
6694 	if (ip == NULL)
6695 	{
6696 		return;
6697 	}
6698 
6699 	Zero(ip, sizeof(IP));
6700 
6701 	ip->address[0] = 0xff;
6702 	ip->address[1] = 0x02;
6703 	ip->address[15] = 0x02;
6704 }
6705 
6706 // Logical operation of the IPv4 address
IPAnd4(IP * dst,IP * a,IP * b)6707 void IPAnd4(IP *dst, IP *a, IP *b)
6708 {
6709 	// Validate arguments
6710 	if (dst == NULL || a == NULL || b == NULL || IsIP4(a) == false || IsIP4(b) == false)
6711 	{
6712 		ZeroIP4(dst);
6713 		return;
6714 	}
6715 
6716 	UINTToIP(dst, IPToUINT(a) & IPToUINT(b));
6717 }
6718 
6719 // Logical operation of the IPv6 address
IPAnd6(IP * dst,IP * a,IP * b)6720 void IPAnd6(IP *dst, IP *a, IP *b)
6721 {
6722 	Zero(dst, sizeof(IP));
6723 
6724 	// Validate arguments
6725 	if (dst == NULL || IsIP6(a) == false || IsIP6(b) == false)
6726 	{
6727 		return;
6728 	}
6729 
6730 	for (BYTE i = 0; i < sizeof(dst->address); ++i)
6731 	{
6732 		dst->address[i] = a->address[i] & b->address[i];
6733 	}
6734 }
6735 
6736 // Creating a subnet mask
IntToSubnetMask6(IP * ip,UINT i)6737 void IntToSubnetMask6(IP *ip, UINT i)
6738 {
6739 	UINT j = i / 8;
6740 	UINT k = i % 8;
6741 	UINT z;
6742 	IP a;
6743 
6744 	Zero(&a, sizeof(IP));
6745 
6746 	for (z = 0; z < sizeof(a.address); ++z)
6747 	{
6748 		if (z < j)
6749 		{
6750 			a.address[z] = 0xff;
6751 		}
6752 		else if (z == j)
6753 		{
6754 			a.address[z] = ~(0xff >> k);
6755 		}
6756 	}
6757 
6758 	Copy(ip, &a, sizeof(IP));
6759 }
6760 
6761 // Convert the IP address to a string
IP6AddrToStr(char * str,UINT size,IPV6_ADDR * addr)6762 void IP6AddrToStr(char *str, UINT size, IPV6_ADDR *addr)
6763 {
6764 	// Validate arguments
6765 	if (str == NULL || addr == NULL)
6766 	{
6767 		return;
6768 	}
6769 
6770 	IPToStr6Array(str, size, addr->Value);
6771 }
IPToStr6Array(char * str,UINT size,UCHAR * bytes)6772 void IPToStr6Array(char *str, UINT size, UCHAR *bytes)
6773 {
6774 	IP ip;
6775 	// Validate arguments
6776 	if (str == NULL || bytes == NULL)
6777 	{
6778 		return;
6779 	}
6780 
6781 	SetIP6(&ip, bytes);
6782 
6783 	IPToStr6(str, size, &ip);
6784 }
IPToStr6(char * str,UINT size,IP * ip)6785 void IPToStr6(char *str, UINT size, IP *ip)
6786 {
6787 	char tmp[MAX_SIZE];
6788 
6789 	IPToStr6Inner(tmp, ip);
6790 
6791 	StrCpy(str, size, tmp);
6792 }
IPToStr6Inner(char * str,IP * ip)6793 void IPToStr6Inner(char *str, IP *ip)
6794 {
6795 	UINT i;
6796 	USHORT values[8];
6797 	UINT zero_started_index;
6798 	UINT max_zero_len;
6799 	UINT max_zero_start;
6800 	IP a;
6801 	// Validate arguments
6802 	if (str == NULL || ip == NULL)
6803 	{
6804 		return;
6805 	}
6806 
6807 	Copy(&a, ip, sizeof(IP));
6808 
6809 	for (i = 0; i < 8; i++)
6810 	{
6811 		Copy(&values[i], &a.address[i * 2], sizeof(USHORT));
6812 		values[i] = Endian16(values[i]);
6813 	}
6814 
6815 	// Search for omittable part
6816 	zero_started_index = INFINITE;
6817 	max_zero_len = 0;
6818 	max_zero_start = INFINITE;
6819 	for (i = 0; i < 9; i++)
6820 	{
6821 		USHORT v = (i != 8 ? values[i] : 1);
6822 
6823 		if (v == 0)
6824 		{
6825 			if (zero_started_index == INFINITE)
6826 			{
6827 				zero_started_index = i;
6828 			}
6829 		}
6830 		else
6831 		{
6832 			UINT zero_len;
6833 
6834 			if (zero_started_index != INFINITE)
6835 			{
6836 				zero_len = i - zero_started_index;
6837 				if (zero_len >= 2)
6838 				{
6839 					if (max_zero_len < zero_len)
6840 					{
6841 						max_zero_start = zero_started_index;
6842 						max_zero_len = zero_len;
6843 					}
6844 				}
6845 
6846 				zero_started_index = INFINITE;
6847 			}
6848 		}
6849 	}
6850 
6851 	// Format a string
6852 	StrCpy(str, 0, "");
6853 	for (i = 0; i < 8; i++)
6854 	{
6855 		char tmp[16];
6856 
6857 		ToHex(tmp, values[i]);
6858 		StrLower(tmp);
6859 
6860 		if (i == max_zero_start)
6861 		{
6862 			if (i == 0)
6863 			{
6864 				StrCat(str, 0, "::");
6865 			}
6866 			else
6867 			{
6868 				StrCat(str, 0, ":");
6869 			}
6870 			i += max_zero_len - 1;
6871 		}
6872 		else
6873 		{
6874 			StrCat(str, 0, tmp);
6875 			if (i != 7)
6876 			{
6877 				StrCat(str, 0, ":");
6878 			}
6879 		}
6880 	}
6881 
6882 	// Scope ID
6883 	if (ip->ipv6_scope_id != 0)
6884 	{
6885 		char tmp[64];
6886 
6887 		StrCat(str, 0, "%");
6888 		ToStr(tmp, ip->ipv6_scope_id);
6889 
6890 		StrCat(str, 0, tmp);
6891 	}
6892 }
6893 
6894 // Convert the string to an IP address
StrToIP6(IP * ip,char * str)6895 bool StrToIP6(IP *ip, char *str)
6896 {
6897 	TOKEN_LIST *t;
6898 	char tmp[MAX_PATH];
6899 	IP a;
6900 	UINT i;
6901 	UINT scope_id = 0;
6902 	// Validate arguments
6903 	if (str == NULL || ip == NULL)
6904 	{
6905 		return false;
6906 	}
6907 
6908 	Zero(&a, sizeof(a));
6909 
6910 	StrCpy(tmp, sizeof(tmp), str);
6911 	Trim(tmp);
6912 
6913 	if (StartWith(tmp, "[") && EndWith(tmp, "]"))
6914 	{
6915 		// If the string is enclosed in square brackets, remove brackets
6916 		StrCpyAllowOverlap(tmp, sizeof(tmp), &tmp[1]);
6917 
6918 		if (StrLen(tmp) >= 1)
6919 		{
6920 			tmp[StrLen(tmp) - 1] = 0;
6921 		}
6922 	}
6923 
6924 	// Remove the scope ID by analyzing if there is it
6925 	i = SearchStrEx(tmp, "%", 0, false);
6926 	if (i != INFINITE)
6927 	{
6928 		char ss[MAX_PATH];
6929 
6930 		StrCpy(ss, sizeof(ss), &tmp[i + 1]);
6931 
6932 		tmp[i] = 0;
6933 
6934 		Trim(tmp);
6935 
6936 		Trim(ss);
6937 
6938 		scope_id = ToInt(ss);
6939 	}
6940 
6941 	// Tokenize
6942 	t = ParseTokenWithNullStr(tmp, ":");
6943 	if (t->NumTokens >= 3 && t->NumTokens <= 8)
6944 	{
6945 		UINT i, n;
6946 		bool b = true;
6947 		UINT k = 0;
6948 
6949 		n = 0;
6950 
6951 		for (i = 0; i < t->NumTokens; i++)
6952 		{
6953 			char *str = t->Token[i];
6954 
6955 			if (i != 0 && i != (t->NumTokens - 1) && StrLen(str) == 0)
6956 			{
6957 				n++;
6958 				if (n == 1)
6959 				{
6960 					k += 2 * (8 - t->NumTokens + 1);
6961 				}
6962 				else
6963 				{
6964 					b = false;
6965 					break;
6966 				}
6967 			}
6968 			else
6969 			{
6970 				UCHAR chars[2];
6971 
6972 				if (CheckIPItemStr6(str) == false)
6973 				{
6974 					b = false;
6975 					break;
6976 				}
6977 
6978 				IPItemStrToChars6(chars, str);
6979 
6980 				a.address[k++] = chars[0];
6981 				a.address[k++] = chars[1];
6982 			}
6983 		}
6984 
6985 		if (n != 0 && n != 1)
6986 		{
6987 			b = false;
6988 		}
6989 		else if (n == 0 && t->NumTokens != 8)
6990 		{
6991 			b = false;
6992 		}
6993 
6994 		if (b == false)
6995 		{
6996 			FreeToken(t);
6997 			return false;
6998 		}
6999 	}
7000 	else
7001 	{
7002 		FreeToken(t);
7003 		return false;
7004 	}
7005 
7006 	FreeToken(t);
7007 
7008 	Copy(ip, &a, sizeof(IP));
7009 
7010 	ip->ipv6_scope_id = scope_id;
7011 
7012 	return true;
7013 }
StrToIP6Addr(IPV6_ADDR * ip,char * str)7014 bool StrToIP6Addr(IPV6_ADDR *ip, char *str)
7015 {
7016 	IP ip2;
7017 	// Validate arguments
7018 	if (ip == NULL || str == NULL)
7019 	{
7020 		Zero(ip, sizeof(IPV6_ADDR));
7021 		return false;
7022 	}
7023 
7024 	if (StrToIP6(&ip2, str) == false)
7025 	{
7026 		return false;
7027 	}
7028 
7029 	if (IPToIPv6Addr(ip, &ip2) == false)
7030 	{
7031 		return false;
7032 	}
7033 
7034 	return true;
7035 }
7036 
7037 // Convert an IP address character to the UCHAR type
IPItemStrToChars6(UCHAR * chars,char * str)7038 void IPItemStrToChars6(UCHAR *chars, char *str)
7039 {
7040 	char tmp[5];
7041 	BUF *b;
7042 	UINT len;
7043 	// Validate arguments
7044 	if (chars == NULL)
7045 	{
7046 		return;
7047 	}
7048 
7049 	Zero(tmp, sizeof(tmp));
7050 
7051 	len = StrLen(str);
7052 	switch (len)
7053 	{
7054 	case 0:
7055 		tmp[0] = tmp[1] = tmp[2] = tmp[3] = '0';
7056 		break;
7057 
7058 	case 1:
7059 		tmp[0] = tmp[1] = tmp[2] = '0';
7060 		tmp[3] = str[0];
7061 		break;
7062 
7063 	case 2:
7064 		tmp[0] = tmp[1] = '0';
7065 		tmp[2] = str[0];
7066 		tmp[3] = str[1];
7067 		break;
7068 
7069 	case 3:
7070 		tmp[0] = '0';
7071 		tmp[1] = str[0];
7072 		tmp[2] = str[1];
7073 		tmp[3] = str[2];
7074 		break;
7075 
7076 	case 4:
7077 		tmp[0] = str[0];
7078 		tmp[1] = str[1];
7079 		tmp[2] = str[2];
7080 		tmp[3] = str[3];
7081 		break;
7082 	}
7083 
7084 	b = StrToBin(tmp);
7085 
7086 	chars[0] = ((UCHAR *)b->Buf)[0];
7087 	chars[1] = ((UCHAR *)b->Buf)[1];
7088 
7089 	FreeBuf(b);
7090 }
7091 
7092 // Check whether invalid characters are included in the element string of the IP address
CheckIPItemStr6(char * str)7093 bool CheckIPItemStr6(char *str)
7094 {
7095 	UINT i, len;
7096 	// Validate arguments
7097 	if (str == NULL)
7098 	{
7099 		return false;
7100 	}
7101 
7102 	len = StrLen(str);
7103 	if (len >= 5)
7104 	{
7105 		// Invalid length
7106 		return false;
7107 	}
7108 
7109 	for (i = 0; i < len; i++)
7110 	{
7111 		char c = str[i];
7112 
7113 		if ((c >= 'a' && c <= 'f') ||
7114 		        (c >= 'A' && c <= 'F') ||
7115 		        (c >= '0' && c <= '9'))
7116 		{
7117 		}
7118 		else
7119 		{
7120 			return false;
7121 		}
7122 	}
7123 
7124 	return true;
7125 }
7126 
7127 // Create an IPv4 address of all zero
ZeroIP4(IP * ip)7128 void ZeroIP4(IP *ip)
7129 {
7130 	// Validate arguments
7131 	if (ip == NULL)
7132 	{
7133 		return;
7134 	}
7135 
7136 	Zero(ip, sizeof(IP));
7137 
7138 	ip->address[10] = 0xff;
7139 	ip->address[11] = 0xff;
7140 }
7141 
7142 // Get the IP address of the localhost
GetLocalHostIP6(IP * ip)7143 void GetLocalHostIP6(IP *ip)
7144 {
7145 	// Validate arguments
7146 	if (ip == NULL)
7147 	{
7148 		return;
7149 	}
7150 
7151 	Zero(ip, sizeof(IP));
7152 
7153 	ip->address[15] = 1;
7154 }
GetLocalHostIP4(IP * ip)7155 void GetLocalHostIP4(IP *ip)
7156 {
7157 	// Validate arguments
7158 	if (ip == NULL)
7159 	{
7160 		return;
7161 	}
7162 
7163 	SetIP(ip, 127, 0, 0, 1);
7164 }
7165 
7166 // Check whether the specified address is a localhost
IsLocalHostIP6(IP * ip)7167 bool IsLocalHostIP6(IP *ip)
7168 {
7169 	IP local;
7170 	// Validate arguments
7171 	if (ip == NULL)
7172 	{
7173 		return false;
7174 	}
7175 	if (IsIP6(ip) == false)
7176 	{
7177 		return false;
7178 	}
7179 
7180 	GetLocalHostIP6(&local);
7181 
7182 	if (CmpIpAddr(&local, ip) == 0)
7183 	{
7184 		return true;
7185 	}
7186 
7187 	return false;
7188 }
IsLocalHostIP4(IP * ip)7189 bool IsLocalHostIP4(IP *ip)
7190 {
7191 	// Validate arguments
7192 	if (ip == NULL)
7193 	{
7194 		return false;
7195 	}
7196 	if (IsIP4(ip) == false)
7197 	{
7198 		return false;
7199 	}
7200 
7201 	if (IPV4(ip->address)[0] == 127)
7202 	{
7203 		return true;
7204 	}
7205 
7206 	return false;
7207 }
IsLocalHostIP(IP * ip)7208 bool IsLocalHostIP(IP *ip)
7209 {
7210 	// Validate arguments
7211 	if (ip == NULL)
7212 	{
7213 		return false;
7214 	}
7215 
7216 	if (IsIP4(ip))
7217 	{
7218 		return IsLocalHostIP4(ip);
7219 	}
7220 	else
7221 	{
7222 		return IsLocalHostIP6(ip);
7223 	}
7224 }
7225 
7226 // Convert the IPV6_ADDR to an IP
IPv6AddrToIP(IP * ip,IPV6_ADDR * addr)7227 void IPv6AddrToIP(IP *ip, IPV6_ADDR *addr)
7228 {
7229 	// Validate arguments
7230 	if (ip == NULL || addr == NULL)
7231 	{
7232 		return;
7233 	}
7234 
7235 	SetIP6(ip, addr->Value);
7236 }
7237 
7238 // Convert the IP to an IPV6_ADDR
IPToIPv6Addr(IPV6_ADDR * addr,IP * ip)7239 bool IPToIPv6Addr(IPV6_ADDR *addr, IP *ip)
7240 {
7241 	UINT i;
7242 	// Validate arguments
7243 	if (addr == NULL || ip == NULL)
7244 	{
7245 		Zero(addr, sizeof(IPV6_ADDR));
7246 		return false;
7247 	}
7248 
7249 	if (IsIP6(ip) == false)
7250 	{
7251 		Zero(addr, sizeof(IPV6_ADDR));
7252 		return false;
7253 	}
7254 
7255 	for (i = 0; i < sizeof(addr->Value); ++i)
7256 	{
7257 		addr->Value[i] = ip->address[i];
7258 	}
7259 
7260 	return true;
7261 }
7262 
7263 // Set an IPv6 address
SetIP6(IP * ip,UCHAR * value)7264 void SetIP6(IP *ip, UCHAR *value)
7265 {
7266 	// Validate arguments
7267 	if (ip == NULL || value == NULL)
7268 	{
7269 		return;
7270 	}
7271 
7272 	Zero(ip, sizeof(IP));
7273 
7274 	for (BYTE i = 0; i < sizeof(ip->address); ++i)
7275 	{
7276 		ip->address[i] = value[i];
7277 	}
7278 }
7279 
7280 // Check whether the specified address is IPv4
IsIP4(IP * ip)7281 bool IsIP4(IP *ip)
7282 {
7283 	// Validate arguments
7284 	if (ip == NULL)
7285 	{
7286 		return false;
7287 	}
7288 
7289 	if (IsZero(ip->address, 10) == false)
7290 	{
7291 		return false;
7292 	}
7293 
7294 	if (ip->address[10] != 0xff || ip->address[11] != 0xff)
7295 	{
7296 		return false;
7297 	}
7298 
7299 	return true;
7300 }
7301 
7302 // Copy the IP address
CopyIP(IP * dst,IP * src)7303 void CopyIP(IP *dst, IP *src)
7304 {
7305 	Copy(dst, src, sizeof(IP));
7306 }
7307 
7308 // Utility functions about IP and MAC address types
7309 // Identify whether the IP address is a normal unicast address
IsValidUnicastIPAddress4(IP * ip)7310 bool IsValidUnicastIPAddress4(IP *ip)
7311 {
7312 	// Validate arguments
7313 	if (IsIP4(ip) == false)
7314 	{
7315 		return false;
7316 	}
7317 
7318 	if (IsZeroIP(ip))
7319 	{
7320 		return false;
7321 	}
7322 
7323 	const BYTE *ipv4 = IPV4(ip->address);
7324 
7325 	if (ipv4[0] >= 224 && ipv4[0] <= 239)
7326 	{
7327 		// IPv4 Multicast
7328 		return false;
7329 	}
7330 
7331 	/// TODO: this is kinda incorrect, but for the correct parsing we need the netmask anyway
7332 	for (BYTE i = 0; i < IPV4_SIZE; ++i)
7333 	{
7334 		if (ipv4[i] != 255)
7335 		{
7336 			return true;
7337 		}
7338 	}
7339 
7340 	return false;
7341 }
IsValidUnicastIPAddressUINT4(UINT ip)7342 bool IsValidUnicastIPAddressUINT4(UINT ip)
7343 {
7344 	IP a;
7345 
7346 	UINTToIP(&a, ip);
7347 
7348 	return IsValidUnicastIPAddress4(&a);
7349 }
7350 
IsValidUnicastIPAddress6(IP * ip)7351 bool IsValidUnicastIPAddress6(IP *ip)
7352 {
7353 	UINT ipv6Type;
7354 
7355 	if (!IsIP6(ip))
7356 	{
7357 		return false;
7358 	}
7359 
7360 	if (IsZeroIP(ip))
7361 	{
7362 		return false;
7363 	}
7364 
7365 	ipv6Type = GetIPAddrType6(ip);
7366 
7367 	if (!(ipv6Type & IPV6_ADDR_LOCAL_UNICAST) &&
7368 	        !(ipv6Type & IPV6_ADDR_GLOBAL_UNICAST))
7369 	{
7370 		return false;
7371 	}
7372 
7373 	return true;
7374 }
7375 
7376 // Check whether the MAC address is valid
IsMacInvalid(UCHAR * mac)7377 bool IsMacInvalid(UCHAR *mac)
7378 {
7379 	UINT i;
7380 	// Validate arguments
7381 	if (mac == NULL)
7382 	{
7383 		return false;
7384 	}
7385 
7386 	for (i = 0; i < 6; i++)
7387 	{
7388 		if (mac[i] != 0x00)
7389 		{
7390 			return false;
7391 		}
7392 	}
7393 	return true;
7394 }
7395 
7396 // Check whether the MAC address is a broadcast address
IsMacBroadcast(UCHAR * mac)7397 bool IsMacBroadcast(UCHAR *mac)
7398 {
7399 	UINT i;
7400 	// Validate arguments
7401 	if (mac == NULL)
7402 	{
7403 		return false;
7404 	}
7405 
7406 	for (i = 0; i < 6; i++)
7407 	{
7408 		if (mac[i] != 0xff)
7409 		{
7410 			return false;
7411 		}
7412 	}
7413 	return true;
7414 }
7415 
7416 // Check wether the MAC address is an IPv4 multicast or an IPv6 multicast
IsMacMulticast(UCHAR * mac)7417 bool IsMacMulticast(UCHAR *mac)
7418 {
7419 	// Validate arguments
7420 	if (mac == NULL)
7421 	{
7422 		return false;
7423 	}
7424 
7425 	if (mac[0] == 0x01 &&
7426 	        mac[1] == 0x00 &&
7427 	        mac[2] == 0x5e)
7428 	{
7429 		// Multicast IPv4 and other IANA multicasts
7430 		return true;
7431 	}
7432 
7433 	if (mac[0] == 0x01)
7434 	{
7435 		// That's not a really reserved for multicast range, but it seems like anything with 0x01 is used as multicast anyway
7436 		// Remove or specify if it causes problems
7437 		return true;
7438 	}
7439 
7440 	if (mac[0] == 0x33 &&
7441 	        mac[1] == 0x33)
7442 	{
7443 		// Multicast IPv6
7444 		return true;
7445 	}
7446 
7447 	return false;
7448 }
7449 
7450 // Check wether the MAC address is a unicast one
IsMacUnicast(UCHAR * mac)7451 bool IsMacUnicast(UCHAR *mac)
7452 {
7453 	// Validate arguments
7454 	if (mac == NULL)
7455 	{
7456 		return false;
7457 	}
7458 
7459 	if (IsMacInvalid(mac))
7460 	{
7461 		return false;
7462 	}
7463 
7464 	if (IsMacBroadcast(mac))
7465 	{
7466 		return false;
7467 	}
7468 
7469 	if (IsMacMulticast(mac))
7470 	{
7471 		return false;
7472 	}
7473 
7474 	return true;
7475 }
7476 
7477 // Get the number of clients connected from the specified IP address
GetNumIpClient(IP * ip)7478 UINT GetNumIpClient(IP *ip)
7479 {
7480 	IP_CLIENT *c;
7481 	UINT ret = 0;
7482 	// Validate arguments
7483 	if (ip == NULL)
7484 	{
7485 		return 0;
7486 	}
7487 
7488 	LockList(ip_clients);
7489 	{
7490 		c = SearchIpClient(ip);
7491 
7492 		if (c != NULL)
7493 		{
7494 			ret = c->NumConnections;
7495 		}
7496 	}
7497 	UnlockList(ip_clients);
7498 
7499 	return ret;
7500 }
7501 
7502 // Add to the IP client entry
AddIpClient(IP * ip)7503 void AddIpClient(IP *ip)
7504 {
7505 	IP_CLIENT *c;
7506 	// Validate arguments
7507 	if (ip == NULL)
7508 	{
7509 		return;
7510 	}
7511 
7512 	LockList(ip_clients);
7513 	{
7514 		c = SearchIpClient(ip);
7515 
7516 		if (c == NULL)
7517 		{
7518 			c = ZeroMallocFast(sizeof(IP_CLIENT));
7519 			Copy(&c->IpAddress, ip, sizeof(IP));
7520 			c->NumConnections = 0;
7521 
7522 			Add(ip_clients, c);
7523 		}
7524 
7525 		c->NumConnections++;
7526 	}
7527 	UnlockList(ip_clients);
7528 
7529 	//Debug("AddIpClient: %r\n", ip);
7530 }
7531 
7532 // Remove from the IP client list
DelIpClient(IP * ip)7533 void DelIpClient(IP *ip)
7534 {
7535 	IP_CLIENT *c;
7536 	// Validate arguments
7537 	if (ip == NULL)
7538 	{
7539 		return;
7540 	}
7541 
7542 	LockList(ip_clients);
7543 	{
7544 		c = SearchIpClient(ip);
7545 
7546 		if (c != NULL)
7547 		{
7548 			c->NumConnections--;
7549 
7550 			if (c->NumConnections == 0)
7551 			{
7552 				Delete(ip_clients, c);
7553 				Free(c);
7554 			}
7555 		}
7556 	}
7557 	UnlockList(ip_clients);
7558 
7559 	//Debug("DelIpClient: %r\n", ip);
7560 }
7561 
7562 // Search for the IP client entry
SearchIpClient(IP * ip)7563 IP_CLIENT *SearchIpClient(IP *ip)
7564 {
7565 	IP_CLIENT t;
7566 	// Validate arguments
7567 	if (ip == NULL)
7568 	{
7569 		return NULL;
7570 	}
7571 
7572 	Zero(&t, sizeof(t));
7573 	Copy(&t.IpAddress, ip, sizeof(IP));
7574 
7575 	return Search(ip_clients, &t);
7576 }
7577 
7578 // Initialization of the client list
InitIpClientList()7579 void InitIpClientList()
7580 {
7581 	ip_clients = NewList(CompareIpClientList);
7582 }
7583 
7584 // Release of the client list
FreeIpClientList()7585 void FreeIpClientList()
7586 {
7587 	UINT i;
7588 
7589 	for (i = 0; i < LIST_NUM(ip_clients); i++)
7590 	{
7591 		IP_CLIENT *c = LIST_DATA(ip_clients, i);
7592 
7593 		Free(c);
7594 	}
7595 
7596 	ReleaseList(ip_clients);
7597 	ip_clients = NULL;
7598 }
7599 
7600 // Comparison of the client list entries
CompareIpClientList(void * p1,void * p2)7601 int CompareIpClientList(void *p1, void *p2)
7602 {
7603 	IP_CLIENT *c1, *c2;
7604 	if (p1 == NULL || p2 == NULL)
7605 	{
7606 		return 0;
7607 	}
7608 	c1 = *(IP_CLIENT **)p1;
7609 	c2 = *(IP_CLIENT **)p2;
7610 	if (c1 == NULL || c2 == NULL)
7611 	{
7612 		return 0;
7613 	}
7614 
7615 	return CmpIpAddr(&c1->IpAddress, &c2->IpAddress);
7616 }
7617 
7618 // Normalization of the MAC address
NormalizeMacAddress(char * dst,UINT size,char * src)7619 bool NormalizeMacAddress(char *dst, UINT size, char *src)
7620 {
7621 	BUF *b;
7622 	bool ret = false;
7623 	// Validate arguments
7624 	if (dst == NULL || src == NULL)
7625 	{
7626 		return false;
7627 	}
7628 
7629 	b = StrToBin(src);
7630 
7631 	if (b != NULL && b->Size == 6)
7632 	{
7633 		ret = true;
7634 
7635 		BinToStr(dst, size, b->Buf, b->Size);
7636 	}
7637 
7638 	FreeBuf(b);
7639 
7640 	return ret;
7641 }
7642 
7643 // Identify whether the IP address is empty
IsZeroIP(IP * ip)7644 bool IsZeroIP(IP *ip)
7645 {
7646 	// Validate arguments
7647 	if (ip == NULL)
7648 	{
7649 		return true;
7650 	}
7651 
7652 	if (IsZero(ip->address, sizeof(ip->address)))
7653 	{
7654 		return true;
7655 	}
7656 
7657 	if (IsIP4(ip))
7658 	{
7659 		return IsZero(IPV4(ip->address), IPV4_SIZE);
7660 	}
7661 
7662 	return false;
7663 }
IsZeroIP6Addr(IPV6_ADDR * addr)7664 bool IsZeroIP6Addr(IPV6_ADDR *addr)
7665 {
7666 	// Validate arguments
7667 	if (addr == NULL)
7668 	{
7669 		return true;
7670 	}
7671 
7672 	return IsZero(addr, sizeof(IPV6_ADDR));
7673 }
7674 
7675 // Examine whether the specified IP address is meaningful as a host
IsHostIPAddress4(IP * ip)7676 bool IsHostIPAddress4(IP *ip)
7677 {
7678 	UINT a;
7679 	// Validate arguments
7680 	if (ip == NULL)
7681 	{
7682 		return false;
7683 	}
7684 
7685 	a = IPToUINT(ip);
7686 
7687 	if (a == 0 || a == 0xffffffff)
7688 	{
7689 		return false;
7690 	}
7691 
7692 	return true;
7693 }
IsHostIPAddress32(UINT ip)7694 bool IsHostIPAddress32(UINT ip)
7695 {
7696 	IP p;
7697 
7698 	UINTToIP(&p, ip);
7699 
7700 	return IsHostIPAddress4(&p);
7701 }
7702 
7703 // Check whether the specified IP address and subnet mask indicates a network correctly
IsNetworkAddress4(IP * ip,IP * mask)7704 bool IsNetworkAddress4(IP *ip, IP *mask)
7705 {
7706 	UINT a, b;
7707 	// Validate arguments
7708 	if (ip == NULL || mask == NULL)
7709 	{
7710 		return false;
7711 	}
7712 
7713 	if (IsIP4(ip) == false || IsIP4(mask) == false)
7714 	{
7715 		return false;
7716 	}
7717 
7718 	if (IsSubnetMask4(mask) == false)
7719 	{
7720 		return false;
7721 	}
7722 
7723 	a = IPToUINT(ip);
7724 	b = IPToUINT(mask);
7725 
7726 	if ((a & b) == a)
7727 	{
7728 		return true;
7729 	}
7730 
7731 	return false;
7732 }
IsNetworkAddress32(UINT ip,UINT mask)7733 bool IsNetworkAddress32(UINT ip, UINT mask)
7734 {
7735 	IP a, b;
7736 
7737 	UINTToIP(&a, ip);
7738 	UINTToIP(&b, mask);
7739 
7740 	return IsNetworkAddress4(&a, &b);
7741 }
7742 
7743 // Convert the integer to a subnet mask
IntToSubnetMask32(UINT i)7744 UINT IntToSubnetMask32(UINT i)
7745 {
7746 	UINT ret = 0xFFFFFFFF;
7747 
7748 	switch (i)
7749 	{
7750 	case 0:
7751 		ret = 0x00000000;
7752 		break;
7753 	case 1:
7754 		ret = 0x80000000;
7755 		break;
7756 	case 2:
7757 		ret = 0xC0000000;
7758 		break;
7759 	case 3:
7760 		ret = 0xE0000000;
7761 		break;
7762 	case 4:
7763 		ret = 0xF0000000;
7764 		break;
7765 	case 5:
7766 		ret = 0xF8000000;
7767 		break;
7768 	case 6:
7769 		ret = 0xFC000000;
7770 		break;
7771 	case 7:
7772 		ret = 0xFE000000;
7773 		break;
7774 	case 8:
7775 		ret = 0xFF000000;
7776 		break;
7777 	case 9:
7778 		ret = 0xFF800000;
7779 		break;
7780 	case 10:
7781 		ret = 0xFFC00000;
7782 		break;
7783 	case 11:
7784 		ret = 0xFFE00000;
7785 		break;
7786 	case 12:
7787 		ret = 0xFFF00000;
7788 		break;
7789 	case 13:
7790 		ret = 0xFFF80000;
7791 		break;
7792 	case 14:
7793 		ret = 0xFFFC0000;
7794 		break;
7795 	case 15:
7796 		ret = 0xFFFE0000;
7797 		break;
7798 	case 16:
7799 		ret = 0xFFFF0000;
7800 		break;
7801 	case 17:
7802 		ret = 0xFFFF8000;
7803 		break;
7804 	case 18:
7805 		ret = 0xFFFFC000;
7806 		break;
7807 	case 19:
7808 		ret = 0xFFFFE000;
7809 		break;
7810 	case 20:
7811 		ret = 0xFFFFF000;
7812 		break;
7813 	case 21:
7814 		ret = 0xFFFFF800;
7815 		break;
7816 	case 22:
7817 		ret = 0xFFFFFC00;
7818 		break;
7819 	case 23:
7820 		ret = 0xFFFFFE00;
7821 		break;
7822 	case 24:
7823 		ret = 0xFFFFFF00;
7824 		break;
7825 	case 25:
7826 		ret = 0xFFFFFF80;
7827 		break;
7828 	case 26:
7829 		ret = 0xFFFFFFC0;
7830 		break;
7831 	case 27:
7832 		ret = 0xFFFFFFE0;
7833 		break;
7834 	case 28:
7835 		ret = 0xFFFFFFF0;
7836 		break;
7837 	case 29:
7838 		ret = 0xFFFFFFF8;
7839 		break;
7840 	case 30:
7841 		ret = 0xFFFFFFFC;
7842 		break;
7843 	case 31:
7844 		ret = 0xFFFFFFFE;
7845 		break;
7846 	case 32:
7847 		ret = 0xFFFFFFFF;
7848 		break;
7849 	}
7850 
7851 	if (IsLittleEndian())
7852 	{
7853 		ret = Swap32(ret);
7854 	}
7855 
7856 	return ret;
7857 }
IntToSubnetMask4(IP * ip,UINT i)7858 void IntToSubnetMask4(IP *ip, UINT i)
7859 {
7860 	UINT m;
7861 	// Validate arguments
7862 	if (ip == NULL)
7863 	{
7864 		return;
7865 	}
7866 
7867 	m = IntToSubnetMask32(i);
7868 
7869 	UINTToIP(ip, m);
7870 }
7871 
7872 // Examine whether the specified IP address is a subnet mask
IsSubnetMask(IP * ip)7873 bool IsSubnetMask(IP *ip)
7874 {
7875 	if (IsIP6(ip))
7876 	{
7877 		return IsSubnetMask6(ip);
7878 	}
7879 	else
7880 	{
7881 		return IsSubnetMask4(ip);
7882 	}
7883 }
IsSubnetMask4(IP * ip)7884 bool IsSubnetMask4(IP *ip)
7885 {
7886 	UINT i;
7887 	// Validate arguments
7888 	if (ip == NULL)
7889 	{
7890 		return false;
7891 	}
7892 
7893 	if (IsIP6(ip))
7894 	{
7895 		return false;
7896 	}
7897 
7898 	i = IPToUINT(ip);
7899 
7900 	if (IsLittleEndian())
7901 	{
7902 		i = Swap32(i);
7903 	}
7904 
7905 	switch (i)
7906 	{
7907 	case 0x00000000:
7908 	case 0x80000000:
7909 	case 0xC0000000:
7910 	case 0xE0000000:
7911 	case 0xF0000000:
7912 	case 0xF8000000:
7913 	case 0xFC000000:
7914 	case 0xFE000000:
7915 	case 0xFF000000:
7916 	case 0xFF800000:
7917 	case 0xFFC00000:
7918 	case 0xFFE00000:
7919 	case 0xFFF00000:
7920 	case 0xFFF80000:
7921 	case 0xFFFC0000:
7922 	case 0xFFFE0000:
7923 	case 0xFFFF0000:
7924 	case 0xFFFF8000:
7925 	case 0xFFFFC000:
7926 	case 0xFFFFE000:
7927 	case 0xFFFFF000:
7928 	case 0xFFFFF800:
7929 	case 0xFFFFFC00:
7930 	case 0xFFFFFE00:
7931 	case 0xFFFFFF00:
7932 	case 0xFFFFFF80:
7933 	case 0xFFFFFFC0:
7934 	case 0xFFFFFFE0:
7935 	case 0xFFFFFFF0:
7936 	case 0xFFFFFFF8:
7937 	case 0xFFFFFFFC:
7938 	case 0xFFFFFFFE:
7939 	case 0xFFFFFFFF:
7940 		return true;
7941 	}
7942 
7943 	return false;
7944 }
IsSubnetMask32(UINT ip)7945 bool IsSubnetMask32(UINT ip)
7946 {
7947 	IP p;
7948 
7949 	UINTToIP(&p, ip);
7950 
7951 	return IsSubnetMask4(&p);
7952 }
7953 
7954 #ifdef	OS_UNIX			// Code for UNIX
7955 
7956 // Turn on and off the non-blocking mode of the socket
UnixSetSocketNonBlockingMode(int fd,bool nonblock)7957 void UnixSetSocketNonBlockingMode(int fd, bool nonblock)
7958 {
7959 	// Validate arguments
7960 	if (fd == INVALID_SOCKET)
7961 	{
7962 		return;
7963 	}
7964 
7965 	const int flags = fcntl(fd, F_GETFL, 0);
7966 	if (flags != -1)
7967 	{
7968 		fcntl(fd, F_SETFL, nonblock ? flags | O_NONBLOCK : flags & ~O_NONBLOCK);
7969 	}
7970 }
7971 
7972 // Do Nothing
UnixGetRouteTable()7973 ROUTE_TABLE *UnixGetRouteTable()
7974 {
7975 	ROUTE_TABLE *ret = ZeroMalloc(sizeof(ROUTE_TABLE));
7976 	ret->NumEntry = 0;
7977 	ret->Entry = ZeroMalloc(0);
7978 
7979 	return ret;
7980 }
7981 
7982 // Do Nothing
UnixAddRouteEntry(ROUTE_ENTRY * e,bool * already_exists)7983 bool UnixAddRouteEntry(ROUTE_ENTRY *e, bool *already_exists)
7984 {
7985 	return true;
7986 }
7987 
7988 // Do Nothing
UnixDeleteRouteEntry(ROUTE_ENTRY * e)7989 void UnixDeleteRouteEntry(ROUTE_ENTRY *e)
7990 {
7991 	return;
7992 }
7993 
7994 // Do Nothing
UnixGetVLanInterfaceID(char * instance_name)7995 UINT UnixGetVLanInterfaceID(char *instance_name)
7996 {
7997 	return 1;
7998 }
7999 
8000 // Do Nothing
UnixEnumVLan(char * tag_name)8001 char **UnixEnumVLan(char *tag_name)
8002 {
8003 	char **list;
8004 
8005 	list = ZeroMalloc(sizeof(char *));
8006 
8007 	return list;
8008 }
8009 
8010 // Get the IP address of the default DNS server
UnixGetDefaultDns(IP * ip)8011 bool UnixGetDefaultDns(IP *ip)
8012 {
8013 	BUF *b;
8014 	// Validate arguments
8015 	if (ip == NULL)
8016 	{
8017 		return false;
8018 	}
8019 
8020 	Lock(unix_dns_server_addr_lock);
8021 	{
8022 		if (IsZero(&unix_dns_server, sizeof(IP)) == false)
8023 		{
8024 			Copy(ip, &unix_dns_server, sizeof(IP));
8025 			Unlock(unix_dns_server_addr_lock);
8026 			return true;
8027 		}
8028 
8029 		GetLocalHostIP4(ip);
8030 
8031 		b = ReadDump("/etc/resolv.conf");
8032 		if (b != NULL)
8033 		{
8034 			char *s;
8035 			bool f = false;
8036 			while ((s = CfgReadNextLine(b)) != NULL)
8037 			{
8038 				TOKEN_LIST *t = ParseToken(s, "\" \t,");
8039 				if (t->NumTokens == 2)
8040 				{
8041 					if (StrCmpi(t->Token[0], "nameserver") == 0)
8042 					{
8043 						StrToIP(ip, t->Token[1]);
8044 						f = IsIP4(ip);
8045 					}
8046 				}
8047 				FreeToken(t);
8048 
8049 				Free(s);
8050 
8051 				if (f)
8052 				{
8053 					break;
8054 				}
8055 			}
8056 			FreeBuf(b);
8057 		}
8058 		Copy(&unix_dns_server, ip, sizeof(IP));
8059 	}
8060 	Unlock(unix_dns_server_addr_lock);
8061 
8062 	return true;
8063 }
8064 
8065 
8066 // Select procedure
UnixSelect(SOCKSET * set,UINT timeout,CANCEL * c1,CANCEL * c2)8067 void UnixSelect(SOCKSET *set, UINT timeout, CANCEL *c1, CANCEL *c2)
8068 {
8069 	UINT reads[MAXIMUM_WAIT_OBJECTS];
8070 	UINT writes[MAXIMUM_WAIT_OBJECTS];
8071 	UINT num_read, num_write, i;
8072 	UINT p1, p2;
8073 	SOCK_EVENT *sock_events[MAXIMUM_WAIT_OBJECTS];
8074 	UINT num_sock_events;
8075 	SOCK *s;
8076 	UCHAR tmp[MAX_SIZE];
8077 	int ret;
8078 	bool any_of_tubes_are_readable = false;
8079 	// Initialization of array
8080 	Zero(reads, sizeof(reads));
8081 	Zero(writes, sizeof(writes));
8082 	Zero(sock_events, sizeof(sock_events));
8083 	num_read = num_write = num_sock_events = 0;
8084 
8085 	// Setting the event array
8086 	if (set != NULL)
8087 	{
8088 		for (i = 0; i < set->NumSocket; i++)
8089 		{
8090 			s = set->Sock[i];
8091 			if (s != NULL)
8092 			{
8093 				UnixInitAsyncSocket(s);
8094 				if (s->Type == SOCK_INPROC)
8095 				{
8096 					TUBE *t = s->RecvTube;
8097 					if (t != NULL)
8098 					{
8099 						reads[num_read++] = t->SockEvent->pipe_read;
8100 
8101 						sock_events[num_sock_events++] = t->SockEvent;
8102 
8103 						if (t->SockEvent->current_pipe_data != 0)
8104 						{
8105 							any_of_tubes_are_readable = true;
8106 						}
8107 					}
8108 				}
8109 				else
8110 				{
8111 					if (s->NoNeedToRead == false)
8112 					{
8113 						reads[num_read++] = s->socket;
8114 					}
8115 				}
8116 
8117 				if (s->BulkRecvTube != NULL)
8118 				{
8119 					TUBE *t = s->BulkRecvTube;
8120 					if (t != NULL)
8121 					{
8122 						reads[num_read++] = t->SockEvent->pipe_read;
8123 
8124 						sock_events[num_sock_events++] = t->SockEvent;
8125 
8126 						if (t->SockEvent->current_pipe_data != 0)
8127 						{
8128 							any_of_tubes_are_readable = true;
8129 						}
8130 					}
8131 				}
8132 
8133 				if (s->WriteBlocked)
8134 				{
8135 					writes[num_write++] = s->socket;
8136 				}
8137 			}
8138 		}
8139 	}
8140 
8141 	if (timeout == 0)
8142 	{
8143 		return;
8144 	}
8145 
8146 	p1 = p2 = -1;
8147 
8148 	if (c1 != NULL)
8149 	{
8150 		reads[num_read++] = p1 = c1->pipe_read;
8151 
8152 		if (c1->SpecialFlag)
8153 		{
8154 			if (c1->pipe_special_read2 != -1 && c1->pipe_special_read2 != 0)
8155 			{
8156 				reads[num_read++] = c1->pipe_special_read2;
8157 			}
8158 
8159 			if (c1->pipe_special_read3 != -1 && c1->pipe_special_read3 != 0)
8160 			{
8161 				reads[num_read++] = c1->pipe_special_read3;
8162 			}
8163 		}
8164 	}
8165 	if (c2 != NULL)
8166 	{
8167 		reads[num_read++] = p2 = c2->pipe_read;
8168 
8169 		if (c2->SpecialFlag)
8170 		{
8171 			if (c2->pipe_special_read2 != -1 && c2->pipe_special_read2 != 0)
8172 			{
8173 				reads[num_read++] = c2->pipe_special_read2;
8174 			}
8175 
8176 			if (c2->pipe_special_read3 != -1 && c2->pipe_special_read3 != 0)
8177 			{
8178 				reads[num_read++] = c2->pipe_special_read3;
8179 			}
8180 		}
8181 	}
8182 
8183 	// Call the select
8184 	if (any_of_tubes_are_readable == false)
8185 	{
8186 		UnixSelectInner(num_read, reads, num_write, writes, timeout);
8187 	}
8188 
8189 	// Read from the pipe
8190 	if (c1 != NULL && c1->SpecialFlag == false && p1 != -1)
8191 	{
8192 		do
8193 		{
8194 			ret = read(p1, tmp, sizeof(tmp));
8195 		}
8196 		while (ret >= 1);
8197 	}
8198 	if (c2 != NULL && c2->SpecialFlag == false && p2 != -1)
8199 	{
8200 		do
8201 		{
8202 			ret = read(p2, tmp, sizeof(tmp));
8203 		}
8204 		while (ret >= 1);
8205 	}
8206 
8207 	// Read from the pipe of sockevent
8208 	for (i = 0; i < num_sock_events; i++)
8209 	{
8210 		SOCK_EVENT *e = sock_events[i];
8211 
8212 		e->current_pipe_data = 0;
8213 
8214 		do
8215 		{
8216 			ret = read(e->pipe_read, tmp, sizeof(tmp));
8217 		}
8218 		while (ret >= 1);
8219 	}
8220 }
8221 
8222 // Cancel
UnixCancel(CANCEL * c)8223 void UnixCancel(CANCEL *c)
8224 {
8225 	// Validate arguments
8226 	if (c == NULL)
8227 	{
8228 		return;
8229 	}
8230 
8231 	UnixWritePipe(c->pipe_write);
8232 }
8233 
8234 // Release of the cancel object
UnixCleanupCancel(CANCEL * c)8235 void UnixCleanupCancel(CANCEL *c)
8236 {
8237 	// Validate arguments
8238 	if (c == NULL)
8239 	{
8240 		return;
8241 	}
8242 
8243 	if (c->SpecialFlag == false)
8244 	{
8245 		UnixDeletePipe(c->pipe_read, c->pipe_write);
8246 	}
8247 
8248 	Free(c);
8249 }
8250 
8251 // Creating a new cancel object
UnixNewCancel()8252 CANCEL *UnixNewCancel()
8253 {
8254 	CANCEL *c = ZeroMallocFast(sizeof(CANCEL));
8255 
8256 	c->ref = NewRef();
8257 	c->SpecialFlag = false;
8258 
8259 	UnixNewPipe(&c->pipe_read, &c->pipe_write);
8260 
8261 	c->pipe_special_read2 = c->pipe_special_read3 = -1;
8262 
8263 	return c;
8264 }
8265 
8266 // Add the socket to the socket event
UnixJoinSockToSockEvent(SOCK * sock,SOCK_EVENT * event)8267 void UnixJoinSockToSockEvent(SOCK *sock, SOCK_EVENT *event)
8268 {
8269 	// Validate arguments
8270 	if (sock == NULL || event == NULL || sock->AsyncMode)
8271 	{
8272 		return;
8273 	}
8274 	if (sock->ListenMode != false || (sock->Type == SOCK_TCP && sock->Connected == false))
8275 	{
8276 		return;
8277 	}
8278 
8279 	sock->AsyncMode = true;
8280 
8281 	LockList(event->SockList);
8282 	{
8283 		Add(event->SockList, sock);
8284 		AddRef(sock->ref);
8285 	}
8286 	UnlockList(event->SockList);
8287 
8288 	// Make the socket asynchronous mode
8289 	if (sock->Type != SOCK_INPROC)
8290 	{
8291 		UnixSetSocketNonBlockingMode(sock->socket, true);
8292 	}
8293 
8294 	// Increase the reference count of the SOCK_EVENT
8295 	AddRef(event->ref);
8296 	sock->SockEvent = event;
8297 
8298 	// Set the socket event
8299 	SetSockEvent(event);
8300 }
8301 
8302 // Wait for a socket event
UnixWaitSockEvent(SOCK_EVENT * event,UINT timeout)8303 bool UnixWaitSockEvent(SOCK_EVENT *event, UINT timeout)
8304 {
8305 	UINT num_read, num_write;
8306 	UINT *reads, *writes;
8307 	UINT n;
8308 	char tmp[MAX_SIZE];
8309 	int readret = 0;
8310 	bool event_pipe_is_readable = false;
8311 	// Validate arguments
8312 	if (event == NULL)
8313 	{
8314 		return false;
8315 	}
8316 
8317 	LockList(event->SockList);
8318 	{
8319 		UINT i;
8320 		reads = ZeroMallocFast(sizeof(SOCK *) * (LIST_NUM(event->SockList) + 1));
8321 
8322 		num_write = 0;
8323 		num_read = 0;
8324 
8325 		for (i = 0; i < LIST_NUM(event->SockList); i++)
8326 		{
8327 			SOCK *s = LIST_DATA(event->SockList, i);
8328 
8329 			if (s->NoNeedToRead == false)
8330 			{
8331 				reads[num_read++] = s->socket;
8332 			}
8333 
8334 			if (s->WriteBlocked)
8335 			{
8336 				num_write++;
8337 			}
8338 		}
8339 
8340 		reads[num_read++] = event->pipe_read;
8341 
8342 		if (event->current_pipe_data != 0)
8343 		{
8344 			event_pipe_is_readable = true;
8345 		}
8346 
8347 		writes = ZeroMallocFast(sizeof(SOCK *) * num_write);
8348 
8349 		n = 0;
8350 
8351 		for (i = 0; i < (num_read - 1); i++)
8352 		{
8353 			SOCK *s = LIST_DATA(event->SockList, i);
8354 			if (s->WriteBlocked)
8355 			{
8356 				writes[n++] = s->socket;
8357 			}
8358 		}
8359 	}
8360 	UnlockList(event->SockList);
8361 
8362 	if (event_pipe_is_readable == false)
8363 	{
8364 		UnixSelectInner(num_read, reads, num_write, writes, timeout);
8365 	}
8366 
8367 	event->current_pipe_data = 0;
8368 	do
8369 	{
8370 		readret = read(event->pipe_read, tmp, sizeof(tmp));
8371 	}
8372 	while (readret >= 1);
8373 
8374 	Free(reads);
8375 	Free(writes);
8376 
8377 	return true;
8378 }
8379 
8380 // Set the socket event
UnixSetSockEvent(SOCK_EVENT * event)8381 void UnixSetSockEvent(SOCK_EVENT *event)
8382 {
8383 	// Validate arguments
8384 	if (event == NULL)
8385 	{
8386 		return;
8387 	}
8388 
8389 	if (event->current_pipe_data <= 100)
8390 	{
8391 		UnixWritePipe(event->pipe_write);
8392 		event->current_pipe_data++;
8393 	}
8394 }
8395 
8396 // This is a helper function for select()
safe_fd_set(int fd,fd_set * fds,int * max_fd)8397 int safe_fd_set(int fd, fd_set *fds, int *max_fd) {
8398 	FD_SET(fd, fds);
8399 	if (fd > *max_fd) {
8400 		*max_fd = fd;
8401 	}
8402 	return 0;
8403 }
8404 
8405 // Execute 'select' for the socket
UnixSelectInner(UINT num_read,UINT * reads,UINT num_write,UINT * writes,UINT timeout)8406 void UnixSelectInner(UINT num_read, UINT *reads, UINT num_write, UINT *writes, UINT timeout)
8407 {
8408 #ifdef	UNIX_MACOS
8409 	fd_set rfds; //read descriptors
8410 	fd_set wfds; //write descriptors
8411 	int max_fd = 0; //maximum descriptor id
8412 	struct timeval tv; //timeval for timeout
8413 #else	// UNIX_MACOS
8414 	struct pollfd *p;
8415 #endif	// UNIX_MACOS
8416 	UINT num;
8417 	UINT i;
8418 	UINT n;
8419 	UINT num_read_total, num_write_total;
8420 
8421 	if (num_read != 0 && reads == NULL)
8422 	{
8423 		num_read = 0;
8424 	}
8425 	if (num_write != 0 && writes == NULL)
8426 	{
8427 		num_write = 0;
8428 	}
8429 
8430 	if (timeout == 0)
8431 	{
8432 		return;
8433 	}
8434 
8435 	num_read_total = num_write_total = 0;
8436 	for (i = 0; i < num_read; i++)
8437 	{
8438 		if (reads[i] != INVALID_SOCKET)
8439 		{
8440 			num_read_total++;
8441 		}
8442 	}
8443 	for (i = 0; i < num_write; i++)
8444 	{
8445 		if (writes[i] != INVALID_SOCKET)
8446 		{
8447 			num_write_total++;
8448 		}
8449 	}
8450 
8451 	num = num_read_total + num_write_total;
8452 #ifdef	UNIX_MACOS
8453 	FD_ZERO(&rfds); //zero out descriptor set for read descriptors
8454 	FD_ZERO(&wfds); //same for write
8455 #else	// UNIX_MACOS
8456 	p = ZeroMallocFast(sizeof(struct pollfd) * num);
8457 #endif	// UNIX_MACOS
8458 
8459 	n = 0;
8460 
8461 	for (i = 0; i < num_read; i++)
8462 	{
8463 		if (reads[i] != INVALID_SOCKET)
8464 		{
8465 #ifdef	UNIX_MACOS
8466 			safe_fd_set(reads[i], &rfds, &max_fd);
8467 #else	// UNIX_MACOS
8468 			struct pollfd *pfd = &p[n++];
8469 			pfd->fd = reads[i];
8470 			pfd->events = POLLIN | POLLPRI | POLLERR | POLLHUP;
8471 #endif	// UNIX_MACOS
8472 		}
8473 	}
8474 
8475 	for (i = 0; i < num_write; i++)
8476 	{
8477 		if (writes[i] != INVALID_SOCKET)
8478 		{
8479 #ifdef	UNIX_MACOS
8480 			safe_fd_set(writes[i], &wfds, &max_fd);
8481 #else	// UNIX_MACOS
8482 			struct pollfd *pfd = &p[n++];
8483 			pfd->fd = writes[i];
8484 			pfd->events = POLLIN | POLLPRI | POLLERR | POLLHUP | POLLOUT;
8485 #endif	// UNIX_MACOS
8486 		}
8487 	}
8488 
8489 	if (num != 0)
8490 	{
8491 #ifdef	UNIX_MACOS
8492 		tv.tv_sec = timeout / 1000;
8493 		tv.tv_usec = (timeout % 1000) * 1000l;
8494 		select(max_fd + 1, &rfds, &wfds, NULL, timeout == INFINITE ? NULL : &tv);
8495 #else	// UNIX_MACOS
8496 		(void)poll(p, num, timeout == INFINITE ? -1 : (int)timeout);
8497 #endif	// UNIX_MACOS
8498 	}
8499 	else
8500 	{
8501 		SleepThread(timeout);
8502 	}
8503 
8504 #ifndef	UNIX_MACOS
8505 	Free(p);
8506 #endif	// not UNIX_MACOS
8507 }
8508 
8509 // Clean-up of the socket event
UnixCleanupSockEvent(SOCK_EVENT * event)8510 void UnixCleanupSockEvent(SOCK_EVENT *event)
8511 {
8512 	UINT i;
8513 	// Validate arguments
8514 	if (event == NULL)
8515 	{
8516 		return;
8517 	}
8518 
8519 	for (i = 0; i < LIST_NUM(event->SockList); i++)
8520 	{
8521 		SOCK *s = LIST_DATA(event->SockList, i);
8522 
8523 		ReleaseSock(s);
8524 	}
8525 
8526 	ReleaseList(event->SockList);
8527 
8528 	UnixDeletePipe(event->pipe_read, event->pipe_write);
8529 
8530 	Free(event);
8531 }
8532 
8533 // Create a socket event
UnixNewSockEvent()8534 SOCK_EVENT *UnixNewSockEvent()
8535 {
8536 	SOCK_EVENT *e = ZeroMallocFast(sizeof(SOCK_EVENT));
8537 
8538 	e->SockList = NewList(NULL);
8539 	e->ref = NewRef();
8540 
8541 	UnixNewPipe(&e->pipe_read, &e->pipe_write);
8542 
8543 	return e;
8544 }
8545 
8546 // Close the pipe
UnixDeletePipe(int p1,int p2)8547 void UnixDeletePipe(int p1, int p2)
8548 {
8549 	if (p1 != -1)
8550 	{
8551 		close(p1);
8552 	}
8553 
8554 	if (p2 != -1)
8555 	{
8556 		close(p2);
8557 	}
8558 }
8559 
8560 // Write to the pipe
UnixWritePipe(int pipe_write)8561 void UnixWritePipe(int pipe_write)
8562 {
8563 	char c = 1;
8564 	write(pipe_write, &c, 1);
8565 }
8566 
8567 // Create a new pipe
UnixNewPipe(int * pipe_read,int * pipe_write)8568 void UnixNewPipe(int *pipe_read, int *pipe_write)
8569 {
8570 	int fd[2];
8571 	// Validate arguments
8572 	if (pipe_read == NULL || pipe_write == NULL)
8573 	{
8574 		return;
8575 	}
8576 
8577 	fd[0] = fd[1] = 0;
8578 
8579 	pipe(fd);
8580 
8581 	*pipe_read = fd[0];
8582 	*pipe_write = fd[1];
8583 
8584 	UnixSetSocketNonBlockingMode(*pipe_write, true);
8585 	UnixSetSocketNonBlockingMode(*pipe_read, true);
8586 }
8587 
8588 // Release the asynchronous socket
UnixFreeAsyncSocket(SOCK * sock)8589 void UnixFreeAsyncSocket(SOCK *sock)
8590 {
8591 	UINT p;
8592 	// Validate arguments
8593 	if (sock == NULL)
8594 	{
8595 		return;
8596 	}
8597 
8598 	Lock(sock->lock);
8599 	{
8600 		if (sock->AsyncMode == false)
8601 		{
8602 			Unlock(sock->lock);
8603 			return;
8604 		}
8605 
8606 		sock->AsyncMode = false;
8607 
8608 		// Examine whether this socket are associated to SockEvent
8609 		if (sock->SockEvent != NULL)
8610 		{
8611 			SOCK_EVENT *e = sock->SockEvent;
8612 
8613 			AddRef(e->ref);
8614 
8615 			p = e->pipe_write;
8616 			LockList(e->SockList);
8617 			{
8618 				if (Delete(e->SockList, sock))
8619 				{
8620 					ReleaseSock(sock);
8621 				}
8622 			}
8623 			UnlockList(e->SockList);
8624 
8625 			// Release the socket event
8626 			ReleaseSockEvent(sock->SockEvent);
8627 			sock->SockEvent = NULL;
8628 
8629 			SetSockEvent(e);
8630 
8631 			ReleaseSockEvent(e);
8632 		}
8633 	}
8634 	Unlock(sock->lock);
8635 }
8636 
8637 // Set the socket to asynchronous mode
UnixInitAsyncSocket(SOCK * sock)8638 void UnixInitAsyncSocket(SOCK *sock)
8639 {
8640 	// Validate arguments
8641 	if (sock == NULL)
8642 	{
8643 		return;
8644 	}
8645 	if (sock->AsyncMode)
8646 	{
8647 		// The socket has been set in asynchronous mode already
8648 		return;
8649 	}
8650 	if (sock->ListenMode != false || ((sock->Type == SOCK_TCP || sock->Type == SOCK_INPROC) && sock->Connected == false))
8651 	{
8652 		return;
8653 	}
8654 
8655 	sock->AsyncMode = true;
8656 
8657 	if (sock->Type != SOCK_INPROC)
8658 	{
8659 		UnixSetSocketNonBlockingMode(sock->socket, true);
8660 	}
8661 
8662 #if OPENSSL_VERSION_NUMBER < 0x10100000L
8663 	if (sock->ssl != NULL && sock->ssl->s3 != NULL)
8664 	{
8665 		sock->Ssl_Init_Async_SendAlert[0] = sock->ssl->s3->send_alert[0];
8666 		sock->Ssl_Init_Async_SendAlert[1] = sock->ssl->s3->send_alert[1];
8667 	}
8668 #endif
8669 }
8670 
8671 // Initializing the socket library
UnixInitSocketLibrary()8672 void UnixInitSocketLibrary()
8673 {
8674 	// Do not do anything special
8675 }
8676 
8677 // Release of the socket library
UnixFreeSocketLibrary()8678 void UnixFreeSocketLibrary()
8679 {
8680 	// Do not do anything special
8681 }
8682 
8683 #endif	// OS_UNIX
8684 
8685 #ifdef OS_WIN32		// Code for Windows
8686 
8687 // Comparison of IP_ADAPTER_INDEX_MAP
CompareIpAdapterIndexMap(void * p1,void * p2)8688 int CompareIpAdapterIndexMap(void *p1, void *p2)
8689 {
8690 	IP_ADAPTER_INDEX_MAP *a1, *a2;
8691 	if (p1 == NULL || p2 == NULL)
8692 	{
8693 		return 0;
8694 	}
8695 	a1 = *(IP_ADAPTER_INDEX_MAP **)p1;
8696 	a2 = *(IP_ADAPTER_INDEX_MAP **)p2;
8697 	if (a1 == NULL || a2 == NULL)
8698 	{
8699 		return 0;
8700 	}
8701 
8702 	if (a1->Index > a2->Index)
8703 	{
8704 		return 1;
8705 	}
8706 	else if (a1->Index < a2->Index)
8707 	{
8708 		return -1;
8709 	}
8710 	else
8711 	{
8712 		return 0;
8713 	}
8714 }
8715 
8716 // Update the IP address of the adapter
Win32RenewAddressByGuid(char * guid)8717 bool Win32RenewAddressByGuid(char *guid)
8718 {
8719 	IP_ADAPTER_INDEX_MAP a;
8720 	// Validate arguments
8721 	if (guid == NULL)
8722 	{
8723 		return false;
8724 	}
8725 
8726 	Zero(&a, sizeof(a));
8727 	if (Win32GetAdapterFromGuid(&a, guid) == false)
8728 	{
8729 		return false;
8730 	}
8731 
8732 	return Win32RenewAddress(&a);
8733 }
Win32RenewAddress(void * a)8734 bool Win32RenewAddress(void *a)
8735 {
8736 	DWORD ret;
8737 	// Validate arguments
8738 	if (a == NULL)
8739 	{
8740 		return false;
8741 	}
8742 
8743 	ret = IpRenewAddress(a);
8744 
8745 	if (ret == NO_ERROR)
8746 	{
8747 		return true;
8748 	}
8749 	else
8750 	{
8751 		Debug("IpRenewAddress: Error: %u\n", ret);
8752 		return false;
8753 	}
8754 }
8755 
8756 // Release the IP address of the adapter
Win32ReleaseAddress(void * a)8757 bool Win32ReleaseAddress(void *a)
8758 {
8759 	DWORD ret;
8760 	// Validate arguments
8761 	if (a == NULL)
8762 	{
8763 		return false;
8764 	}
8765 	if (IpReleaseAddress == NULL)
8766 	{
8767 		return false;
8768 	}
8769 
8770 	ret = IpReleaseAddress(a);
8771 
8772 	if (ret == NO_ERROR)
8773 	{
8774 		return true;
8775 	}
8776 	else
8777 	{
8778 		Debug("IpReleaseAddress: Error: %u\n", ret);
8779 		return false;
8780 	}
8781 }
Win32ReleaseAddressByGuid(char * guid)8782 bool Win32ReleaseAddressByGuid(char *guid)
8783 {
8784 	IP_ADAPTER_INDEX_MAP a;
8785 	// Validate arguments
8786 	if (guid == NULL)
8787 	{
8788 		return false;
8789 	}
8790 
8791 	Zero(&a, sizeof(a));
8792 	if (Win32GetAdapterFromGuid(&a, guid) == false)
8793 	{
8794 		return false;
8795 	}
8796 
8797 	return Win32ReleaseAddress(&a);
8798 }
Win32ReleaseAddressByGuidExThread(THREAD * t,void * param)8799 void Win32ReleaseAddressByGuidExThread(THREAD *t, void *param)
8800 {
8801 	WIN32_RELEASEADDRESS_THREAD_PARAM *p;
8802 	// Validate arguments
8803 	if (t == NULL || param == NULL)
8804 	{
8805 		return;
8806 	}
8807 
8808 	p = (WIN32_RELEASEADDRESS_THREAD_PARAM *)param;
8809 
8810 	AddRef(p->Ref);
8811 
8812 	NoticeThreadInit(t);
8813 
8814 	AddWaitThread(t);
8815 
8816 	if (p->Renew == false)
8817 	{
8818 		p->Ok = Win32ReleaseAddressByGuid(p->Guid);
8819 	}
8820 	else
8821 	{
8822 		p->Ok = Win32RenewAddressByGuid(p->Guid);
8823 	}
8824 
8825 	ReleaseWin32ReleaseAddressByGuidThreadParam(p);
8826 
8827 	DelWaitThread(t);
8828 }
Win32RenewAddressByGuidEx(char * guid,UINT timeout)8829 bool Win32RenewAddressByGuidEx(char *guid, UINT timeout)
8830 {
8831 	return Win32ReleaseOrRenewAddressByGuidEx(guid, timeout, true);
8832 }
Win32ReleaseAddressByGuidEx(char * guid,UINT timeout)8833 bool Win32ReleaseAddressByGuidEx(char *guid, UINT timeout)
8834 {
8835 	return Win32ReleaseOrRenewAddressByGuidEx(guid, timeout, false);
8836 }
Win32ReleaseOrRenewAddressByGuidEx(char * guid,UINT timeout,bool renew)8837 bool Win32ReleaseOrRenewAddressByGuidEx(char *guid, UINT timeout, bool renew)
8838 {
8839 	THREAD *t;
8840 	WIN32_RELEASEADDRESS_THREAD_PARAM *p;
8841 	bool ret = false;
8842 	UINT64 start_tick = 0;
8843 	UINT64 end_tick = 0;
8844 	// Validate arguments
8845 	if (guid == NULL)
8846 	{
8847 		return false;
8848 	}
8849 	if (timeout == 0)
8850 	{
8851 		timeout = INFINITE;
8852 	}
8853 
8854 	p = ZeroMalloc(sizeof(WIN32_RELEASEADDRESS_THREAD_PARAM));
8855 	p->Ref = NewRef();
8856 	StrCpy(p->Guid, sizeof(p->Guid), guid);
8857 	p->Timeout = timeout;
8858 	p->Renew = renew;
8859 
8860 	t = NewThread(Win32ReleaseAddressByGuidExThread, p);
8861 	WaitThreadInit(t);
8862 	start_tick = Tick64();
8863 	end_tick = start_tick + (UINT64)timeout;
8864 
8865 	while (true)
8866 	{
8867 		UINT64 now = Tick64();
8868 		UINT64 remain;
8869 		UINT remain32;
8870 
8871 		if (now >= end_tick)
8872 		{
8873 			break;
8874 		}
8875 
8876 		remain = end_tick - now;
8877 		remain32 = MIN((UINT)remain, 100);
8878 
8879 		if (WaitThread(t, remain32))
8880 		{
8881 			break;
8882 		}
8883 	}
8884 
8885 	ReleaseThread(t);
8886 
8887 	if (p->Ok)
8888 	{
8889 		ret = true;
8890 	}
8891 
8892 	ReleaseWin32ReleaseAddressByGuidThreadParam(p);
8893 
8894 	return ret;
8895 }
ReleaseWin32ReleaseAddressByGuidThreadParam(WIN32_RELEASEADDRESS_THREAD_PARAM * p)8896 void ReleaseWin32ReleaseAddressByGuidThreadParam(WIN32_RELEASEADDRESS_THREAD_PARAM *p)
8897 {
8898 	// Validate arguments
8899 	if (p == NULL)
8900 	{
8901 		return;
8902 	}
8903 
8904 	if (Release(p->Ref) == 0)
8905 	{
8906 		Free(p);
8907 	}
8908 }
8909 
8910 // Get the adapter by the GUID
Win32GetAdapterFromGuid(void * a,char * guid)8911 bool Win32GetAdapterFromGuid(void *a, char *guid)
8912 {
8913 	bool ret = false;
8914 	IP_INTERFACE_INFO *info;
8915 	ULONG size;
8916 	int i;
8917 	LIST *o;
8918 	wchar_t tmp[MAX_SIZE];
8919 
8920 	// Validate arguments
8921 	if (a == NULL || guid == NULL)
8922 	{
8923 		return false;
8924 	}
8925 
8926 	UniFormat(tmp, sizeof(tmp), L"\\DEVICE\\TCPIP_%S", guid);
8927 
8928 	size = sizeof(IP_INTERFACE_INFO);
8929 	info = ZeroMallocFast(size);
8930 
8931 	if (GetInterfaceInfo(info, &size) == ERROR_INSUFFICIENT_BUFFER)
8932 	{
8933 		Free(info);
8934 		info = ZeroMallocFast(size);
8935 	}
8936 
8937 	if (GetInterfaceInfo(info, &size) != NO_ERROR)
8938 	{
8939 		Free(info);
8940 		return false;
8941 	}
8942 
8943 	o = NewListFast(CompareIpAdapterIndexMap);
8944 
8945 	for (i = 0; i < info->NumAdapters; i++)
8946 	{
8947 		IP_ADAPTER_INDEX_MAP *a = &info->Adapter[i];
8948 
8949 		Add(o, a);
8950 	}
8951 
8952 	Sort(o);
8953 
8954 	for (i = 0; i < (int)(LIST_NUM(o)); i++)
8955 	{
8956 		IP_ADAPTER_INDEX_MAP *e = LIST_DATA(o, i);
8957 
8958 		if (UniStrCmpi(e->Name, tmp) == 0)
8959 		{
8960 			Copy(a, e, sizeof(IP_ADAPTER_INDEX_MAP));
8961 			ret = true;
8962 			break;
8963 		}
8964 	}
8965 
8966 	ReleaseList(o);
8967 
8968 	Free(info);
8969 
8970 	return ret;
8971 }
8972 
8973 // Clear the DNS cache on Win32
Win32FlushDnsCache()8974 void Win32FlushDnsCache()
8975 {
8976 	Run("ipconfig.exe", "/flushdns", true, false);
8977 }
8978 
8979 // Update the DHCP address of the specified LAN card
Win32RenewDhcp9x(UINT if_id)8980 void Win32RenewDhcp9x(UINT if_id)
8981 {
8982 	IP_INTERFACE_INFO *info;
8983 	ULONG size;
8984 	int i;
8985 	LIST *o;
8986 	// Validate arguments
8987 	if (if_id == 0)
8988 	{
8989 		return;
8990 	}
8991 
8992 	size = sizeof(IP_INTERFACE_INFO);
8993 	info = ZeroMallocFast(size);
8994 
8995 	if (GetInterfaceInfo(info, &size) == ERROR_INSUFFICIENT_BUFFER)
8996 	{
8997 		Free(info);
8998 		info = ZeroMallocFast(size);
8999 	}
9000 
9001 	if (GetInterfaceInfo(info, &size) != NO_ERROR)
9002 	{
9003 		Free(info);
9004 		return;
9005 	}
9006 
9007 	o = NewListFast(CompareIpAdapterIndexMap);
9008 
9009 	for (i = 0; i < info->NumAdapters; i++)
9010 	{
9011 		IP_ADAPTER_INDEX_MAP *a = &info->Adapter[i];
9012 
9013 		Add(o, a);
9014 	}
9015 
9016 	Sort(o);
9017 
9018 	for (i = 0; i < (int)(LIST_NUM(o)); i++)
9019 	{
9020 		IP_ADAPTER_INDEX_MAP *a = LIST_DATA(o, i);
9021 
9022 		if (a->Index == if_id)
9023 		{
9024 			char arg[MAX_PATH];
9025 			Format(arg, sizeof(arg), "/renew %u", i);
9026 			Run("ipconfig.exe", arg, true, false);
9027 		}
9028 	}
9029 
9030 	ReleaseList(o);
9031 
9032 	Free(info);
9033 }
9034 
9035 // Release the DHCP address of the specified LAN card
Win32ReleaseDhcp9x(UINT if_id,bool wait)9036 void Win32ReleaseDhcp9x(UINT if_id, bool wait)
9037 {
9038 	IP_INTERFACE_INFO *info;
9039 	ULONG size;
9040 	int i;
9041 	LIST *o;
9042 	// Validate arguments
9043 	if (if_id == 0)
9044 	{
9045 		return;
9046 	}
9047 
9048 	size = sizeof(IP_INTERFACE_INFO);
9049 	info = ZeroMallocFast(size);
9050 
9051 	if (GetInterfaceInfo(info, &size) == ERROR_INSUFFICIENT_BUFFER)
9052 	{
9053 		Free(info);
9054 		info = ZeroMallocFast(size);
9055 	}
9056 
9057 	if (GetInterfaceInfo(info, &size) != NO_ERROR)
9058 	{
9059 		Free(info);
9060 		return;
9061 	}
9062 
9063 	o = NewListFast(CompareIpAdapterIndexMap);
9064 
9065 	for (i = 0; i < info->NumAdapters; i++)
9066 	{
9067 		IP_ADAPTER_INDEX_MAP *a = &info->Adapter[i];
9068 
9069 		Add(o, a);
9070 	}
9071 
9072 	Sort(o);
9073 
9074 	for (i = 0; i < (int)(LIST_NUM(o)); i++)
9075 	{
9076 		IP_ADAPTER_INDEX_MAP *a = LIST_DATA(o, i);
9077 
9078 		if (a->Index == if_id)
9079 		{
9080 			char arg[MAX_PATH];
9081 			Format(arg, sizeof(arg), "/release %u", i);
9082 			Run("ipconfig.exe", arg, true, wait);
9083 		}
9084 	}
9085 
9086 	ReleaseList(o);
9087 
9088 	Free(info);
9089 }
9090 
9091 // Enumerate a list of virtual LAN cards that contains the specified string
Win32EnumVLan(char * tag_name)9092 char **Win32EnumVLan(char *tag_name)
9093 {
9094 	MIB_IFTABLE *p;
9095 	UINT ret;
9096 	ULONG size_needed;
9097 	UINT num_retry = 0;
9098 	UINT i;
9099 	LIST *o;
9100 	char **ss;
9101 	// Validate arguments
9102 	if (tag_name == 0)
9103 	{
9104 		return NULL;
9105 	}
9106 
9107 RETRY:
9108 	p = ZeroMallocFast(sizeof(MIB_IFTABLE));
9109 	size_needed = 0;
9110 
9111 	// Examine the needed size
9112 	ret = GetIfTable(p, &size_needed, 0);
9113 	if (ret == ERROR_INSUFFICIENT_BUFFER)
9114 	{
9115 		// Re-allocate the memory block of the needed size
9116 		Free(p);
9117 		p = ZeroMallocFast(size_needed);
9118 	}
9119 	else if (ret != NO_ERROR)
9120 	{
9121 		// Acquisition failure
9122 FAILED:
9123 		Free(p);
9124 		return NULL;
9125 	}
9126 
9127 	// Actually get
9128 	ret = GetIfTable(p, &size_needed, FALSE);
9129 	if (ret != NO_ERROR)
9130 	{
9131 		// Acquisition failure
9132 		if ((++num_retry) >= 5)
9133 		{
9134 			goto FAILED;
9135 		}
9136 		Free(p);
9137 		goto RETRY;
9138 	}
9139 
9140 	// Search
9141 	ret = 0;
9142 	o = NewListFast(CompareStr);
9143 	for (i = 0; i < p->dwNumEntries; i++)
9144 	{
9145 		MIB_IFROW *r = &p->table[i];
9146 		if (SearchStrEx(r->bDescr, tag_name, 0, false) != INFINITE)
9147 		{
9148 			char *s = CopyStr(r->bDescr);
9149 			Add(o, s);
9150 		}
9151 	}
9152 
9153 	Free(p);
9154 
9155 	// Sort
9156 	Sort(o);
9157 
9158 	// Convert to string
9159 	ss = ZeroMallocFast(sizeof(char *) * (LIST_NUM(o) + 1));
9160 	for (i = 0; i < LIST_NUM(o); i++)
9161 	{
9162 		ss[i] = LIST_DATA(o, i);
9163 	}
9164 	ss[LIST_NUM(o)] = NULL;
9165 
9166 	ReleaseList(o);
9167 
9168 	return ss;
9169 }
9170 
9171 // Get the ID of the virtual LAN card from the instance name of the virtual LAN card
Win32GetVLanInterfaceID(char * instance_name)9172 UINT Win32GetVLanInterfaceID(char *instance_name)
9173 {
9174 	MIB_IFTABLE *p;
9175 	BOOL ret;
9176 	ULONG size_needed;
9177 	UINT num_retry = 0;
9178 	UINT i;
9179 	char ps_miniport_str[MAX_SIZE];
9180 	char ps_miniport_str2[MAX_SIZE];
9181 	UINT min_len = 0x7FFFFFFF;
9182 	// Validate arguments
9183 	if (instance_name == 0)
9184 	{
9185 		return 0;
9186 	}
9187 
9188 RETRY:
9189 	p = ZeroMallocFast(sizeof(MIB_IFTABLE));
9190 	size_needed = 0;
9191 
9192 	// Examine the needed size
9193 	ret = GetIfTable(p, &size_needed, 0);
9194 	if (ret == ERROR_INSUFFICIENT_BUFFER)
9195 	{
9196 		// Re-allocate the memory block of the needed size
9197 		Free(p);
9198 		p = ZeroMallocFast(size_needed);
9199 	}
9200 	else if (ret != NO_ERROR)
9201 	{
9202 		// Acquisition failure
9203 FAILED:
9204 		Free(p);
9205 		Debug("******** GetIfTable Failed 1. Err = %u\n", ret);
9206 		return 0;
9207 	}
9208 
9209 	// Actually get
9210 	ret = GetIfTable(p, &size_needed, FALSE);
9211 	if (ret != NO_ERROR)
9212 	{
9213 		// Acquisition failure
9214 		if ((++num_retry) >= 5)
9215 		{
9216 			goto FAILED;
9217 		}
9218 		Free(p);
9219 		Debug("******** GetIfTable Failed 2. Err = %u\n", ret);
9220 		goto RETRY;
9221 	}
9222 
9223 	// "%s - Packet scheduler miniport"
9224 	Format(ps_miniport_str, sizeof(ps_miniport_str), "%s - ", instance_name);
9225 	Format(ps_miniport_str2, sizeof(ps_miniport_str2), "%s (Microsoft", instance_name);
9226 
9227 	// Search
9228 	ret = 0;
9229 	for (i = 0; i < p->dwNumEntries; i++)
9230 	{
9231 		MIB_IFROW *r = &p->table[i];
9232 		if (instance_name[0] != '@')
9233 		{
9234 			if (StrCmpi(r->bDescr, instance_name) == 0 || StartWith(r->bDescr, ps_miniport_str) || StartWith(r->bDescr, ps_miniport_str2))
9235 			{
9236 				UINT len = StrLen(r->bDescr);
9237 
9238 				if (len < min_len)
9239 				{
9240 					ret = r->dwIndex;
9241 
9242 					min_len = len;
9243 				}
9244 			}
9245 		}
9246 		else
9247 		{
9248 			if (SearchStrEx(r->bDescr, &instance_name[1], 0, false) != INFINITE)
9249 			{
9250 				ret = r->dwIndex;
9251 			}
9252 		}
9253 
9254 		//Debug("if[%u] (dwIndex=%u): %u, %s\n", i, r->dwIndex, r->dwType, r->bDescr);
9255 	}
9256 
9257 	Free(p);
9258 
9259 	return ret;
9260 }
9261 
9262 // Get the DNS suffix in another way
Win32GetDnsSuffix(char * domain,UINT size)9263 bool Win32GetDnsSuffix(char *domain, UINT size)
9264 {
9265 	IP_ADAPTER_ADDRESSES_XP *info;
9266 	IP_ADAPTER_ADDRESSES_XP *cur;
9267 	ULONG info_size;
9268 	bool ret = false;
9269 	// Validate arguments
9270 	ClearStr(domain, size);
9271 	if (domain == NULL)
9272 	{
9273 		return false;
9274 	}
9275 
9276 	info_size = 0;
9277 	info = ZeroMalloc(sizeof(IP_ADAPTER_ADDRESSES_XP));
9278 	if (GetAdaptersAddresses(AF_INET, 0, NULL, info, &info_size) == ERROR_BUFFER_OVERFLOW)
9279 	{
9280 		Free(info);
9281 		info = ZeroMalloc(info_size);
9282 	}
9283 	if (GetAdaptersAddresses(AF_INET, 0, NULL, info, &info_size) != NO_ERROR)
9284 	{
9285 		Free(info);
9286 		return false;
9287 	}
9288 
9289 	cur = info;
9290 
9291 	while (cur != NULL)
9292 	{
9293 		if (UniIsEmptyStr(cur->DnsSuffix) == false)
9294 		{
9295 			UniToStr(domain, size, cur->DnsSuffix);
9296 			ret = true;
9297 			break;
9298 		}
9299 
9300 		cur = cur->Next;
9301 	}
9302 
9303 	Free(info);
9304 
9305 	return ret;
9306 }
9307 
9308 // Get the DNS server address of the default
Win32GetDefaultDns(IP * ip,char * domain,UINT size)9309 bool Win32GetDefaultDns(IP *ip, char *domain, UINT size)
9310 {
9311 	FIXED_INFO *info;
9312 	ULONG info_size;
9313 	char *dns_name;
9314 	// Validate arguments
9315 	ClearStr(domain, size);
9316 	if (ip == NULL)
9317 	{
9318 		return false;
9319 	}
9320 	Zero(ip, sizeof(IP));
9321 
9322 	info_size = 0;
9323 	info = ZeroMallocFast(sizeof(FIXED_INFO));
9324 	if (GetNetworkParams(info, &info_size) == ERROR_BUFFER_OVERFLOW)
9325 	{
9326 		Free(info);
9327 		info = ZeroMallocFast(info_size);
9328 	}
9329 	if (GetNetworkParams(info, &info_size) != NO_ERROR)
9330 	{
9331 		Free(info);
9332 		return false;
9333 	}
9334 
9335 	dns_name = info->DnsServerList.IpAddress.String;
9336 	StrToIP(ip, dns_name);
9337 
9338 	if (domain != NULL)
9339 	{
9340 		StrCpy(domain, size, info->DomainName);
9341 		Trim(domain);
9342 	}
9343 
9344 	Free(info);
9345 
9346 	return true;
9347 }
9348 
9349 // IP conversion function for Win32
Win32UINTToIP(IP * ip,UINT i)9350 void Win32UINTToIP(IP *ip, UINT i)
9351 {
9352 	UINTToIP(ip, i);
9353 }
9354 
9355 // IP conversion function for Win32
Win32IPToUINT(IP * ip)9356 UINT Win32IPToUINT(IP *ip)
9357 {
9358 	return IPToUINT(ip);
9359 }
9360 
9361 // Remove a routing entry from the routing table
Win32DeleteRouteEntry(ROUTE_ENTRY * e)9362 void Win32DeleteRouteEntry(ROUTE_ENTRY *e)
9363 {
9364 	MIB_IPFORWARDROW *p;
9365 	// Validate arguments
9366 	if (e == NULL)
9367 	{
9368 		return;
9369 	}
9370 
9371 	p = ZeroMallocFast(sizeof(MIB_IPFORWARDROW));
9372 	Win32RouteEntryToIpForwardRow(p, e);
9373 
9374 	DeleteIpForwardEntry(p);
9375 	Free(p);
9376 }
9377 
9378 // Add a routing entry to the routing table
Win32AddRouteEntry(ROUTE_ENTRY * e,bool * already_exists)9379 bool Win32AddRouteEntry(ROUTE_ENTRY *e, bool *already_exists)
9380 {
9381 	bool ret = false;
9382 	bool dummy = false;
9383 	MIB_IPFORWARDROW *p;
9384 	UINT err = 0;
9385 	// Validate arguments
9386 	if (e == NULL)
9387 	{
9388 		return false;
9389 	}
9390 	if (already_exists == NULL)
9391 	{
9392 		already_exists = &dummy;
9393 	}
9394 
9395 	*already_exists = false;
9396 
9397 	p = ZeroMallocFast(sizeof(MIB_IPFORWARDROW));
9398 	Win32RouteEntryToIpForwardRow(p, e);
9399 
9400 	err = CreateIpForwardEntry(p);
9401 	if (err != 0)
9402 	{
9403 		if (err == ERROR_OBJECT_ALREADY_EXISTS)
9404 		{
9405 			Debug("CreateIpForwardEntry: Already Exists\n");
9406 			*already_exists = true;
9407 			ret = true;
9408 		}
9409 		else
9410 		{
9411 			Debug("CreateIpForwardEntry Error: %u\n", err);
9412 			ret = false;
9413 		}
9414 	}
9415 	else
9416 	{
9417 		ret = true;
9418 	}
9419 
9420 	Free(p);
9421 
9422 	return ret;
9423 }
9424 
9425 // Get the routing table
Win32GetRouteTable()9426 ROUTE_TABLE *Win32GetRouteTable()
9427 {
9428 	ROUTE_TABLE *t = ZeroMallocFast(sizeof(ROUTE_TABLE));
9429 	MIB_IPFORWARDTABLE *p;
9430 	UINT ret;
9431 	ULONG size_needed;
9432 	UINT num_retry = 0;
9433 	LIST *o;
9434 	UINT i;
9435 	ROUTE_ENTRY *e;
9436 
9437 RETRY:
9438 	p = ZeroMallocFast(sizeof(MIB_IFTABLE));
9439 	size_needed = 0;
9440 
9441 	// Examine the needed size
9442 	ret = GetIpForwardTable(p, &size_needed, 0);
9443 	if (ret == ERROR_INSUFFICIENT_BUFFER)
9444 	{
9445 		// Re-allocate the memory block of the needed size
9446 		Free(p);
9447 		p = ZeroMallocFast(size_needed);
9448 	}
9449 	else if (ret != NO_ERROR)
9450 	{
9451 		// Acquisition failure
9452 FAILED:
9453 		Free(p);
9454 		t->Entry = MallocFast(0);
9455 		return t;
9456 	}
9457 
9458 	// Actually get
9459 	ret = GetIpForwardTable(p, &size_needed, FALSE);
9460 	if (ret != NO_ERROR)
9461 	{
9462 		// Acquisition failure
9463 		if ((++num_retry) >= 5)
9464 		{
9465 			goto FAILED;
9466 		}
9467 		Free(p);
9468 		goto RETRY;
9469 	}
9470 
9471 	// Add to the list along
9472 	o = NewListFast(Win32CompareRouteEntryByMetric);
9473 	for (i = 0; i < p->dwNumEntries; i++)
9474 	{
9475 		e = ZeroMallocFast(sizeof(ROUTE_ENTRY));
9476 		Win32IpForwardRowToRouteEntry(e, &p->table[i]);
9477 		Add(o, e);
9478 	}
9479 	Free(p);
9480 
9481 	// Sort by metric
9482 	Sort(o);
9483 
9484 	// Combine the results
9485 	t->NumEntry = LIST_NUM(o);
9486 	t->Entry = ToArrayEx(o, true);
9487 	ReleaseList(o);
9488 
9489 	return t;
9490 }
9491 
9492 // Sort the routing entries by metric
Win32CompareRouteEntryByMetric(void * p1,void * p2)9493 int Win32CompareRouteEntryByMetric(void *p1, void *p2)
9494 {
9495 	ROUTE_ENTRY *e1, *e2;
9496 	// Validate arguments
9497 	if (p1 == NULL || p2 == NULL)
9498 	{
9499 		return 0;
9500 	}
9501 
9502 	e1 = *(ROUTE_ENTRY **)p1;
9503 	e2 = *(ROUTE_ENTRY **)p2;
9504 	if (e1 == NULL || e2 == NULL)
9505 	{
9506 		return 0;
9507 	}
9508 
9509 	if (e1->Metric > e2->Metric)
9510 	{
9511 		return 1;
9512 	}
9513 	else if (e1->Metric == e2->Metric)
9514 	{
9515 		return 0;
9516 	}
9517 	else
9518 	{
9519 		return -1;
9520 	}
9521 }
9522 
9523 // Convert the ROUTE_ENTRY to a MIB_IPFORWARDROW
Win32RouteEntryToIpForwardRow(void * ip_forward_row,ROUTE_ENTRY * entry)9524 void Win32RouteEntryToIpForwardRow(void *ip_forward_row, ROUTE_ENTRY *entry)
9525 {
9526 	MIB_IPFORWARDROW *r;
9527 	// Validate arguments
9528 	if (entry == NULL || ip_forward_row == NULL)
9529 	{
9530 		return;
9531 	}
9532 
9533 	r = (MIB_IPFORWARDROW *)ip_forward_row;
9534 	Zero(r, sizeof(MIB_IPFORWARDROW));
9535 
9536 	// IP address
9537 	r->dwForwardDest = Win32IPToUINT(&entry->DestIP);
9538 	// Subnet mask
9539 	r->dwForwardMask = Win32IPToUINT(&entry->DestMask);
9540 	// Gateway IP address
9541 	r->dwForwardNextHop = Win32IPToUINT(&entry->GatewayIP);
9542 	// Local routing flag
9543 	if (entry->LocalRouting)
9544 	{
9545 		// Local
9546 		r->dwForwardType = 3;
9547 	}
9548 	else
9549 	{
9550 		// Remote router
9551 		r->dwForwardType = 4;
9552 	}
9553 	// Protocol
9554 	r->dwForwardProto = r->dwForwardType - 1;	// Subtract by 1 in most cases
9555 	if (entry->PPPConnection)
9556 	{
9557 		// Isn't this a PPP? Danger!
9558 		r->dwForwardProto++;
9559 	}
9560 	// Metric
9561 	r->dwForwardMetric1 = entry->Metric;
9562 	r->dwForwardMetric2 = r->dwForwardMetric3 = r->dwForwardMetric4 = r->dwForwardMetric5 = 0;
9563 	r->dwForwardAge = 163240;
9564 
9565 	// Interface ID
9566 	r->dwForwardIfIndex = entry->InterfaceID;
9567 
9568 	Debug("Win32RouteEntryToIpForwardRow()\n");
9569 	Debug(" r->dwForwardDest=%X\n", r->dwForwardDest);
9570 	Debug(" r->dwForwardMask=%X\n", r->dwForwardMask);
9571 	Debug(" r->dwForwardNextHop=%X\n", r->dwForwardNextHop);
9572 	Debug(" r->dwForwardType=%u\n", r->dwForwardType);
9573 	Debug(" r->dwForwardProto=%u\n", r->dwForwardProto);
9574 	Debug(" r->dwForwardMetric1=%u\n", r->dwForwardMetric1);
9575 	Debug(" r->dwForwardMetric2=%u\n", r->dwForwardMetric2);
9576 	Debug(" r->dwForwardIfIndex=%u\n", r->dwForwardIfIndex);
9577 }
9578 
9579 // Convert the MIB_IPFORWARDROW to a ROUTE_ENTRY
Win32IpForwardRowToRouteEntry(ROUTE_ENTRY * entry,void * ip_forward_row)9580 void Win32IpForwardRowToRouteEntry(ROUTE_ENTRY *entry, void *ip_forward_row)
9581 {
9582 	MIB_IPFORWARDROW *r;
9583 	// Validate arguments
9584 	if (entry == NULL || ip_forward_row == NULL)
9585 	{
9586 		return;
9587 	}
9588 
9589 	r = (MIB_IPFORWARDROW *)ip_forward_row;
9590 
9591 	Zero(entry, sizeof(ROUTE_ENTRY));
9592 	// IP address
9593 	Win32UINTToIP(&entry->DestIP, r->dwForwardDest);
9594 	// Subnet mask
9595 	Win32UINTToIP(&entry->DestMask, r->dwForwardMask);
9596 	// Gateway IP address
9597 	Win32UINTToIP(&entry->GatewayIP, r->dwForwardNextHop);
9598 	// Local routing flag
9599 	if (r->dwForwardType == 3)
9600 	{
9601 		entry->LocalRouting = true;
9602 	}
9603 	else
9604 	{
9605 		entry->LocalRouting = false;
9606 	}
9607 	if (entry->LocalRouting && r->dwForwardProto == 3)
9608 	{
9609 		// PPP. Danger!
9610 		entry->PPPConnection = true;
9611 	}
9612 	// Metric
9613 	entry->Metric = r->dwForwardMetric1;
9614 	// Interface ID
9615 	entry->InterfaceID = r->dwForwardIfIndex;
9616 }
9617 
9618 // Initializing the socket library
Win32InitSocketLibrary()9619 void Win32InitSocketLibrary()
9620 {
9621 	WSADATA data;
9622 	Zero(&data, sizeof(data));
9623 	WSAStartup(MAKEWORD(2, 2), &data);
9624 }
9625 
9626 // Release of the socket library
Win32FreeSocketLibrary()9627 void Win32FreeSocketLibrary()
9628 {
9629 	WSACleanup();
9630 }
9631 
9632 // Cancel
Win32Cancel(CANCEL * c)9633 void Win32Cancel(CANCEL *c)
9634 {
9635 	// Validate arguments
9636 	if (c == NULL)
9637 	{
9638 		return;
9639 	}
9640 
9641 	SetEvent((HANDLE)c->hEvent);
9642 }
9643 
9644 // Cleanup of the cancel object
Win32CleanupCancel(CANCEL * c)9645 void Win32CleanupCancel(CANCEL *c)
9646 {
9647 	// Validate arguments
9648 	if (c == NULL)
9649 	{
9650 		return;
9651 	}
9652 
9653 	if (c->SpecialFlag == false)
9654 	{
9655 		CloseHandle(c->hEvent);
9656 	}
9657 
9658 	Free(c);
9659 }
9660 
9661 // New cancel object
Win32NewCancel()9662 CANCEL *Win32NewCancel()
9663 {
9664 	CANCEL *c = ZeroMallocFast(sizeof(CANCEL));
9665 	c->ref = NewRef();
9666 	c->SpecialFlag = false;
9667 	c->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
9668 
9669 	return c;
9670 }
9671 
9672 // Waiting for a socket event
Win32WaitSockEvent(SOCK_EVENT * event,UINT timeout)9673 bool Win32WaitSockEvent(SOCK_EVENT *event, UINT timeout)
9674 {
9675 	// Validate arguments
9676 	if (event == NULL || timeout == 0)
9677 	{
9678 		return false;
9679 	}
9680 
9681 	if (WaitForSingleObject((HANDLE)event->hEvent, timeout) == WAIT_OBJECT_0)
9682 	{
9683 		return true;
9684 	}
9685 	else
9686 	{
9687 		return false;
9688 	}
9689 }
9690 
9691 // Clean-up of the socket event
Win32CleanupSockEvent(SOCK_EVENT * event)9692 void Win32CleanupSockEvent(SOCK_EVENT *event)
9693 {
9694 	// Validate arguments
9695 	if (event == NULL)
9696 	{
9697 		return;
9698 	}
9699 
9700 	CloseHandle((HANDLE)event->hEvent);
9701 
9702 	Free(event);
9703 }
9704 
9705 // Set of the socket event
Win32SetSockEvent(SOCK_EVENT * event)9706 void Win32SetSockEvent(SOCK_EVENT *event)
9707 {
9708 	// Validate arguments
9709 	if (event == NULL)
9710 	{
9711 		return;
9712 	}
9713 
9714 	SetEvent((HANDLE)event->hEvent);
9715 }
9716 
9717 // Creating a socket event
Win32NewSockEvent()9718 SOCK_EVENT *Win32NewSockEvent()
9719 {
9720 	SOCK_EVENT *e = ZeroMallocFast(sizeof(SOCK_EVENT));
9721 
9722 	e->ref = NewRef();
9723 	e->hEvent = (void *)CreateEvent(NULL, FALSE, FALSE, NULL);
9724 
9725 	return e;
9726 }
9727 
9728 // Associate the socket with socket event and set it to asynchronous mode
Win32JoinSockToSockEvent(SOCK * sock,SOCK_EVENT * event)9729 void Win32JoinSockToSockEvent(SOCK *sock, SOCK_EVENT *event)
9730 {
9731 	HANDLE hEvent;
9732 	// Validate arguments
9733 	if (sock == NULL || event == NULL || sock->AsyncMode)
9734 	{
9735 		return;
9736 	}
9737 	if (sock->ListenMode != false || (sock->Type != SOCK_UDP && sock->Connected == false))
9738 	{
9739 		return;
9740 	}
9741 
9742 	sock->AsyncMode = true;
9743 
9744 	hEvent = event->hEvent;
9745 
9746 	// Association
9747 	WSAEventSelect(sock->socket, hEvent, FD_READ | FD_WRITE | FD_CLOSE);
9748 
9749 	// Increase the reference count of the SOCK_EVENT
9750 	AddRef(event->ref);
9751 	sock->SockEvent = event;
9752 }
9753 
9754 // Set the socket to asynchronous mode
Win32InitAsyncSocket(SOCK * sock)9755 void Win32InitAsyncSocket(SOCK *sock)
9756 {
9757 	// Validate arguments
9758 	if (sock == NULL)
9759 	{
9760 		return;
9761 	}
9762 	if (sock->AsyncMode)
9763 	{
9764 		// This socket is already in asynchronous mode
9765 		return;
9766 	}
9767 	if (sock->ListenMode || ((sock->Type == SOCK_TCP || sock->Type == SOCK_INPROC) && sock->Connected == false))
9768 	{
9769 		return;
9770 	}
9771 
9772 	sock->AsyncMode = true;
9773 
9774 	if (sock->Type == SOCK_INPROC)
9775 	{
9776 		// Fetch the event of the TUBE
9777 		TUBE *t = sock->RecvTube;
9778 
9779 		if (t != NULL)
9780 		{
9781 			if (t->SockEvent != NULL)
9782 			{
9783 				sock->hEvent = t->SockEvent->hEvent;
9784 			}
9785 		}
9786 	}
9787 	else
9788 	{
9789 		// Creating an Event
9790 		sock->hEvent = (void *)CreateEvent(NULL, FALSE, FALSE, NULL);
9791 
9792 		// Association
9793 		WSAEventSelect(sock->socket, sock->hEvent, FD_READ | FD_WRITE | FD_CLOSE);
9794 	}
9795 }
9796 
9797 // Release the asynchronous socket
Win32FreeAsyncSocket(SOCK * sock)9798 void Win32FreeAsyncSocket(SOCK *sock)
9799 {
9800 	// Validate arguments
9801 	if (sock == NULL)
9802 	{
9803 		return;
9804 	}
9805 
9806 	// Asynchronous socket
9807 	if (sock->hEvent != NULL)
9808 	{
9809 		if (sock->Type != SOCK_INPROC)
9810 		{
9811 			CloseHandle((HANDLE)sock->hEvent);
9812 		}
9813 	}
9814 	sock->hEvent = NULL;
9815 	sock->AsyncMode = false;
9816 
9817 	// Socket event
9818 	if (sock->SockEvent != NULL)
9819 	{
9820 		ReleaseSockEvent(sock->SockEvent);
9821 		sock->SockEvent = NULL;
9822 	}
9823 }
9824 
9825 // Select function for Win32
Win32Select(SOCKSET * set,UINT timeout,CANCEL * c1,CANCEL * c2)9826 void Win32Select(SOCKSET *set, UINT timeout, CANCEL *c1, CANCEL *c2)
9827 {
9828 	HANDLE array[MAXIMUM_WAIT_OBJECTS];
9829 	UINT n, i;
9830 	SOCK *s;
9831 	// Initialization of array
9832 	Zero(array, sizeof(array));
9833 	n = 0;
9834 
9835 	// Setting the event array
9836 	if (set != NULL)
9837 	{
9838 		for (i = 0; i < set->NumSocket; i++)
9839 		{
9840 			s = set->Sock[i];
9841 			if (s != NULL)
9842 			{
9843 				Win32InitAsyncSocket(s);
9844 				if (s->hEvent != NULL)
9845 				{
9846 					array[n++] = (HANDLE)s->hEvent;
9847 				}
9848 
9849 				if (s->BulkRecvTube != NULL)
9850 				{
9851 					array[n++] = (HANDLE)s->BulkRecvTube->SockEvent->hEvent;
9852 				}
9853 			}
9854 		}
9855 	}
9856 	if (c1 != NULL && c1->hEvent != NULL)
9857 	{
9858 		array[n++] = c1->hEvent;
9859 	}
9860 	if (c2 != NULL && c2->hEvent != NULL)
9861 	{
9862 		array[n++] = c2->hEvent;
9863 	}
9864 
9865 	if (timeout == 0)
9866 	{
9867 		return;
9868 	}
9869 
9870 	if (n == 0)
9871 	{
9872 		// Call normal waiting function if no events to wait are registered
9873 		SleepThread(timeout);
9874 	}
9875 	else
9876 	{
9877 		// Wait for the event if events are registered at least one
9878 		if (n == 1)
9879 		{
9880 			// Calling a lightweight version If the event is only one
9881 			WaitForSingleObject(array[0], timeout);
9882 		}
9883 		else
9884 		{
9885 			// In case of multiple events
9886 			WaitForMultipleObjects(n, array, false, timeout);
9887 		}
9888 	}
9889 }
9890 
9891 #endif	// OS_WIN32
9892 
9893 // Check whether the IPv6 is supported
IsIPv6Supported()9894 bool IsIPv6Supported()
9895 {
9896 #ifdef	NO_IPV6
9897 	return false;
9898 #else	// NO_IPV6
9899 	SOCKET s;
9900 
9901 	s = socket(AF_INET6, SOCK_STREAM, 0);
9902 	if (s == INVALID_SOCKET)
9903 	{
9904 		return false;
9905 	}
9906 
9907 	closesocket(s);
9908 
9909 	return true;
9910 #endif	// NO_IPV6
9911 }
9912 
9913 // Add the thread to the thread waiting list
AddWaitThread(THREAD * t)9914 void AddWaitThread(THREAD *t)
9915 {
9916 	// Validate arguments
9917 	if (t == NULL)
9918 	{
9919 		return;
9920 	}
9921 
9922 	AddRef(t->ref);
9923 
9924 	LockList(WaitThreadList);
9925 	{
9926 		Add(WaitThreadList, t);
9927 	}
9928 	UnlockList(WaitThreadList);
9929 }
9930 
9931 // Remove the thread from the waiting list
DelWaitThread(THREAD * t)9932 void DelWaitThread(THREAD *t)
9933 {
9934 	// Validate arguments
9935 	if (t == NULL)
9936 	{
9937 		return;
9938 	}
9939 
9940 	LockList(WaitThreadList);
9941 	{
9942 		if (Delete(WaitThreadList, t))
9943 		{
9944 			ReleaseThread(t);
9945 		}
9946 	}
9947 	UnlockList(WaitThreadList);
9948 }
9949 
9950 // Creating a thread waiting list
InitWaitThread()9951 void InitWaitThread()
9952 {
9953 	WaitThreadList = NewList(NULL);
9954 }
9955 
9956 // Release of the thread waiting list
FreeWaitThread()9957 void FreeWaitThread()
9958 {
9959 	UINT i, num;
9960 	THREAD **threads;
9961 
9962 	LockList(WaitThreadList);
9963 	{
9964 		num = LIST_NUM(WaitThreadList);
9965 		threads = ToArray(WaitThreadList);
9966 		DeleteAll(WaitThreadList);
9967 	}
9968 	UnlockList(WaitThreadList);
9969 
9970 	for (i = 0; i < num; i++)
9971 	{
9972 		THREAD *t = threads[i];
9973 		WaitThread(t, INFINITE);
9974 		ReleaseThread(t);
9975 	}
9976 
9977 	Free(threads);
9978 
9979 	ReleaseList(WaitThreadList);
9980 	WaitThreadList = NULL;
9981 }
9982 
9983 // Get a domain name for UNIX
UnixGetDomainName(char * name,UINT size)9984 bool UnixGetDomainName(char *name, UINT size)
9985 {
9986 	bool ret = false;
9987 	BUF *b = ReadDump("/etc/resolv.conf");
9988 
9989 	if (b == NULL)
9990 	{
9991 		return false;
9992 	}
9993 
9994 	while (true)
9995 	{
9996 		char *s = CfgReadNextLine(b);
9997 		TOKEN_LIST *t;
9998 
9999 		if (s == NULL)
10000 		{
10001 			break;
10002 		}
10003 
10004 		Trim(s);
10005 
10006 		t = ParseToken(s, " \t");
10007 		if (t != NULL)
10008 		{
10009 			if (t->NumTokens == 2)
10010 			{
10011 				if (StrCmpi(t->Token[0], "domain") == 0)
10012 				{
10013 					StrCpy(name, size, t->Token[1]);
10014 					ret = true;
10015 				}
10016 			}
10017 			FreeToken(t);
10018 		}
10019 
10020 		Free(s);
10021 	}
10022 
10023 	FreeBuf(b);
10024 
10025 	return ret;
10026 }
10027 
10028 // Get the domain name
GetDomainName(char * name,UINT size)10029 bool GetDomainName(char *name, UINT size)
10030 {
10031 	bool ret = false;
10032 	IP ip;
10033 	// Validate arguments
10034 	ClearStr(name, size);
10035 	if (name == NULL)
10036 	{
10037 		return false;
10038 	}
10039 
10040 #ifdef	OS_WIN32
10041 	ClearStr(name, size);
10042 	ret = Win32GetDefaultDns(&ip, name, size);
10043 
10044 	if (ret == false || IsEmptyStr(name))
10045 	{
10046 		ret = Win32GetDnsSuffix(name, size);
10047 	}
10048 #else	// OS_WIN32
10049 	ret = UnixGetDomainName(name, size);
10050 #endif	// OS_WIN32
10051 
10052 	if (ret == false)
10053 	{
10054 		return false;
10055 	}
10056 
10057 	return (IsEmptyStr(name) ? false : true);
10058 }
10059 
10060 // Get the default DNS server
GetDefaultDns(IP * ip)10061 bool GetDefaultDns(IP *ip)
10062 {
10063 #ifdef	OS_WIN32
10064 	return Win32GetDefaultDns(ip, NULL, 0);
10065 #else
10066 	return UnixGetDefaultDns(ip);
10067 #endif	// OS_WIN32
10068 }
10069 
10070 // Creating a socket event
NewSockEvent()10071 SOCK_EVENT *NewSockEvent()
10072 {
10073 #ifdef	OS_WIN32
10074 	return Win32NewSockEvent();
10075 #else
10076 	return UnixNewSockEvent();
10077 #endif	// OS_WIN32
10078 }
10079 
10080 // Set of the socket event
SetSockEvent(SOCK_EVENT * event)10081 void SetSockEvent(SOCK_EVENT *event)
10082 {
10083 #ifdef	OS_WIN32
10084 	Win32SetSockEvent(event);
10085 #else
10086 	UnixSetSockEvent(event);
10087 #endif	// OS_WIN32
10088 }
10089 
10090 // Clean-up of the socket event
CleanupSockEvent(SOCK_EVENT * event)10091 void CleanupSockEvent(SOCK_EVENT *event)
10092 {
10093 #ifdef	OS_WIN32
10094 	Win32CleanupSockEvent(event);
10095 #else
10096 	UnixCleanupSockEvent(event);
10097 #endif	// OS_WIN32
10098 }
10099 
10100 // Waiting for the socket event
WaitSockEvent(SOCK_EVENT * event,UINT timeout)10101 bool WaitSockEvent(SOCK_EVENT *event, UINT timeout)
10102 {
10103 	bool ret = false;
10104 #ifdef	OS_WIN32
10105 	ret = Win32WaitSockEvent(event, timeout);
10106 #else
10107 	ret = UnixWaitSockEvent(event, timeout);
10108 #endif	// OS_WIN32
10109 	return ret;
10110 }
10111 
10112 // Release of the socket event
ReleaseSockEvent(SOCK_EVENT * event)10113 void ReleaseSockEvent(SOCK_EVENT *event)
10114 {
10115 	// Validate arguments
10116 	if (event == NULL)
10117 	{
10118 		return;
10119 	}
10120 
10121 	if (Release(event->ref) == 0)
10122 	{
10123 		CleanupSockEvent(event);
10124 	}
10125 }
10126 
10127 // Let belonging the socket to the socket event
JoinSockToSockEvent(SOCK * sock,SOCK_EVENT * event)10128 void JoinSockToSockEvent(SOCK *sock, SOCK_EVENT *event)
10129 {
10130 	// Validate arguments
10131 	if (sock == NULL || event == NULL)
10132 	{
10133 		return;
10134 	}
10135 
10136 	if (sock->Type == SOCK_INPROC)
10137 	{
10138 		// Set the SockEvent on the receiver TUBE for in-process type socket
10139 		SetTubeSockEvent(sock->RecvTube, event);
10140 		return;
10141 	}
10142 
10143 	if (sock->BulkRecvTube != NULL)
10144 	{
10145 		// Set the SockEvent on the receiver TUBE in case of R-UDP socket
10146 		SetTubeSockEvent(sock->BulkRecvTube, event);
10147 	}
10148 
10149 #ifdef	OS_WIN32
10150 	Win32JoinSockToSockEvent(sock, event);
10151 #else
10152 	UnixJoinSockToSockEvent(sock, event);
10153 #endif	// OS_WIN32
10154 }
10155 
10156 // New special cancel object
NewCancelSpecial(void * hEvent)10157 CANCEL *NewCancelSpecial(void *hEvent)
10158 {
10159 	CANCEL *c;
10160 	// Validate arguments
10161 	if (hEvent == NULL)
10162 	{
10163 		return NULL;
10164 	}
10165 
10166 	c = ZeroMalloc(sizeof(CANCEL));
10167 	c->ref = NewRef();
10168 	c->SpecialFlag = true;
10169 
10170 #ifdef	OS_WIN32
10171 	c->hEvent = (HANDLE)hEvent;
10172 #else	// OS_WIN32
10173 	c->pipe_read = (int)hEvent;
10174 	c->pipe_write = -1;
10175 #endif	// OS_WIN32
10176 
10177 	return c;
10178 }
10179 
10180 // Creating a cancel object
NewCancel()10181 CANCEL *NewCancel()
10182 {
10183 	CANCEL *c = NULL;
10184 #ifdef	OS_WIN32
10185 	c = Win32NewCancel();
10186 #else
10187 	c = UnixNewCancel();
10188 #endif	// OS_WIN32
10189 	return c;
10190 }
10191 
10192 // Release of the cancel object
ReleaseCancel(CANCEL * c)10193 void ReleaseCancel(CANCEL *c)
10194 {
10195 	// Validate arguments
10196 	if (c == NULL)
10197 	{
10198 		return;
10199 	}
10200 
10201 	if (Release(c->ref) == 0)
10202 	{
10203 		CleanupCancel(c);
10204 	}
10205 }
10206 
10207 // Clean up of the cancel object
CleanupCancel(CANCEL * c)10208 void CleanupCancel(CANCEL *c)
10209 {
10210 #ifdef	OS_WIN32
10211 	Win32CleanupCancel(c);
10212 #else
10213 	UnixCleanupCancel(c);
10214 #endif
10215 }
10216 
10217 // Cancellation triggered
Cancel(CANCEL * c)10218 void Cancel(CANCEL *c)
10219 {
10220 #ifdef	OS_WIN32
10221 	Win32Cancel(c);
10222 #else
10223 	UnixCancel(c);
10224 #endif
10225 }
10226 
10227 // Calculate the optimal route from the specified routing table
GetBestRouteEntryFromRouteTableEx(ROUTE_TABLE * table,IP * ip,UINT exclude_if_id)10228 ROUTE_ENTRY *GetBestRouteEntryFromRouteTableEx(ROUTE_TABLE *table, IP *ip, UINT exclude_if_id)
10229 {
10230 	UINT i;
10231 	ROUTE_ENTRY *ret = NULL;
10232 	ROUTE_ENTRY *tmp = NULL;
10233 	UINT64 min_score = 0;
10234 	// Validate arguments
10235 	if (ip == NULL || table == NULL)
10236 	{
10237 		return NULL;
10238 	}
10239 
10240 	if (IsIP6(ip))
10241 	{
10242 		// IPv6 is not supported
10243 		return NULL;
10244 	}
10245 
10246 	// Select routing table entry by following rule
10247 	// 1. Largest subnet mask
10248 	// 2. Smallest metric value
10249 	for (i = 0; i < table->NumEntry; i++)
10250 	{
10251 		ROUTE_ENTRY *e = table->Entry[i];
10252 		UINT dest, net, mask;
10253 
10254 		dest = IPToUINT(ip);
10255 		net = IPToUINT(&e->DestIP);
10256 		mask = IPToUINT(&e->DestMask);
10257 
10258 		if (exclude_if_id != 0)
10259 		{
10260 			if (e->InterfaceID == exclude_if_id)
10261 			{
10262 				continue;
10263 			}
10264 		}
10265 
10266 		// Mask test
10267 		if ((dest & mask) == (net & mask))
10268 		{
10269 			// Calculate the score
10270 			UINT score_high32 = mask;
10271 			UINT score_low32 = 0xFFFFFFFF - e->Metric;
10272 			UINT64 score64 = (UINT64)score_high32 * (UINT64)0x80000000 * (UINT64)2 + (UINT64)score_low32;
10273 			if (score64 == 0)
10274 			{
10275 				score64 = 1;
10276 			}
10277 
10278 			e->InnerScore = score64;
10279 		}
10280 	}
10281 
10282 	tmp = NULL;
10283 
10284 	// Search for the item with maximum score
10285 	for (i = 0; i < table->NumEntry; i++)
10286 	{
10287 		ROUTE_ENTRY *e = table->Entry[i];
10288 
10289 		if (e->InnerScore != 0)
10290 		{
10291 			if (e->InnerScore >= min_score)
10292 			{
10293 				tmp = e;
10294 				min_score = e->InnerScore;
10295 			}
10296 		}
10297 	}
10298 
10299 	if (tmp != NULL)
10300 	{
10301 		UINT dest, gateway, mask;
10302 
10303 		// Generate an entry
10304 		ret = ZeroMallocFast(sizeof(ROUTE_ENTRY));
10305 
10306 		Copy(&ret->DestIP, ip, sizeof(IP));
10307 		SetIP(&ret->DestMask, 255, 255, 255, 255);
10308 		Copy(&ret->GatewayIP, &tmp->GatewayIP, sizeof(IP));
10309 		ret->InterfaceID = tmp->InterfaceID;
10310 		ret->LocalRouting = tmp->LocalRouting;
10311 		ret->OldIfMetric = tmp->Metric;
10312 		ret->Metric = 1;
10313 		ret->PPPConnection = tmp->PPPConnection;
10314 
10315 		// Calculation related to routing control
10316 		dest = IPToUINT(&tmp->DestIP);
10317 		gateway = IPToUINT(&tmp->GatewayIP);
10318 		mask = IPToUINT(&tmp->DestMask);
10319 	}
10320 
10321 	return ret;
10322 }
10323 
10324 // Release the routing entry
FreeRouteEntry(ROUTE_ENTRY * e)10325 void FreeRouteEntry(ROUTE_ENTRY *e)
10326 {
10327 	// Validate arguments
10328 	if (e == NULL)
10329 	{
10330 		return;
10331 	}
10332 
10333 	Free(e);
10334 }
10335 
10336 // Get the best route entry by analyzing the current routing table
GetBestRouteEntry(IP * ip)10337 ROUTE_ENTRY *GetBestRouteEntry(IP *ip)
10338 {
10339 	return GetBestRouteEntryEx(ip, 0);
10340 }
GetBestRouteEntryEx(IP * ip,UINT exclude_if_id)10341 ROUTE_ENTRY *GetBestRouteEntryEx(IP *ip, UINT exclude_if_id)
10342 {
10343 	ROUTE_TABLE *table;
10344 	ROUTE_ENTRY *e = NULL;
10345 	// Validate arguments
10346 	if (ip == NULL)
10347 	{
10348 		return NULL;
10349 	}
10350 
10351 	table = GetRouteTable();
10352 	if (table == NULL)
10353 	{
10354 		return NULL;
10355 	}
10356 
10357 	e = GetBestRouteEntryFromRouteTableEx(table, ip, exclude_if_id);
10358 	FreeRouteTable(table);
10359 
10360 	return e;
10361 }
10362 
10363 // Get the interface ID of the virtual LAN card
GetVLanInterfaceID(char * tag_name)10364 UINT GetVLanInterfaceID(char *tag_name)
10365 {
10366 	UINT ret = 0;
10367 #ifdef	OS_WIN32
10368 	ret = Win32GetVLanInterfaceID(tag_name);
10369 #else	// OS_WIN32
10370 	ret = UnixGetVLanInterfaceID(tag_name);
10371 #endif	// OS_WIN32
10372 	return ret;
10373 }
10374 
10375 // Release of enumeration variable of virtual LAN card
FreeEnumVLan(char ** s)10376 void FreeEnumVLan(char **s)
10377 {
10378 	char *a;
10379 	UINT i;
10380 	// Validate arguments
10381 	if (s == NULL)
10382 	{
10383 		return;
10384 	}
10385 
10386 	i = 0;
10387 	while (true)
10388 	{
10389 		a = s[i++];
10390 		if (a == NULL)
10391 		{
10392 			break;
10393 		}
10394 		Free(a);
10395 	}
10396 
10397 	Free(s);
10398 }
10399 
10400 // Enumeration of virtual LAN cards
EnumVLan(char * tag_name)10401 char **EnumVLan(char *tag_name)
10402 {
10403 	char **ret = NULL;
10404 #ifdef	OS_WIN32
10405 	ret = Win32EnumVLan(tag_name);
10406 #else	// OS_WIN32
10407 	ret = UnixEnumVLan(tag_name);
10408 #endif	// OS_WIN32
10409 	return ret;
10410 }
10411 
10412 // Display the routing table
DebugPrintRouteTable(ROUTE_TABLE * r)10413 void DebugPrintRouteTable(ROUTE_TABLE *r)
10414 {
10415 	UINT i;
10416 	// Validate arguments
10417 	if (r == NULL)
10418 	{
10419 		return;
10420 	}
10421 
10422 	if (IsDebug() == false)
10423 	{
10424 		return;
10425 	}
10426 
10427 	Debug("---- Routing Table (%u Entries) ----\n", r->NumEntry);
10428 
10429 	for (i = 0; i < r->NumEntry; i++)
10430 	{
10431 		Debug("   ");
10432 
10433 		DebugPrintRoute(r->Entry[i]);
10434 	}
10435 
10436 	Debug("------------------------------------\n");
10437 }
10438 
10439 // Display the routing table entry
DebugPrintRoute(ROUTE_ENTRY * e)10440 void DebugPrintRoute(ROUTE_ENTRY *e)
10441 {
10442 	char tmp[MAX_SIZE];
10443 	// Validate arguments
10444 	if (e == NULL)
10445 	{
10446 		return;
10447 	}
10448 
10449 	if (IsDebug() == false)
10450 	{
10451 		return;
10452 	}
10453 
10454 	RouteToStr(tmp, sizeof(tmp), e);
10455 
10456 	Debug("%s\n", tmp);
10457 }
10458 
10459 // Convert the routing table entry to string
RouteToStr(char * str,UINT str_size,ROUTE_ENTRY * e)10460 void RouteToStr(char *str, UINT str_size, ROUTE_ENTRY *e)
10461 {
10462 	char dest_ip[MAX_PATH];
10463 	char dest_mask[MAX_PATH];
10464 	char gateway_ip[MAX_PATH];
10465 	// Validate arguments
10466 	if (str == NULL || e == NULL)
10467 	{
10468 		return;
10469 	}
10470 
10471 	IPToStr(dest_ip, sizeof(dest_ip), &e->DestIP);
10472 	IPToStr(dest_mask, sizeof(dest_mask), &e->DestMask);
10473 	IPToStr(gateway_ip, sizeof(gateway_ip), &e->GatewayIP);
10474 
10475 	Format(str, str_size, "%s/%s %s m=%u oif=%u if=%u lo=%u p=%u",
10476 	       dest_ip, dest_mask, gateway_ip,
10477 	       e->Metric, e->OldIfMetric, e->InterfaceID,
10478 	       e->LocalRouting, e->PPPConnection);
10479 }
10480 
10481 // Delete the routing table
DeleteRouteEntry(ROUTE_ENTRY * e)10482 void DeleteRouteEntry(ROUTE_ENTRY *e)
10483 {
10484 	Debug("DeleteRouteEntry();\n");
10485 #ifdef	OS_WIN32
10486 	Win32DeleteRouteEntry(e);
10487 #else	// OS_WIN32
10488 	UnixDeleteRouteEntry(e);
10489 #endif
10490 }
10491 
10492 // Add to the routing table
AddRouteEntry(ROUTE_ENTRY * e)10493 bool AddRouteEntry(ROUTE_ENTRY *e)
10494 {
10495 	bool dummy = false;
10496 	return AddRouteEntryEx(e, &dummy);
10497 }
AddRouteEntryEx(ROUTE_ENTRY * e,bool * already_exists)10498 bool AddRouteEntryEx(ROUTE_ENTRY *e, bool *already_exists)
10499 {
10500 	bool ret = false;
10501 	Debug("AddRouteEntryEx();\n");
10502 #ifdef	OS_WIN32
10503 	ret = Win32AddRouteEntry(e, already_exists);
10504 #else	// OS_WIN32
10505 	ret = UnixAddRouteEntry(e, already_exists);
10506 #endif
10507 	return ret;
10508 }
10509 
10510 // Get the routing table
GetRouteTable()10511 ROUTE_TABLE *GetRouteTable()
10512 {
10513 	ROUTE_TABLE *t = NULL;
10514 	UINT i;
10515 	BUF *buf = NewBuf();
10516 	UCHAR hash[MD5_SIZE];
10517 
10518 #ifdef	OS_WIN32
10519 	t = Win32GetRouteTable();
10520 #else	//OS_WIN32
10521 	t = UnixGetRouteTable();
10522 #endif	// OS_WIN32
10523 
10524 	WriteBuf(buf, &t->NumEntry, sizeof(t->NumEntry));
10525 
10526 	for (i = 0; i < t->NumEntry; i++)
10527 	{
10528 		ROUTE_ENTRY *e = t->Entry[i];
10529 
10530 		WriteBuf(buf, e, sizeof(ROUTE_ENTRY));
10531 	}
10532 
10533 	Md5(hash, buf->Buf, buf->Size);
10534 
10535 	FreeBuf(buf);
10536 
10537 	Copy(&t->HashedValue, hash, sizeof(t->HashedValue));
10538 
10539 	return t;
10540 }
10541 
10542 // Release of the routing table
FreeRouteTable(ROUTE_TABLE * t)10543 void FreeRouteTable(ROUTE_TABLE *t)
10544 {
10545 	UINT i;
10546 	// Validate arguments
10547 	if (t == NULL)
10548 	{
10549 		return;
10550 	}
10551 
10552 	for (i = 0; i < t->NumEntry; i++)
10553 	{
10554 		Free(t->Entry[i]);
10555 	}
10556 	Free(t->Entry);
10557 	Free(t);
10558 }
10559 
10560 // UDP receiving
RecvFrom(SOCK * sock,IP * src_addr,UINT * src_port,void * data,UINT size)10561 UINT RecvFrom(SOCK *sock, IP *src_addr, UINT *src_port, void *data, UINT size)
10562 {
10563 	struct sockaddr_in addr;
10564 	int ret = 0;
10565 #ifdef	OS_WIN32
10566 	int socklen = sizeof(addr);
10567 #else
10568 	socklen_t socklen = sizeof(addr);
10569 #endif
10570 
10571 	// Validate arguments
10572 	if (sock != NULL)
10573 	{
10574 		if (sock->IPv6)
10575 		{
10576 			return RecvFrom6(sock, src_addr, src_port, data, size);
10577 		}
10578 
10579 		sock->IgnoreRecvErr = false;
10580 	}
10581 	else
10582 	{
10583 		return 0;
10584 	}
10585 
10586 	if (src_addr == NULL || src_port == NULL || data == NULL || size == 0)
10587 	{
10588 		return 0;
10589 	}
10590 
10591 	if (sock->Type != SOCK_UDP || sock->socket == INVALID_SOCKET)
10592 	{
10593 		return 0;
10594 	}
10595 
10596 	ret = recvfrom(sock->socket, data, size, 0, (struct sockaddr *)&addr, &socklen);
10597 	if (ret > 0)
10598 	{
10599 		InAddrToIP(src_addr, &addr.sin_addr);
10600 		*src_port = (UINT)ntohs(addr.sin_port);
10601 		if (sock->IsRawSocket)
10602 		{
10603 			*src_port = sock->LocalPort;
10604 		}
10605 
10606 		Lock(sock->lock);
10607 		{
10608 			sock->RecvNum++;
10609 			sock->RecvSize += (UINT64)ret;
10610 		}
10611 		Unlock(sock->lock);
10612 
10613 		return (UINT)ret;
10614 	}
10615 	else
10616 	{
10617 #ifdef	OS_WIN32
10618 		if (WSAGetLastError() == WSAECONNRESET || WSAGetLastError() == WSAENETRESET || WSAGetLastError() == WSAEMSGSIZE || WSAGetLastError() == WSAENETUNREACH ||
10619 		        WSAGetLastError() == WSAENOBUFS || WSAGetLastError() == WSAEHOSTUNREACH || WSAGetLastError() == WSAEUSERS || WSAGetLastError() == WSAEADDRNOTAVAIL || WSAGetLastError() == WSAEADDRNOTAVAIL)
10620 		{
10621 			sock->IgnoreRecvErr = true;
10622 		}
10623 		else if (WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINPROGRESS)
10624 		{
10625 			return SOCK_LATER;
10626 		}
10627 		else
10628 		{
10629 			Debug("RecvFrom(): recvfrom() failed with error: %u\n", WSAGetLastError());
10630 		}
10631 #else
10632 		if (errno == ECONNREFUSED || errno == ECONNRESET || errno == EMSGSIZE || errno == ENOBUFS || errno == ENOMEM || errno == EINTR)
10633 		{
10634 			sock->IgnoreRecvErr = true;
10635 		}
10636 		else if (errno == EAGAIN)
10637 		{
10638 			return SOCK_LATER;
10639 		}
10640 		else
10641 		{
10642 			Debug("RecvFrom(): recvfrom() failed with error: %s\n", strerror(errno));
10643 		}
10644 #endif
10645 		return 0;
10646 	}
10647 }
RecvFrom6(SOCK * sock,IP * src_addr,UINT * src_port,void * data,UINT size)10648 UINT RecvFrom6(SOCK *sock, IP *src_addr, UINT *src_port, void *data, UINT size)
10649 {
10650 	struct sockaddr_in6 addr;
10651 	int ret = 0;
10652 #ifdef	OS_WIN32
10653 	int socklen = sizeof(addr);
10654 #else
10655 	socklen_t socklen = sizeof(addr);
10656 #endif
10657 
10658 	// Validate arguments
10659 	if (sock != NULL)
10660 	{
10661 		sock->IgnoreRecvErr = false;
10662 	}
10663 	else
10664 	{
10665 		return 0;
10666 	}
10667 
10668 	if (src_addr == NULL || src_port == NULL || data == NULL || size == 0)
10669 	{
10670 		return 0;
10671 	}
10672 
10673 	if (sock->Type != SOCK_UDP || sock->socket == INVALID_SOCKET)
10674 	{
10675 		return 0;
10676 	}
10677 
10678 
10679 	ret = recvfrom(sock->socket, data, size, 0, (struct sockaddr *)&addr, &socklen);
10680 	if (ret > 0)
10681 	{
10682 		InAddrToIP6(src_addr, &addr.sin6_addr);
10683 		src_addr->ipv6_scope_id = addr.sin6_scope_id;
10684 		*src_port = (UINT)ntohs(addr.sin6_port);
10685 		if (sock->IsRawSocket)
10686 		{
10687 			*src_port = sock->LocalPort;
10688 		}
10689 
10690 		Lock(sock->lock);
10691 		{
10692 			sock->RecvNum++;
10693 			sock->RecvSize += (UINT64)ret;
10694 		}
10695 		Unlock(sock->lock);
10696 
10697 		return (UINT)ret;
10698 	}
10699 	else
10700 	{
10701 #ifdef	OS_WIN32
10702 		if (WSAGetLastError() == WSAECONNRESET || WSAGetLastError() == WSAENETRESET || WSAGetLastError() == WSAEMSGSIZE || WSAGetLastError() == WSAENETUNREACH ||
10703 		        WSAGetLastError() == WSAENOBUFS || WSAGetLastError() == WSAEHOSTUNREACH || WSAGetLastError() == WSAEUSERS || WSAGetLastError() == WSAEADDRNOTAVAIL || WSAGetLastError() == WSAEADDRNOTAVAIL)
10704 		{
10705 			sock->IgnoreRecvErr = true;
10706 		}
10707 		else if (WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINPROGRESS)
10708 		{
10709 			return SOCK_LATER;
10710 		}
10711 		else
10712 		{
10713 			Debug("RecvFrom(): recvfrom() failed with error: %u\n", WSAGetLastError());
10714 		}
10715 #else
10716 		if (errno == ECONNREFUSED || errno == ECONNRESET || errno == EMSGSIZE || errno == ENOBUFS || errno == ENOMEM || errno == EINTR)
10717 		{
10718 			sock->IgnoreRecvErr = true;
10719 		}
10720 		else if (errno == EAGAIN)
10721 		{
10722 			return SOCK_LATER;
10723 		}
10724 		else
10725 		{
10726 			Debug("RecvFrom(): recvfrom() failed with error: %s\n", strerror(errno));
10727 		}
10728 #endif
10729 		return 0;
10730 	}
10731 }
10732 
10733 // UDP transmission
SendTo(SOCK * sock,IP * dest_addr,UINT dest_port,void * data,UINT size)10734 UINT SendTo(SOCK *sock, IP *dest_addr, UINT dest_port, void *data, UINT size)
10735 {
10736 	return SendToEx(sock, dest_addr, dest_port, data, size, false);
10737 }
SendToEx(SOCK * sock,IP * dest_addr,UINT dest_port,void * data,UINT size,bool broadcast)10738 UINT SendToEx(SOCK *sock, IP *dest_addr, UINT dest_port, void *data, UINT size, bool broadcast)
10739 {
10740 	SOCKET s;
10741 	int ret;
10742 	struct sockaddr_in addr;
10743 	// Validate arguments
10744 	if (sock != NULL)
10745 	{
10746 		sock->IgnoreSendErr = false;
10747 	}
10748 	if (sock == NULL || dest_addr == NULL || (sock->IsRawSocket == false && dest_port == 0) || data == NULL)
10749 	{
10750 		return 0;
10751 	}
10752 	if (dest_port >= 65536 && sock->IsRawSocket == false)
10753 	{
10754 		return 0;
10755 	}
10756 	if (sock->Type != SOCK_UDP || sock->socket == INVALID_SOCKET)
10757 	{
10758 		return 0;
10759 	}
10760 	if (size == 0)
10761 	{
10762 		return 0;
10763 	}
10764 
10765 	if (sock->IPv6)
10766 	{
10767 		return SendTo6Ex(sock, dest_addr, dest_port, data, size, broadcast);
10768 	}
10769 
10770 	if (IsIP4(dest_addr) == false)
10771 	{
10772 		return 0;
10773 	}
10774 
10775 	s = sock->socket;
10776 	Zero(&addr, sizeof(addr));
10777 	addr.sin_family = AF_INET;
10778 	if (sock->IsRawSocket == false)
10779 	{
10780 		addr.sin_port = htons((USHORT)dest_port);
10781 	}
10782 	IPToInAddr(&addr.sin_addr, dest_addr);
10783 
10784 	const BYTE *ipv4 = IPV4(dest_addr->address);
10785 	if ((ipv4[0] == 255 && ipv4[1] == 255 && ipv4[2] == 255 && ipv4[3] == 255) ||
10786 		(ipv4[0] >= 224 && ipv4[0] <= 239) ||
10787 		broadcast)
10788 	{
10789 		if (sock->UdpBroadcast == false)
10790 		{
10791 			bool yes = true;
10792 
10793 			sock->UdpBroadcast = true;
10794 
10795 			(void)setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char *)&yes, sizeof(yes));
10796 		}
10797 	}
10798 
10799 	ret = sendto(s, data, size, 0, (struct sockaddr *)&addr, sizeof(addr));
10800 	if (ret != (int)size)
10801 	{
10802 		sock->IgnoreSendErr = false;
10803 
10804 #ifdef	OS_WIN32
10805 		if (WSAGetLastError() == WSAECONNRESET || WSAGetLastError() == WSAENETRESET || WSAGetLastError() == WSAEMSGSIZE || WSAGetLastError() == WSAENETUNREACH ||
10806 		        WSAGetLastError() == WSAENOBUFS || WSAGetLastError() == WSAEHOSTUNREACH || WSAGetLastError() == WSAEUSERS || WSAGetLastError() == WSAEINVAL || WSAGetLastError() == WSAEADDRNOTAVAIL)
10807 		{
10808 			sock->IgnoreSendErr = true;
10809 		}
10810 		else if (WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINPROGRESS)
10811 		{
10812 			return SOCK_LATER;
10813 		}
10814 		else
10815 		{
10816 			UINT e = WSAGetLastError();
10817 			Debug("SendTo Error; %u\n", e);
10818 		}
10819 #else	// OS_WIN32
10820 		if (errno == ECONNREFUSED || errno == ECONNRESET || errno == EMSGSIZE || errno == ENOBUFS || errno == ENOMEM || errno == EINTR || errno == EINVAL)
10821 		{
10822 			sock->IgnoreSendErr = true;
10823 		}
10824 		else if (errno == EAGAIN)
10825 		{
10826 			return SOCK_LATER;
10827 		}
10828 #endif	// OS_WIN32
10829 		return 0;
10830 	}
10831 
10832 	Lock(sock->lock);
10833 	{
10834 		sock->SendSize += (UINT64)size;
10835 		sock->SendNum++;
10836 	}
10837 	Unlock(sock->lock);
10838 
10839 	return ret;
10840 }
SendTo6Ex(SOCK * sock,IP * dest_addr,UINT dest_port,void * data,UINT size,bool broadcast)10841 UINT SendTo6Ex(SOCK *sock, IP *dest_addr, UINT dest_port, void *data, UINT size, bool broadcast)
10842 {
10843 	SOCKET s;
10844 	int ret;
10845 	struct sockaddr_in6 addr;
10846 	UINT type;
10847 	// Validate arguments
10848 	if (sock != NULL)
10849 	{
10850 		sock->IgnoreSendErr = false;
10851 	}
10852 	if (sock == NULL || dest_addr == NULL || (sock->IsRawSocket == false && dest_port == 0) || data == NULL)
10853 	{
10854 		return 0;
10855 	}
10856 	if (dest_port >= 65536 && sock->IsRawSocket == false)
10857 	{
10858 		return 0;
10859 	}
10860 	if (sock->Type != SOCK_UDP || sock->socket == INVALID_SOCKET)
10861 	{
10862 		return 0;
10863 	}
10864 	if (size == 0)
10865 	{
10866 		return 0;
10867 	}
10868 
10869 	if (IsIP6(dest_addr) == false)
10870 	{
10871 		return 0;
10872 	}
10873 
10874 	s = sock->socket;
10875 	Zero(&addr, sizeof(addr));
10876 	addr.sin6_family = AF_INET6;
10877 	if (sock->IsRawSocket == false)
10878 	{
10879 		addr.sin6_port = htons((USHORT)dest_port);
10880 	}
10881 	IPToInAddr6(&addr.sin6_addr, dest_addr);
10882 	addr.sin6_scope_id = dest_addr->ipv6_scope_id;
10883 
10884 	type = GetIPAddrType6(dest_addr);
10885 
10886 	if ((type & IPV6_ADDR_MULTICAST) || broadcast)
10887 	{
10888 		if (sock->UdpBroadcast == false)
10889 		{
10890 			bool yes = true;
10891 
10892 			sock->UdpBroadcast = true;
10893 
10894 			(void)setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char *)&yes, sizeof(yes));
10895 		}
10896 	}
10897 
10898 	ret = sendto(s, data, size, 0, (struct sockaddr *)&addr, sizeof(addr));
10899 	if (ret != (int)size)
10900 	{
10901 		sock->IgnoreSendErr = false;
10902 
10903 #ifdef	OS_WIN32
10904 		if (WSAGetLastError() == WSAECONNRESET || WSAGetLastError() == WSAENETRESET || WSAGetLastError() == WSAEMSGSIZE || WSAGetLastError() == WSAENETUNREACH ||
10905 		        WSAGetLastError() == WSAENOBUFS || WSAGetLastError() == WSAEHOSTUNREACH || WSAGetLastError() == WSAEUSERS || WSAGetLastError() == WSAEINVAL || WSAGetLastError() == WSAEADDRNOTAVAIL)
10906 		{
10907 			sock->IgnoreSendErr = true;
10908 		}
10909 		else if (WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINPROGRESS)
10910 		{
10911 			return SOCK_LATER;
10912 		}
10913 #else	// OS_WIN32
10914 		if (errno == ECONNREFUSED || errno == ECONNRESET || errno == EMSGSIZE || errno == ENOBUFS || errno == ENOMEM || errno == EINTR)
10915 		{
10916 			sock->IgnoreSendErr = true;
10917 		}
10918 		else if (errno == EAGAIN)
10919 		{
10920 			return SOCK_LATER;
10921 		}
10922 #endif	// OS_WIN32
10923 		return 0;
10924 	}
10925 
10926 	Lock(sock->lock);
10927 	{
10928 		sock->SendSize += (UINT64)size;
10929 		sock->SendNum++;
10930 	}
10931 	Unlock(sock->lock);
10932 
10933 	return ret;
10934 }
10935 
10936 // 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)10937 SOCK *NewUDPEx2Rand(bool ipv6, IP *ip, void *rand_seed, UINT rand_seed_size, UINT num_retry)
10938 {
10939 	UINT i;
10940 	// Validate arguments
10941 	if (rand_seed == NULL || rand_seed_size == 0)
10942 	{
10943 		return NULL;
10944 	}
10945 	if (num_retry == 0)
10946 	{
10947 		num_retry = RAND_UDP_PORT_DEFAULT_NUM_RETRY;
10948 	}
10949 
10950 	for (i = 0; i < (num_retry + 1); i++)
10951 	{
10952 		BUF *buf = NewBuf();
10953 		UCHAR hash[SHA1_SIZE];
10954 		UINT port = 0;
10955 		SOCK *s;
10956 
10957 		WriteBuf(buf, rand_seed, rand_seed_size);
10958 		WriteBufInt(buf, i);
10959 
10960 		Sha1(hash, buf->Buf, buf->Size);
10961 
10962 		FreeBuf(buf);
10963 
10964 		port = READ_UINT(hash);
10965 
10966 		port = RAND_UDP_PORT_START + (port % (RAND_UDP_PORT_END - RAND_UDP_PORT_START));
10967 
10968 		s = NewUDPEx2(port, ipv6, ip);
10969 
10970 		if (s != NULL)
10971 		{
10972 			return s;
10973 		}
10974 	}
10975 
10976 	return NewUDPEx2(0, ipv6, ip);
10977 }
10978 
10979 // Open the UDP port (based on the EXE path and machine key)
NewUDPEx2RandMachineAndExePath(bool ipv6,IP * ip,UINT num_retry,UCHAR rand_port_id)10980 SOCK *NewUDPEx2RandMachineAndExePath(bool ipv6, IP *ip, UINT num_retry, UCHAR rand_port_id)
10981 {
10982 	BUF *b;
10983 	char machine_name[MAX_SIZE];
10984 	wchar_t exe_path[MAX_PATH];
10985 	char *product_id = NULL;
10986 	UCHAR hash[SHA1_SIZE];
10987 
10988 #ifdef	OS_WIN32
10989 	product_id = MsRegReadStr(REG_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "ProductId");
10990 	if (product_id == NULL)
10991 	{
10992 		product_id = MsRegReadStr(REG_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion", "ProductId");
10993 	}
10994 #endif	// OS_WIN32
10995 
10996 	b = NewBuf();
10997 
10998 	GetMachineHostName(machine_name, sizeof(machine_name));
10999 	Trim(machine_name);
11000 	StrUpper(machine_name);
11001 
11002 	GetExeNameW(exe_path, sizeof(exe_path));
11003 	UniTrim(exe_path);
11004 	UniStrUpper(exe_path);
11005 
11006 	WriteBuf(b, machine_name, StrSize(machine_name));
11007 	WriteBuf(b, exe_path, UniStrSize(exe_path));
11008 	WriteBuf(b, product_id, StrSize(product_id));
11009 	WriteBufChar(b, rand_port_id);
11010 	//WriteBufInt(b, GetHostIPAddressHash32());
11011 
11012 	Sha1(hash, b->Buf, b->Size);
11013 
11014 	FreeBuf(b);
11015 
11016 	Free(product_id);
11017 
11018 	return NewUDPEx2Rand(ipv6, ip, hash, sizeof(hash), num_retry);
11019 }
11020 
11021 // Set the DF bit of the socket
ClearSockDfBit(SOCK * s)11022 void ClearSockDfBit(SOCK *s)
11023 {
11024 #ifdef	IP_PMTUDISC_DONT
11025 #ifdef	IP_MTU_DISCOVER
11026 	UINT value = IP_PMTUDISC_DONT;
11027 	if (s == NULL)
11028 	{
11029 		return;
11030 	}
11031 
11032 	(void)setsockopt(s->socket, IPPROTO_IP, IP_MTU_DISCOVER, (char *)&value, sizeof(value));
11033 #endif	// IP_MTU_DISCOVER
11034 #endif	// IP_PMTUDISC_DONT
11035 }
11036 
11037 // Set the header-include option
SetRawSockHeaderIncludeOption(SOCK * s,bool enable)11038 void SetRawSockHeaderIncludeOption(SOCK *s, bool enable)
11039 {
11040 	UINT value = BOOL_TO_INT(enable);
11041 	if (s == NULL || s->IsRawSocket == false)
11042 	{
11043 		return;
11044 	}
11045 
11046 	(void)setsockopt(s->socket, IPPROTO_IP, IP_HDRINCL, (char *)&value, sizeof(value));
11047 
11048 	s->RawIP_HeaderIncludeFlag = enable;
11049 }
11050 
11051 // Create and initialize the UDP socket
11052 // If port is specified as 0, system assigns a certain port.
NewUDP(UINT port)11053 SOCK *NewUDP(UINT port)
11054 {
11055 	return NewUDPEx(port, false);
11056 }
NewUDPEx(UINT port,bool ipv6)11057 SOCK *NewUDPEx(UINT port, bool ipv6)
11058 {
11059 	return NewUDPEx2(port, ipv6, NULL);
11060 }
NewUDPEx2(UINT port,bool ipv6,IP * ip)11061 SOCK *NewUDPEx2(UINT port, bool ipv6, IP *ip)
11062 {
11063 	if (ipv6 == false)
11064 	{
11065 		return NewUDP4(port, ip);
11066 	}
11067 	else
11068 	{
11069 		return NewUDP6(port, ip);
11070 	}
11071 }
NewUDPEx3(UINT port,IP * ip)11072 SOCK *NewUDPEx3(UINT port, IP *ip)
11073 {
11074 	// Validate arguments
11075 	if (ip == NULL)
11076 	{
11077 		return NewUDPEx2(port, false, NULL);
11078 	}
11079 
11080 	if (IsIP4(ip))
11081 	{
11082 		return NewUDPEx2(port, false, ip);
11083 	}
11084 	else
11085 	{
11086 		return NewUDPEx2(port, true, ip);
11087 	}
11088 }
NewUDP4(UINT port,IP * ip)11089 SOCK *NewUDP4(UINT port, IP *ip)
11090 {
11091 	SOCK *sock;
11092 	SOCKET s;
11093 	struct sockaddr_in addr;
11094 	// Validate arguments
11095 	if (ip != NULL && IsIP4(ip) == false)
11096 	{
11097 		return NULL;
11098 	}
11099 
11100 	if (IS_SPECIAL_PORT(port) == false)
11101 	{
11102 		s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
11103 	}
11104 	else
11105 	{
11106 		s = socket(AF_INET, SOCK_RAW, GET_SPECIAL_PORT(port));
11107 	}
11108 	if (s == INVALID_SOCKET)
11109 	{
11110 		return NULL;
11111 	}
11112 
11113 	Zero(&addr, sizeof(addr));
11114 	addr.sin_family = AF_INET;
11115 
11116 	if (ip == NULL || IsZeroIP(ip))
11117 	{
11118 		addr.sin_addr.s_addr = htonl(INADDR_ANY);
11119 	}
11120 	else
11121 	{
11122 		IPToInAddr(&addr.sin_addr, ip);
11123 	}
11124 
11125 	if (port == 0 || IS_SPECIAL_PORT(port))
11126 	{
11127 		addr.sin_port = 0;
11128 	}
11129 	else
11130 	{
11131 		addr.sin_port = htons((USHORT)port);
11132 	}
11133 
11134 	if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) != 0)
11135 	{
11136 		// Failure
11137 		if (port != 0)
11138 		{
11139 			bool true_flag = true;
11140 			(void)setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&true_flag, sizeof(bool));
11141 			if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) != 0)
11142 			{
11143 				bool false_flag = false;
11144 				(void)setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&false_flag, sizeof(bool));
11145 #ifdef	SO_EXCLUSIVEADDRUSE
11146 				(void)setsockopt(s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char *)&true_flag, sizeof(bool));
11147 #endif	// SO_EXCLUSIVEADDRUSE
11148 				if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) != 0)
11149 				{
11150 					closesocket(s);
11151 					return NULL;
11152 				}
11153 			}
11154 		}
11155 		else
11156 		{
11157 			closesocket(s);
11158 			return NULL;
11159 		}
11160 	}
11161 
11162 	sock = NewSock();
11163 
11164 	sock->Type = SOCK_UDP;
11165 	sock->Connected = false;
11166 	sock->AsyncMode = false;
11167 	sock->ServerMode = false;
11168 	if (port != 0)
11169 	{
11170 		sock->ServerMode = true;
11171 	}
11172 
11173 	sock->socket = s;
11174 
11175 	InitUdpSocketBufferSize((int)s);
11176 
11177 	if (IS_SPECIAL_PORT(port))
11178 	{
11179 		bool no = false;
11180 		(void)setsockopt(sock->socket, IPPROTO_IP, IP_HDRINCL, (char *)&no, sizeof(no));
11181 
11182 		sock->IsRawSocket = true;
11183 		sock->RawSocketIPProtocol = GET_SPECIAL_PORT(port);
11184 	}
11185 
11186 	QuerySocketInformation(sock);
11187 
11188 	return sock;
11189 }
NewUDP6(UINT port,IP * ip)11190 SOCK *NewUDP6(UINT port, IP *ip)
11191 {
11192 	SOCK *sock;
11193 	SOCKET s;
11194 	struct sockaddr_in6 addr;
11195 	// Validate arguments
11196 	if (ip != NULL && IsIP6(ip) == false)
11197 	{
11198 		return NULL;
11199 	}
11200 
11201 	if (IS_SPECIAL_PORT(port) == false)
11202 	{
11203 		s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
11204 	}
11205 	else
11206 	{
11207 		s = socket(AF_INET6, SOCK_RAW, GET_SPECIAL_PORT(port));
11208 	}
11209 	if (s == INVALID_SOCKET)
11210 	{
11211 		return NULL;
11212 	}
11213 
11214 	Zero(&addr, sizeof(addr));
11215 	addr.sin6_family = AF_INET6;
11216 	if (port == 0)
11217 	{
11218 		addr.sin6_port = 0;
11219 	}
11220 	else
11221 	{
11222 		addr.sin6_port = htons((USHORT)port);
11223 	}
11224 
11225 	if (ip != NULL && IsZeroIP(ip) == false)
11226 	{
11227 		IPToInAddr6(&addr.sin6_addr, ip);
11228 		addr.sin6_scope_id = ip->ipv6_scope_id;
11229 	}
11230 
11231 	if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) != 0)
11232 	{
11233 		// Failure
11234 		if (port != 0)
11235 		{
11236 			bool true_flag = true;
11237 			(void)setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&true_flag, sizeof(bool));
11238 			if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) != 0)
11239 			{
11240 				bool false_flag = false;
11241 				(void)setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&false_flag, sizeof(bool));
11242 #ifdef	SO_EXCLUSIVEADDRUSE
11243 				(void)setsockopt(s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char *)&true_flag, sizeof(bool));
11244 #endif	// SO_EXCLUSIVEADDRUSE
11245 				if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) != 0)
11246 				{
11247 					closesocket(s);
11248 					return NULL;
11249 				}
11250 			}
11251 		}
11252 		else
11253 		{
11254 			closesocket(s);
11255 			return NULL;
11256 		}
11257 	}
11258 
11259 	sock = NewSock();
11260 
11261 	sock->Type = SOCK_UDP;
11262 	sock->Connected = false;
11263 	sock->AsyncMode = false;
11264 	sock->ServerMode = false;
11265 	sock->IPv6 = true;
11266 	if (port != 0)
11267 	{
11268 		sock->ServerMode = true;
11269 	}
11270 
11271 	sock->socket = s;
11272 
11273 	InitUdpSocketBufferSize(s);
11274 
11275 	if (IS_SPECIAL_PORT(port))
11276 	{
11277 		bool no = false;
11278 #ifdef	IPV6_HDRINCL
11279 		(void)setsockopt(sock->socket, IPPROTO_IP, IPV6_HDRINCL, (char *)&no, sizeof(no));
11280 #endif	// IPV6_HDRINCL
11281 		(void)setsockopt(sock->socket, IPPROTO_IP, IP_HDRINCL, (char *)&no, sizeof(no));
11282 
11283 		sock->IsRawSocket = true;
11284 		sock->RawSocketIPProtocol = GET_SPECIAL_PORT(port);
11285 	}
11286 
11287 	QuerySocketInformation(sock);
11288 
11289 	return sock;
11290 }
11291 
11292 // Select function
Select(SOCKSET * set,UINT timeout,CANCEL * c1,CANCEL * c2)11293 void Select(SOCKSET *set, UINT timeout, CANCEL *c1, CANCEL *c2)
11294 {
11295 #ifdef	OS_WIN32
11296 	Win32Select(set, timeout, c1, c2);
11297 #else
11298 	UnixSelect(set, timeout, c1, c2);
11299 #endif	// OS_WIN32
11300 }
11301 
11302 // Add a socket to the socket set
AddSockSet(SOCKSET * set,SOCK * sock)11303 void AddSockSet(SOCKSET *set, SOCK *sock)
11304 {
11305 	// Validate arguments
11306 	if (set == NULL || sock == NULL)
11307 	{
11308 		return;
11309 	}
11310 	if (sock->Type == SOCK_TCP && sock->Connected == false)
11311 	{
11312 		return;
11313 	}
11314 
11315 	if (set->NumSocket >= MAX_SOCKSET_NUM)
11316 	{
11317 		// Upper limit
11318 		return;
11319 	}
11320 	set->Sock[set->NumSocket++] = sock;
11321 }
11322 
11323 // Initializing the socket set
InitSockSet(SOCKSET * set)11324 void InitSockSet(SOCKSET *set)
11325 {
11326 	// Validate arguments
11327 	if (set == NULL)
11328 	{
11329 		return;
11330 	}
11331 
11332 	Zero(set, sizeof(SOCKSET));
11333 }
11334 
11335 // Receive data and discard all of them
RecvAllWithDiscard(SOCK * sock,UINT size,bool secure)11336 bool RecvAllWithDiscard(SOCK *sock, UINT size, bool secure)
11337 {
11338 	static UCHAR buffer[4096];
11339 	UINT recv_size, sz, ret;
11340 	if (sock == NULL)
11341 	{
11342 		return false;
11343 	}
11344 	if (size == 0)
11345 	{
11346 		return true;
11347 	}
11348 	if (sock->AsyncMode)
11349 	{
11350 		return false;
11351 	}
11352 
11353 	recv_size = 0;
11354 
11355 	while (true)
11356 	{
11357 		sz = MIN(size - recv_size, sizeof(buffer));
11358 		ret = Recv(sock, buffer, sz, secure);
11359 		if (ret == 0)
11360 		{
11361 			return false;
11362 		}
11363 		if (ret == SOCK_LATER)
11364 		{
11365 			// I suppose that this is safe because the RecvAll() function is used only
11366 			// if the sock->AsyncMode == true. And the Recv() function may return
11367 			// SOCK_LATER only if the sock->AsyncMode == false. Therefore the call of
11368 			// Recv() function in the RecvAll() function never returns SOCK_LATER.
11369 			return false;
11370 		}
11371 		recv_size += ret;
11372 		if (recv_size >= size)
11373 		{
11374 			return true;
11375 		}
11376 	}
11377 }
11378 
11379 // Receive all by TCP
RecvAll(SOCK * sock,void * data,UINT size,bool secure)11380 bool RecvAll(SOCK *sock, void *data, UINT size, bool secure)
11381 {
11382 	UINT recv_size, sz, ret;
11383 	// Validate arguments
11384 	if (sock == NULL || data == NULL)
11385 	{
11386 		return false;
11387 	}
11388 	if (size == 0)
11389 	{
11390 		return true;
11391 	}
11392 	if (sock->AsyncMode)
11393 	{
11394 		return false;
11395 	}
11396 
11397 	recv_size = 0;
11398 
11399 	while (true)
11400 	{
11401 		sz = size - recv_size;
11402 		ret = Recv(sock, (UCHAR *)data + recv_size, sz, secure);
11403 		if (ret == 0)
11404 		{
11405 			return false;
11406 		}
11407 		if (ret == SOCK_LATER)
11408 		{
11409 			// I suppose that this is safe because the RecvAll() function is used only
11410 			// if the sock->AsyncMode == true. And the Recv() function may return
11411 			// SOCK_LATER only if the sock->AsyncMode == false. Therefore the call of
11412 			// Recv() function in the RecvAll() function never returns SOCK_LATER.
11413 			return false;
11414 		}
11415 		recv_size += ret;
11416 		if (recv_size >= size)
11417 		{
11418 			return true;
11419 		}
11420 	}
11421 }
11422 
11423 // Send the TCP send buffer
SendNow(SOCK * sock,int secure)11424 bool SendNow(SOCK *sock, int secure)
11425 {
11426 	bool ret;
11427 	// Validate arguments
11428 	if (sock == NULL || sock->AsyncMode != false)
11429 	{
11430 		return false;
11431 	}
11432 	if (sock->SendBuf->Size == 0)
11433 	{
11434 		return true;
11435 	}
11436 
11437 	ret = SendAll(sock, sock->SendBuf->Buf, sock->SendBuf->Size, secure);
11438 	ClearBuf(sock->SendBuf);
11439 
11440 	return ret;
11441 }
11442 
11443 // Append to the TCP send buffer
SendAdd(SOCK * sock,void * data,UINT size)11444 void SendAdd(SOCK *sock, void *data, UINT size)
11445 {
11446 	// Validate arguments
11447 	if (sock == NULL || data == NULL || size == 0 || sock->AsyncMode != false)
11448 	{
11449 		return;
11450 	}
11451 
11452 	WriteBuf(sock->SendBuf, data, size);
11453 }
11454 
11455 // Send all by TCP
SendAll(SOCK * sock,void * data,UINT size,bool secure)11456 bool SendAll(SOCK *sock, void *data, UINT size, bool secure)
11457 {
11458 	UCHAR *buf;
11459 	UINT sent_size;
11460 	UINT ret;
11461 	// Validate arguments
11462 	if (sock == NULL || data == NULL)
11463 	{
11464 		return false;
11465 	}
11466 	if (sock->AsyncMode)
11467 	{
11468 		return false;
11469 	}
11470 	if (size == 0)
11471 	{
11472 		return true;
11473 	}
11474 
11475 	buf = (UCHAR *)data;
11476 	sent_size = 0;
11477 
11478 	while (true)
11479 	{
11480 		ret = Send(sock, buf, size - sent_size, secure);
11481 		if (ret == 0)
11482 		{
11483 			return false;
11484 		}
11485 		sent_size += ret;
11486 		buf += ret;
11487 		if (sent_size >= size)
11488 		{
11489 			return true;
11490 		}
11491 	}
11492 }
11493 
11494 // Set the cipher algorithm name to want to use
SetWantToUseCipher(SOCK * sock,char * name)11495 void SetWantToUseCipher(SOCK *sock, char *name)
11496 {
11497 	// Validate arguments
11498 	if (sock == NULL || name == NULL)
11499 	{
11500 		return;
11501 	}
11502 
11503 	if (sock->WaitToUseCipher)
11504 	{
11505 		Free(sock->WaitToUseCipher);
11506 	}
11507 
11508 	sock->WaitToUseCipher = CopyStr(name);
11509 }
11510 
11511 // Add all the chain certificates in the chain_certs directory
AddChainSslCertOnDirectory(struct ssl_ctx_st * ctx)11512 void AddChainSslCertOnDirectory(struct ssl_ctx_st *ctx)
11513 {
11514 	wchar_t dirname[MAX_SIZE];
11515 	wchar_t exedir[MAX_SIZE];
11516 	wchar_t txtname[MAX_SIZE];
11517 	DIRLIST *dir;
11518 	LIST *o;
11519 	UINT i;
11520 
11521 	// Validate arguments
11522 	if (ctx == NULL)
11523 	{
11524 		return;
11525 	}
11526 
11527 	o = NewListFast(NULL);
11528 
11529 	GetDbDirW(exedir, sizeof(exedir));
11530 
11531 	CombinePathW(dirname, sizeof(dirname), exedir, L"chain_certs");
11532 
11533 	MakeDirExW(dirname);
11534 
11535 	CombinePathW(txtname, sizeof(txtname), dirname, L"Readme_Chain_Certs.txt");
11536 
11537 	if (IsFileExistsW(txtname) == false)
11538 	{
11539 		FileCopyW(L"|chain_certs.txt", txtname);
11540 	}
11541 
11542 	dir = EnumDirW(dirname);
11543 
11544 	if (dir != NULL)
11545 	{
11546 		for (i = 0; i < dir->NumFiles; i++)
11547 		{
11548 			DIRENT *e = dir->File[i];
11549 
11550 			if (e->Folder == false)
11551 			{
11552 				wchar_t tmp[MAX_SIZE];
11553 				X *x;
11554 
11555 				CombinePathW(tmp, sizeof(tmp), dirname, e->FileNameW);
11556 
11557 				x = FileToXW(tmp);
11558 
11559 				if (x != NULL)
11560 				{
11561 					UINT j;
11562 					bool exists = false;
11563 					UCHAR hash[SHA1_SIZE];
11564 
11565 					GetXDigest(x, hash, true);
11566 
11567 					for (j = 0; j < LIST_NUM(o); j++)
11568 					{
11569 						UCHAR *hash2 = LIST_DATA(o, j);
11570 
11571 						if (Cmp(hash, hash2, SHA1_SIZE) == 0)
11572 						{
11573 							exists = true;
11574 						}
11575 					}
11576 
11577 					if (exists == false)
11578 					{
11579 						AddChainSslCert(ctx, x);
11580 
11581 						Add(o, Clone(hash, SHA1_SIZE));
11582 					}
11583 
11584 					FreeX(x);
11585 				}
11586 			}
11587 		}
11588 
11589 		FreeDir(dir);
11590 	}
11591 
11592 	for (i = 0; i < LIST_NUM(o); i++)
11593 	{
11594 		UCHAR *hash = LIST_DATA(o, i);
11595 
11596 		Free(hash);
11597 	}
11598 
11599 	ReleaseList(o);
11600 }
11601 
11602 // Add the chain certificate
AddChainSslCert(struct ssl_ctx_st * ctx,X * x)11603 bool AddChainSslCert(struct ssl_ctx_st *ctx, X *x)
11604 {
11605 	bool ret = false;
11606 	X *x_copy;
11607 	// Validate arguments
11608 	if (ctx == NULL || x == NULL)
11609 	{
11610 		return ret;
11611 	}
11612 
11613 	x_copy = CloneX(x);
11614 
11615 	if (x_copy != NULL)
11616 	{
11617 		if (x_copy->root_cert)
11618 		{
11619 			X509_STORE *store = SSL_CTX_get_cert_store(ctx);
11620 			X509_STORE_add_cert(store, x_copy->x509);
11621 			X509_free(x_copy->x509);
11622 		}
11623 		else
11624 		{
11625 			SSL_CTX_add_extra_chain_cert(ctx, x_copy->x509);
11626 		}
11627 		x_copy->do_not_free = true;
11628 
11629 		ret = true;
11630 
11631 		FreeX(x_copy);
11632 	}
11633 
11634 	return ret;
11635 }
11636 
11637 // Start a TCP-SSL communication
StartSSL(SOCK * sock,X * x,K * priv)11638 bool StartSSL(SOCK *sock, X *x, K *priv)
11639 {
11640 	return StartSSLEx(sock, x, priv, 0, NULL);
11641 }
StartSSLEx(SOCK * sock,X * x,K * priv,UINT ssl_timeout,char * sni_hostname)11642 bool StartSSLEx(SOCK *sock, X *x, K *priv, UINT ssl_timeout, char *sni_hostname)
11643 {
11644 	X509 *x509;
11645 	EVP_PKEY *key;
11646 	UINT prev_timeout = 1024;
11647 	SSL_CTX *ssl_ctx;
11648 
11649 #ifdef UNIX_SOLARIS
11650 	SOCKET_TIMEOUT_PARAM *ttparam;
11651 #endif //UNIX_SOLARIS
11652 
11653 	// Validate arguments
11654 	if (sock == NULL)
11655 	{
11656 		Debug("StartSSL Error: #0\n");
11657 		return false;
11658 	}
11659 	if (sock->Connected && sock->Type == SOCK_INPROC && sock->ListenMode == false)
11660 	{
11661 		sock->SecureMode = true;
11662 		return true;
11663 	}
11664 	if (sock->Connected == false || sock->socket == INVALID_SOCKET ||
11665 	        sock->ListenMode != false)
11666 	{
11667 		Debug("StartSSL Error: #1\n");
11668 		return false;
11669 	}
11670 	if (x != NULL && priv == NULL)
11671 	{
11672 		Debug("StartSSL Error: #2\n");
11673 		return false;
11674 	}
11675 	if (ssl_timeout == 0)
11676 	{
11677 		ssl_timeout = TIMEOUT_SSL_CONNECT;
11678 	}
11679 
11680 	if (sock->SecureMode)
11681 	{
11682 		//Debug("StartSSL Error: #3\n");
11683 		// SSL communication has already started
11684 		return true;
11685 	}
11686 
11687 	Lock(sock->ssl_lock);
11688 	if (sock->SecureMode)
11689 	{
11690 		//Debug("StartSSL Error: #4\n");
11691 		// SSL communication has already started
11692 		Unlock(sock->ssl_lock);
11693 		return true;
11694 	}
11695 
11696 	ssl_ctx = NewSSLCtx(sock->ServerMode);
11697 
11698 	Lock(openssl_lock);
11699 	{
11700 		if (sock->ServerMode)
11701 		{
11702 #ifdef	SSL_OP_NO_TLSv1
11703 			if (sock->SslAcceptSettings.Tls_Disable1_0)
11704 			{
11705 				SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TLSv1);
11706 			}
11707 #endif	// SSL_OP_NO_TLSv1
11708 
11709 #ifdef	SSL_OP_NO_TLSv1_1
11710 			if (sock->SslAcceptSettings.Tls_Disable1_1)
11711 			{
11712 				SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TLSv1_1);
11713 			}
11714 #endif	// SSL_OP_NO_TLSv1_1
11715 
11716 #ifdef	SSL_OP_NO_TLSv1_2
11717 			if (sock->SslAcceptSettings.Tls_Disable1_2)
11718 			{
11719 				SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TLSv1_2);
11720 			}
11721 #endif	// SSL_OP_NO_TLSv1_2
11722 
11723 #ifdef	SSL_OP_NO_TLSv1_3
11724 			if (sock->SslAcceptSettings.Tls_Disable1_3)
11725 			{
11726 				SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TLSv1_3);
11727 			}
11728 #endif	// SSL_OP_NO_TLSv1_3
11729 
11730 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
11731 			if (sock->SslAcceptSettings.Override_Security_Level)
11732 			{
11733 				SSL_CTX_set_security_level(ssl_ctx, sock->SslAcceptSettings.Override_Security_Level_Value);
11734 			}
11735 #endif
11736 
11737 			Unlock(openssl_lock);
11738 			AddChainSslCertOnDirectory(ssl_ctx);
11739 			Lock(openssl_lock);
11740 		}
11741 
11742 		sock->ssl = SSL_new(ssl_ctx);
11743 		SSL_set_fd(sock->ssl, (int)sock->socket);
11744 
11745 #ifdef	SSL_CTRL_SET_TLSEXT_HOSTNAME
11746 		if (sock->ServerMode == false)
11747 		{
11748 			if (IsEmptyStr(sni_hostname) == false)
11749 			{
11750 				// Set the SNI host name
11751 				SSL_set_tlsext_host_name(sock->ssl, sni_hostname);
11752 			}
11753 		}
11754 #endif	// SSL_CTRL_SET_TLSEXT_HOSTNAME
11755 
11756 	}
11757 	Unlock(openssl_lock);
11758 
11759 	if (x != NULL)
11760 	{
11761 		// Check the certificate and the private key
11762 		if (CheckXandK(x, priv))
11763 		{
11764 			// Use the certificate
11765 			x509 = x->x509;
11766 			key = priv->pkey;
11767 
11768 			Lock(openssl_lock);
11769 			{
11770 				SSL_use_certificate(sock->ssl, x509);
11771 				SSL_use_PrivateKey(sock->ssl, key);
11772 			}
11773 			Unlock(openssl_lock);
11774 		}
11775 	}
11776 
11777 	if (sock->WaitToUseCipher != NULL)
11778 	{
11779 		// Set the cipher algorithm name to want to use
11780 		Lock(openssl_lock);
11781 		{
11782 			if (SSL_set_cipher_list(sock->ssl, sock->WaitToUseCipher) == 0)
11783 				SSL_set_cipher_list(sock->ssl, DEFAULT_CIPHER_LIST);
11784 		}
11785 		Unlock(openssl_lock);
11786 	}
11787 
11788 	if (sock->ServerMode)
11789 	{
11790 //		Lock(ssl_connect_lock);
11791 
11792 // Run the time-out thread for SOLARIS
11793 #ifdef UNIX_SOLARIS
11794 		ttparam = NewSocketTimeout(sock);
11795 #endif // UNIX_SOLARIS
11796 
11797 		// Server mode
11798 		if (SSL_accept(sock->ssl) <= 0)
11799 		{
11800 
11801 // Stop the timeout thread
11802 #ifdef UNIX_SOLARIS
11803 			FreeSocketTimeout(ttparam);
11804 #endif // UNIX_SOLARIS
11805 
11806 			//			Unlock(ssl_connect_lock);
11807 			// SSL-Accept failure
11808 			Lock(openssl_lock);
11809 			{
11810 				SSL_free(sock->ssl);
11811 				sock->ssl = NULL;
11812 			}
11813 			Unlock(openssl_lock);
11814 
11815 			Unlock(sock->ssl_lock);
11816 			Debug("StartSSL Error: #5\n");
11817 			FreeSSLCtx(ssl_ctx);
11818 			return false;
11819 		}
11820 
11821 #ifdef	SSL_CTRL_SET_TLSEXT_HOSTNAME
11822 #ifdef	TLSEXT_NAMETYPE_host_name
11823 		if (true)
11824 		{
11825 			// Get the SNI host name
11826 			const char *sni_recv_hostname = SSL_get_servername(sock->ssl, TLSEXT_NAMETYPE_host_name);
11827 
11828 			if (IsEmptyStr((char *)sni_recv_hostname) == false)
11829 			{
11830 				StrCpy(sock->SniHostname, sizeof(sock->SniHostname), (char *)sni_recv_hostname);
11831 			}
11832 		}
11833 #endif	// TLSEXT_NAMETYPE_host_name
11834 #endif	// SSL_CTRL_SET_TLSEXT_HOSTNAME
11835 
11836 // Stop the timeout thread
11837 #ifdef UNIX_SOLARIS
11838 		FreeSocketTimeout(ttparam);
11839 #endif // UNIX_SOLARIS
11840 
11841 		//		Unlock(ssl_connect_lock);
11842 	}
11843 	else
11844 	{
11845 		prev_timeout = GetTimeout(sock);
11846 		SetTimeout(sock, ssl_timeout);
11847 		// Client mode
11848 		if (SSL_connect(sock->ssl) <= 0)
11849 		{
11850 			// SSL-connect failure
11851 			Lock(openssl_lock);
11852 			{
11853 				SSL_free(sock->ssl);
11854 				sock->ssl = NULL;
11855 			}
11856 			Unlock(openssl_lock);
11857 
11858 			Unlock(sock->ssl_lock);
11859 			Debug("StartSSL Error: #5\n");
11860 			SetTimeout(sock, prev_timeout);
11861 			FreeSSLCtx(ssl_ctx);
11862 			return false;
11863 		}
11864 		SetTimeout(sock, prev_timeout);
11865 	}
11866 
11867 	// SSL communication is initiated
11868 	sock->SecureMode = true;
11869 
11870 	// Get the certificate of the remote host
11871 	Lock(openssl_lock);
11872 	{
11873 		x509 = SSL_get_peer_certificate(sock->ssl);
11874 
11875 		sock->SslVersion = SSL_get_version(sock->ssl);
11876 	}
11877 	Unlock(openssl_lock);
11878 
11879 	if (x509 == NULL)
11880 	{
11881 		// The certificate does not exist on the remote host
11882 		sock->RemoteX = NULL;
11883 	}
11884 	else
11885 	{
11886 		// Got a certificate
11887 		sock->RemoteX = X509ToX(x509);
11888 	}
11889 
11890 	// Get the certificate of local host
11891 	Lock(openssl_lock);
11892 	{
11893 		x509 = SSL_get_certificate(sock->ssl);
11894 	}
11895 	Unlock(openssl_lock);
11896 
11897 	if (x509 == NULL)
11898 	{
11899 		// The certificate does not exist on the remote host
11900 		sock->LocalX = NULL;
11901 	}
11902 	else
11903 	{
11904 		X *local_x;
11905 		// Got a certificate
11906 		local_x = X509ToX(x509);
11907 		local_x->do_not_free = true;
11908 		sock->LocalX = CloneX(local_x);
11909 		FreeX(local_x);
11910 	}
11911 
11912 	// Automatic retry mode
11913 	SSL_set_mode(sock->ssl, SSL_MODE_AUTO_RETRY);
11914 
11915 	// Strange flag
11916 	SSL_set_mode(sock->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
11917 
11918 	sock->ssl_ctx = ssl_ctx;
11919 
11920 	// Get the algorithm name used to encrypt
11921 	Lock(openssl_lock);
11922 	{
11923 		sock->CipherName = CopyStr((char *)SSL_get_cipher(sock->ssl));
11924 	}
11925 	Unlock(openssl_lock);
11926 
11927 	Unlock(sock->ssl_lock);
11928 
11929 #ifdef	ENABLE_SSL_LOGGING
11930 	if (sock->ServerMode)
11931 	{
11932 		SockEnableSslLogging(sock);
11933 	}
11934 #endif	// ENABLE_SSL_LOGGING
11935 
11936 	return true;
11937 }
11938 
11939 
11940 
11941 #ifdef	ENABLE_SSL_LOGGING
11942 
11943 // Enable SSL logging
SockEnableSslLogging(SOCK * s)11944 void SockEnableSslLogging(SOCK *s)
11945 {
11946 	char dirname[MAX_PATH];
11947 	char tmp[MAX_PATH];
11948 	char dtstr[MAX_PATH];
11949 	char fn1[MAX_PATH], fn2[MAX_PATH];
11950 	// Validate arguments
11951 	if (s == NULL)
11952 	{
11953 		return;
11954 	}
11955 
11956 	if (s->IsSslLoggingEnabled)
11957 	{
11958 		return;
11959 	}
11960 
11961 	s->IsSslLoggingEnabled = true;
11962 
11963 	GetDateTimeStrMilli64ForFileName(dtstr, sizeof(dtstr), LocalTime64());
11964 	Format(tmp, sizeof(tmp), "%s__%r_%u__%r_%u", dtstr,
11965 	       &s->LocalIP, s->LocalPort, &s->RemoteIP, s->RemotePort);
11966 
11967 	CombinePath(dirname, sizeof(dirname), SSL_LOGGING_DIRNAME, tmp);
11968 
11969 	MakeDirEx(dirname);
11970 
11971 	CombinePath(fn1, sizeof(fn1), dirname, "send.c");
11972 	CombinePath(fn2, sizeof(fn2), dirname, "recv.c");
11973 
11974 	s->SslLogging_Send = FileCreate(fn1);
11975 	s->SslLogging_Recv = FileCreate(fn2);
11976 
11977 	s->SslLogging_Lock = NewLock();
11978 }
11979 
11980 // Close SSL logging
SockCloseSslLogging(SOCK * s)11981 void SockCloseSslLogging(SOCK *s)
11982 {
11983 	// Validate arguments
11984 	if (s == NULL)
11985 	{
11986 		return;
11987 	}
11988 
11989 	if (s->IsSslLoggingEnabled == false)
11990 	{
11991 		return;
11992 	}
11993 
11994 	s->IsSslLoggingEnabled = false;
11995 
11996 	FileClose(s->SslLogging_Recv);
11997 	s->SslLogging_Recv = NULL;
11998 
11999 	FileClose(s->SslLogging_Send);
12000 	s->SslLogging_Send = NULL;
12001 
12002 	DeleteLock(s->SslLogging_Lock);
12003 	s->SslLogging_Lock = NULL;
12004 }
12005 
12006 // Write SSL log
SockWriteSslLog(SOCK * s,void * send_data,UINT send_size,void * recv_data,UINT recv_size)12007 void SockWriteSslLog(SOCK *s, void *send_data, UINT send_size, void *recv_data, UINT recv_size)
12008 {
12009 	// Validate arguments
12010 	if (s == NULL)
12011 	{
12012 		return;
12013 	}
12014 
12015 	if (s->IsSslLoggingEnabled == false)
12016 	{
12017 		return;
12018 	}
12019 
12020 	Lock(s->SslLogging_Lock);
12021 	{
12022 		if (s->SslLogging_Send != NULL)
12023 		{
12024 			if (send_size >= 1 && send_data != NULL)
12025 			{
12026 				FileWrite(s->SslLogging_Send, send_data, send_size);
12027 			}
12028 		}
12029 
12030 		if (s->SslLogging_Recv != NULL)
12031 		{
12032 			if (recv_size >= 1 && recv_data != NULL)
12033 			{
12034 				FileWrite(s->SslLogging_Recv, recv_data, recv_size);
12035 			}
12036 		}
12037 	}
12038 	Unlock(s->SslLogging_Lock);
12039 }
12040 
12041 #endif	// ENABLE_SSL_LOGGING
12042 
12043 // Set the flag to indicate that the socket doesn't require reading
SetNoNeedToRead(SOCK * sock)12044 void SetNoNeedToRead(SOCK *sock)
12045 {
12046 	// Validate arguments
12047 	if (sock == NULL)
12048 	{
12049 		return;
12050 	}
12051 
12052 	sock->NoNeedToRead = true;
12053 }
12054 
12055 // TCP-SSL receive
SecureRecv(SOCK * sock,void * data,UINT size)12056 UINT SecureRecv(SOCK *sock, void *data, UINT size)
12057 {
12058 	int ret, e = SSL_ERROR_NONE;
12059 	SSL *ssl;
12060 
12061 #ifdef UNIX_SOLARIS
12062 	SOCKET_TIMEOUT_PARAM *ttparam;
12063 #endif //UNIX_SOLARIS
12064 
12065 	ssl = sock->ssl;
12066 
12067 	if (sock->AsyncMode)
12068 	{
12069 		// Confirm whether the data is readable even 1 byte in the case of asynchronous mode.
12070 		// To read data results blocking, if there is no readable data.
12071 		// We must avoid blocking.
12072 		char c;
12073 		Lock(sock->ssl_lock);
12074 		{
12075 			if (sock->Connected == false)
12076 			{
12077 				Unlock(sock->ssl_lock);
12078 				Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__);
12079 				return 0;
12080 			}
12081 			ret = SSL_peek(ssl, &c, sizeof(c));
12082 		}
12083 		Unlock(sock->ssl_lock);
12084 		if (ret == 0)
12085 		{
12086 			// The communication have been disconnected
12087 			Disconnect(sock);
12088 			Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__);
12089 			return 0;
12090 		}
12091 		if (ret < 0)
12092 		{
12093 			// An error has occurred
12094 			e = SSL_get_error(ssl, ret);
12095 			if (e == SSL_ERROR_WANT_READ || e == SSL_ERROR_WANT_WRITE || e == SSL_ERROR_SSL)
12096 			{
12097 				if (e == SSL_ERROR_SSL
12098 #if OPENSSL_VERSION_NUMBER < 0x10100000L
12099 				        &&
12100 				        sock->ssl->s3->send_alert[0] == SSL3_AL_FATAL &&
12101 				        sock->ssl->s3->send_alert[0] != sock->Ssl_Init_Async_SendAlert[0] &&
12102 				        sock->ssl->s3->send_alert[1] != sock->Ssl_Init_Async_SendAlert[1]
12103 #endif
12104 				   )
12105 				{
12106 					Debug("%s %u SSL Fatal Error on ASYNC socket !!!\n", __FILE__, __LINE__);
12107 					Disconnect(sock);
12108 					return 0;
12109 				}
12110 				// Packet has not arrived yet, that is not to be read
12111 				return SOCK_LATER;
12112 			}
12113 		}
12114 	}
12115 
12116 	// Receive
12117 	Lock(sock->ssl_lock);
12118 	{
12119 		if (sock->Connected == false)
12120 		{
12121 			Unlock(sock->ssl_lock);
12122 			Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__);
12123 			return 0;
12124 		}
12125 
12126 #ifdef	OS_UNIX
12127 		if (sock->AsyncMode == false)
12128 		{
12129 			sock->CallingThread = pthread_self();
12130 		}
12131 #endif	// OS_UNIX
12132 
12133 // Run the time-out thread for SOLARIS
12134 #ifdef UNIX_SOLARIS
12135 		ttparam = NewSocketTimeout(sock);
12136 #endif // UNIX_SOLARIS
12137 
12138 		ret = SSL_read(ssl, data, size);
12139 
12140 // Stop the timeout thread
12141 #ifdef UNIX_SOLARIS
12142 		FreeSocketTimeout(ttparam);
12143 #endif // UNIX_SOLARIS
12144 
12145 
12146 #ifdef	OS_UNIX
12147 		if (sock->AsyncMode == false)
12148 		{
12149 			sock->CallingThread = 0;
12150 		}
12151 #endif	// OS_UNIX
12152 
12153 		if (ret < 0)
12154 		{
12155 			e = SSL_get_error(ssl, ret);
12156 		}
12157 
12158 	}
12159 	Unlock(sock->ssl_lock);
12160 
12161 #ifdef	ENABLE_SSL_LOGGING
12162 	if (ret > 0)
12163 	{
12164 		SockWriteSslLog(sock, NULL, 0, data, ret);
12165 	}
12166 #endif	// ENABLE_SSL_LOGGING
12167 
12168 	if (ret > 0)
12169 	{
12170 		// Successful reception
12171 		sock->RecvSize += (UINT64)ret;
12172 		sock->RecvNum++;
12173 
12174 		return (UINT)ret;
12175 	}
12176 	if (ret == 0)
12177 	{
12178 		// Disconnect the communication
12179 		Disconnect(sock);
12180 		//Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__);
12181 		return 0;
12182 	}
12183 	if (sock->AsyncMode)
12184 	{
12185 		if (e == SSL_ERROR_WANT_READ || e == SSL_ERROR_WANT_WRITE || e == SSL_ERROR_SSL)
12186 		{
12187 			if (e == SSL_ERROR_SSL
12188 #if OPENSSL_VERSION_NUMBER < 0x10100000L
12189 			        &&
12190 			        sock->ssl->s3->send_alert[0] == SSL3_AL_FATAL &&
12191 			        sock->ssl->s3->send_alert[0] != sock->Ssl_Init_Async_SendAlert[0] &&
12192 			        sock->ssl->s3->send_alert[1] != sock->Ssl_Init_Async_SendAlert[1]
12193 #endif
12194 			   )
12195 			{
12196 				Debug("%s %u SSL Fatal Error on ASYNC socket !!!\n", __FILE__, __LINE__);
12197 				Disconnect(sock);
12198 				return 0;
12199 			}
12200 
12201 			// Packet has not yet arrived
12202 			return SOCK_LATER;
12203 		}
12204 	}
12205 	Disconnect(sock);
12206 	Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__);
12207 	return 0;
12208 }
12209 
12210 // TCP-SSL transmission
SecureSend(SOCK * sock,void * data,UINT size)12211 UINT SecureSend(SOCK *sock, void *data, UINT size)
12212 {
12213 	int ret, e = SSL_ERROR_NONE;
12214 	SSL *ssl;
12215 	ssl = sock->ssl;
12216 
12217 	if (sock->AsyncMode)
12218 	{
12219 		// Asynchronous mode
12220 		SSL_set_mode(ssl, SSL_MODE_ENABLE_PARTIAL_WRITE);
12221 	}
12222 
12223 	// Transmission
12224 	Lock(sock->ssl_lock);
12225 	{
12226 		if (sock->Connected == false)
12227 		{
12228 			Unlock(sock->ssl_lock);
12229 			Debug("%s %u SecureSend() Disconnect\n", __FILE__, __LINE__);
12230 			return 0;
12231 		}
12232 
12233 		ret = SSL_write(ssl, data, size);
12234 		if (ret < 0)
12235 		{
12236 			e = SSL_get_error(ssl, ret);
12237 		}
12238 	}
12239 	Unlock(sock->ssl_lock);
12240 
12241 #ifdef	ENABLE_SSL_LOGGING
12242 	if (ret > 0)
12243 	{
12244 		SockWriteSslLog(sock, data, ret, NULL, 0);
12245 	}
12246 #endif	// ENABLE_SSL_LOGGING
12247 
12248 	if (ret > 0)
12249 	{
12250 		// Successful transmission
12251 		sock->SendSize += (UINT64)ret;
12252 		sock->SendNum++;
12253 		sock->WriteBlocked = false;
12254 		return (UINT)ret;
12255 	}
12256 	if (ret == 0)
12257 	{
12258 		// Disconnect
12259 		Debug("%s %u SecureSend() Disconnect\n", __FILE__, __LINE__);
12260 		Disconnect(sock);
12261 		return 0;
12262 	}
12263 
12264 	if (sock->AsyncMode)
12265 	{
12266 		// Confirmation of the error value
12267 		if (e == SSL_ERROR_WANT_READ || e == SSL_ERROR_WANT_WRITE || e == SSL_ERROR_SSL)
12268 		{
12269 			sock->WriteBlocked = true;
12270 			return SOCK_LATER;
12271 		}
12272 		Debug("%s %u e=%u\n", __FILE__, __LINE__, e);
12273 	}
12274 	//Debug("%s %u SecureSend() Disconnect\n", __FILE__, __LINE__);
12275 	Disconnect(sock);
12276 	return 0;
12277 }
12278 
12279 // Peep the TCP
Peek(SOCK * sock,void * data,UINT size)12280 UINT Peek(SOCK *sock, void *data, UINT size)
12281 {
12282 	SOCKET s;
12283 	int ret;
12284 
12285 	// Validate arguments
12286 	if (sock == NULL || data == NULL || size == 0)
12287 	{
12288 		return 0;
12289 	}
12290 	if (sock->Type == SOCK_INPROC)
12291 	{
12292 		return 0;
12293 	}
12294 	if (sock->Type != SOCK_TCP || sock->Connected == false || sock->ListenMode != false ||
12295 	        sock->socket == INVALID_SOCKET)
12296 	{
12297 		return 0;
12298 	}
12299 	if (sock->AsyncMode)
12300 	{
12301 		return 0;
12302 	}
12303 
12304 	// Receive
12305 	s = sock->socket;
12306 
12307 	ret = recv(s, data, size, MSG_PEEK);
12308 
12309 	//Debug("Peek: %u\n", ret);
12310 
12311 	if (ret > 0)
12312 	{
12313 		return ret;
12314 	}
12315 
12316 	return 0;
12317 }
12318 
12319 // TCP receive
Recv(SOCK * sock,void * data,UINT size,bool secure)12320 UINT Recv(SOCK *sock, void *data, UINT size, bool secure)
12321 {
12322 	SOCKET s;
12323 	int ret;
12324 
12325 #ifdef UNIX_SOLARIS
12326 	SOCKET_TIMEOUT_PARAM *ttparam;
12327 #endif //UNIX_SOLARIS
12328 
12329 	// Validate arguments
12330 	if (sock == NULL || data == NULL || size == 0)
12331 	{
12332 		return 0;
12333 	}
12334 
12335 	sock->NoNeedToRead = false;
12336 
12337 	if (sock->Type == SOCK_INPROC)
12338 	{
12339 		return RecvInProc(sock, data, size);
12340 	}
12341 	if (sock->Type != SOCK_TCP || sock->Connected == false || sock->ListenMode != false ||
12342 	        sock->socket == INVALID_SOCKET)
12343 	{
12344 		return 0;
12345 	}
12346 	if (secure != false && sock->SecureMode == false)
12347 	{
12348 		return 0;
12349 	}
12350 
12351 	if (secure)
12352 	{
12353 		return SecureRecv(sock, data, size);
12354 	}
12355 
12356 	// Receive
12357 	s = sock->socket;
12358 
12359 
12360 #ifdef	OS_UNIX
12361 	if (sock->AsyncMode == false)
12362 	{
12363 		sock->CallingThread = pthread_self();
12364 	}
12365 #endif	// OS_UNIX
12366 
12367 // Start of the timeout thread for SOLARIS
12368 #ifdef UNIX_SOLARIS
12369 	ttparam = NewSocketTimeout(sock);
12370 #endif // UNIX_SOLARIS
12371 
12372 	ret = recv(s, data, size, 0);
12373 
12374 // Stop the timeout thread
12375 #ifdef UNIX_SOLARIS
12376 	FreeSocketTimeout(ttparam);
12377 #endif // UNIX_SOLARIS
12378 
12379 #ifdef	OS_UNIX
12380 	if (sock->AsyncMode == false)
12381 	{
12382 		sock->CallingThread = 0;
12383 	}
12384 #endif	// OS_UNIX
12385 
12386 	if (ret > 0)
12387 	{
12388 		// Successful reception
12389 		Lock(sock->lock);
12390 		{
12391 			sock->RecvSize += (UINT64)ret;
12392 			sock->SendNum++;
12393 		}
12394 		Unlock(sock->lock);
12395 		return (UINT)ret;
12396 	}
12397 
12398 	// Transmission failure
12399 	if (sock->AsyncMode)
12400 	{
12401 		// In asynchronous mode, examine the error
12402 		if (ret == SOCKET_ERROR)
12403 		{
12404 #ifdef	OS_WIN32
12405 			if (WSAGetLastError() == WSAEWOULDBLOCK)
12406 			{
12407 				// In blocking
12408 				return SOCK_LATER;
12409 			}
12410 			else
12411 			{
12412 				//Debug("Socket Error: %u\n", WSAGetLastError());
12413 			}
12414 #else	// OS_WIN32
12415 			if (errno == EAGAIN)
12416 			{
12417 				// In blocking
12418 				return SOCK_LATER;
12419 			}
12420 #endif	// OS_WIN32
12421 		}
12422 	}
12423 
12424 	// Disconnected
12425 	Disconnect(sock);
12426 	return 0;
12427 }
12428 
12429 // TCP transmission
Send(SOCK * sock,void * data,UINT size,bool secure)12430 UINT Send(SOCK *sock, void *data, UINT size, bool secure)
12431 {
12432 	SOCKET s;
12433 	int ret;
12434 	// Validate arguments
12435 	if (sock == NULL || data == NULL || size == 0)
12436 	{
12437 		return 0;
12438 	}
12439 	if (sock->Type == SOCK_INPROC)
12440 	{
12441 		return SendInProc(sock, data, size);
12442 	}
12443 	size = MIN(size, MAX_SEND_BUF_MEM_SIZE);
12444 	if (sock->Type != SOCK_TCP || sock->Connected == false || sock->ListenMode != false ||
12445 	        sock->socket == INVALID_SOCKET)
12446 	{
12447 		return 0;
12448 	}
12449 	if (secure != false && sock->SecureMode == false)
12450 	{
12451 		return 0;
12452 	}
12453 
12454 	if (secure)
12455 	{
12456 		return SecureSend(sock, data, size);
12457 	}
12458 
12459 	// Transmission
12460 	s = sock->socket;
12461 	ret = send(s, data, size, 0);
12462 	if (ret > 0)
12463 	{
12464 		// Successful transmission
12465 		Lock(sock->lock);
12466 		{
12467 			sock->SendSize += (UINT64)ret;
12468 			sock->SendNum++;
12469 		}
12470 		Unlock(sock->lock);
12471 		sock->WriteBlocked = false;
12472 		return (UINT)ret;
12473 	}
12474 
12475 	// Transmission failure
12476 	if (sock->AsyncMode)
12477 	{
12478 		// In asynchronous mode, examine the error
12479 		if (ret == SOCKET_ERROR)
12480 		{
12481 #ifdef	OS_WIN32
12482 			if (WSAGetLastError() == WSAEWOULDBLOCK)
12483 			{
12484 				// In blocking
12485 				sock->WriteBlocked = true;
12486 				return SOCK_LATER;
12487 			}
12488 			else
12489 			{
12490 				//Debug("Socket Error: %u\n", WSAGetLastError());
12491 			}
12492 #else	// OS_WIN32
12493 			if (errno == EAGAIN)
12494 			{
12495 				// In blocking
12496 				sock->WriteBlocked = true;
12497 				return SOCK_LATER;
12498 			}
12499 #endif	// OS_WIN32
12500 		}
12501 	}
12502 
12503 	// Disconnected
12504 	Disconnect(sock);
12505 	return 0;
12506 }
12507 
12508 // Get the time-out value (in milliseconds)
GetTimeout(SOCK * sock)12509 UINT GetTimeout(SOCK *sock)
12510 {
12511 	// Validate arguments
12512 	if (sock == NULL)
12513 	{
12514 		return INFINITE;
12515 	}
12516 	if (sock->Type != SOCK_TCP && sock->Type != SOCK_INPROC)
12517 	{
12518 		return INFINITE;
12519 	}
12520 
12521 	return sock->TimeOut;
12522 }
12523 
12524 // Setting the time-out value (in milliseconds)
SetTimeout(SOCK * sock,UINT timeout)12525 void SetTimeout(SOCK *sock, UINT timeout)
12526 {
12527 	// Validate arguments
12528 	if (sock == NULL)
12529 	{
12530 		return;
12531 	}
12532 	if (sock->Type == SOCK_UDP)
12533 	{
12534 		return;
12535 	}
12536 
12537 	if (timeout == INFINITE)
12538 	{
12539 		timeout = TIMEOUT_INFINITE;
12540 	}
12541 
12542 	sock->TimeOut = timeout;
12543 
12544 //	Debug("SetTimeout(%u)\n",timeout);
12545 
12546 	if (sock->Type != SOCK_INPROC)
12547 	{
12548 #ifdef OS_WIN32
12549 		setsockopt(sock->socket, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(UINT));
12550 		setsockopt(sock->socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(UINT));
12551 #endif
12552 
12553 #ifdef OS_UNIX
12554 #ifndef UNIX_SOLARIS
12555 		{
12556 			struct timeval tv_timeout;
12557 
12558 			tv_timeout.tv_sec = timeout / 1000; // miliseconds to seconds
12559 			tv_timeout.tv_usec = (timeout % 1000) * 1000; // miliseconds to microseconds
12560 
12561 			(void)setsockopt(sock->socket, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv_timeout, sizeof(tv_timeout));
12562 			(void)setsockopt(sock->socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv_timeout, sizeof(tv_timeout));
12563 		}
12564 #endif // UNIX_SOLARIS
12565 #endif // OS_UNIX
12566 	}
12567 }
12568 
12569 // Disable GetHostName call by accepting new TCP connection
DisableGetHostNameWhenAcceptInit()12570 void DisableGetHostNameWhenAcceptInit()
12571 {
12572 	disable_gethostname_by_accept = true;
12573 }
12574 
12575 // Initialize the connection acceptance
AcceptInit(SOCK * s)12576 void AcceptInit(SOCK *s)
12577 {
12578 	AcceptInitEx(s, false);
12579 }
AcceptInitEx(SOCK * s,bool no_lookup_hostname)12580 void AcceptInitEx(SOCK *s, bool no_lookup_hostname)
12581 {
12582 	char tmp[MAX_SIZE];
12583 	// Validate arguments
12584 	if (s == NULL)
12585 	{
12586 		return;
12587 	}
12588 
12589 	Zero(tmp, sizeof(tmp));
12590 
12591 	if (disable_gethostname_by_accept == false && no_lookup_hostname == false)
12592 	{
12593 		if (GetHostName(tmp, sizeof(tmp), &s->RemoteIP) == false ||
12594 		        IsEmptyStr(tmp))
12595 		{
12596 			IPToStr(tmp, sizeof(tmp), &s->RemoteIP);
12597 		}
12598 	}
12599 	else
12600 	{
12601 		IPToStr(tmp, sizeof(tmp), &s->RemoteIP);
12602 	}
12603 
12604 	if (s->RemoteHostname != NULL)
12605 	{
12606 		Free(s->RemoteHostname);
12607 	}
12608 
12609 	s->RemoteHostname = CopyStr(tmp);
12610 }
12611 
12612 // TCP connection acceptance (IPv4)
Accept(SOCK * sock)12613 SOCK *Accept(SOCK *sock)
12614 {
12615 	SOCK *ret;
12616 	SOCKET s, new_socket;
12617 	int size;
12618 	struct sockaddr_in addr;
12619 	bool true_flag = true;
12620 	// Validate arguments
12621 	if (sock == NULL)
12622 	{
12623 		return NULL;
12624 	}
12625 	if (sock->Type == SOCK_INPROC)
12626 	{
12627 		return AcceptInProc(sock);
12628 	}
12629 	if (sock->Type == SOCK_REVERSE_LISTEN)
12630 	{
12631 		return AcceptReverse(sock);
12632 	}
12633 	if (sock->Type == SOCK_RUDP_LISTEN)
12634 	{
12635 		return AcceptRUDP(sock);
12636 	}
12637 	if (sock->ListenMode == false || sock->Type != SOCK_TCP || sock->ServerMode == false)
12638 	{
12639 		return NULL;
12640 	}
12641 	if (sock->CancelAccept)
12642 	{
12643 		return NULL;
12644 	}
12645 	if (sock->IPv6)
12646 	{
12647 		return Accept6(sock);
12648 	}
12649 
12650 	s = sock->socket;
12651 	if (s == INVALID_SOCKET)
12652 	{
12653 		return NULL;
12654 	}
12655 	Zero(&addr, sizeof(addr));
12656 	size = sizeof(addr);
12657 
12658 #ifdef	OS_UNIX
12659 #if	defined(UNIX_LINUX) || defined(UNIX_MACOS)
12660 	UnixIgnoreSignalForThread(SIGUSR1);
12661 #endif	// defined(UNIX_LINUX) || defined(UNIX_MACOS)
12662 	sock->CallingThread = pthread_self();
12663 #endif	// OS_UNIX
12664 
12665 #ifdef	OS_WIN32
12666 	if (sock->EnableConditionalAccept)
12667 	{
12668 		new_socket = Win32Accept(sock, s, (struct sockaddr *)&addr,(int *)&size, false);
12669 	}
12670 	else
12671 	{
12672 		new_socket = accept(s, (struct sockaddr *)&addr,(int *)&size);
12673 	}
12674 #else	// OS_WIN32
12675 	new_socket = accept(s, (struct sockaddr *)&addr,(int *)&size);
12676 #endif	// OS_WIN32
12677 
12678 #ifdef	OS_UNIX
12679 	sock->CallingThread = 0;
12680 #endif	// OS_UNIX
12681 
12682 	if (new_socket == INVALID_SOCKET)
12683 	{
12684 		if (sock->CancelAccept)
12685 		{
12686 			sock->AcceptCanceled = true;
12687 		}
12688 		return NULL;
12689 	}
12690 	if (sock->CancelAccept)
12691 	{
12692 		sock->AcceptCanceled = true;
12693 		closesocket(new_socket);
12694 		return NULL;
12695 	}
12696 
12697 	ret = NewSock();
12698 	ret->socket = new_socket;
12699 	ret->Connected = true;
12700 	ret->AsyncMode = false;
12701 	ret->Type = SOCK_TCP;
12702 	ret->ServerMode = true;
12703 	ret->SecureMode = false;
12704 
12705 	// Configuring the TCP options
12706 	(void)setsockopt(ret->socket, IPPROTO_TCP, TCP_NODELAY, (char *)&true_flag, sizeof(bool));
12707 
12708 	// Initialization of the time-out value
12709 	SetTimeout(ret, TIMEOUT_INFINITE);
12710 
12711 	// Socket information
12712 	QuerySocketInformation(ret);
12713 
12714 	if (IsLocalHostIP(&ret->RemoteIP) == false)
12715 	{
12716 		ret->IpClientAdded = true;
12717 		AddIpClient(&ret->RemoteIP);
12718 	}
12719 
12720 	if (IsZeroIp(&sock->LocalIP) == false && IsLocalHostIP(&sock->LocalIP) == false)
12721 	{
12722 		IP current_ip;
12723 
12724 		if (GetCurrentGlobalIP(&current_ip, false) == false)
12725 		{
12726 			SetCurrentGlobalIP(&sock->LocalIP, false);
12727 		}
12728 	}
12729 
12730 	StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_NATIVE_V4);
12731 
12732 	AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails), "IPv4");
12733 
12734 	return ret;
12735 }
12736 
12737 // TCP connection acceptance (IPv6)
Accept6(SOCK * sock)12738 SOCK *Accept6(SOCK *sock)
12739 {
12740 	SOCK *ret;
12741 	SOCKET s, new_socket;
12742 	int size;
12743 	struct sockaddr_in6 addr;
12744 	// Validate arguments
12745 	if (sock == NULL)
12746 	{
12747 		return NULL;
12748 	}
12749 	if (sock->ListenMode == false || sock->Type != SOCK_TCP || sock->ServerMode == false)
12750 	{
12751 		return NULL;
12752 	}
12753 	if (sock->CancelAccept)
12754 	{
12755 		return NULL;
12756 	}
12757 	if (sock->IPv6 == false)
12758 	{
12759 		return NULL;
12760 	}
12761 
12762 	s = sock->socket;
12763 	if (s == INVALID_SOCKET)
12764 	{
12765 		return NULL;
12766 	}
12767 	Zero(&addr, sizeof(addr));
12768 	size = sizeof(addr);
12769 
12770 #ifdef	OS_UNIX
12771 #if	defined(UNIX_LINUX) || defined(UNIX_MACOS)
12772 	UnixIgnoreSignalForThread(SIGUSR1);
12773 #endif	// defined(UNIX_LINUX) || defined(UNIX_MACOS)
12774 	sock->CallingThread = pthread_self();
12775 #endif	// OS_UNIX
12776 
12777 #ifdef	OS_WIN32
12778 	if (sock->EnableConditionalAccept)
12779 	{
12780 		new_socket = Win32Accept(sock, s, (struct sockaddr *)&addr,(int *)&size, true);
12781 	}
12782 	else
12783 	{
12784 		new_socket = accept(s, (struct sockaddr *)&addr,(int *)&size);
12785 	}
12786 #else	// OS_WIN32
12787 	new_socket = accept(s, (struct sockaddr *)&addr,(int *)&size);
12788 #endif	// OS_WIN32
12789 
12790 #ifdef	OS_UNIX
12791 	sock->CallingThread = 0;
12792 #endif	// OS_UNIX
12793 
12794 	if (new_socket == INVALID_SOCKET)
12795 	{
12796 		if (sock->CancelAccept)
12797 		{
12798 			sock->AcceptCanceled = true;
12799 		}
12800 		return NULL;
12801 	}
12802 	if (sock->CancelAccept)
12803 	{
12804 		sock->AcceptCanceled = true;
12805 		closesocket(new_socket);
12806 		return NULL;
12807 	}
12808 
12809 	ret = NewSock();
12810 	ret->socket = new_socket;
12811 	ret->Connected = true;
12812 	ret->AsyncMode = false;
12813 	ret->Type = SOCK_TCP;
12814 	ret->ServerMode = true;
12815 	ret->SecureMode = false;
12816 
12817 	// Configuring the TCP options
12818 	bool true_flag = true;
12819 	(void)setsockopt(ret->socket, IPPROTO_TCP, TCP_NODELAY, (char *)&true_flag, sizeof(bool));
12820 
12821 	// Initialize the time-out value
12822 	SetTimeout(ret, TIMEOUT_INFINITE);
12823 
12824 	// Socket information
12825 	QuerySocketInformation(ret);
12826 
12827 	if (IsLocalHostIP(&ret->RemoteIP) == false)
12828 	{
12829 		ret->IpClientAdded = true;
12830 		AddIpClient(&ret->RemoteIP);
12831 	}
12832 	if (IsZeroIp(&sock->LocalIP) == false && IsLocalHostIP(&sock->LocalIP) == false)
12833 	{
12834 		IP current_ip;
12835 
12836 		if (GetCurrentGlobalIP(&current_ip, true) == false)
12837 		{
12838 			SetCurrentGlobalIP(&sock->LocalIP, true);
12839 		}
12840 	}
12841 
12842 	StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_NATIVE_V6);
12843 
12844 	AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails), "IPv6");
12845 
12846 	return ret;
12847 }
12848 
12849 // Standby for TCP (IPv6)
ListenEx6(UINT port,bool local_only)12850 SOCK *ListenEx6(UINT port, bool local_only)
12851 {
12852 	return ListenEx62(port, local_only, false);
12853 }
ListenEx62(UINT port,bool local_only,bool enable_ca)12854 SOCK *ListenEx62(UINT port, bool local_only, bool enable_ca)
12855 {
12856 	SOCKET s;
12857 	SOCK *sock;
12858 	struct sockaddr_in6 addr;
12859 	struct in6_addr in;
12860 	IP localhost;
12861 	UINT backlog = SOMAXCONN;
12862 	// Validate arguments
12863 	if (port == 0 || port >= 65536)
12864 	{
12865 		return NULL;
12866 	}
12867 
12868 	// Initialization
12869 	Zero(&addr, sizeof(addr));
12870 	Zero(&in, sizeof(in));
12871 	GetLocalHostIP6(&localhost);
12872 
12873 	addr.sin6_port = htons((UINT)port);
12874 	addr.sin6_family = AF_INET6;
12875 
12876 	if (local_only)
12877 	{
12878 		IPToInAddr6(&addr.sin6_addr, &localhost);
12879 
12880 		enable_ca = false;
12881 	}
12882 
12883 	// Creating a socket
12884 	s = socket(AF_INET6, SOCK_STREAM, 0);
12885 	if (s == INVALID_SOCKET)
12886 	{
12887 		return NULL;
12888 	}
12889 
12890 	bool true_flag = true;
12891 #ifdef	OS_UNIX
12892 	// It is necessary to set the IPv6 Only flag on a UNIX system
12893 	(void)setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &true_flag, sizeof(true_flag));
12894 	// This only have enabled for UNIX system since there is a bug
12895 	// in the implementation of REUSEADDR in Windows OS
12896 	(void)setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&true_flag, sizeof(bool));
12897 #endif	// OS_UNIX
12898 
12899 	if (bind(s, (struct sockaddr *)&addr, sizeof(struct sockaddr_in6)) != 0)
12900 	{
12901 		// Bind failure
12902 		closesocket(s);
12903 		return NULL;
12904 	}
12905 
12906 #ifdef OS_WIN32
12907 	if (enable_ca)
12908 	{
12909 		setsockopt(s, SOL_SOCKET, SO_CONDITIONAL_ACCEPT, (char *)&true_flag, sizeof(bool));
12910 		backlog = 1;
12911 	}
12912 #endif
12913 
12914 	if (listen(s, backlog))
12915 	{
12916 		// Listen failure
12917 		closesocket(s);
12918 		return NULL;
12919 	}
12920 
12921 	// Success
12922 	sock = NewSock();
12923 	sock->Connected = false;
12924 	sock->AsyncMode = false;
12925 	sock->ServerMode = true;
12926 	sock->Type = SOCK_TCP;
12927 	sock->socket = s;
12928 	sock->ListenMode = true;
12929 	sock->SecureMode = false;
12930 	sock->LocalPort = port;
12931 	sock->IPv6 = true;
12932 	sock->LocalOnly = local_only;
12933 	sock->EnableConditionalAccept = enable_ca;
12934 
12935 	return sock;
12936 }
12937 
12938 // Standby for the TCP
Listen(UINT port)12939 SOCK *Listen(UINT port)
12940 {
12941 	return ListenEx(port, false);
12942 }
ListenEx(UINT port,bool local_only)12943 SOCK *ListenEx(UINT port, bool local_only)
12944 {
12945 	return ListenEx2(port, local_only, false, NULL);
12946 }
ListenEx2(UINT port,bool local_only,bool enable_ca,IP * listen_ip)12947 SOCK *ListenEx2(UINT port, bool local_only, bool enable_ca, IP *listen_ip)
12948 {
12949 	SOCKET s;
12950 	SOCK *sock;
12951 	struct sockaddr_in addr;
12952 	struct in_addr in;
12953 	IP localhost;
12954 	UINT backlog = SOMAXCONN;
12955 	// Validate arguments
12956 	if (port == 0 || port >= 65536)
12957 	{
12958 		return NULL;
12959 	}
12960 
12961 	// Initialization
12962 	Zero(&addr, sizeof(addr));
12963 	Zero(&in, sizeof(in));
12964 	SetIP(&localhost, 127, 0, 0, 1);
12965 
12966 	addr.sin_port = htons((UINT)port);
12967 	if (listen_ip == NULL)
12968 	{
12969 		*((UINT *)&addr.sin_addr) = htonl(INADDR_ANY);
12970 	}
12971 	else
12972 	{
12973 		IPToInAddr(&addr.sin_addr, listen_ip);
12974 	}
12975 	addr.sin_family = AF_INET;
12976 
12977 	if (local_only)
12978 	{
12979 		IPToInAddr(&addr.sin_addr, &localhost);
12980 
12981 		enable_ca = false;
12982 	}
12983 
12984 	// Creating a socket
12985 	s = socket(AF_INET, SOCK_STREAM, 0);
12986 	if (s == INVALID_SOCKET)
12987 	{
12988 		return NULL;
12989 	}
12990 
12991 	bool true_flag = true;
12992 #ifdef	OS_UNIX
12993 	// This only have enabled for UNIX system since there is a bug
12994 	// in the implementation of REUSEADDR in Windows OS
12995 	(void)setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&true_flag, sizeof(bool));
12996 #endif	// OS_UNIX
12997 
12998 	if (bind(s, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) != 0)
12999 	{
13000 		// Bind failure
13001 		closesocket(s);
13002 		return NULL;
13003 	}
13004 
13005 #ifdef	OS_WIN32
13006 	if (enable_ca)
13007 	{
13008 		setsockopt(s, SOL_SOCKET, SO_CONDITIONAL_ACCEPT, (char *)&true_flag, sizeof(bool));
13009 		backlog = 1;
13010 	}
13011 #endif	// OS_WIN32
13012 
13013 	if (listen(s, backlog))
13014 	{
13015 		// Listen failure
13016 		closesocket(s);
13017 		return NULL;
13018 	}
13019 
13020 	// Success
13021 	sock = NewSock();
13022 	sock->Connected = false;
13023 	sock->AsyncMode = false;
13024 	sock->ServerMode = true;
13025 	sock->Type = SOCK_TCP;
13026 	sock->socket = s;
13027 	sock->ListenMode = true;
13028 	sock->SecureMode = false;
13029 	sock->LocalPort = port;
13030 	sock->LocalOnly = local_only;
13031 	sock->EnableConditionalAccept = enable_ca;
13032 
13033 	return sock;
13034 }
13035 
13036 // TCP disconnect
Disconnect(SOCK * sock)13037 void Disconnect(SOCK *sock)
13038 {
13039 	SOCKET s;
13040 	// Validate arguments
13041 	if (sock == NULL)
13042 	{
13043 		return;
13044 	}
13045 
13046 	sock->Disconnecting = true;
13047 
13048 #ifdef	ENABLE_SSL_LOGGING
13049 	SockCloseSslLogging(sock);
13050 #endif	// ENABLE_SSL_LOGGING
13051 
13052 #ifdef	OS_UNIX
13053 	UnixFreeAsyncSocket(sock);
13054 #endif	// UnixFreeAsyncSocket
13055 
13056 	if (sock->Type == SOCK_TCP && sock->ListenMode)
13057 	{
13058 		bool no_tcp_check_port = false;
13059 
13060 		// Connect to localhost if the socket is in listening
13061 		sock->CancelAccept = true;
13062 
13063 #if	defined(UNIX_LINUX) || defined(UNIX_MACOS)
13064 		{
13065 			pthread_t t = sock->CallingThread;
13066 
13067 			// Send a signal to the socket to abort accept() forcibly on Linux
13068 			if (t != 0)
13069 			{
13070 				pthread_kill(t, SIGUSR1);
13071 
13072 				SleepThread(200);
13073 			}
13074 		}
13075 #endif	// defined(UNIX_LINUX) || defined(UNIX_MACOS)
13076 
13077 #ifdef	OS_WIN32
13078 		if (sock->hAcceptEvent != NULL)
13079 		{
13080 			SetEvent(sock->hAcceptEvent);
13081 
13082 			no_tcp_check_port = true;
13083 		}
13084 #endif	// OS_WIN32
13085 
13086 		if (sock->AcceptCanceled == false)
13087 		{
13088 			if (no_tcp_check_port == false)
13089 			{
13090 				if (sock->IPv6 == false)
13091 				{
13092 					CheckTCPPort("127.0.0.1", sock->LocalPort);
13093 				}
13094 				else
13095 				{
13096 					CheckTCPPort("::1", sock->LocalPort);
13097 				}
13098 			}
13099 		}
13100 	}
13101 
13102 	Lock(disconnect_function_lock);
13103 
13104 	Lock(sock->disconnect_lock);
13105 
13106 	if (sock->Type == SOCK_TCP)
13107 	{
13108 		if (sock->socket != INVALID_SOCKET)
13109 		{
13110 			// Forced disconnection flag
13111 #ifdef	SO_DONTLINGER
13112 			bool true_flag = true;
13113 			(void)setsockopt(sock->socket, SOL_SOCKET, SO_DONTLINGER, (char *)&true_flag, sizeof(bool));
13114 #else	// SO_DONTLINGER
13115 			bool false_flag = false;
13116 			(void)setsockopt(sock->socket, SOL_SOCKET, SO_LINGER, (char *)&false_flag, sizeof(bool));
13117 #endif	// SO_DONTLINGER
13118 //			setsockopt(sock->socket, SOL_SOCKET, SO_REUSEADDR, (char *)&true_flag, sizeof(bool));
13119 		}
13120 
13121 		// TCP socket
13122 		Lock(sock->lock);
13123 		{
13124 			if (sock->socket == INVALID_SOCKET)
13125 			{
13126 				Unlock(sock->lock);
13127 				Unlock(sock->disconnect_lock);
13128 				Unlock(disconnect_function_lock);
13129 				return;
13130 			}
13131 			s = sock->socket;
13132 
13133 			if (sock->Connected)
13134 			{
13135 				struct linger ling;
13136 				Zero(&ling, sizeof(ling));
13137 
13138 
13139 #if	0
13140 				// SSL disconnect
13141 				Lock(sock->ssl_lock);
13142 				{
13143 					if (sock->SecureMode)
13144 					{
13145 						SSL_shutdown(sock->ssl);
13146 					}
13147 				}
13148 				Unlock(sock->ssl_lock);
13149 #endif
13150 				// Disconnect
13151 				shutdown(s, 2);
13152 			}
13153 
13154 			// Close the socket
13155 			closesocket(s);
13156 
13157 #ifdef	OS_UNIX
13158 #ifdef	FIX_SSL_BLOCKING
13159 			if (sock->CallingThread != NULL)
13160 			{
13161 				pthread_kill(sock->CallingThread, 64);
13162 			}
13163 #endif	// FIX_SSL_BLOCKING
13164 #endif	// OS_UNIX
13165 
13166 			// Release the SSL
13167 			Lock(sock->ssl_lock);
13168 			{
13169 				if (sock->SecureMode)
13170 				{
13171 					if (sock->ssl != NULL)
13172 					{
13173 						Lock(openssl_lock);
13174 						{
13175 							SSL_free(sock->ssl);
13176 							FreeSSLCtx(sock->ssl_ctx);
13177 						}
13178 						Unlock(openssl_lock);
13179 						sock->ssl = NULL;
13180 						sock->ssl_ctx = NULL;
13181 					}
13182 					sock->Connected = false;
13183 					sock->SecureMode = false;
13184 				}
13185 			}
13186 			Unlock(sock->ssl_lock);
13187 
13188 			// Initialization
13189 			sock->socket = INVALID_SOCKET;
13190 			sock->Type = 0;
13191 			sock->AsyncMode = false;
13192 			sock->Connected = false;
13193 			sock->ListenMode = false;
13194 			sock->SecureMode = false;
13195 
13196 			if (sock->IpClientAdded)
13197 			{
13198 				DelIpClient(&sock->RemoteIP);
13199 				sock->IpClientAdded = false;
13200 			}
13201 		}
13202 		Unlock(sock->lock);
13203 
13204 		if (sock->BulkSendTube != NULL)
13205 		{
13206 			TubeDisconnect(sock->BulkSendTube);
13207 		}
13208 
13209 		if (sock->BulkRecvTube != NULL)
13210 		{
13211 			TubeDisconnect(sock->BulkRecvTube);
13212 		}
13213 	}
13214 	else if (sock->Type == SOCK_UDP)
13215 	{
13216 		// UDP socket
13217 		Lock(sock->lock);
13218 		{
13219 			if (sock->socket == INVALID_SOCKET)
13220 			{
13221 				Unlock(sock->lock);
13222 				Unlock(sock->disconnect_lock);
13223 				Unlock(disconnect_function_lock);
13224 				return;
13225 			}
13226 
13227 			s = sock->socket;
13228 
13229 			// Close the socket
13230 			closesocket(s);
13231 
13232 			// Initialization
13233 			sock->socket = INVALID_SOCKET;
13234 			sock->Type = 0;
13235 			sock->AsyncMode = false;
13236 			sock->Connected = false;
13237 			sock->ListenMode = false;
13238 			sock->SecureMode = false;
13239 		}
13240 		Unlock(sock->lock);
13241 	}
13242 	else if (sock->Type == SOCK_INPROC)
13243 	{
13244 		// In-process socket
13245 		if (sock->ListenMode)
13246 		{
13247 			// Stop the Accept process
13248 			sock->CancelAccept = true;
13249 
13250 			Set(sock->InProcAcceptEvent);
13251 
13252 			LockQueue(sock->InProcAcceptQueue);
13253 			{
13254 				while (true)
13255 				{
13256 					SOCK *ss = GetNext(sock->InProcAcceptQueue);
13257 					if (ss == NULL)
13258 					{
13259 						break;
13260 					}
13261 
13262 					Disconnect(ss);
13263 					ReleaseSock(ss);
13264 				}
13265 			}
13266 			UnlockQueue(sock->InProcAcceptQueue);
13267 		}
13268 		else
13269 		{
13270 			// Disconnect the Tube
13271 			TubeDisconnect(sock->SendTube);
13272 			TubeDisconnect(sock->RecvTube);
13273 
13274 			sock->socket = INVALID_SOCKET;
13275 			sock->AsyncMode = false;
13276 			sock->Connected = false;
13277 			sock->ListenMode = false;
13278 			sock->SecureMode = false;
13279 		}
13280 	}
13281 	else if (sock->Type == SOCK_RUDP_LISTEN)
13282 	{
13283 		// RUDP Listen socket
13284 		if (sock->ListenMode)
13285 		{
13286 			// Stop the Accept process
13287 			sock->CancelAccept = true;
13288 
13289 			Set(sock->R_UDP_Stack->NewSockConnectEvent);
13290 
13291 			sock->R_UDP_Stack->Halt = true;
13292 			Set(sock->R_UDP_Stack->HaltEvent);
13293 			SetSockEvent(sock->R_UDP_Stack->SockEvent);
13294 		}
13295 	}
13296 	else if (sock->Type == SOCK_REVERSE_LISTEN)
13297 	{
13298 		// Reverse Listen socket
13299 		if (sock->ListenMode)
13300 		{
13301 			// Stop the Accept process
13302 			sock->CancelAccept = true;
13303 
13304 			Set(sock->ReverseAcceptEvent);
13305 
13306 			LockQueue(sock->ReverseAcceptQueue);
13307 			{
13308 				while (true)
13309 				{
13310 					SOCK *ss = GetNext(sock->ReverseAcceptQueue);
13311 					if (ss == NULL)
13312 					{
13313 						break;
13314 					}
13315 
13316 					Disconnect(ss);
13317 					ReleaseSock(ss);
13318 				}
13319 			}
13320 			UnlockQueue(sock->ReverseAcceptQueue);
13321 		}
13322 	}
13323 	Unlock(sock->disconnect_lock);
13324 
13325 	Unlock(disconnect_function_lock);
13326 }
13327 
13328 typedef struct TCP_PORT_CHECK
13329 {
13330 	REF *ref;
13331 	char hostname[MAX_SIZE];
13332 	UINT port;
13333 	bool ok;
13334 } TCP_PORT_CHECK;
13335 
13336 // Check whether the TCP port can be connected
CheckTCPPortEx(char * hostname,UINT port,UINT timeout)13337 bool CheckTCPPortEx(char *hostname, UINT port, UINT timeout)
13338 {
13339 	SOCK *s;
13340 	// Validate arguments
13341 	if (hostname == NULL || port == 0 || port >= 65536)
13342 	{
13343 		return false;
13344 	}
13345 
13346 	if (timeout == 0)
13347 	{
13348 		timeout = TIMEOUT_TCP_PORT_CHECK;
13349 	}
13350 
13351 	s = ConnectEx(hostname, port, timeout);
13352 	if (s == NULL)
13353 	{
13354 		return false;
13355 	}
13356 	else
13357 	{
13358 		Disconnect(s);
13359 		ReleaseSock(s);
13360 		return true;
13361 	}
13362 }
CheckTCPPort(char * hostname,UINT port)13363 bool CheckTCPPort(char *hostname, UINT port)
13364 {
13365 	return CheckTCPPortEx(hostname, port, TIMEOUT_TCP_PORT_CHECK);
13366 }
13367 
13368 #ifdef	OS_UNIX
13369 // Connection with timeout (UNIX version)
connect_timeout(SOCKET s,struct sockaddr * addr,int size,int timeout,bool * cancel_flag)13370 int connect_timeout(SOCKET s, struct sockaddr *addr, int size, int timeout, bool *cancel_flag)
13371 {
13372 	SOCKSET set;
13373 	bool ok = false;
13374 	UINT64 start_time;
13375 	// Validate arguments
13376 	if (s == INVALID_SOCKET || addr == NULL)
13377 	{
13378 		return -1;
13379 	}
13380 	if (timeout == 0)
13381 	{
13382 		timeout = TIMEOUT_TCP_PORT_CHECK;
13383 	}
13384 
13385 	UnixSetSocketNonBlockingMode(s, true);
13386 
13387 	start_time = Tick64();
13388 
13389 	while (true)
13390 	{
13391 		int ret;
13392 		ret = connect(s, addr, size);
13393 		if (ret == 0 || errno == EISCONN)
13394 		{
13395 			ok = true;
13396 			break;
13397 		}
13398 		else
13399 		{
13400 			if (((start_time + (UINT64)timeout) <= Tick64()) || (errno != EAGAIN && errno != EINPROGRESS && errno != EALREADY))
13401 			{
13402 				// Failure
13403 				break;
13404 			}
13405 			else if (*cancel_flag)
13406 			{
13407 				// Cancel
13408 				break;
13409 			}
13410 			else
13411 			{
13412 				// Connecting
13413 				SleepThread(50);
13414 				UnixSelectInner(1, (UINT *)&s, 1, (UINT *)&s, 100);
13415 			}
13416 		}
13417 	}
13418 
13419 	UnixSetSocketNonBlockingMode(s, false);
13420 
13421 	if (ok)
13422 	{
13423 		return 0;
13424 	}
13425 	else
13426 	{
13427 		return -1;
13428 	}
13429 }
13430 #else
13431 // Connection with timeout (Win32 version)
connect_timeout(SOCKET s,struct sockaddr * addr,int size,int timeout,bool * cancel_flag)13432 int connect_timeout(SOCKET s, struct sockaddr *addr, int size, int timeout, bool *cancel_flag)
13433 {
13434 	UINT64 start_time;
13435 	bool ok = false;
13436 	bool timeouted = false;
13437 	WSAEVENT hEvent;
13438 	UINT zero = 0;
13439 	UINT tmp = 0;
13440 	DWORD ret_size = 0;
13441 	// Validate arguments
13442 	if (s == INVALID_SOCKET || addr == NULL)
13443 	{
13444 		return -1;
13445 	}
13446 	if (timeout == 0)
13447 	{
13448 		timeout = TIMEOUT_TCP_PORT_CHECK;
13449 	}
13450 
13451 	// Create an event
13452 	hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
13453 
13454 	// Associate the socket with the event
13455 	WSAEventSelect(s, hEvent, FD_CONNECT);
13456 
13457 	start_time = Tick64();
13458 
13459 	while (true)
13460 	{
13461 		int ret;
13462 
13463 		ret = connect(s, addr, size);
13464 
13465 		if (ret == 0)
13466 		{
13467 			ok = true;
13468 			break;
13469 		}
13470 		else
13471 		{
13472 			int err = WSAGetLastError();
13473 			//Debug("err=%u\n", err);
13474 			//Debug("cancel_flag=%u\n", *cancel_flag);
13475 			if (timeouted && err == WSAEALREADY)
13476 			{
13477 				// Time-out
13478 				ok = false;
13479 				break;
13480 			}
13481 			if (*cancel_flag)
13482 			{
13483 				// Cancel
13484 				ok = false;
13485 				break;
13486 			}
13487 			if (err == WSAEISCONN || err == WSAEINVAL)
13488 			{
13489 				ok = true;
13490 				break;
13491 			}
13492 			if (((start_time + (UINT64)timeout) <= Tick64()) || (err != WSAEWOULDBLOCK && err != WSAEALREADY))
13493 			{
13494 				// Failure (timeout)
13495 				break;
13496 			}
13497 			else
13498 			{
13499 				SleepThread(10);
13500 				// Connecting
13501 				if (WaitForSingleObject(hEvent, 100) == WAIT_OBJECT_0)
13502 				{
13503 					timeouted = true;
13504 				}
13505 			}
13506 		}
13507 	}
13508 
13509 	// Remove the socket from the event
13510 	WSAEventSelect(s, hEvent, 0);
13511 
13512 	// Restore to synchronized socket
13513 	WSAIoctl(s, FIONBIO, &zero, sizeof(zero), &tmp, sizeof(tmp), &ret_size, NULL, NULL);
13514 
13515 	// Close the event
13516 	CloseHandle(hEvent);
13517 
13518 	if (ok)
13519 	{
13520 		return 0;
13521 	}
13522 	else
13523 	{
13524 		return -1;
13525 	}
13526 }
13527 #endif	// OS_UNIX
13528 
13529 // Set the TOS value of the socket
SetSockTos(SOCK * s,int tos)13530 void SetSockTos(SOCK *s, int tos)
13531 {
13532 	// Validate arguments
13533 	if (s == NULL)
13534 	{
13535 		return;
13536 	}
13537 
13538 	if (s->CurrentTos == tos)
13539 	{
13540 		return;
13541 	}
13542 
13543 #ifdef	IP_TOS
13544 	(void)setsockopt(s->socket, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int));
13545 #endif	// IP_TOS
13546 
13547 	s->CurrentTos = tos;
13548 }
13549 
13550 // Set the priority of the socket
SetSockHighPriority(SOCK * s,bool flag)13551 void SetSockHighPriority(SOCK *s, bool flag)
13552 {
13553 	// Validate arguments
13554 	if (s == NULL)
13555 	{
13556 		return;
13557 	}
13558 
13559 	SetSockTos(s, (flag ? 16 : 0));
13560 }
13561 
13562 // Connect to the IPv4 host using a socket
ConnectTimeoutIPv4(IP * ip,UINT port,UINT timeout,bool * cancel_flag)13563 SOCKET ConnectTimeoutIPv4(IP *ip, UINT port, UINT timeout, bool *cancel_flag)
13564 {
13565 	SOCKET s;
13566 	struct sockaddr_in sockaddr4;
13567 	struct in_addr addr4;
13568 
13569 	Zero(&sockaddr4, sizeof(sockaddr4));
13570 	Zero(&addr4, sizeof(addr4));
13571 
13572 	// Generate a sockaddr_in
13573 	IPToInAddr(&addr4, ip);
13574 	sockaddr4.sin_port = htons((USHORT)port);
13575 	sockaddr4.sin_family = AF_INET;
13576 	sockaddr4.sin_addr.s_addr = addr4.s_addr;
13577 
13578 	// Socket creation
13579 	s = socket(AF_INET, SOCK_STREAM, 0);
13580 	if (s != INVALID_SOCKET)
13581 	{
13582 		// Connection
13583 		if (connect_timeout(s, (struct sockaddr *)&sockaddr4, sizeof(struct sockaddr_in), timeout, cancel_flag) != 0)
13584 		{
13585 			// Connection failure
13586 			closesocket(s);
13587 			s = INVALID_SOCKET;
13588 		}
13589 	}
13590 
13591 	return s;
13592 }
13593 
13594 // Identify whether the HTTPS server to be connected is a SoftEther VPN
DetectIsServerSoftEtherVPN(SOCK * s)13595 bool DetectIsServerSoftEtherVPN(SOCK *s)
13596 {
13597 	HTTP_HEADER *h;
13598 	char ip_str[MAX_SIZE];
13599 	char *send_str;
13600 	UINT content_len;
13601 	BUF *recv_buf;
13602 	void *socket_buffer;
13603 	UINT socket_buffer_size = 32768;
13604 	bool ok = false;
13605 	// Validate arguments
13606 	if (s == NULL)
13607 	{
13608 		return false;
13609 	}
13610 
13611 	IPToStr(ip_str, sizeof(ip_str), &s->RemoteIP);
13612 
13613 	// Request generation
13614 	h = NewHttpHeaderEx("GET", "/", "HTTP/1.1", true);
13615 	AddHttpValue(h, NewHttpValue("X-VPN", "1"));
13616 	AddHttpValue(h, NewHttpValue("Host", ip_str));
13617 	AddHttpValue(h, NewHttpValue("Keep-Alive", HTTP_KEEP_ALIVE));
13618 	AddHttpValue(h, NewHttpValue("Connection", "Keep-Alive"));
13619 	AddHttpValue(h, NewHttpValue("Accept-Language", "ja"));
13620 	AddHttpValue(h, NewHttpValue("User-Agent", DEFAULT_USER_AGENT));
13621 	AddHttpValue(h, NewHttpValue("Pragma", "no-cache"));
13622 	AddHttpValue(h, NewHttpValue("Cache-Control", "no-cache"));
13623 
13624 
13625 
13626 	send_str = HttpHeaderToStr(h);
13627 	FreeHttpHeader(h);
13628 
13629 	// Transmission
13630 	if (SendAll(s, send_str, StrLen(send_str), true) == false)
13631 	{
13632 		Free(send_str);
13633 		return false;
13634 	}
13635 
13636 	Free(send_str);
13637 
13638 	// Receive
13639 	h = RecvHttpHeader(s);
13640 	if (h == NULL)
13641 	{
13642 		return false;
13643 	}
13644 
13645 	// Get the length of the content
13646 	content_len = GetContentLength(h);
13647 	FreeHttpHeader(h);
13648 
13649 	if (content_len == 0 || content_len >= (1024 * 1024))
13650 	{
13651 		return false;
13652 	}
13653 
13654 	// Receive contents
13655 	recv_buf = NewBuf();
13656 	socket_buffer = Malloc(socket_buffer_size);
13657 
13658 	while (true)
13659 	{
13660 		UINT recvsize = MIN(socket_buffer_size, content_len - recv_buf->Size);
13661 		UINT size;
13662 
13663 		if (recvsize == 0)
13664 		{
13665 			ok = true;
13666 			break;
13667 		}
13668 
13669 		size = Recv(s, socket_buffer, recvsize, true);
13670 		if (size == 0)
13671 		{
13672 			// Disconnected
13673 			break;
13674 		}
13675 
13676 		WriteBuf(recv_buf, socket_buffer, size);
13677 	}
13678 
13679 	SeekBuf(recv_buf, 0, 0);
13680 	Free(socket_buffer);
13681 
13682 	if (ok)
13683 	{
13684 		// Examine to confirm whether the incoming data is a SoftEther VPN protocol
13685 		char tmp[1024];
13686 
13687 		Zero(tmp, sizeof(tmp));
13688 
13689 		Copy(tmp, recv_buf->Buf, MIN(recv_buf->Size, (sizeof(tmp) - 1)));
13690 
13691 		ok = false;
13692 
13693 		if (StartWith(tmp, http_detect_server_startwith))
13694 		{
13695 			ok = true;
13696 		}
13697 		else if (InStr(tmp, http_detect_server_tag_future))
13698 		{
13699 			ok = true;
13700 		}
13701 	}
13702 
13703 	FreeBuf(recv_buf);
13704 
13705 	return ok;
13706 }
13707 
13708 // TCP connection thread
ConnectThreadForTcp(THREAD * thread,void * param)13709 void ConnectThreadForTcp(THREAD *thread, void *param)
13710 {
13711 	SOCK *sock;
13712 	char hostname[MAX_SIZE];
13713 	CONNECT_TCP_RUDP_PARAM *p = (CONNECT_TCP_RUDP_PARAM *)param;
13714 	if (thread == NULL || p == NULL)
13715 	{
13716 		return;
13717 	}
13718 
13719 	// Delay
13720 	if (p->Delay >= 1)
13721 	{
13722 		WaitEx(NULL, p->Delay, p->CancelFlag);
13723 	}
13724 
13725 	// Connecting process
13726 	IPToStr(hostname, sizeof(hostname), &p->Ip);
13727 	sock = ConnectEx3(hostname, p->Port, p->Timeout, p->CancelFlag, NULL, NULL, false, true);
13728 
13729 	if (sock != NULL && p->Tcp_TryStartSsl)
13730 	{
13731 		bool ssl_ret = false;
13732 
13733 		p->Tcp_InNegotiation = true;
13734 
13735 		// Attempt the SSL negotiation to take this opportunity
13736 		Lock(p->CancelLock);
13737 		{
13738 			if ((*p->CancelFlag) == false)
13739 			{
13740 				p->CancelDisconnectSock = sock;
13741 				AddRef(sock->ref);
13742 			}
13743 			else
13744 			{
13745 				Debug("User Cancel to StartSSL.\n");
13746 				goto LABEL_CANCEL;
13747 			}
13748 		}
13749 		Unlock(p->CancelLock);
13750 
13751 		// Start the SSL communication
13752 		ssl_ret = StartSSLEx(sock, NULL, NULL, 0, p->Hostname);
13753 
13754 		if (ssl_ret)
13755 		{
13756 			// Identify whether the HTTPS server to be connected is a SoftEther VPN
13757 			SetTimeout(sock, (10 * 1000));
13758 			ssl_ret = DetectIsServerSoftEtherVPN(sock);
13759 			SetTimeout(sock, INFINITE);
13760 
13761 			if (ssl_ret == false)
13762 			{
13763 				Debug("DetectIsServerSoftEtherVPN Error.\n");
13764 			}
13765 		}
13766 
13767 		Lock(p->CancelLock);
13768 		{
13769 			ReleaseSock(p->CancelDisconnectSock);
13770 			p->CancelDisconnectSock = NULL;
13771 		}
13772 LABEL_CANCEL:
13773 		Unlock(p->CancelLock);
13774 
13775 		if (ssl_ret == false)
13776 		{
13777 			// SSL negotiation failure
13778 			Disconnect(sock);
13779 			ReleaseSock(sock);
13780 
13781 			Debug("Fail to StartSSL.\n");
13782 
13783 			sock = NULL;
13784 		}
13785 	}
13786 
13787 	p->Result_Tcp_Sock = sock;
13788 	p->Ok = (p->Result_Tcp_Sock == NULL ? false : true);
13789 	p->FinishedTick = Tick64();
13790 	p->Finished = true;
13791 	p->Tcp_InNegotiation = false;
13792 
13793 	Set(p->FinishEvent);
13794 }
13795 
13796 // R-UDP over ICMP / over DNS connection thread
ConnectThreadForOverDnsOrIcmp(THREAD * thread,void * param)13797 void ConnectThreadForOverDnsOrIcmp(THREAD *thread, void *param)
13798 {
13799 	SOCK *sock;
13800 	CONNECT_TCP_RUDP_PARAM *p = (CONNECT_TCP_RUDP_PARAM *)param;
13801 	if (thread == NULL || p == NULL)
13802 	{
13803 		return;
13804 	}
13805 
13806 	// Delay
13807 	if (p->Delay >= 1)
13808 	{
13809 		WaitEx(NULL, p->Delay, p->CancelFlag);
13810 	}
13811 
13812 	// Connecting process
13813 	sock = NewRUDPClientDirect(p->SvcName, &p->Ip,
13814 	                           (p->RUdpProtocol == RUDP_PROTOCOL_DNS ? 53 : MAKE_SPECIAL_PORT(IP_PROTO_ICMPV4)),
13815 	                           &p->NatT_ErrorCode, p->Timeout, p->CancelFlag, NULL, NULL,
13816 	                           (p->RUdpProtocol == RUDP_PROTOCOL_DNS ? 0 : MAKE_SPECIAL_PORT(IP_PROTO_ICMPV4)),
13817 	                           (p->RUdpProtocol == RUDP_PROTOCOL_DNS ? true : false));
13818 
13819 	p->Result_Nat_T_Sock = sock;
13820 	p->Ok = (p->Result_Nat_T_Sock == NULL ? false : true);
13821 	p->FinishedTick = Tick64();
13822 	p->Finished = true;
13823 
13824 	Set(p->FinishEvent);
13825 }
13826 
13827 // R-UDP (via NAT-T) connection thread
ConnectThreadForRUDP(THREAD * thread,void * param)13828 void ConnectThreadForRUDP(THREAD *thread, void *param)
13829 {
13830 	SOCK *sock;
13831 	CONNECT_TCP_RUDP_PARAM *p = (CONNECT_TCP_RUDP_PARAM *)param;
13832 	if (thread == NULL || p == NULL)
13833 	{
13834 		return;
13835 	}
13836 
13837 	// Delay
13838 	if (p->Delay >= 1)
13839 	{
13840 		WaitEx(NULL, p->Delay, p->CancelFlag);
13841 	}
13842 
13843 	// Connecting process
13844 	sock = NewRUDPClientNatT(p->SvcName, &p->Ip, &p->NatT_ErrorCode, p->Timeout, p->CancelFlag, p->HintStr, p->TargetHostname);
13845 
13846 	p->Result_Nat_T_Sock = sock;
13847 	p->Ok = (p->Result_Nat_T_Sock == NULL ? false : true);
13848 	p->FinishedTick = Tick64();
13849 	p->Finished = true;
13850 
13851 	Set(p->FinishEvent);
13852 }
13853 
13854 // TCP connection
Connect(char * hostname,UINT port)13855 SOCK *Connect(char *hostname, UINT port)
13856 {
13857 	return ConnectEx(hostname, port, 0);
13858 }
ConnectEx(char * hostname,UINT port,UINT timeout)13859 SOCK *ConnectEx(char *hostname, UINT port, UINT timeout)
13860 {
13861 	return ConnectEx2(hostname, port, timeout, NULL);
13862 }
ConnectEx2(char * hostname,UINT port,UINT timeout,bool * cancel_flag)13863 SOCK *ConnectEx2(char *hostname, UINT port, UINT timeout, bool *cancel_flag)
13864 {
13865 	return ConnectEx3(hostname, port, timeout, cancel_flag, NULL, NULL, false, true);
13866 }
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 no_get_hostname)13867 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 no_get_hostname)
13868 {
13869 	return ConnectEx4(hostname, port, timeout, cancel_flag, nat_t_svc_name, nat_t_error_code, try_start_ssl, no_get_hostname, NULL);
13870 }
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 no_get_hostname,IP * ret_ip)13871 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 no_get_hostname, IP *ret_ip)
13872 {
13873 	SOCK *sock;
13874 	SOCKET s;
13875 	struct linger ling;
13876 	IP ip4;
13877 	IP ip6;
13878 	char tmp[MAX_SIZE];
13879 	IP current_ip;
13880 	bool is_ipv6 = false;
13881 	bool dummy = false;
13882 	bool use_natt = false;
13883 	char hostname_original[MAX_SIZE];
13884 	char hint_str[MAX_SIZE];
13885 	bool force_use_natt = false;
13886 	UINT dummy_int = 0;
13887 	IP dummy_ret_ip;
13888 	// Validate arguments
13889 	if (hostname == NULL || port == 0 || port >= 65536 || IsEmptyStr(hostname))
13890 	{
13891 		return NULL;
13892 	}
13893 	if (timeout == 0)
13894 	{
13895 		timeout = TIMEOUT_TCP_PORT_CHECK;
13896 	}
13897 	if (cancel_flag == NULL)
13898 	{
13899 		cancel_flag = &dummy;
13900 	}
13901 	if (nat_t_error_code == NULL)
13902 	{
13903 		nat_t_error_code = &dummy_int;
13904 	}
13905 
13906 	Zero(&dummy_ret_ip, sizeof(IP));
13907 	if (ret_ip == NULL)
13908 	{
13909 		ret_ip = &dummy_ret_ip;
13910 	}
13911 
13912 	Zero(hint_str, sizeof(hint_str));
13913 	StrCpy(hostname_original, sizeof(hostname_original), hostname);
13914 
13915 	use_natt = (IsEmptyStr(nat_t_svc_name) ? false : true);
13916 
13917 	if (use_natt)
13918 	{
13919 		// In case of using NAT-T, split host name if the '/' is included in the host name
13920 		UINT i = SearchStrEx(hostname, "/", 0, false);
13921 
13922 		if (i == INFINITE)
13923 		{
13924 			// Not included
13925 			StrCpy(hostname_original, sizeof(hostname_original), hostname);
13926 		}
13927 		else
13928 		{
13929 			// Included
13930 			StrCpy(hostname_original, sizeof(hostname_original), hostname);
13931 			hostname_original[i] = 0;
13932 
13933 			// Force to use the NAT-T
13934 			force_use_natt = true;
13935 
13936 			// Copy the hint string
13937 			StrCpy(hint_str, sizeof(hint_str), hostname + i + 1);
13938 
13939 			if (StrCmpi(hint_str, "tcp") == 0 || StrCmpi(hint_str, "disable") == 0
13940 			        || StrCmpi(hint_str, "disabled") == 0
13941 			        || StrCmpi(hint_str, "no") == 0 || StrCmpi(hint_str, "none") == 0)
13942 			{
13943 				// Force not to use the NAT-T
13944 				force_use_natt = false;
13945 				use_natt = false;
13946 			}
13947 		}
13948 	}
13949 	else
13950 	{
13951 		StrCpy(hostname_original, sizeof(hostname_original), hostname);
13952 	}
13953 
13954 	Zero(&current_ip, sizeof(current_ip));
13955 
13956 	Zero(&ip4, sizeof(ip4));
13957 	Zero(&ip6, sizeof(ip6));
13958 
13959 	if (IsZeroIp(ret_ip) == false)
13960 	{
13961 		// Skip name resolution
13962 		if (IsIP6(ret_ip))
13963 		{
13964 			Copy(&ip6, ret_ip, sizeof(IP));
13965 		}
13966 		else
13967 		{
13968 			Copy(&ip4, ret_ip, sizeof(IP));
13969 		}
13970 
13971 		//Debug("Using cached IP address: %s = %r\n", hostname_original, ret_ip);
13972 	}
13973 	else
13974 	{
13975 		// Forward resolution
13976 		if (DnsResolve(&ip6, &ip4, hostname_original, 0, cancel_flag) == false)
13977 		{
13978 			return NULL;
13979 		}
13980 	}
13981 
13982 	if (IsZeroIp(&ip4) == false && IsIPLocalHostOrMySelf(&ip4))
13983 	{
13984 		// NAT-T isn't used in the case of connection to localhost
13985 		force_use_natt = false;
13986 		use_natt = false;
13987 	}
13988 
13989 	s = INVALID_SOCKET;
13990 
13991 	// Attempt to connect with IPv4
13992 	if (IsZeroIp(&ip4) == false)
13993 	{
13994 		if (use_natt == false)
13995 		{
13996 			// Normal connection without using NAT-T
13997 			s = ConnectTimeoutIPv4(&ip4, port, timeout, cancel_flag);
13998 
13999 			if (s != INVALID_SOCKET)
14000 			{
14001 				Copy(&current_ip, &ip4, sizeof(IP));
14002 
14003 				Copy(ret_ip, &ip4, sizeof(IP));
14004 			}
14005 		}
14006 		else if (force_use_natt)
14007 		{
14008 			// The connection by forcing the use of NAT-T (not to connection with normal TCP)
14009 			SOCK *nat_t_sock = NewRUDPClientNatT(nat_t_svc_name, &ip4, nat_t_error_code, timeout, cancel_flag,
14010 			                                     hint_str, hostname);
14011 
14012 			if (nat_t_sock != NULL)
14013 			{
14014 				StrCpy(nat_t_sock->UnderlayProtocol, sizeof(nat_t_sock->UnderlayProtocol), SOCK_UNDERLAY_NAT_T);
14015 				AddProtocolDetailsStr(nat_t_sock->ProtocolDetails, sizeof(nat_t_sock->ProtocolDetails), "RUDP");
14016 			}
14017 
14018 			Copy(ret_ip, &ip4, sizeof(IP));
14019 
14020 			return nat_t_sock;
14021 		}
14022 		else
14023 		{
14024 			// Use the connections using NAT-T with normal TCP connection together
14025 			// (Use multiple threads to try to connect in four connection methods concurrently)
14026 			CONNECT_TCP_RUDP_PARAM p1, p2, p3, p4;
14027 			EVENT *finish_event;
14028 			THREAD *t1, *t2, *t3, *t4;
14029 			UINT64 start_tick = Tick64();
14030 			UINT64 giveup_for_all_tick = start_tick + (UINT64)SOCK_CONNECT_WAIT_FOR_ICMP_AND_DNS_AT_LEAST;
14031 			bool cancel_flag2 = false;
14032 			SOCK *cancel_sock = NULL;
14033 
14034 			finish_event = NewEvent();
14035 
14036 			Zero(&p1, sizeof(p1));
14037 			Zero(&p2, sizeof(p2));
14038 			Zero(&p3, sizeof(p3));
14039 			Zero(&p4, sizeof(p4));
14040 
14041 			// p1: TCP
14042 			StrCpy(p1.Hostname, sizeof(p1.Hostname), hostname_original);
14043 			Copy(&p1.Ip, &ip4, sizeof(IP));
14044 			p1.Port = port;
14045 			p1.Timeout = timeout;
14046 			p1.CancelFlag = &cancel_flag2;
14047 			p1.FinishEvent = finish_event;
14048 			p1.Tcp_TryStartSsl = try_start_ssl;
14049 			p1.CancelLock = NewLock();
14050 
14051 			// p2: NAT-T
14052 			StrCpy(p2.Hostname, sizeof(p2.Hostname), hostname_original);
14053 			Copy(&p2.Ip, &ip4, sizeof(IP));
14054 			p2.Port = port;
14055 			p2.Timeout = timeout;
14056 			p2.CancelFlag = &cancel_flag2;
14057 			p2.FinishEvent = finish_event;
14058 
14059 			StrCpy(p2.HintStr, sizeof(p2.HintStr), hint_str);
14060 			StrCpy(p2.TargetHostname, sizeof(p2.TargetHostname), hostname);
14061 			StrCpy(p2.SvcName, sizeof(p2.SvcName), nat_t_svc_name);
14062 			p2.Delay = 30;		// Delay by 30ms
14063 
14064 			// p3: over ICMP
14065 			StrCpy(p3.Hostname, sizeof(p3.Hostname), hostname_original);
14066 			Copy(&p3.Ip, &ip4, sizeof(IP));
14067 			p3.Port = port;
14068 			p3.Timeout = timeout;
14069 			p3.CancelFlag = &cancel_flag2;
14070 			p3.FinishEvent = finish_event;
14071 			StrCpy(p3.SvcName, sizeof(p3.SvcName), nat_t_svc_name);
14072 			p3.RUdpProtocol = RUDP_PROTOCOL_ICMP;
14073 			p3.Delay = 200;		// Delay by 200ms
14074 
14075 			// p4: over DNS
14076 			StrCpy(p4.Hostname, sizeof(p4.Hostname), hostname_original);
14077 			Copy(&p4.Ip, &ip4, sizeof(IP));
14078 			p4.Port = port;
14079 			p4.Timeout = timeout;
14080 			p4.CancelFlag = &cancel_flag2;
14081 			p4.FinishEvent = finish_event;
14082 			StrCpy(p4.SvcName, sizeof(p4.SvcName), nat_t_svc_name);
14083 			p4.RUdpProtocol = RUDP_PROTOCOL_DNS;
14084 			p4.Delay = 100;		// Delay by 100ms
14085 
14086 			t1 = NewThread(ConnectThreadForTcp, &p1);
14087 			t2 = NewThread(ConnectThreadForRUDP, &p2);
14088 			t4 = NewThread(ConnectThreadForOverDnsOrIcmp, &p4);
14089 			t3 = NewThread(ConnectThreadForOverDnsOrIcmp, &p3);
14090 
14091 			while (true)
14092 			{
14093 				UINT64 now = Tick64();
14094 
14095 				if (*cancel_flag)
14096 				{
14097 					// Cancel by the user
14098 					break;
14099 				}
14100 
14101 				if (p1.Finished && p2.Finished)
14102 				{
14103 					// Results for both the TCP and the NAT-T were confirmed
14104 					if (now >= giveup_for_all_tick)
14105 					{
14106 						// Wait at least minimum time until successful of the ICMP or the DNS
14107 						break;
14108 					}
14109 
14110 					if (p3.Ok || p4.Ok)
14111 					{
14112 						// Exit the loop immediately if any of the ICMP or the DNS is successful
14113 						break;
14114 					}
14115 				}
14116 
14117 				if (p1.Finished && p1.Ok)
14118 				{
14119 					// Have successfully connected by TCP
14120 					break;
14121 				}
14122 
14123 				if (p2.Finished && p2.Ok)
14124 				{
14125 					UINT p1_wait_time;
14126 					UINT64 tcp_giveup_tick;
14127 					UINT p2_spent_time;
14128 					// Have successfully connected by R-UDP
14129 					if (p1.Finished)
14130 					{
14131 						// Result of TCP is confirmed
14132 						break;
14133 					}
14134 
14135 					// Calculate the time takes to complete connection of R-UDP
14136 					p2_spent_time = (UINT)(p2.FinishedTick - start_tick);
14137 
14138 					// Decide the grace time for results of TCP until settled.
14139 					// The grace time is four times the duration of the R-UDP, and at least 400 milliseconds from the start,
14140 					// and up to 2500 milliseconds after the R-UDP results settled
14141 					p1_wait_time = p2_spent_time * 4;
14142 					p1_wait_time = MAX(p1_wait_time, 400);
14143 					//Debug("p2_spent_time = %u,   p1_wait_time = %u\n", p2_spent_time, p1_wait_time);
14144 
14145 					tcp_giveup_tick = start_tick + (UINT64)p1_wait_time;
14146 					tcp_giveup_tick = MIN(tcp_giveup_tick, (p2.FinishedTick + 2500ULL));
14147 
14148 					if (now >= tcp_giveup_tick)
14149 					{
14150 						// Result of the TCP is uncertain, but give up
14151 						if (p1.Finished || p1.Tcp_InNegotiation == false)
14152 						{
14153 							// Break only when TCP SSL negotiation is not being processed
14154 							break;
14155 						}
14156 					}
14157 				}
14158 
14159 				Wait(finish_event, 25);
14160 			}
14161 
14162 			cancel_flag2 = true;
14163 
14164 			Lock(p1.CancelLock);
14165 			{
14166 				if (p1.CancelDisconnectSock != NULL)
14167 				{
14168 					cancel_sock = p1.CancelDisconnectSock;
14169 
14170 					AddRef(cancel_sock->ref);
14171 				}
14172 			}
14173 			Unlock(p1.CancelLock);
14174 
14175 			if (cancel_sock != NULL)
14176 			{
14177 				Disconnect(cancel_sock);
14178 				ReleaseSock(cancel_sock);
14179 			}
14180 
14181 			WaitThread(t1, INFINITE);
14182 			WaitThread(t2, INFINITE);
14183 			WaitThread(t3, INFINITE);
14184 			WaitThread(t4, INFINITE);
14185 			ReleaseThread(t1);
14186 			ReleaseThread(t2);
14187 			ReleaseThread(t3);
14188 			ReleaseThread(t4);
14189 			ReleaseEvent(finish_event);
14190 
14191 			DeleteLock(p1.CancelLock);
14192 
14193 			if (*cancel_flag)
14194 			{
14195 				// Abandon all the results because the user canceled
14196 				Disconnect(p1.Result_Nat_T_Sock);
14197 				ReleaseSock(p1.Result_Nat_T_Sock);
14198 				Disconnect(p2.Result_Nat_T_Sock);
14199 				ReleaseSock(p2.Result_Nat_T_Sock);
14200 				Disconnect(p3.Result_Nat_T_Sock);
14201 				ReleaseSock(p3.Result_Nat_T_Sock);
14202 				Disconnect(p4.Result_Nat_T_Sock);
14203 				ReleaseSock(p4.Result_Nat_T_Sock);
14204 
14205 				return NULL;
14206 			}
14207 
14208 			if (p1.Ok)
14209 			{
14210 				char hostname[MAX_SIZE];
14211 
14212 				// Use the results of the TCP
14213 				// Dispose other results
14214 				Disconnect(p2.Result_Nat_T_Sock);
14215 				ReleaseSock(p2.Result_Nat_T_Sock);
14216 				Disconnect(p3.Result_Nat_T_Sock);
14217 				ReleaseSock(p3.Result_Nat_T_Sock);
14218 				Disconnect(p4.Result_Nat_T_Sock);
14219 				ReleaseSock(p4.Result_Nat_T_Sock);
14220 
14221 				if (GetHostName(hostname, sizeof(hostname), &ip4))
14222 				{
14223 					Free(p1.Result_Tcp_Sock->RemoteHostname);
14224 					p1.Result_Tcp_Sock->RemoteHostname = CopyStr(hostname);
14225 				}
14226 
14227 				Copy(ret_ip, &ip4, sizeof(IP));
14228 
14229 				return p1.Result_Tcp_Sock;
14230 			}
14231 			else if (p2.Ok)
14232 			{
14233 				// Use the results of the R-UDP
14234 				// Dispose other results
14235 				Disconnect(p3.Result_Nat_T_Sock);
14236 				ReleaseSock(p3.Result_Nat_T_Sock);
14237 				Disconnect(p4.Result_Nat_T_Sock);
14238 				ReleaseSock(p4.Result_Nat_T_Sock);
14239 
14240 				StrCpy(p2.Result_Nat_T_Sock->UnderlayProtocol, sizeof(p2.Result_Nat_T_Sock->UnderlayProtocol), SOCK_UNDERLAY_NAT_T);
14241 				AddProtocolDetailsStr(p2.Result_Nat_T_Sock->UnderlayProtocol, sizeof(p2.Result_Nat_T_Sock->UnderlayProtocol), "RUDP/UDP");
14242 
14243 				Copy(ret_ip, &ip4, sizeof(IP));
14244 
14245 				return p2.Result_Nat_T_Sock;
14246 			}
14247 			else if (p4.Ok)
14248 			{
14249 				// Use this if over-DNS success
14250 				// Dispose other results
14251 				Disconnect(p3.Result_Nat_T_Sock);
14252 				ReleaseSock(p3.Result_Nat_T_Sock);
14253 
14254 				StrCpy(p4.Result_Nat_T_Sock->UnderlayProtocol, sizeof(p4.Result_Nat_T_Sock->UnderlayProtocol), SOCK_UNDERLAY_DNS);
14255 				AddProtocolDetailsStr(p4.Result_Nat_T_Sock->UnderlayProtocol, sizeof(p4.Result_Nat_T_Sock->UnderlayProtocol), "RUDP/DNS");
14256 
14257 				Copy(ret_ip, &ip4, sizeof(IP));
14258 
14259 				return p4.Result_Nat_T_Sock;
14260 			}
14261 			else if (p3.Ok)
14262 			{
14263 				// Use this if over ICMP success
14264 				StrCpy(p3.Result_Nat_T_Sock->UnderlayProtocol, sizeof(p3.Result_Nat_T_Sock->UnderlayProtocol), SOCK_UNDERLAY_ICMP);
14265 				AddProtocolDetailsStr(p3.Result_Nat_T_Sock->UnderlayProtocol, sizeof(p3.Result_Nat_T_Sock->UnderlayProtocol), "RUDP/ICMP");
14266 
14267 				Copy(ret_ip, &ip4, sizeof(IP));
14268 
14269 				return p3.Result_Nat_T_Sock;
14270 			}
14271 			else
14272 			{
14273 				// Continue the process if all trials failed
14274 				*nat_t_error_code = p2.NatT_ErrorCode;
14275 			}
14276 		}
14277 	}
14278 
14279 	// Attempt to connect with IPv6
14280 	if (s == INVALID_SOCKET && IsZeroIp(&ip6) == false)
14281 	{
14282 		struct sockaddr_in6 sockaddr6;
14283 		struct in6_addr addr6;
14284 
14285 		Zero(&sockaddr6, sizeof(sockaddr6));
14286 		Zero(&addr6, sizeof(addr6));
14287 
14288 		// Generation of the sockaddr_in6
14289 		IPToInAddr6(&addr6, &ip6);
14290 		sockaddr6.sin6_port = htons((USHORT)port);
14291 		sockaddr6.sin6_family = AF_INET6;
14292 		sockaddr6.sin6_scope_id = ip6.ipv6_scope_id;
14293 		Copy(&sockaddr6.sin6_addr, &addr6, sizeof(addr6));
14294 
14295 		// Socket creation
14296 		s = socket(AF_INET6, SOCK_STREAM, 0);
14297 		if (s != INVALID_SOCKET)
14298 		{
14299 			// Connection
14300 			if (connect_timeout(s, (struct sockaddr *)&sockaddr6, sizeof(struct sockaddr_in6), timeout, cancel_flag) != 0)
14301 			{
14302 				// Connection failure
14303 				closesocket(s);
14304 				s = INVALID_SOCKET;
14305 			}
14306 			else
14307 			{
14308 				Copy(&current_ip, &ip6, sizeof(IP));
14309 
14310 				is_ipv6 = true;
14311 
14312 				Copy(ret_ip, &ip6, sizeof(IP));
14313 			}
14314 		}
14315 	}
14316 
14317 	if (s == INVALID_SOCKET)
14318 	{
14319 		// Connection fails on both of IPv4, IPv6
14320 		return NULL;
14321 	}
14322 
14323 	// Creating a SOCK
14324 	sock = NewSock();
14325 	sock->socket = s;
14326 	sock->Type = SOCK_TCP;
14327 	sock->ServerMode = false;
14328 
14329 	StrCpy(sock->UnderlayProtocol, sizeof(sock->UnderlayProtocol), is_ipv6 ? SOCK_UNDERLAY_NATIVE_V6 : SOCK_UNDERLAY_NATIVE_V4);
14330 	AddProtocolDetailsStr(sock->ProtocolDetails, sizeof(sock->ProtocolDetails), is_ipv6 ? "IPv6" : "IPv4");
14331 
14332 	// Host name resolution
14333 	if (no_get_hostname || (GetHostName(tmp, sizeof(tmp), &current_ip) == false))
14334 	{
14335 		StrCpy(tmp, sizeof(tmp), hostname_original);
14336 	}
14337 
14338 	//Debug("PTR: %s\n", tmp);
14339 
14340 	sock->RemoteHostname = CopyStr(tmp);
14341 
14342 //	Debug("new socket: %u\n", s);
14343 
14344 	Zero(&ling, sizeof(ling));
14345 
14346 	bool true_flag = true;
14347 	// Forced disconnection flag
14348 #ifdef	SO_DONTLINGER
14349 	(void)setsockopt(sock->socket, SOL_SOCKET, SO_DONTLINGER, (char *)&true_flag, sizeof(bool));
14350 #else	// SO_DONTLINGER
14351 	bool false_flag = false;
14352 	(void)setsockopt(sock->socket, SOL_SOCKET, SO_LINGER, (char *)&false_flag, sizeof(bool));
14353 #endif	// SO_DONTLINGER
14354 //	setsockopt(sock->socket, SOL_SOCKET, SO_REUSEADDR, (char *)&true_flag, sizeof(bool));
14355 
14356 	// Configuring TCP options
14357 	(void)setsockopt(sock->socket, IPPROTO_TCP, TCP_NODELAY, (char *)&true_flag, sizeof(bool));
14358 
14359 	// Initialization of the time-out value
14360 	SetTimeout(sock, TIMEOUT_INFINITE);
14361 
14362 	// Get the socket information
14363 	QuerySocketInformation(sock);
14364 
14365 	if (IsZeroIp(&sock->LocalIP) == false && IsLocalHostIP(&sock->LocalIP) == false)
14366 	{
14367 		IP current_ip;
14368 
14369 		if (GetCurrentGlobalIP(&current_ip, is_ipv6) == false)
14370 		{
14371 			SetCurrentGlobalIP(&sock->LocalIP, is_ipv6);
14372 		}
14373 	}
14374 
14375 	sock->Connected = true;
14376 	sock->AsyncMode = false;
14377 	sock->SecureMode = false;
14378 	sock->IPv6 = is_ipv6;
14379 
14380 	return sock;
14381 }
14382 
14383 // Add a protocol details strings
AddProtocolDetailsStr(char * dst,UINT dst_size,char * str)14384 void AddProtocolDetailsStr(char *dst, UINT dst_size, char *str)
14385 {
14386 	TOKEN_LIST *t1, *t2;
14387 	UINT i, j;
14388 	if (dst == NULL || str == NULL)
14389 	{
14390 		return;
14391 	}
14392 
14393 	t1 = ParseTokenWithoutNullStr(dst, " ");
14394 	t2 = ParseTokenWithoutNullStr(str, " ");
14395 
14396 	for (i = 0; i < t2->NumTokens; i++)
14397 	{
14398 		bool exists = false;
14399 		for (j = 0; j < t1->NumTokens; j++)
14400 		{
14401 			if (StrCmpi(t1->Token[j], t2->Token[i]) == 0)
14402 			{
14403 				exists = true;
14404 				break;
14405 			}
14406 		}
14407 
14408 		if (exists == false)
14409 		{
14410 			StrCat(dst, dst_size, t2->Token[i]);
14411 			StrCat(dst, dst_size, " ");
14412 		}
14413 	}
14414 
14415 	FreeToken(t1);
14416 	FreeToken(t2);
14417 }
14418 
AddProtocolDetailsKeyValueStr(char * dst,UINT dst_size,char * key,char * value)14419 void AddProtocolDetailsKeyValueStr(char *dst, UINT dst_size, char *key, char *value)
14420 {
14421 	char tmp[128];
14422 	StrCpy(tmp, sizeof(tmp), key);
14423 	StrCat(tmp, sizeof(tmp), "=");
14424 	StrCat(tmp, sizeof(tmp), value);
14425 	AddProtocolDetailsStr(dst, dst_size, tmp);
14426 }
14427 
AddProtocolDetailsKeyValueInt(char * dst,UINT dst_size,char * key,UINT value)14428 void AddProtocolDetailsKeyValueInt(char *dst, UINT dst_size, char *key, UINT value)
14429 {
14430 	char tmp[128];
14431 	ToStr(tmp, value);
14432 	AddProtocolDetailsKeyValueStr(dst, dst_size, key, tmp);
14433 }
14434 
14435 
14436 // Setting the buffer size of the socket
SetSocketBufferSize(SOCKET s,bool send,UINT size)14437 bool SetSocketBufferSize(SOCKET s, bool send, UINT size)
14438 {
14439 	int value = (int)size;
14440 	// Validate arguments
14441 	if (s == INVALID_SOCKET)
14442 	{
14443 		return false;
14444 	}
14445 
14446 	if (setsockopt(s, SOL_SOCKET, (send ? SO_SNDBUF : SO_RCVBUF), (char *)&value, sizeof(int)) != 0)
14447 	{
14448 		return false;
14449 	}
14450 
14451 	return true;
14452 }
SetSocketBufferSizeWithBestEffort(SOCKET s,bool send,UINT size)14453 UINT SetSocketBufferSizeWithBestEffort(SOCKET s, bool send, UINT size)
14454 {
14455 	// Validate arguments
14456 	if (s == INVALID_SOCKET)
14457 	{
14458 		return 0;
14459 	}
14460 
14461 	while (true)
14462 	{
14463 		if (SetSocketBufferSize(s, send, size))
14464 		{
14465 			return size;
14466 		}
14467 
14468 		size = (UINT)((double)size / 1.5);
14469 
14470 		if (size <= 32767)
14471 		{
14472 			return 0;
14473 		}
14474 	}
14475 }
14476 
14477 // Initialize the buffer size of the UDP socket
InitUdpSocketBufferSize(SOCKET s)14478 void InitUdpSocketBufferSize(SOCKET s)
14479 {
14480 	SetSocketBufferSizeWithBestEffort(s, true, UDP_MAX_BUFFER_SIZE);
14481 	SetSocketBufferSizeWithBestEffort(s, false, UDP_MAX_BUFFER_SIZE);
14482 }
14483 
14484 // Get the socket information
QuerySocketInformation(SOCK * sock)14485 void QuerySocketInformation(SOCK *sock)
14486 {
14487 	// Validate arguments
14488 	if (sock == NULL)
14489 	{
14490 		return;
14491 	}
14492 
14493 	Lock(sock->lock);
14494 	{
14495 		struct sockaddr_in6 sockaddr6;
14496 		struct in6_addr *addr6;
14497 		int size;
14498 		UINT dw;
14499 		UINT opt_value = 0;
14500 
14501 		if (sock->Type == SOCK_TCP)
14502 		{
14503 			// Get the information of the remote host
14504 			size = sizeof(sockaddr6);
14505 			if (getpeername(sock->socket, (struct sockaddr *)&sockaddr6, (int *)&size) == 0)
14506 			{
14507 				if (size >= sizeof(struct sockaddr_in6))
14508 				{
14509 					sock->RemotePort = (UINT)ntohs(sockaddr6.sin6_port);
14510 					addr6 = &sockaddr6.sin6_addr;
14511 					InAddrToIP6(&sock->RemoteIP, addr6);
14512 					sock->RemoteIP.ipv6_scope_id = sockaddr6.sin6_scope_id;
14513 				}
14514 				else
14515 				{
14516 					struct sockaddr_in *sockaddr;
14517 					struct in_addr *addr;
14518 
14519 					sockaddr = (struct sockaddr_in *)&sockaddr6;
14520 					sock->RemotePort = (UINT)ntohs(sockaddr->sin_port);
14521 					addr = &sockaddr->sin_addr;
14522 					InAddrToIP(&sock->RemoteIP, addr);
14523 				}
14524 			}
14525 		}
14526 
14527 		// Get the local host information
14528 		size = sizeof(sockaddr6);
14529 		if (getsockname(sock->socket, (struct sockaddr *)&sockaddr6, (int *)&size) == 0)
14530 		{
14531 			if (size >= sizeof(struct sockaddr_in6))
14532 			{
14533 				sock->LocalPort = (UINT)ntohs(sockaddr6.sin6_port);
14534 				addr6 = &sockaddr6.sin6_addr;
14535 				InAddrToIP6(&sock->LocalIP, addr6);
14536 				sock->LocalIP.ipv6_scope_id = sockaddr6.sin6_scope_id;
14537 			}
14538 			else
14539 			{
14540 				struct sockaddr_in *sockaddr;
14541 				struct in_addr *addr;
14542 
14543 				sockaddr = (struct sockaddr_in *)&sockaddr6;
14544 				sock->LocalPort = (UINT)ntohs(sockaddr->sin_port);
14545 				addr = &sockaddr->sin_addr;
14546 				InAddrToIP(&sock->LocalIP, addr);
14547 			}
14548 		}
14549 
14550 		if (sock->IsRawSocket)
14551 		{
14552 			sock->LocalPort = sock->RemotePort = MAKE_SPECIAL_PORT(sock->RawSocketIPProtocol);
14553 		}
14554 
14555 		if (sock->Type == SOCK_UDP)
14556 		{
14557 			sock->UdpMaxMsgSize = UDP_MAX_MSG_SIZE_DEFAULT;
14558 
14559 #ifdef	OS_WIN32
14560 			if (true)
14561 			{
14562 				// Get the buffer size that can be transmitted and received at once
14563 				UINT max_value = 0;
14564 				int len = sizeof(UINT);
14565 
14566 				if (getsockopt(sock->socket, SOL_SOCKET, SO_MAX_MSG_SIZE, (char *)&max_value, &len) == 0)
14567 				{
14568 					sock->UdpMaxMsgSize = max_value;
14569 				}
14570 			}
14571 #endif	// OS_WIN32
14572 		}
14573 
14574 		if (sock->IPv6)
14575 		{
14576 #ifdef	IPV6_UNICAST_HOPS
14577 			opt_value = IPV6_UNICAST_HOPS;
14578 #endif	// IPV6_UNICAST_HOPS
14579 		}
14580 		else
14581 		{
14582 #ifdef	IP_TTL
14583 			opt_value = IP_TTL;
14584 #endif	// IP_TTL
14585 		}
14586 
14587 		// Support of the TTL value
14588 		size = sizeof(UINT);
14589 		if (opt_value == 0 ||
14590 		        getsockopt(sock->socket, (sock->IPv6 ? IPPROTO_IPV6 : IPPROTO_IP), opt_value, (char *)&dw, &size) != 0)
14591 		{
14592 			sock->IsTtlSupported = false;
14593 		}
14594 		else
14595 		{
14596 			sock->IsTtlSupported = true;
14597 			sock->CurrentTtl = dw;
14598 		}
14599 	}
14600 	Unlock(sock->lock);
14601 }
14602 
14603 // Setting the TTL value
SetTtl(SOCK * sock,UINT ttl)14604 bool SetTtl(SOCK *sock, UINT ttl)
14605 {
14606 	UINT dw;
14607 	int size;
14608 	UINT opt_value = 0;
14609 	// Validate arguments
14610 	if (sock == NULL)
14611 	{
14612 		return false;
14613 	}
14614 
14615 	if (sock->IsTtlSupported == false)
14616 	{
14617 		return false;
14618 	}
14619 
14620 	if (sock->CurrentTtl == ttl)
14621 	{
14622 		return true;
14623 	}
14624 
14625 	dw = ttl;
14626 	size = sizeof(UINT);
14627 
14628 	if (sock->IPv6)
14629 	{
14630 #ifdef	IPV6_UNICAST_HOPS
14631 		opt_value = IPV6_UNICAST_HOPS;
14632 #endif	// IPV6_UNICAST_HOPS
14633 	}
14634 	else
14635 	{
14636 #ifdef	IP_TTL
14637 		opt_value = IP_TTL;
14638 #endif	// IP_TTL
14639 	}
14640 
14641 	if (opt_value == 0 ||
14642 	        setsockopt(sock->socket, (sock->IPv6 ? IPPROTO_IPV6 : IPPROTO_IP), opt_value, (char *)&dw, size) == false)
14643 	{
14644 		return false;
14645 	}
14646 
14647 	sock->CurrentTtl = ttl;
14648 
14649 	return true;
14650 }
14651 
14652 // Release of the socket
ReleaseSock(SOCK * s)14653 void ReleaseSock(SOCK *s)
14654 {
14655 	// Validate arguments
14656 	if (s == NULL)
14657 	{
14658 		return;
14659 	}
14660 
14661 	if (Release(s->ref) == 0)
14662 	{
14663 		if (s->ListenMode == false && s->ServerMode)
14664 		{
14665 			Print("");
14666 		}
14667 		CleanupSock(s);
14668 	}
14669 }
14670 
14671 // Clean-up of the socket
CleanupSock(SOCK * s)14672 void CleanupSock(SOCK *s)
14673 {
14674 	// Validate arguments
14675 	if (s == NULL)
14676 	{
14677 		return;
14678 	}
14679 
14680 //	{Debug("CleanupSock: Disconnect() Called: %s %u\n", __FILE__, __LINE__);Disconnect(s);}
14681 	Disconnect(s);
14682 
14683 	if (s->InProcAcceptQueue != NULL)
14684 	{
14685 		while (true)
14686 		{
14687 			SOCK *ss = GetNext(s->InProcAcceptQueue);
14688 			if (ss == NULL)
14689 			{
14690 				break;
14691 			}
14692 
14693 			Disconnect(ss);
14694 			ReleaseSock(ss);
14695 		}
14696 
14697 		ReleaseQueue(s->InProcAcceptQueue);
14698 	}
14699 
14700 	if (s->InProcAcceptEvent != NULL)
14701 	{
14702 		ReleaseEvent(s->InProcAcceptEvent);
14703 	}
14704 
14705 	if (s->ReverseAcceptQueue != NULL)
14706 	{
14707 		while (true)
14708 		{
14709 			SOCK *ss = GetNext(s->ReverseAcceptQueue);
14710 			if (ss == NULL)
14711 			{
14712 				break;
14713 			}
14714 
14715 			Disconnect(ss);
14716 			ReleaseSock(ss);
14717 		}
14718 
14719 		ReleaseQueue(s->ReverseAcceptQueue);
14720 	}
14721 
14722 	if (s->ReverseAcceptEvent != NULL)
14723 	{
14724 		ReleaseEvent(s->ReverseAcceptEvent);
14725 	}
14726 
14727 	if (s->SendTube != NULL)
14728 	{
14729 		TubeDisconnect(s->SendTube);
14730 		ReleaseTube(s->SendTube);
14731 	}
14732 
14733 	if (s->RecvTube != NULL)
14734 	{
14735 		TubeDisconnect(s->RecvTube);
14736 		ReleaseTube(s->RecvTube);
14737 	}
14738 
14739 	if (s->BulkRecvTube != NULL)
14740 	{
14741 		TubeDisconnect(s->BulkRecvTube);
14742 		ReleaseTube(s->BulkRecvTube);
14743 	}
14744 
14745 	if (s->BulkSendTube != NULL)
14746 	{
14747 		TubeDisconnect(s->BulkSendTube);
14748 		ReleaseTube(s->BulkSendTube);
14749 	}
14750 
14751 	if (s->BulkSendKey != NULL)
14752 	{
14753 		ReleaseSharedBuffer(s->BulkSendKey);
14754 	}
14755 
14756 	if (s->BulkRecvKey != NULL)
14757 	{
14758 		ReleaseSharedBuffer(s->BulkRecvKey);
14759 	}
14760 
14761 	if (s->InProcRecvFifo != NULL)
14762 	{
14763 		ReleaseFifo(s->InProcRecvFifo);
14764 	}
14765 
14766 	if (s->R_UDP_Stack != NULL)
14767 	{
14768 		FreeRUDP(s->R_UDP_Stack);
14769 	}
14770 
14771 #ifdef	OS_WIN32
14772 	Win32FreeAsyncSocket(s);
14773 #else	// OS_WIN32
14774 	UnixFreeAsyncSocket(s);
14775 #endif	// OS_WIN32
14776 
14777 	FreeBuf(s->SendBuf);
14778 	if (s->socket != INVALID_SOCKET)
14779 	{
14780 #ifdef	OS_WIN32
14781 		closesocket(s->socket);
14782 #else	// OS_WIN32
14783 		close(s->socket);
14784 #endif	// OS_WIN32
14785 	}
14786 	Free(s->RemoteHostname);
14787 
14788 #ifdef	OS_WIN32
14789 	if (s->hAcceptEvent != NULL)
14790 	{
14791 		CloseHandle(s->hAcceptEvent);
14792 	}
14793 #endif	// OS_WIN32
14794 
14795 	// Release the certificate
14796 	if (s->RemoteX != NULL)
14797 	{
14798 		FreeX(s->RemoteX);
14799 		s->RemoteX = NULL;
14800 	}
14801 	if (s->LocalX != NULL)
14802 	{
14803 		FreeX(s->LocalX);
14804 		s->LocalX = NULL;
14805 	}
14806 
14807 	// Cipher algorithm name
14808 	if (s->CipherName != NULL)
14809 	{
14810 		Free(s->CipherName);
14811 		s->CipherName = NULL;
14812 	}
14813 
14814 	Free(s->WaitToUseCipher);
14815 	DeleteLock(s->lock);
14816 	DeleteLock(s->ssl_lock);
14817 	DeleteLock(s->disconnect_lock);
14818 
14819 	Dec(num_tcp_connections);
14820 
14821 	Free(s);
14822 }
14823 
14824 // Creating a new socket
NewSock()14825 SOCK *NewSock()
14826 {
14827 	SOCK *s = ZeroMallocFast(sizeof(SOCK));
14828 
14829 	s->ref = NewRef();
14830 	s->lock = NewLock();
14831 	s->SendBuf = NewBuf();
14832 	s->socket = INVALID_SOCKET;
14833 	s->ssl_lock = NewLock();
14834 	s->disconnect_lock = NewLock();
14835 
14836 	Inc(num_tcp_connections);
14837 
14838 	return s;
14839 }
14840 
14841 // Convert the IP to UINT
IPToUINT(IP * ip)14842 UINT IPToUINT(IP *ip)
14843 {
14844 	// Validate arguments
14845 	if (ip == NULL)
14846 	{
14847 		return 0;
14848 	}
14849 
14850 	UINT value;
14851 
14852 	for (BYTE i = 0; i < IPV4_SIZE; ++i)
14853 	{
14854 		((BYTE *)&value)[i] = IPV4(ip->address)[i];
14855 	}
14856 
14857 	return value;
14858 }
14859 
14860 // Convert UINT to IP
UINTToIP(IP * ip,UINT value)14861 void UINTToIP(IP *ip, UINT value)
14862 {
14863 	// Validate arguments
14864 	if (ip == NULL)
14865 	{
14866 		return;
14867 	}
14868 
14869 	ZeroIP4(ip);
14870 
14871 	for (BYTE i = 0; i < IPV4_SIZE; ++i)
14872 	{
14873 		IPV4(ip->address)[i] = ((BYTE *)&value)[i];
14874 	}
14875 }
14876 
14877 // Get the host name of the computer
GetMachineHostName(char * name,UINT size)14878 void GetMachineHostName(char *name, UINT size)
14879 {
14880 	char tmp[MAX_SIZE];
14881 	UINT i, len;
14882 	// Validate arguments
14883 	if (name == NULL)
14884 	{
14885 		return;
14886 	}
14887 
14888 	GetMachineName(tmp, sizeof(tmp));
14889 
14890 	len = StrLen(tmp);
14891 	for (i = 0; i < len; i++)
14892 	{
14893 		if (tmp[i] == '.')
14894 		{
14895 			tmp[i] = 0;
14896 		}
14897 	}
14898 
14899 	ConvertSafeFileName(name, size, tmp);
14900 }
14901 
14902 // Get the computer name from 'hosts'
GetMachineNameFromHosts(char * name,UINT size)14903 bool GetMachineNameFromHosts(char *name, UINT size)
14904 {
14905 	bool ret = false;
14906 	char *s;
14907 	BUF *b;
14908 	// Validate arguments
14909 	if (name == NULL)
14910 	{
14911 		return false;
14912 	}
14913 
14914 	b = ReadDump("/etc/hosts");
14915 	if (b == NULL)
14916 	{
14917 		return false;
14918 	}
14919 
14920 	while (true)
14921 	{
14922 		s = CfgReadNextLine(b);
14923 		if (s == NULL)
14924 		{
14925 			break;
14926 		}
14927 		else
14928 		{
14929 			TOKEN_LIST *t = ParseToken(s, " \t");
14930 
14931 			if (t != NULL)
14932 			{
14933 				if (t->NumTokens >= 2)
14934 				{
14935 					if (StrCmpi(t->Token[0], "127.0.0.1") == 0)
14936 					{
14937 						UINT i;
14938 
14939 						for (i = 1; i < t->NumTokens; i++)
14940 						{
14941 							if (StartWith(t->Token[i], "localhost") == false)
14942 							{
14943 								StrCpy(name, size, t->Token[i]);
14944 								ret = true;
14945 							}
14946 						}
14947 					}
14948 				}
14949 			}
14950 			FreeToken(t);
14951 		}
14952 
14953 		Free(s);
14954 	}
14955 
14956 	FreeBuf(b);
14957 
14958 	return ret;
14959 }
14960 
14961 // Get the computer name of this computer
GetMachineName(char * name,UINT size)14962 void GetMachineName(char *name, UINT size)
14963 {
14964 	GetMachineNameEx(name, size, false);
14965 }
GetMachineNameEx(char * name,UINT size,bool no_load_hosts)14966 void GetMachineNameEx(char *name, UINT size, bool no_load_hosts)
14967 {
14968 	static char name_cache[MAX_SIZE];
14969 	static bool name_cached = false;
14970 	char tmp[MAX_SIZE];
14971 	char tmp2[MAX_SIZE];
14972 	// Validate arguments
14973 	if (name == NULL)
14974 	{
14975 		return;
14976 	}
14977 
14978 	Lock(machine_name_lock);
14979 	{
14980 		if (name_cached != false)
14981 		{
14982 			StrCpy(name, size, name_cache);
14983 			Unlock(machine_name_lock);
14984 			return;
14985 		}
14986 		ClearStr(tmp, sizeof(tmp));
14987 		if (gethostname(tmp, MAX_SIZE) != 0)
14988 		{
14989 			StrCpy(name, size, "Unknown");
14990 			Unlock(machine_name_lock);
14991 			return;
14992 		}
14993 		ClearStr(name, size);
14994 		StrCpy(name, size, tmp);
14995 		if (IsEmptyStr(name) || StartWith(name, "localhost"))
14996 		{
14997 #ifdef	OS_WIN32
14998 			ClearStr(name, size);
14999 			MsGetComputerName(name, size);
15000 #endif	// OS_WIN32
15001 		}
15002 		if (IsEmptyStr(name) || StartWith(name, "localhost"))
15003 		{
15004 			if (no_load_hosts == false && OS_IS_UNIX(GetOsInfo()->OsType))
15005 			{
15006 				if (GetMachineNameFromHosts(tmp2, sizeof(tmp2)))
15007 				{
15008 					StrCpy(name, size, tmp2);
15009 				}
15010 			}
15011 		}
15012 
15013 		StrCpy(name_cache, sizeof(name_cache), name);
15014 		name_cached = true;
15015 	}
15016 	Unlock(machine_name_lock);
15017 }
15018 
15019 // Get the host name
GetHostName(char * hostname,UINT size,IP * ip)15020 bool GetHostName(char *hostname, UINT size, IP *ip)
15021 {
15022 	if (hostname == NULL || size == 0 || ip == NULL)
15023 	{
15024 		return false;
15025 	}
15026 
15027 	if (DnsResolveReverse(hostname, size, ip, 0, NULL))
15028 	{
15029 		return true;
15030 	}
15031 
15032 	if (IsIP4(ip) && GetNetBiosName(hostname, size, ip))
15033 	{
15034 		DnsCacheReverseUpdate(ip, hostname);
15035 		return true;
15036 	}
15037 
15038 	return false;
15039 }
15040 
15041 #define	NUM_NBT_QUERYS_SEND			3
15042 
15043 // Get the NetBIOS name of the machine from the IP address
GetNetBiosName(char * name,UINT size,IP * ip)15044 bool GetNetBiosName(char *name, UINT size, IP *ip)
15045 {
15046 	SOCK *s;
15047 	UINT i, j;
15048 	bool flag = false;
15049 	bool ok = false;
15050 	NBTREQUEST req;
15051 	UCHAR buf[1024];
15052 	USHORT tran_id[NUM_NBT_QUERYS_SEND];
15053 	UINT64 timeout_tick;
15054 	// Validate arguments
15055 	if (name == NULL || ip == NULL)
15056 	{
15057 		return false;
15058 	}
15059 
15060 	IPToStr(name, size, ip);
15061 
15062 	for (i = 0; i < NUM_NBT_QUERYS_SEND; i++)
15063 	{
15064 		tran_id[i] = Rand16();
15065 	}
15066 
15067 	s = NewUDP(0);
15068 	if (s == NULL)
15069 	{
15070 		return false;
15071 	}
15072 
15073 	for (j = 0; j < NUM_NBT_QUERYS_SEND; j++)
15074 	{
15075 		Zero(&req, sizeof(req));
15076 		req.TransactionId = Endian16(tran_id[j]);
15077 		req.NumQuestions = Endian16(1);
15078 		req.Query[0] = 0x20;
15079 		req.Query[1] = 0x43;
15080 		req.Query[2] = 0x4b;
15081 		for (i = 3; i <= 32; i++)
15082 		{
15083 			req.Query[i] = 0x41;
15084 		}
15085 		req.Query[35] = 0x21;
15086 		req.Query[37] = 0x01;
15087 
15088 		if (SendTo(s, ip, 137, &req, sizeof(req)) == 0)
15089 		{
15090 			ReleaseSock(s);
15091 			return false;
15092 		}
15093 	}
15094 
15095 	timeout_tick = Tick64() + (UINT64)TIMEOUT_NETBIOS_HOSTNAME;
15096 
15097 	while (1)
15098 	{
15099 		UINT ret;
15100 		IP src_ip;
15101 		UINT src_port;
15102 		SOCKSET set;
15103 		if (Tick64() >= timeout_tick)
15104 		{
15105 			break;
15106 		}
15107 		InitSockSet(&set);
15108 		AddSockSet(&set, s);
15109 		Select(&set, 100, NULL, NULL);
15110 
15111 		if (flag == false)
15112 		{
15113 			flag = true;
15114 		}
15115 		else
15116 		{
15117 			SleepThread(10);
15118 		}
15119 
15120 		ret = RecvFrom(s, &src_ip, &src_port, buf, sizeof(buf));
15121 
15122 		if (ret == SOCK_LATER)
15123 		{
15124 			continue;
15125 		}
15126 		else if (ret == 0)
15127 		{
15128 			break;
15129 		}
15130 		else
15131 		{
15132 			if (ret >= sizeof(NBTRESPONSE))
15133 			{
15134 				NBTRESPONSE *r = (NBTRESPONSE *)buf;
15135 				bool b = false;
15136 				UINT i;
15137 				USHORT id = Endian16(r->TransactionId);
15138 				for (i = 0; i < NUM_NBT_QUERYS_SEND; i++)
15139 				{
15140 					if (id == tran_id[i])
15141 					{
15142 						b = true;
15143 						break;
15144 					}
15145 				}
15146 				if (b)
15147 				{
15148 					if (r->Flags != 0 && r->NumQuestions == 0 && r->AnswerRRs >= 1)
15149 					{
15150 						if (r->Response[0] == 0x20 && r->Response[1] == 0x43 &&
15151 						        r->Response[2] == 0x4b)
15152 						{
15153 							if (r->Response[34] == 0x00 && r->Response[35] == 0x21 &&
15154 							        r->Response[36] == 0x00 && r->Response[37] == 0x01)
15155 							{
15156 								char *a = (char *)(&r->Response[45]);
15157 								if (StrCheckLen(a, 15))
15158 								{
15159 									if (IsEmptyStr(a) == false)
15160 									{
15161 										StrCpy(name, size, a);
15162 										Trim(name);
15163 										ok = true;
15164 									}
15165 									else
15166 									{
15167 										ok = false;
15168 										break;
15169 									}
15170 								}
15171 							}
15172 						}
15173 					}
15174 				}
15175 			}
15176 		}
15177 	}
15178 
15179 	ReleaseSock(s);
15180 	return ok;
15181 }
15182 
15183 // Set the IP address
SetIP(IP * ip,UCHAR a1,UCHAR a2,UCHAR a3,UCHAR a4)15184 void SetIP(IP *ip, UCHAR a1, UCHAR a2, UCHAR a3, UCHAR a4)
15185 {
15186 	// Validate arguments
15187 	if (ip == NULL)
15188 	{
15189 		return;
15190 	}
15191 
15192 	ZeroIP4(ip);
15193 
15194 	ip->address[12] = a1;
15195 	ip->address[13] = a2;
15196 	ip->address[14] = a3;
15197 	ip->address[15] = a4;
15198 }
SetIP32(UCHAR a1,UCHAR a2,UCHAR a3,UCHAR a4)15199 UINT SetIP32(UCHAR a1, UCHAR a2, UCHAR a3, UCHAR a4)
15200 {
15201 	IP ip;
15202 
15203 	Zero(&ip, sizeof(ip));
15204 	SetIP(&ip, a1, a2, a3, a4);
15205 
15206 	return IPToUINT(&ip);
15207 }
15208 
15209 // Convert the IP to a string
IPToUniStr(wchar_t * str,UINT size,IP * ip)15210 void IPToUniStr(wchar_t *str, UINT size, IP *ip)
15211 {
15212 	char tmp[128];
15213 
15214 	IPToStr(tmp, sizeof(tmp), ip);
15215 	StrToUni(str, size, tmp);
15216 }
15217 
15218 // Convert the IP to a string (32bit UINT)
IPToUniStr32(wchar_t * str,UINT size,UINT ip)15219 void IPToUniStr32(wchar_t *str, UINT size, UINT ip)
15220 {
15221 	char tmp[128];
15222 
15223 	IPToStr32(tmp, sizeof(tmp), ip);
15224 	StrToUni(str, size, tmp);
15225 }
15226 
15227 // Convert the IP to a string (32bit UINT)
IPToStr32(char * str,UINT size,UINT ip)15228 void IPToStr32(char *str, UINT size, UINT ip)
15229 {
15230 	IP ip_st;
15231 	// Validate arguments
15232 	if (str == NULL)
15233 	{
15234 		return;
15235 	}
15236 
15237 	UINTToIP(&ip_st, ip);
15238 	IPToStr(str, size, &ip_st);
15239 }
15240 
15241 // Convert IPv4 or IPv6 to a string
IPToStr4or6(char * str,UINT size,UINT ip_4_uint,UCHAR * ip_6_bytes)15242 void IPToStr4or6(char *str, UINT size, UINT ip_4_uint, UCHAR *ip_6_bytes)
15243 {
15244 	IP ip4;
15245 	IP ip6;
15246 	IP ip;
15247 	// Validate arguments
15248 	if (str == NULL)
15249 	{
15250 		return;
15251 	}
15252 
15253 	Zero(&ip, sizeof(ip));
15254 
15255 	UINTToIP(&ip4, ip_4_uint);
15256 	SetIP6(&ip6, ip_6_bytes);
15257 
15258 	if (IsIP6(&ip4) || (IsZeroIp(&ip4) && (IsZeroIp(&ip6) == false)))
15259 	{
15260 		Copy(&ip, &ip6, sizeof(IP));
15261 	}
15262 	else
15263 	{
15264 		Copy(&ip, &ip4, sizeof(IP));
15265 	}
15266 
15267 	IPToStr(str, size, &ip);
15268 }
15269 
15270 // Convert the IP to a string
IPToStr(char * str,UINT size,IP * ip)15271 void IPToStr(char *str, UINT size, IP *ip)
15272 {
15273 	// Validate arguments
15274 	if (str == NULL || ip == NULL)
15275 	{
15276 		return;
15277 	}
15278 
15279 	if (IsIP6(ip))
15280 	{
15281 		IPToStr6(str, size, ip);
15282 	}
15283 	else
15284 	{
15285 		const BYTE *ipv4 = IPV4(ip->address);
15286 		Format(str, size, "%hhu.%hhu.%hhu.%hhu", ipv4[0], ipv4[1], ipv4[2], ipv4[3]);
15287 	}
15288 }
15289 
15290 // Convert the string to an IP
StrToIP(IP * ip,char * str)15291 bool StrToIP(IP *ip, char *str)
15292 {
15293 	TOKEN_LIST *token;
15294 	char *tmp;
15295 	// Validate arguments
15296 	if (ip == NULL || str == NULL)
15297 	{
15298 		return false;
15299 	}
15300 
15301 	if (StrToIP6(ip, str))
15302 	{
15303 		return true;
15304 	}
15305 
15306 	ZeroIP4(ip);
15307 
15308 	tmp = CopyStr(str);
15309 	Trim(tmp);
15310 	token = ParseToken(tmp, ".");
15311 	Free(tmp);
15312 
15313 	if (token->NumTokens != 4)
15314 	{
15315 		FreeToken(token);
15316 		return false;
15317 	}
15318 	for (BYTE i = 0; i < IPV4_SIZE; ++i)
15319 	{
15320 		char *s = token->Token[i];
15321 		if (s[0] < '0' || s[0] > '9' ||
15322 		        (ToInt(s) >= 256))
15323 		{
15324 			FreeToken(token);
15325 			return false;
15326 		}
15327 	}
15328 
15329 	for (BYTE i = 0; i < IPV4_SIZE; ++i)
15330 	{
15331 		IPV4(ip->address)[i] = (BYTE)ToInt(token->Token[i]);
15332 	}
15333 
15334 	FreeToken(token);
15335 
15336 	return true;
15337 }
StrToIP32(char * str)15338 UINT StrToIP32(char *str)
15339 {
15340 	IP ip;
15341 	// Validate arguments
15342 	if (str == NULL)
15343 	{
15344 		return 0;
15345 	}
15346 
15347 	if (StrToIP(&ip, str) == false)
15348 	{
15349 		return 0;
15350 	}
15351 
15352 	return IPToUINT(&ip);
15353 }
UniStrToIP32(wchar_t * str)15354 UINT UniStrToIP32(wchar_t *str)
15355 {
15356 	UINT ret;
15357 	char *tmp;
15358 
15359 	tmp = CopyUniToStr(str);
15360 	ret = StrToIP32(tmp);
15361 	Free(tmp);
15362 
15363 	return ret;
15364 }
15365 
15366 // Convert the IP to the in_addr
IPToInAddr(struct in_addr * addr,IP * ip)15367 void IPToInAddr(struct in_addr *addr, IP *ip)
15368 {
15369 	UINT i;
15370 	// Validate arguments
15371 	if (addr == NULL || IsIP4(ip) == false)
15372 	{
15373 		return;
15374 	}
15375 
15376 	Zero(addr, sizeof(struct in_addr));
15377 
15378 	const BYTE *ipv4 = IPV4(ip->address);
15379 	for (i = 0; i < IPV4_SIZE; ++i)
15380 	{
15381 		((BYTE *)addr)[i] = ipv4[i];
15382 	}
15383 }
15384 
15385 // Convert the IP to the in6_addr
IPToInAddr6(struct in6_addr * addr,IP * ip)15386 void IPToInAddr6(struct in6_addr *addr, IP *ip)
15387 {
15388 	// Validate arguments
15389 	if (addr == NULL || ip == NULL)
15390 	{
15391 		return;
15392 	}
15393 
15394 	Zero(addr, sizeof(struct in6_addr));
15395 
15396 	for (BYTE i = 0; i < sizeof(ip->address); ++i)
15397 	{
15398 		((BYTE *)addr)[i] = ip->address[i];
15399 	}
15400 }
15401 
15402 // Convert the in_addr to the IP
InAddrToIP(IP * ip,struct in_addr * addr)15403 void InAddrToIP(IP *ip, struct in_addr *addr)
15404 {
15405 	if (ip == NULL || addr == NULL)
15406 	{
15407 		return;
15408 	}
15409 
15410 	ZeroIP4(ip);
15411 
15412 	BYTE *ipv4 = IPV4(ip->address);
15413 
15414 	for (BYTE i = 0; i < IPV4_SIZE; ++i)
15415 	{
15416 		ipv4[i] = ((UCHAR *)addr)[i];
15417 	}
15418 }
15419 
15420 // Convert the in6_addr to the IP
InAddrToIP6(IP * ip,struct in6_addr * addr)15421 void InAddrToIP6(IP *ip, struct in6_addr *addr)
15422 {
15423 	// Validate arguments
15424 	if (ip == NULL || addr == NULL)
15425 	{
15426 		return;
15427 	}
15428 
15429 	Zero(ip, sizeof(IP));
15430 
15431 	for (BYTE i = 0; i < sizeof(ip->address); ++i)
15432 	{
15433 		ip->address[i] = ((UCHAR *)addr)[i];
15434 	}
15435 }
15436 
15437 // DH temp key callback
TmpDhCallback(SSL * ssl,int is_export,int keylength)15438 DH *TmpDhCallback(SSL *ssl, int is_export, int keylength)
15439 {
15440 	DH *ret = NULL;
15441 
15442 	if (dh_param != NULL)
15443 	{
15444 		ret = dh_param->dh;
15445 	}
15446 
15447 	return ret;
15448 }
15449 
15450 // Create the SSL_CTX
NewSSLCtx(bool server_mode)15451 struct ssl_ctx_st *NewSSLCtx(bool server_mode)
15452 {
15453 	struct ssl_ctx_st *ctx = SSL_CTX_new(SSLv23_method());
15454 
15455 	// It resets some parameters.
15456 	if (server_mode)
15457 	{
15458 		SSL_CTX_set_ssl_version(ctx, SSLv23_server_method());
15459 	}
15460 	else
15461 	{
15462 		SSL_CTX_set_ssl_version(ctx, SSLv23_client_method());
15463 	}
15464 
15465 #ifdef	SSL_OP_NO_SSLv3
15466 	SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3);
15467 #endif	// SSL_OP_NO_SSLv3
15468 
15469 #ifdef	SSL_OP_NO_TICKET
15470 	SSL_CTX_set_options(ctx, SSL_OP_NO_TICKET);
15471 #endif	// SSL_OP_NO_TICKET
15472 
15473 #ifdef	SSL_OP_CIPHER_SERVER_PREFERENCE
15474 	if (server_mode)
15475 	{
15476 		SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
15477 	}
15478 #endif	// SSL_OP_CIPHER_SERVER_PREFERENCE
15479 
15480 	SSL_CTX_set_tmp_dh_callback(ctx, TmpDhCallback);
15481 
15482 #ifdef	SSL_CTX_set_ecdh_auto
15483 	SSL_CTX_set_ecdh_auto(ctx, 1);
15484 #endif	// SSL_CTX_set_ecdh_auto
15485 
15486 	return ctx;
15487 }
15488 
15489 // Release of the SSL_CTX
FreeSSLCtx(struct ssl_ctx_st * ctx)15490 void FreeSSLCtx(struct ssl_ctx_st *ctx)
15491 {
15492 	// Validate arguments
15493 	if (ctx == NULL)
15494 	{
15495 		return;
15496 	}
15497 
15498 	SSL_CTX_free(ctx);
15499 }
15500 
15501 // Get OS (maximum) Security Level
GetOSSecurityLevel()15502 UINT GetOSSecurityLevel()
15503 {
15504 	UINT security_level_new = 0, security_level_set_ssl_version = 0;
15505 	struct ssl_ctx_st *ctx = SSL_CTX_new(SSLv23_method());
15506 
15507 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
15508 	security_level_new = SSL_CTX_get_security_level(ctx);
15509 #endif
15510 
15511 	security_level_set_ssl_version = SSL_CTX_set_ssl_version(ctx, SSLv23_server_method());
15512 
15513 	FreeSSLCtx(ctx);
15514 
15515 	if(security_level_new >= security_level_set_ssl_version)
15516 	{
15517 		return security_level_new;
15518 	}
15519 
15520 	return security_level_set_ssl_version;
15521 }
15522 
15523 // Initialize the network communication module
InitNetwork()15524 void InitNetwork()
15525 {
15526 	disable_gethostname_by_accept = false;
15527 
15528 
15529 	InitDynList();
15530 
15531 
15532 	host_ip_address_list_cache_lock = NewLock();
15533 	host_ip_address_list_cache_last = 0;
15534 
15535 	num_tcp_connections = NewCounter();
15536 
15537 	// Initialization of client list
15538 	InitIpClientList();
15539 
15540 	// Thread related initialization
15541 	InitWaitThread();
15542 
15543 #ifdef	OS_WIN32
15544 	// Initializing the socket library
15545 	Win32InitSocketLibrary();
15546 #else
15547 	UnixInitSocketLibrary();
15548 #endif	// OS_WIN32
15549 
15550 	DnsInit();
15551 
15552 	// Locking initialization
15553 	machine_name_lock = NewLock();
15554 	disconnect_function_lock = NewLock();
15555 	machine_ip_process_hash_lock = NewLock();
15556 	unix_dns_server_addr_lock = NewLock();
15557 	Zero(&unix_dns_server, sizeof(unix_dns_server));
15558 	local_mac_list_lock = NewLock();
15559 
15560 	current_global_ip_lock = NewLock();
15561 	current_fqdn_lock = NewLock();
15562 	current_global_ip_set = false;
15563 
15564 	Zero(rand_port_numbers, sizeof(rand_port_numbers));
15565 }
15566 
15567 // Get the cipher algorithm list
GetCipherList()15568 TOKEN_LIST *GetCipherList()
15569 {
15570 	UINT i;
15571 	SSL *ssl;
15572 	SSL_CTX *ctx;
15573 	const char *name;
15574 	STACK_OF(SSL_CIPHER) *sk;
15575 
15576 	TOKEN_LIST *ciphers = ZeroMalloc(sizeof(TOKEN_LIST));
15577 
15578 	ctx = NewSSLCtx(true);
15579 	if (ctx == NULL)
15580 	{
15581 		return ciphers;
15582 	}
15583 
15584 	ssl = SSL_new(ctx);
15585 	if (ssl == NULL)
15586 	{
15587 		FreeSSLCtx(ctx);
15588 		return ciphers;
15589 	}
15590 
15591 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
15592 	sk = SSL_get1_supported_ciphers(ssl);
15593 #else
15594 	sk = SSL_get_ciphers(ssl);
15595 #endif
15596 
15597 	for (i = 0; i < (UINT)sk_SSL_CIPHER_num(sk); i++)
15598 	{
15599 		const SSL_CIPHER *c = sk_SSL_CIPHER_value(sk, i);
15600 
15601 		name = SSL_CIPHER_get_name(c);
15602 		if (IsEmptyStr((char *)name))
15603 		{
15604 			break;
15605 		}
15606 
15607 		ciphers->NumTokens++;
15608 
15609 		if (ciphers->Token != NULL)
15610 		{
15611 			ciphers->Token = ReAlloc(ciphers->Token, sizeof(char *) * ciphers->NumTokens);
15612 		}
15613 		else
15614 		{
15615 			ciphers->Token = Malloc(sizeof(char *));
15616 		}
15617 
15618 		ciphers->Token[i] = CopyStr((char *)name);
15619 	}
15620 
15621 	sk_SSL_CIPHER_free(sk);
15622 	SSL_free(ssl);
15623 
15624 	return ciphers;
15625 }
15626 
15627 // Get the TCP connections counter
GetNumTcpConnectionsCounter()15628 COUNTER *GetNumTcpConnectionsCounter()
15629 {
15630 	return num_tcp_connections;
15631 }
15632 
15633 // Get the current global IP address
GetCurrentGlobalIP(IP * ip,bool ipv6)15634 bool GetCurrentGlobalIP(IP *ip, bool ipv6)
15635 {
15636 	bool ret = false;
15637 	// Validate arguments
15638 	if (ip == NULL)
15639 	{
15640 		return false;
15641 	}
15642 
15643 	Zero(ip, sizeof(IP));
15644 
15645 	Lock(current_global_ip_lock);
15646 	{
15647 		if (ipv6 == false)
15648 		{
15649 			Copy(ip, &current_glocal_ipv4, sizeof(IP));
15650 		}
15651 		else
15652 		{
15653 			Copy(ip, &current_glocal_ipv6, sizeof(IP));
15654 		}
15655 
15656 		ret = current_global_ip_set;
15657 	}
15658 	Unlock(current_global_ip_lock);
15659 
15660 	return ret;
15661 }
15662 
15663 // Check whether the specified IP address is assigned to the local host
IsIPMyHost(IP * ip)15664 bool IsIPMyHost(IP *ip)
15665 {
15666 	LIST *o;
15667 	UINT i;
15668 	bool ret = false;
15669 	// Validate arguments
15670 	if (ip == NULL)
15671 	{
15672 		return false;
15673 	}
15674 
15675 	if (IsZeroIp(ip))
15676 	{
15677 		return false;
15678 	}
15679 
15680 	// Search to check whether it matches to any of the IP of the local host
15681 	o = GetHostIPAddressList();
15682 
15683 	for (i = 0; i < LIST_NUM(o); i++)
15684 	{
15685 		IP *p = LIST_DATA(o, i);
15686 
15687 		if (CmpIpAddr(p, ip) == 0)
15688 		{
15689 			// Matched
15690 			ret = true;
15691 			break;
15692 		}
15693 	}
15694 
15695 	FreeHostIPAddressList(o);
15696 
15697 	if (ret == false)
15698 	{
15699 		if (IsLocalHostIP(ip))
15700 		{
15701 			// localhost IP addresses
15702 			ret = true;
15703 		}
15704 	}
15705 
15706 	return ret;
15707 }
15708 
15709 // Check whether the specified IP address is a private IP address
IsIPPrivate(IP * ip)15710 bool IsIPPrivate(IP *ip)
15711 {
15712 	// Validate arguments
15713 	if (IsIP4(ip) == false)
15714 	{
15715 		return false;
15716 	}
15717 
15718 	const BYTE *ipv4 = IPV4(ip->address);
15719 
15720 	// RFC 1918 defines 10.0.0.0/8
15721 	if (ipv4[0] == 10)
15722 	{
15723 		return true;
15724 	}
15725 
15726 	// RFC 1918 defines 172.16.0.0/12
15727 	if (ipv4[0] == 172)
15728 	{
15729 		if (ipv4[1] >= 16 && ipv4[1] <= 31)
15730 		{
15731 			return true;
15732 		}
15733 	}
15734 
15735 	// RFC 1918 defines 192.168.0.0/16
15736 	if (ipv4[0] == 192 && ipv4[1] == 168)
15737 	{
15738 		return true;
15739 	}
15740 
15741 	// RFC 3927 defines 169.254.0.0/16
15742 	if (ipv4[0] == 169 && ipv4[1] == 254)
15743 	{
15744 		return true;
15745 	}
15746 
15747 	// RFC 6598 defines 100.64.0.0/10
15748 	if (ipv4[0] == 100)
15749 	{
15750 		if (ipv4[1] >= 64 && ipv4[1] <= 127)
15751 		{
15752 			return true;
15753 		}
15754 	}
15755 
15756 	if (g_private_ip_list != NULL)
15757 	{
15758 		return IsOnPrivateIPFile(IPToUINT(ip));
15759 	}
15760 
15761 	return false;
15762 }
15763 
15764 // Read a private IP list file
LoadPrivateIPFile()15765 void LoadPrivateIPFile()
15766 {
15767 	BUF *b = ReadDump(PRIVATE_IP_TXT_FILENAME);
15768 	LIST *o;
15769 	if (b == NULL)
15770 	{
15771 		return;
15772 	}
15773 
15774 	o = NewList(NULL);
15775 
15776 	while (true)
15777 	{
15778 		char *line = CfgReadNextLine(b);
15779 		if (line == NULL)
15780 		{
15781 			break;
15782 		}
15783 
15784 		Trim(line);
15785 
15786 		if (IsEmptyStr(line) == false)
15787 		{
15788 			UINT ip = 0, mask = 0;
15789 
15790 			if (ParseIpAndSubnetMask4(line, &ip, &mask))
15791 			{
15792 				PRIVATE_IP_SUBNET *p = ZeroMalloc(sizeof(PRIVATE_IP_SUBNET));
15793 
15794 				p->Ip = ip;
15795 				p->Mask = mask;
15796 				p->Ip2 = ip & mask;
15797 
15798 				Add(o, p);
15799 			}
15800 		}
15801 
15802 		Free(line);
15803 	}
15804 
15805 	g_private_ip_list = o;
15806 	g_use_privateip_file = true;
15807 
15808 	FreeBuf(b);
15809 }
15810 
15811 // Examine whether the specified IP address is in the private IP file
IsOnPrivateIPFile(UINT ip)15812 bool IsOnPrivateIPFile(UINT ip)
15813 {
15814 	bool ret = false;
15815 
15816 	if (g_private_ip_list != NULL)
15817 	{
15818 		LIST *o = g_private_ip_list;
15819 		UINT i;
15820 
15821 		for (i = 0; i < LIST_NUM(o); i++)
15822 		{
15823 			PRIVATE_IP_SUBNET *p = LIST_DATA(o, i);
15824 
15825 			if ((ip & p->Mask) == p->Ip2)
15826 			{
15827 				ret = true;
15828 			}
15829 		}
15830 	}
15831 
15832 	return ret;
15833 }
15834 
15835 // Free the private IP file
FreePrivateIPFile()15836 void FreePrivateIPFile()
15837 {
15838 	if (g_private_ip_list != NULL)
15839 	{
15840 		LIST *o = g_private_ip_list;
15841 		UINT i;
15842 
15843 		g_private_ip_list = NULL;
15844 
15845 		for (i = 0; i < LIST_NUM(o); i++)
15846 		{
15847 			PRIVATE_IP_SUBNET *p = LIST_DATA(o, i);
15848 
15849 			Free(p);
15850 		}
15851 
15852 		ReleaseList(o);
15853 	}
15854 
15855 	g_use_privateip_file = false;
15856 }
15857 
15858 // Check whether the specified IP address is in the same network to this computer
IsIPAddressInSameLocalNetwork(IP * a)15859 bool IsIPAddressInSameLocalNetwork(IP *a)
15860 {
15861 	bool ret = false;
15862 	LIST *o;
15863 	UINT i;
15864 	// Validate arguments
15865 	if (a == NULL)
15866 	{
15867 		return false;
15868 	}
15869 
15870 	o = GetHostIPAddressList();
15871 
15872 	if (o != NULL)
15873 	{
15874 		for (i = 0; i < LIST_NUM(o); i++)
15875 		{
15876 			IP *p = LIST_DATA(o, i);
15877 
15878 			if (IsIP4(p))
15879 			{
15880 				if (IsZeroIp(p) == false && IsLocalHostIP4(a) == false)
15881 				{
15882 					if (IsInSameNetwork4Standard(p, a))
15883 					{
15884 						ret = true;
15885 						break;
15886 					}
15887 				}
15888 			}
15889 		}
15890 
15891 		FreeHostIPAddressList(o);
15892 	}
15893 
15894 	return ret;
15895 }
15896 
15897 // Guess the IPv4, IPv6 global address from the IP address list of the current interface
GetCurrentGlobalIPGuess(IP * ip,bool ipv6)15898 void GetCurrentGlobalIPGuess(IP *ip, bool ipv6)
15899 {
15900 	LIST *o;
15901 	UINT i;
15902 	// Validate arguments
15903 	if (ip == NULL)
15904 	{
15905 		return;
15906 	}
15907 
15908 	Zero(ip, sizeof(IP));
15909 
15910 	o = GetHostIPAddressList();
15911 
15912 	if (ipv6 == false)
15913 	{
15914 		// IPv4
15915 		for (i = 0; i < LIST_NUM(o); i++)
15916 		{
15917 			IP *p = LIST_DATA(o, i);
15918 
15919 			if (IsIP4(p))
15920 			{
15921 				if (IsZeroIp(p) == false && IsIPPrivate(p) == false && IsLocalHostIP4(p) == false)
15922 				{
15923 					Copy(ip, p, sizeof(IP));
15924 				}
15925 			}
15926 		}
15927 
15928 		if (IsZeroIp(ip))
15929 		{
15930 			for (i = 0; i < LIST_NUM(o); i++)
15931 			{
15932 				IP *p = LIST_DATA(o, i);
15933 
15934 				if (IsIP4(p))
15935 				{
15936 					if (IsZeroIp(p) == false && IsIPPrivate(p) && IsLocalHostIP4(p) == false)
15937 					{
15938 						Copy(ip, p, sizeof(IP));
15939 					}
15940 				}
15941 			}
15942 		}
15943 
15944 		if (IsZeroIp(ip))
15945 		{
15946 			SetIP(ip, 127, 0, 0, 1);
15947 		}
15948 	}
15949 	else
15950 	{
15951 		// IPv6
15952 		for (i = 0; i < LIST_NUM(o); i++)
15953 		{
15954 			IP *p = LIST_DATA(o, i);
15955 
15956 			if (IsIP6(p))
15957 			{
15958 				UINT type = GetIPAddrType6(p);
15959 
15960 				if ((type & IPV6_ADDR_GLOBAL_UNICAST) && ((type & IPV6_ADDR_ZERO) == 0) && ((type & IPV6_ADDR_LOOPBACK) == 0))
15961 				{
15962 					Copy(ip, p, sizeof(IP));
15963 				}
15964 			}
15965 		}
15966 	}
15967 
15968 	FreeHostIPAddressList(o);
15969 }
15970 
15971 // Record the current global IP address
SetCurrentGlobalIP(IP * ip,bool ipv6)15972 void SetCurrentGlobalIP(IP *ip, bool ipv6)
15973 {
15974 	// Validate arguments
15975 	if (ip == NULL)
15976 	{
15977 		return;
15978 	}
15979 
15980 	if (IsZeroIp(ip))
15981 	{
15982 		return;
15983 	}
15984 
15985 	Lock(current_global_ip_lock);
15986 	{
15987 		if (ipv6 == false)
15988 		{
15989 			Copy(&current_glocal_ipv4, ip, sizeof(IP));
15990 		}
15991 		else
15992 		{
15993 			Copy(&current_glocal_ipv6, ip, sizeof(IP));
15994 		}
15995 
15996 		current_global_ip_set = true;
15997 	}
15998 	Unlock(current_global_ip_lock);
15999 }
16000 
16001 // Release of the network communication module
FreeNetwork()16002 void FreeNetwork()
16003 {
16004 
16005 	if (dh_param != NULL)
16006 	{
16007 		DhFree(dh_param);
16008 		dh_param = NULL;
16009 	}
16010 
16011 	// Release of thread-related
16012 	FreeWaitThread();
16013 
16014 	Zero(&unix_dns_server, sizeof(unix_dns_server));
16015 
16016 	// Release the locks
16017 	DeleteLock(unix_dns_server_addr_lock);
16018 	DeleteLock(machine_name_lock);
16019 	DeleteLock(disconnect_function_lock);
16020 	DeleteLock(machine_ip_process_hash_lock);
16021 	machine_name_lock = disconnect_function_lock = machine_ip_process_hash_lock = NULL;
16022 
16023 	DnsFree();
16024 
16025 #ifdef	OS_WIN32
16026 	// Release of the socket library
16027 	Win32FreeSocketLibrary();
16028 #else
16029 	UnixFreeSocketLibrary();
16030 #endif	// OS_WIN32
16031 
16032 	DeleteCounter(num_tcp_connections);
16033 	num_tcp_connections = NULL;
16034 
16035 	// Release of client list
16036 	FreeIpClientList();
16037 
16038 	DeleteLock(current_global_ip_lock);
16039 	current_global_ip_lock = NULL;
16040 
16041 	DeleteLock(current_fqdn_lock);
16042 	current_fqdn_lock = NULL;
16043 
16044 	// Release of the local MAC list
16045 	if (local_mac_list != NULL)
16046 	{
16047 		FreeNicList(local_mac_list);
16048 		local_mac_list = NULL;
16049 	}
16050 
16051 	DeleteLock(local_mac_list_lock);
16052 	local_mac_list_lock = NULL;
16053 
16054 	DeleteLock(host_ip_address_list_cache_lock);
16055 	host_ip_address_list_cache_lock = NULL;
16056 
16057 	FreeHostIPAddressList(host_ip_address_cache);
16058 	host_ip_address_cache = NULL;
16059 
16060 	FreeDynList();
16061 }
16062 
16063 // Stop all the sockets in the list and delete it
StopSockList(SOCKLIST * sl)16064 void StopSockList(SOCKLIST *sl)
16065 {
16066 	SOCK **ss;
16067 	UINT num, i;
16068 	// Validate arguments
16069 	if (sl == NULL)
16070 	{
16071 		return;
16072 	}
16073 
16074 	LockList(sl->SockList);
16075 	{
16076 		num = LIST_NUM(sl->SockList);
16077 		ss = ToArray(sl->SockList);
16078 
16079 		DeleteAll(sl->SockList);
16080 	}
16081 	UnlockList(sl->SockList);
16082 
16083 	for (i = 0; i < num; i++)
16084 	{
16085 		SOCK *s = ss[i];
16086 
16087 		Disconnect(s);
16088 		ReleaseSock(s);
16089 	}
16090 
16091 	Free(ss);
16092 }
16093 
16094 // Delete the socket list
FreeSockList(SOCKLIST * sl)16095 void FreeSockList(SOCKLIST *sl)
16096 {
16097 	// Validate arguments
16098 	if (sl == NULL)
16099 	{
16100 		return;
16101 	}
16102 
16103 	StopSockList(sl);
16104 
16105 	ReleaseList(sl->SockList);
16106 
16107 	Free(sl);
16108 }
16109 
16110 // Creating a socket list
NewSockList()16111 SOCKLIST *NewSockList()
16112 {
16113 	SOCKLIST *sl = ZeroMallocFast(sizeof(SOCKLIST));
16114 
16115 	sl->SockList = NewList(NULL);
16116 
16117 	return sl;
16118 }
16119 
16120 // Time-out thread of the socket on Solaris
SocketTimeoutThread(THREAD * t,void * param)16121 void SocketTimeoutThread(THREAD *t, void *param)
16122 {
16123 	SOCKET_TIMEOUT_PARAM *ttparam;
16124 	ttparam = (SOCKET_TIMEOUT_PARAM *)param;
16125 
16126 	// Wait for time-out period
16127 	Select(NULL, ttparam->sock->TimeOut, ttparam->cancel, NULL);
16128 
16129 	// Disconnect if it is blocked
16130 	if(! ttparam->unblocked)
16131 	{
16132 //		Debug("Socket timeouted\n");
16133 		closesocket(ttparam->sock->socket);
16134 	}
16135 	else
16136 	{
16137 //		Debug("Socket timeout cancelled\n");
16138 	}
16139 }
16140 
16141 // Initialize and start the thread for time-out
NewSocketTimeout(SOCK * sock)16142 SOCKET_TIMEOUT_PARAM *NewSocketTimeout(SOCK *sock)
16143 {
16144 	SOCKET_TIMEOUT_PARAM *ttp;
16145 	if(! sock->AsyncMode && sock->TimeOut != TIMEOUT_INFINITE)
16146 	{
16147 //		Debug("NewSockTimeout(%u)\n",sock->TimeOut);
16148 
16149 		ttp = (SOCKET_TIMEOUT_PARAM *)Malloc(sizeof(SOCKET_TIMEOUT_PARAM));
16150 
16151 		// Set the parameters of the time-out thread
16152 		ttp->cancel = NewCancel();
16153 		ttp->sock = sock;
16154 		ttp->unblocked = false;
16155 		ttp->thread = NewThread(SocketTimeoutThread, ttp);
16156 		return ttp;
16157 	}
16158 	return NULL;
16159 }
16160 
16161 // Stop and free the thread for timeout
FreeSocketTimeout(SOCKET_TIMEOUT_PARAM * ttp)16162 void FreeSocketTimeout(SOCKET_TIMEOUT_PARAM *ttp)
16163 {
16164 	if(ttp == NULL)
16165 	{
16166 		return;
16167 	}
16168 
16169 	ttp->unblocked = true;
16170 	Cancel(ttp->cancel);
16171 	WaitThread(ttp->thread, INFINITE);
16172 	ReleaseCancel(ttp->cancel);
16173 	ReleaseThread(ttp->thread);
16174 	Free(ttp);
16175 //	Debug("FreeSocketTimeout succeed\n");
16176 	return;
16177 }
16178 
16179 // Parse the IP address and subnet mask
ParseIpAndSubnetMask46(char * src,IP * ip,IP * mask)16180 bool ParseIpAndSubnetMask46(char *src, IP *ip, IP *mask)
16181 {
16182 	// Validate arguments
16183 	if (src == NULL || ip == NULL || mask == NULL)
16184 	{
16185 		return false;
16186 	}
16187 
16188 	if (ParseIpAndMask46(src, ip, mask) == false)
16189 	{
16190 		return false;
16191 	}
16192 
16193 	if (IsIP4(ip))
16194 	{
16195 		return IsSubnetMask4(mask);
16196 	}
16197 	else
16198 	{
16199 		return IsSubnetMask6(mask);
16200 	}
16201 }
ParseIpAndSubnetMask4(char * src,UINT * ip,UINT * mask)16202 bool ParseIpAndSubnetMask4(char *src, UINT *ip, UINT *mask)
16203 {
16204 	IP ip2, mask2;
16205 	// Validate arguments
16206 	if (src == NULL)
16207 	{
16208 		return false;
16209 	}
16210 
16211 	if (ParseIpAndSubnetMask46(src, &ip2, &mask2) == false)
16212 	{
16213 		return false;
16214 	}
16215 
16216 	if (IsIP4(&ip2) == false)
16217 	{
16218 		return false;
16219 	}
16220 
16221 	if (ip != NULL)
16222 	{
16223 		*ip = IPToUINT(&ip2);
16224 	}
16225 
16226 	if (mask != NULL)
16227 	{
16228 		*mask = IPToUINT(&mask2);
16229 	}
16230 
16231 	return true;
16232 }
16233 
16234 
16235 // Parse the IP address and the mask
ParseIpAndMask46(char * src,IP * ip,IP * mask)16236 bool ParseIpAndMask46(char *src, IP *ip, IP *mask)
16237 {
16238 	TOKEN_LIST *t;
16239 	char *ipstr;
16240 	char *subnetstr;
16241 	bool ret = false;
16242 	IP ip2;
16243 	IP mask2;
16244 	// Validate arguments
16245 	if (src == NULL || ip == NULL || mask == NULL)
16246 	{
16247 		return false;
16248 	}
16249 
16250 	Zero(&ip2, sizeof(IP));
16251 	Zero(&mask2, sizeof(IP));
16252 
16253 	t = ParseToken(src, "/");
16254 	if (t->NumTokens != 2)
16255 	{
16256 		FreeToken(t);
16257 		return false;
16258 	}
16259 
16260 	ipstr = t->Token[0];
16261 	subnetstr = t->Token[1];
16262 	Trim(ipstr);
16263 	Trim(subnetstr);
16264 
16265 	if (StrToIP(&ip2, ipstr))
16266 	{
16267 		if (StrToIP(&mask2, subnetstr))
16268 		{
16269 			// Compare the kind of the mask part and the IP address part to confirm same
16270 			if (IsIP6(&ip2) && IsIP6(&mask2))
16271 			{
16272 				// Both are IPv6
16273 				ret = true;
16274 				Copy(ip, &ip2, sizeof(IP));
16275 				Copy(mask, &mask2, sizeof(IP));
16276 			}
16277 			else if (IsIP4(&ip2) && IsIP4(&mask2))
16278 			{
16279 				// Both are IPv4
16280 				ret = true;
16281 				Copy(ip, &ip2, sizeof(IP));
16282 				Copy(mask, &mask2, sizeof(IP));
16283 			}
16284 		}
16285 		else
16286 		{
16287 			if (IsNum(subnetstr))
16288 			{
16289 				UINT i = ToInt(subnetstr);
16290 				// Mask part is a number
16291 				if (IsIP6(&ip2) && i <= 128)
16292 				{
16293 					ret = true;
16294 					Copy(ip, &ip2, sizeof(IP));
16295 					IntToSubnetMask6(mask, i);
16296 				}
16297 				else if (i <= 32)
16298 				{
16299 					ret = true;
16300 					Copy(ip, &ip2, sizeof(IP));
16301 					IntToSubnetMask4(mask, i);
16302 				}
16303 			}
16304 		}
16305 	}
16306 
16307 	FreeToken(t);
16308 
16309 	return ret;
16310 }
ParseIpAndMask4(char * src,UINT * ip,UINT * mask)16311 bool ParseIpAndMask4(char *src, UINT *ip, UINT *mask)
16312 {
16313 	IP ip_ip, ip_mask;
16314 	if (ParseIpAndMask46(src, &ip_ip, &ip_mask) == false)
16315 	{
16316 		return false;
16317 	}
16318 
16319 	if (IsIP4(&ip_ip) == false)
16320 	{
16321 		return false;
16322 	}
16323 
16324 	if (ip != NULL)
16325 	{
16326 		*ip = IPToUINT(&ip_ip);
16327 	}
16328 
16329 	if (mask != NULL)
16330 	{
16331 		*mask = IPToUINT(&ip_mask);
16332 	}
16333 
16334 	return true;
16335 }
ParseIpAndMask6(char * src,IP * ip,IP * mask)16336 bool ParseIpAndMask6(char *src, IP *ip, IP *mask)
16337 {
16338 	if (ParseIpAndMask46(src, ip, mask) == false)
16339 	{
16340 		return false;
16341 	}
16342 
16343 	if (IsIP6(ip) == false)
16344 	{
16345 		return false;
16346 	}
16347 
16348 	return true;
16349 }
16350 
16351 
16352 // Check whether the specification of the IPv4 address is correct
IsIpStr4(char * str)16353 bool IsIpStr4(char *str)
16354 {
16355 	// Validate arguments
16356 	if (str == NULL)
16357 	{
16358 		return false;
16359 	}
16360 
16361 	if (StrToIP32(str) == 0 && StrCmpi(str, "0.0.0.0") != 0)
16362 	{
16363 		return false;
16364 	}
16365 
16366 	return true;
16367 }
16368 
16369 // Check whether the specification of the IPv6 address is correct
IsIpStr6(char * str)16370 bool IsIpStr6(char *str)
16371 {
16372 	IP ip;
16373 	// Validate arguments
16374 	if (str == NULL)
16375 	{
16376 		return false;
16377 	}
16378 
16379 	if (StrToIP6(&ip, str) == false)
16380 	{
16381 		return false;
16382 	}
16383 
16384 	return true;
16385 }
16386 
16387 // Convert the string to an IPv6 mask
StrToMask6(IP * mask,char * str)16388 bool StrToMask6(IP *mask, char *str)
16389 {
16390 	// Validate arguments
16391 	if (mask == NULL || str == NULL)
16392 	{
16393 		return false;
16394 	}
16395 
16396 	if (str[0] == '/')
16397 	{
16398 		str++;
16399 	}
16400 
16401 	if (IsNum(str))
16402 	{
16403 		UINT n = ToInt(str);
16404 
16405 		if (n <= 128)
16406 		{
16407 			IntToSubnetMask6(mask, n);
16408 			return true;
16409 		}
16410 		else
16411 		{
16412 			return false;
16413 		}
16414 	}
16415 	else
16416 	{
16417 		if (StrToIP(mask, str) == false)
16418 		{
16419 			return false;
16420 		}
16421 		else
16422 		{
16423 			return IsIP6(mask);
16424 		}
16425 	}
16426 }
StrToMask6Addr(IPV6_ADDR * mask,char * str)16427 bool StrToMask6Addr(IPV6_ADDR *mask, char *str)
16428 {
16429 	IP ip;
16430 
16431 	if (StrToMask6(&ip, str) == false)
16432 	{
16433 		return false;
16434 	}
16435 
16436 	if (IPToIPv6Addr(mask, &ip) == false)
16437 	{
16438 		return false;
16439 	}
16440 
16441 	return true;
16442 }
16443 
16444 // Convert the IPv4 / IPv6 mask to a string
MaskToStr(char * str,UINT size,IP * mask)16445 void MaskToStr(char *str, UINT size, IP *mask)
16446 {
16447 	MaskToStrEx(str, size, mask, false);
16448 }
MaskToStrEx(char * str,UINT size,IP * mask,bool always_full_address)16449 void MaskToStrEx(char *str, UINT size, IP *mask, bool always_full_address)
16450 {
16451 	// Validate arguments
16452 	if (str == NULL || mask == NULL)
16453 	{
16454 		return;
16455 	}
16456 
16457 	if (always_full_address == false && IsSubnetMask(mask))
16458 	{
16459 		ToStr(str, SubnetMaskToInt(mask));
16460 	}
16461 	else
16462 	{
16463 		IPToStr(str, size, mask);
16464 	}
16465 }
MaskToStr32(char * str,UINT size,UINT mask)16466 void MaskToStr32(char *str, UINT size, UINT mask)
16467 {
16468 	MaskToStr32Ex(str, size, mask, false);
16469 }
MaskToStr32Ex(char * str,UINT size,UINT mask,bool always_full_address)16470 void MaskToStr32Ex(char *str, UINT size, UINT mask, bool always_full_address)
16471 {
16472 	IP ip;
16473 
16474 	UINTToIP(&ip, mask);
16475 
16476 	MaskToStrEx(str, size, &ip, always_full_address);
16477 }
Mask6AddrToStrEx(char * str,UINT size,IPV6_ADDR * mask,bool always_full_address)16478 void Mask6AddrToStrEx(char *str, UINT size, IPV6_ADDR *mask, bool always_full_address)
16479 {
16480 	IP ip;
16481 
16482 	// Validate arguments
16483 	if (str == NULL || mask == NULL)
16484 	{
16485 		StrCpy(str, size, "");
16486 		return;
16487 	}
16488 
16489 	IPv6AddrToIP(&ip, mask);
16490 
16491 	MaskToStrEx(str, size, &ip, always_full_address);
16492 }
Mask6AddrToStr(char * str,UINT size,IPV6_ADDR * mask)16493 void Mask6AddrToStr(char *str, UINT size, IPV6_ADDR *mask)
16494 {
16495 	Mask6AddrToStrEx(str, size, mask, false);
16496 }
16497 
16498 // Disconnecting of the tube
TubeDisconnect(TUBE * t)16499 void TubeDisconnect(TUBE *t)
16500 {
16501 	// Validate arguments
16502 	if (t == NULL)
16503 	{
16504 		return;
16505 	}
16506 
16507 	if (t->TubePairData == NULL)
16508 	{
16509 		return;
16510 	}
16511 
16512 	Lock(t->TubePairData->Lock);
16513 	{
16514 		t->TubePairData->IsDisconnected = true;
16515 
16516 		Set(t->TubePairData->Event1);
16517 		Set(t->TubePairData->Event2);
16518 		SetSockEvent(t->TubePairData->SockEvent1);
16519 		SetSockEvent(t->TubePairData->SockEvent2);
16520 	}
16521 	Unlock(t->TubePairData->Lock);
16522 }
16523 
16524 // Creating a tube pair
NewTubePair(TUBE ** t1,TUBE ** t2,UINT size_of_header)16525 void NewTubePair(TUBE **t1, TUBE **t2, UINT size_of_header)
16526 {
16527 	TUBEPAIR_DATA *d;
16528 	// Validate arguments
16529 	if (t1 == NULL || t2 == NULL)
16530 	{
16531 		return;
16532 	}
16533 
16534 	*t1 = NewTube(size_of_header);
16535 	*t2 = NewTube(size_of_header);
16536 
16537 	(*t1)->IndexInTubePair = 0;
16538 	(*t2)->IndexInTubePair = 1;
16539 
16540 	d = NewTubePairData();
16541 	AddRef(d->Ref);
16542 
16543 	(*t1)->TubePairData = d;
16544 	(*t2)->TubePairData = d;
16545 
16546 	d->Event1 = (*t1)->Event;
16547 	d->Event2 = (*t2)->Event;
16548 
16549 	AddRef(d->Event1->ref);
16550 	AddRef(d->Event2->ref);
16551 }
16552 
16553 // Creating a tube pair data
NewTubePairData()16554 TUBEPAIR_DATA *NewTubePairData()
16555 {
16556 	TUBEPAIR_DATA *d = ZeroMalloc(sizeof(TUBEPAIR_DATA));
16557 
16558 	d->Ref = NewRef();
16559 
16560 	d->Lock = NewLock();
16561 
16562 	return d;
16563 }
16564 
16565 // Set the SockEvent to the tube
SetTubeSockEvent(TUBE * t,SOCK_EVENT * e)16566 void SetTubeSockEvent(TUBE *t, SOCK_EVENT *e)
16567 {
16568 	// Validate arguments
16569 	if (t == NULL)
16570 	{
16571 		return;
16572 	}
16573 
16574 	Lock(t->Lock);
16575 	{
16576 		TUBEPAIR_DATA *d;
16577 
16578 		if (t->SockEvent != e)
16579 		{
16580 			if (t->SockEvent != NULL)
16581 			{
16582 				ReleaseSockEvent(t->SockEvent);
16583 			}
16584 
16585 			if (e != NULL)
16586 			{
16587 				AddRef(e->ref);
16588 			}
16589 
16590 			t->SockEvent = e;
16591 		}
16592 
16593 		d = t->TubePairData;
16594 
16595 		if (d != NULL)
16596 		{
16597 			Lock(d->Lock);
16598 			{
16599 				SOCK_EVENT **sep = (t->IndexInTubePair == 0 ? &d->SockEvent1 : &d->SockEvent2);
16600 
16601 				if (*sep != e)
16602 				{
16603 					if (*sep != NULL)
16604 					{
16605 						ReleaseSockEvent(*sep);
16606 					}
16607 
16608 					if (e != NULL)
16609 					{
16610 						AddRef(e->ref);
16611 					}
16612 
16613 					*sep = e;
16614 				}
16615 			}
16616 			Unlock(d->Lock);
16617 		}
16618 	}
16619 	Unlock(t->Lock);
16620 }
16621 
16622 // Release of the tube pair data
ReleaseTubePairData(TUBEPAIR_DATA * d)16623 void ReleaseTubePairData(TUBEPAIR_DATA *d)
16624 {
16625 	// Validate arguments
16626 	if (d == NULL)
16627 	{
16628 		return;
16629 	}
16630 
16631 	if (Release(d->Ref) == 0)
16632 	{
16633 		CleanupTubePairData(d);
16634 	}
16635 }
CleanupTubePairData(TUBEPAIR_DATA * d)16636 void CleanupTubePairData(TUBEPAIR_DATA *d)
16637 {
16638 	// Validate arguments
16639 	if (d == NULL)
16640 	{
16641 		return;
16642 	}
16643 
16644 	ReleaseEvent(d->Event1);
16645 	ReleaseEvent(d->Event2);
16646 
16647 	ReleaseSockEvent(d->SockEvent1);
16648 	ReleaseSockEvent(d->SockEvent2);
16649 
16650 	DeleteLock(d->Lock);
16651 
16652 	Free(d);
16653 }
16654 
16655 // Check whether the tube is connected to the opponent still
IsTubeConnected(TUBE * t)16656 bool IsTubeConnected(TUBE *t)
16657 {
16658 	// Validate arguments
16659 	if (t == NULL)
16660 	{
16661 		return false;
16662 	}
16663 
16664 	if (t->TubePairData == NULL)
16665 	{
16666 		return true;
16667 	}
16668 
16669 	if (t->TubePairData->IsDisconnected)
16670 	{
16671 		return false;
16672 	}
16673 
16674 	return true;
16675 }
16676 
16677 // Send the data to the tube
TubeSend(TUBE * t,void * data,UINT size,void * header)16678 bool TubeSend(TUBE *t, void *data, UINT size, void *header)
16679 {
16680 	return TubeSendEx(t, data, size, header, false);
16681 }
TubeSendEx(TUBE * t,void * data,UINT size,void * header,bool no_flush)16682 bool TubeSendEx(TUBE *t, void *data, UINT size, void *header, bool no_flush)
16683 {
16684 	return TubeSendEx2(t, data, size, header, no_flush, 0);
16685 }
TubeSendEx2(TUBE * t,void * data,UINT size,void * header,bool no_flush,UINT max_num_in_queue)16686 bool TubeSendEx2(TUBE *t, void *data, UINT size, void *header, bool no_flush, UINT max_num_in_queue)
16687 {
16688 	// Validate arguments
16689 	if (t == NULL || data == NULL || size == 0)
16690 	{
16691 		return false;
16692 	}
16693 
16694 	if (IsTubeConnected(t) == false)
16695 	{
16696 		return false;
16697 	}
16698 
16699 	LockQueue(t->Queue);
16700 	{
16701 		if (max_num_in_queue == 0 || (t->Queue->num_item <= max_num_in_queue))
16702 		{
16703 			InsertQueue(t->Queue, NewTubeData(data, size, header, t->SizeOfHeader));
16704 		}
16705 		else
16706 		{
16707 			no_flush = true;
16708 		}
16709 	}
16710 	UnlockQueue(t->Queue);
16711 
16712 	if (no_flush == false)
16713 	{
16714 		Set(t->Event);
16715 		SetSockEvent(t->SockEvent);
16716 	}
16717 
16718 	return true;
16719 }
16720 
16721 // Flush the tube
TubeFlush(TUBE * t)16722 void TubeFlush(TUBE *t)
16723 {
16724 	TubeFlushEx(t, false);
16725 }
TubeFlushEx(TUBE * t,bool force)16726 void TubeFlushEx(TUBE *t, bool force)
16727 {
16728 	// Validate arguments
16729 	if (t == NULL)
16730 	{
16731 		return;
16732 	}
16733 
16734 	if (IsTubeConnected(t) == false)
16735 	{
16736 		return;
16737 	}
16738 
16739 	if (force == false)
16740 	{
16741 		if (t->Queue->num_item == 0)
16742 		{
16743 			return;
16744 		}
16745 	}
16746 
16747 	Set(t->Event);
16748 	SetSockEvent(t->SockEvent);
16749 }
16750 
16751 // Receive the data from the tube (asynchronous)
TubeRecvAsync(TUBE * t)16752 TUBEDATA *TubeRecvAsync(TUBE *t)
16753 {
16754 	TUBEDATA *d;
16755 	// Validate arguments
16756 	if (t == NULL)
16757 	{
16758 		return NULL;
16759 	}
16760 
16761 	if (IsTubeConnected(t) == false)
16762 	{
16763 		return NULL;
16764 	}
16765 
16766 	LockQueue(t->Queue);
16767 	{
16768 		d = GetNext(t->Queue);
16769 	}
16770 	UnlockQueue(t->Queue);
16771 
16772 	return d;
16773 }
16774 
16775 // Get the SockEvent associated with the tube
GetTubeSockEvent(TUBE * t)16776 SOCK_EVENT *GetTubeSockEvent(TUBE *t)
16777 {
16778 	SOCK_EVENT *e = NULL;
16779 	// Validate arguments
16780 	if (t == NULL)
16781 	{
16782 		return NULL;
16783 	}
16784 
16785 	Lock(t->Lock);
16786 	{
16787 		if (t->SockEvent != NULL)
16788 		{
16789 			AddRef(t->SockEvent->ref);
16790 
16791 			e = t->SockEvent;
16792 		}
16793 	}
16794 	Unlock(t->Lock);
16795 
16796 	return e;
16797 }
16798 
16799 // Receive the data from the tube (synchronous)
TubeRecvSync(TUBE * t,UINT timeout)16800 TUBEDATA *TubeRecvSync(TUBE *t, UINT timeout)
16801 {
16802 	UINT64 start_tick, timeout_tick;
16803 	TUBEDATA *d = NULL;
16804 	// Validate arguments
16805 	if (t == NULL)
16806 	{
16807 		return NULL;
16808 	}
16809 
16810 	if (IsTubeConnected(t) == false)
16811 	{
16812 		return NULL;
16813 	}
16814 
16815 	start_tick = Tick64();
16816 	timeout_tick = start_tick + (UINT64)timeout;
16817 
16818 	while (true)
16819 	{
16820 		UINT64 now = Tick64();
16821 		UINT remain_time;
16822 		SOCK_EVENT *e;
16823 		UINT interval;
16824 
16825 		d = NULL;
16826 
16827 		if (IsTubeConnected(t) == false)
16828 		{
16829 			break;
16830 		}
16831 
16832 		LockQueue(t->Queue);
16833 		{
16834 			d = GetNext(t->Queue);
16835 		}
16836 		UnlockQueue(t->Queue);
16837 
16838 		if (d != NULL)
16839 		{
16840 			break;
16841 		}
16842 
16843 		if (timeout != INFINITE && now >= timeout_tick)
16844 		{
16845 			return NULL;
16846 		}
16847 
16848 		remain_time = (UINT)(timeout_tick - now);
16849 
16850 		e = GetTubeSockEvent(t);
16851 
16852 		interval = (timeout == INFINITE ? INFINITE : remain_time);
16853 
16854 		if (e == NULL)
16855 		{
16856 			Wait(t->Event, interval);
16857 		}
16858 		else
16859 		{
16860 			WaitSockEvent(e, interval);
16861 
16862 			ReleaseSockEvent(e);
16863 		}
16864 	}
16865 
16866 	return d;
16867 }
16868 
16869 // Creating a tube
NewTube(UINT size_of_header)16870 TUBE *NewTube(UINT size_of_header)
16871 {
16872 	TUBE *t = ZeroMalloc(sizeof(TUBE));
16873 
16874 	t->Event = NewEvent();
16875 	t->Queue = NewQueue();
16876 	t->Ref = NewRef();
16877 	t->Lock = NewLock();
16878 	t->SockEvent = NewSockEvent();
16879 
16880 	t->SizeOfHeader = size_of_header;
16881 
16882 	return t;
16883 }
16884 
16885 // Release of the tube
ReleaseTube(TUBE * t)16886 void ReleaseTube(TUBE *t)
16887 {
16888 	// Validate arguments
16889 	if (t == NULL)
16890 	{
16891 		return;
16892 	}
16893 
16894 	if (Release(t->Ref) == 0)
16895 	{
16896 		CleanupTube(t);
16897 	}
16898 }
CleanupTube(TUBE * t)16899 void CleanupTube(TUBE *t)
16900 {
16901 	// Validate arguments
16902 	if (t == NULL)
16903 	{
16904 		return;
16905 	}
16906 
16907 	while (true)
16908 	{
16909 		TUBEDATA *d = GetNext(t->Queue);
16910 		if (d == NULL)
16911 		{
16912 			break;
16913 		}
16914 
16915 		FreeTubeData(d);
16916 	}
16917 
16918 	ReleaseQueue(t->Queue);
16919 	ReleaseEvent(t->Event);
16920 	ReleaseSockEvent(t->SockEvent);
16921 
16922 	ReleaseTubePairData(t->TubePairData);
16923 
16924 	DeleteLock(t->Lock);
16925 
16926 	Free(t);
16927 }
16928 
16929 // Creating a tube data
NewTubeData(void * data,UINT size,void * header,UINT header_size)16930 TUBEDATA *NewTubeData(void *data, UINT size, void *header, UINT header_size)
16931 {
16932 	TUBEDATA *d;
16933 	// Validate arguments
16934 	if (size == 0 || data == NULL)
16935 	{
16936 		return NULL;
16937 	}
16938 
16939 	d = ZeroMalloc(sizeof(TUBEDATA));
16940 
16941 	d->Data = Clone(data, size);
16942 	d->DataSize = size;
16943 	if (header != NULL)
16944 	{
16945 		d->Header = Clone(header, header_size);
16946 		d->HeaderSize = header_size;
16947 	}
16948 	else
16949 	{
16950 		d->Header = ZeroMalloc(header_size);
16951 	}
16952 
16953 	return d;
16954 }
16955 
16956 // Release of the tube data
FreeTubeData(TUBEDATA * d)16957 void FreeTubeData(TUBEDATA *d)
16958 {
16959 	// Validate arguments
16960 	if (d == NULL)
16961 	{
16962 		return;
16963 	}
16964 
16965 	Free(d->Data);
16966 	Free(d->Header);
16967 
16968 	Free(d);
16969 }
16970 
16971 // Release of the IP address list of the host
FreeHostIPAddressList(LIST * o)16972 void FreeHostIPAddressList(LIST *o)
16973 {
16974 	UINT i;
16975 	// Validate arguments
16976 	if (o == NULL)
16977 	{
16978 		return;
16979 	}
16980 
16981 	for (i = 0; i < LIST_NUM(o); i++)
16982 	{
16983 		IP *ip = LIST_DATA(o, i);
16984 
16985 		Free(ip);
16986 	}
16987 
16988 	ReleaseList(o);
16989 }
16990 
16991 // Get whether the specified IP address is held by this host
IsMyIPAddress(IP * ip)16992 bool IsMyIPAddress(IP *ip)
16993 {
16994 	LIST *o;
16995 	UINT i;
16996 	bool ret = false;
16997 	// Validate arguments
16998 	if (ip == NULL)
16999 	{
17000 		return false;
17001 	}
17002 
17003 	o = GetHostIPAddressList();
17004 
17005 	for (i = 0; i < LIST_NUM(o); i++)
17006 	{
17007 		IP *a = LIST_DATA(o, i);
17008 
17009 		if (CmpIpAddr(ip, a) == 0)
17010 		{
17011 			ret = true;
17012 			break;
17013 		}
17014 	}
17015 
17016 	FreeHostIPAddressList(o);
17017 
17018 	return ret;
17019 }
17020 
17021 // Add the IP address to the list
AddHostIPAddressToList(LIST * o,IP * ip)17022 void AddHostIPAddressToList(LIST *o, IP *ip)
17023 {
17024 	IP *r;
17025 	// Validate arguments
17026 	if (o == NULL || ip == NULL)
17027 	{
17028 		return;
17029 	}
17030 
17031 	r = Search(o, ip);
17032 	if (r != NULL)
17033 	{
17034 		return;
17035 	}
17036 
17037 	Insert(o, Clone(ip, sizeof(IP)));
17038 }
17039 
17040 // Comparison of the IP address list items
CmpIpAddressList(void * p1,void * p2)17041 int CmpIpAddressList(void *p1, void *p2)
17042 {
17043 	IP *ip1, *ip2;
17044 	UINT r;
17045 	// Validate arguments
17046 	if (p1 == NULL || p2 == NULL)
17047 	{
17048 		return 0;
17049 	}
17050 	ip1 = *(IP **)p1;
17051 	ip2 = *(IP **)p2;
17052 	if (ip1 == NULL || ip2 == NULL)
17053 	{
17054 		return 0;
17055 	}
17056 
17057 	// IPv4 < IPv6
17058 	r = COMPARE_RET(IsIP6(ip1), IsIP6(ip2));
17059 	if (r != 0)
17060 	{
17061 		return r;
17062 	}
17063 
17064 	// any > specified IP
17065 	if (IsZeroIP(ip1) && IsZeroIP(ip2) == false)
17066 	{
17067 		return 1;
17068 	}
17069 	if (IsZeroIP(ip1) == false && IsZeroIP(ip2))
17070 	{
17071 		return -1;
17072 	}
17073 
17074 	// local > others
17075 	if (IsLocalHostIP(ip1) && IsLocalHostIP(ip2) == false)
17076 	{
17077 		return 1;
17078 	}
17079 	if (IsLocalHostIP(ip1) == false && IsLocalHostIP(ip2))
17080 	{
17081 		return -1;
17082 	}
17083 
17084 	// ip address
17085 	r = CmpIpAddr(ip1, ip2);
17086 	if (r != 0)
17087 	{
17088 		return r;
17089 	}
17090 
17091 	// interface index
17092 	if (IsIP6(ip1))
17093 	{
17094 		r = COMPARE_RET(ip1->ipv6_scope_id, ip2->ipv6_scope_id);
17095 	}
17096 	else
17097 	{
17098 		r = 0;
17099 	}
17100 
17101 	return r;
17102 }
17103 
17104 // Get the IP address list hash of the host
GetHostIPAddressListHash()17105 UINT64 GetHostIPAddressListHash()
17106 {
17107 	UINT i;
17108 	LIST *o;
17109 	BUF *buf = NewBuf();
17110 	UCHAR hash[SHA1_SIZE];
17111 	UINT64 ret = 0;
17112 
17113 	o = GetHostIPAddressList();
17114 
17115 	if (o != NULL)
17116 	{
17117 		for (i = 0; i < LIST_NUM(o); i++)
17118 		{
17119 			IP *ip = LIST_DATA(o, i);
17120 			char tmp[128];
17121 
17122 			Zero(tmp, sizeof(tmp));
17123 			IPToStr(tmp, sizeof(tmp), ip);
17124 
17125 			WriteBufStr(buf, tmp);
17126 		}
17127 
17128 		FreeHostIPAddressList(o);
17129 	}
17130 
17131 	WriteBufStr(buf, "test");
17132 
17133 	Sha1(hash, buf->Buf, buf->Size);
17134 
17135 	FreeBuf(buf);
17136 
17137 	Copy(&ret, hash, sizeof(UINT64));
17138 
17139 	ret = Endian64(ret);
17140 
17141 	return ret;
17142 }
17143 
17144 // Get the IP address list of the host (using cache)
GetHostIPAddressList()17145 LIST *GetHostIPAddressList()
17146 {
17147 	LIST *o = NULL;
17148 	if (host_ip_address_list_cache_lock == NULL)
17149 	{
17150 		return GetHostIPAddressListInternal();
17151 	}
17152 
17153 	Lock(host_ip_address_list_cache_lock);
17154 	{
17155 		UINT64 now = Tick64();
17156 
17157 		if (host_ip_address_list_cache_last == 0 ||
17158 		        ((host_ip_address_list_cache_last + (UINT64)HOST_IP_ADDRESS_LIST_CACHE) < now) ||
17159 		        host_ip_address_cache == NULL)
17160 		{
17161 			if (host_ip_address_cache != NULL)
17162 			{
17163 				FreeHostIPAddressList(host_ip_address_cache);
17164 			}
17165 
17166 			host_ip_address_cache = GetHostIPAddressListInternal();
17167 
17168 			host_ip_address_list_cache_last = now;
17169 		}
17170 
17171 		o = CloneIPAddressList(host_ip_address_cache);
17172 	}
17173 	Unlock(host_ip_address_list_cache_lock);
17174 
17175 	if (o == NULL)
17176 	{
17177 		o = GetHostIPAddressListInternal();
17178 	}
17179 
17180 	return o;
17181 }
17182 
17183 // Copy of the IP address list
CloneIPAddressList(LIST * o)17184 LIST *CloneIPAddressList(LIST *o)
17185 {
17186 	LIST *ret;
17187 	UINT i;
17188 	// Validate arguments
17189 	if (o == NULL)
17190 	{
17191 		return NULL;
17192 	}
17193 
17194 	ret = NewListFast(CmpIpAddressList);
17195 
17196 	for (i = 0; i < LIST_NUM(o); i++)
17197 	{
17198 		IP *ip = LIST_DATA(o, i);
17199 
17200 		if (ip != NULL)
17201 		{
17202 			ip = Clone(ip, sizeof(IP));
17203 
17204 			Add(ret, ip);
17205 		}
17206 	}
17207 
17208 	return ret;
17209 }
17210 
17211 // Get an IP address list of the host
GetHostIPAddressListInternal()17212 LIST *GetHostIPAddressListInternal()
17213 {
17214 	char hostname[MAX_SIZE];
17215 	LIST *o;
17216 	IP any6, any4;
17217 	IP local6, local4;
17218 	bool is_v6_supported = IsIPv6Supported();
17219 
17220 	GetLocalHostIP4(&local4);
17221 	GetLocalHostIP6(&local6);
17222 
17223 	ZeroIP4(&any4);
17224 	Zero(&any6, sizeof(any6));
17225 
17226 	Zero(hostname, sizeof(hostname));
17227 
17228 	gethostname(hostname, sizeof(hostname));
17229 
17230 	o = NewListFast(CmpIpAddressList);
17231 
17232 	// any
17233 	AddHostIPAddressToList(o, &any4);
17234 	if (is_v6_supported)
17235 	{
17236 		AddHostIPAddressToList(o, &any6);
17237 	}
17238 
17239 	// localhost
17240 	AddHostIPAddressToList(o, &local4);
17241 	if (is_v6_supported)
17242 	{
17243 		AddHostIPAddressToList(o, &local6);
17244 	}
17245 
17246 #ifndef	MAYAQUA_SUPPORTS_GETIFADDRS
17247 	// IPv4
17248 	if (true)
17249 	{
17250 		struct sockaddr_in in;
17251 		struct in_addr addr;
17252 		struct addrinfo hint;
17253 		struct addrinfo *info;
17254 
17255 		Zero(&hint, sizeof(hint));
17256 		hint.ai_family = AF_INET;
17257 		hint.ai_socktype = SOCK_DGRAM;
17258 		hint.ai_protocol = IPPROTO_UDP;
17259 		info = NULL;
17260 
17261 		if (getaddrinfo(hostname, NULL, &hint, &info) == 0)
17262 		{
17263 			if (info->ai_family == AF_INET)
17264 			{
17265 				struct addrinfo *current = info;
17266 				while (current != NULL)
17267 				{
17268 					IP ip;
17269 
17270 					Copy(&in, current->ai_addr, sizeof(in));
17271 					Copy(&addr, &in.sin_addr, sizeof(addr));
17272 
17273 					InAddrToIP(&ip, &addr);
17274 					AddHostIPAddressToList(o, &ip);
17275 
17276 					current = current->ai_next;
17277 				}
17278 			}
17279 
17280 			freeaddrinfo(info);
17281 		}
17282 	}
17283 
17284 #ifndef	UNIX_LINUX
17285 	// IPv6
17286 	if (is_v6_supported)
17287 	{
17288 		struct sockaddr_in6 in;
17289 		struct in6_addr addr;
17290 		struct addrinfo hint;
17291 		struct addrinfo *info;
17292 
17293 		Zero(&hint, sizeof(hint));
17294 		hint.ai_family = AF_INET6;
17295 		hint.ai_socktype = SOCK_DGRAM;
17296 		hint.ai_protocol = IPPROTO_UDP;
17297 		info = NULL;
17298 
17299 		if (getaddrinfo(hostname, NULL, &hint, &info) == 0)
17300 		{
17301 			if (info->ai_family == AF_INET6)
17302 			{
17303 				struct addrinfo *current = info;
17304 				while (current != NULL)
17305 				{
17306 					IP ip;
17307 
17308 					Copy(&in, current->ai_addr, sizeof(in));
17309 					Copy(&addr, &in.sin6_addr, sizeof(addr));
17310 
17311 					InAddrToIP6(&ip, &addr);
17312 					ip.ipv6_scope_id = in.sin6_scope_id;
17313 
17314 					AddHostIPAddressToList(o, &ip);
17315 
17316 					current = current->ai_next;
17317 				}
17318 			}
17319 
17320 			freeaddrinfo(info);
17321 		}
17322 	}
17323 #endif	// UNIX_LINUX
17324 #endif	// MAYAQUA_SUPPORTS_GETIFADDRS
17325 
17326 #ifdef	MAYAQUA_SUPPORTS_GETIFADDRS
17327 	// If the getifaddrs is available, use this
17328 	if (true)
17329 	{
17330 		struct ifaddrs *aa = NULL;
17331 
17332 		if (getifaddrs(&aa) == 0)
17333 		{
17334 			struct ifaddrs *a = aa;
17335 
17336 			while (a != NULL)
17337 			{
17338 				if (a->ifa_addr != NULL)
17339 				{
17340 					struct sockaddr *addr = a->ifa_addr;
17341 
17342 					if (addr->sa_family == AF_INET)
17343 					{
17344 						IP ip;
17345 						struct sockaddr_in *d = (struct sockaddr_in *)addr;
17346 						struct in_addr *addr = &d->sin_addr;
17347 
17348 						InAddrToIP(&ip, addr);
17349 
17350 						AddHostIPAddressToList(o, &ip);
17351 					}
17352 					else if (addr->sa_family == AF_INET6)
17353 					{
17354 						IP ip;
17355 						struct sockaddr_in6 *d = (struct sockaddr_in6 *)addr;
17356 						UINT scope_id = d->sin6_scope_id;
17357 						struct in6_addr *addr = &d->sin6_addr;
17358 
17359 						InAddrToIP6(&ip, addr);
17360 						ip.ipv6_scope_id = scope_id;
17361 
17362 						AddHostIPAddressToList(o, &ip);
17363 					}
17364 				}
17365 
17366 				a = a->ifa_next;
17367 			}
17368 
17369 			freeifaddrs(aa);
17370 		}
17371 	}
17372 #endif	// MAYAQUA_SUPPORTS_GETIFADDRS
17373 
17374 	return o;
17375 }
17376 
17377 // Get whether the UDP listener opens the specified port
IsUdpPortOpened(UDPLISTENER * u,IP * server_ip,UINT port)17378 bool IsUdpPortOpened(UDPLISTENER *u, IP *server_ip, UINT port)
17379 {
17380 	UINT i;
17381 	// Validate arguments
17382 	if (u == NULL || port == 0)
17383 	{
17384 		return false;
17385 	}
17386 
17387 	if (server_ip != NULL)
17388 	{
17389 		for (i = 0; i < LIST_NUM(u->SockList); i++)
17390 		{
17391 			UDPLISTENER_SOCK *us = LIST_DATA(u->SockList, i);
17392 
17393 			if (us->Sock != NULL && us->HasError == false)
17394 			{
17395 				if (us->Port == port)
17396 				{
17397 					if (CmpIpAddr(server_ip, &us->IpAddress) == 0)
17398 					{
17399 						return true;
17400 					}
17401 				}
17402 			}
17403 		}
17404 	}
17405 
17406 	for (i = 0; i < LIST_NUM(u->SockList); i++)
17407 	{
17408 		UDPLISTENER_SOCK *us = LIST_DATA(u->SockList, i);
17409 
17410 		if (us->Sock != NULL && us->HasError == false)
17411 		{
17412 			if (us->Port == port)
17413 			{
17414 				if (IsZeroIP(&us->IpAddress))
17415 				{
17416 					return true;
17417 				}
17418 			}
17419 		}
17420 	}
17421 
17422 	return false;
17423 }
17424 
17425 // IP address acquisition thread
QueryIpThreadMain(THREAD * thread,void * param)17426 void QueryIpThreadMain(THREAD *thread, void *param)
17427 {
17428 	QUERYIPTHREAD *t = (QUERYIPTHREAD *)param;
17429 	// Validate arguments
17430 	if (thread == NULL || param == NULL)
17431 	{
17432 		return;
17433 	}
17434 
17435 	while (t->Halt == false)
17436 	{
17437 		UINT next_wait_time = 0;
17438 		IP ip;
17439 		bool ok = false;
17440 
17441 		if (GetIP4Ex(&ip, t->Hostname, 5000, &t->Halt))
17442 		{
17443 			if (IsZeroIP(&ip) == false)
17444 			{
17445 				Lock(t->Lock);
17446 				{
17447 					Copy(&t->Ip, &ip, sizeof(IP));
17448 				}
17449 				Unlock(t->Lock);
17450 
17451 				ok = true;
17452 			}
17453 		}
17454 
17455 		if (ok == false)
17456 		{
17457 			next_wait_time = t->IntervalLastNg;
17458 		}
17459 		else
17460 		{
17461 			next_wait_time = t->IntervalLastOk;
17462 		}
17463 
17464 		if (t->Halt)
17465 		{
17466 			break;
17467 		}
17468 
17469 		Wait(t->HaltEvent, next_wait_time);
17470 	}
17471 }
17472 
17473 // Creating an IP address acquisition thread
NewQueryIpThread(char * hostname,UINT interval_last_ok,UINT interval_last_ng)17474 QUERYIPTHREAD *NewQueryIpThread(char *hostname, UINT interval_last_ok, UINT interval_last_ng)
17475 {
17476 	QUERYIPTHREAD *t;
17477 
17478 	t = ZeroMalloc(sizeof(QUERYIPTHREAD));
17479 
17480 	t->HaltEvent = NewEvent();
17481 	t->Lock = NewLock();
17482 	StrCpy(t->Hostname, sizeof(t->Hostname), hostname);
17483 	t->IntervalLastOk = interval_last_ok;
17484 	t->IntervalLastNg = interval_last_ng;
17485 
17486 	t->Thread = NewThread(QueryIpThreadMain, t);
17487 
17488 	return t;
17489 }
17490 
17491 // Get the results of the IP address acquisition thread
GetQueryIpThreadResult(QUERYIPTHREAD * t,IP * ip)17492 bool GetQueryIpThreadResult(QUERYIPTHREAD *t, IP *ip)
17493 {
17494 	bool ret = false;
17495 	Zero(ip, sizeof(IP));
17496 	// Validate arguments
17497 	if (t == NULL || ip == NULL)
17498 	{
17499 		return false;
17500 	}
17501 
17502 	Lock(t->Lock);
17503 
17504 	if (IsZero(&t->Ip, sizeof(IP)))
17505 	{
17506 		ret = false;
17507 	}
17508 	else
17509 	{
17510 		Copy(ip, &t->Ip, sizeof(IP));
17511 	}
17512 
17513 	Unlock(t->Lock);
17514 
17515 	return ret;
17516 }
17517 
17518 // Release of the IP address acquisition thread
FreeQueryIpThread(QUERYIPTHREAD * t)17519 void FreeQueryIpThread(QUERYIPTHREAD *t)
17520 {
17521 	// Validate arguments
17522 	if (t == NULL)
17523 	{
17524 		return;
17525 	}
17526 
17527 	t->Halt = true;
17528 	Set(t->HaltEvent);
17529 
17530 	WaitThread(t->Thread, INFINITE);
17531 	ReleaseThread(t->Thread);
17532 
17533 	ReleaseEvent(t->HaltEvent);
17534 
17535 	DeleteLock(t->Lock);
17536 
17537 	Free(t);
17538 }
17539 
17540 // UDP listener thread
UdpListenerThread(THREAD * thread,void * param)17541 void UdpListenerThread(THREAD *thread, void *param)
17542 {
17543 	UDPLISTENER *u = (UDPLISTENER *)param;
17544 	UINT i, j, k;
17545 	UINT buf_size = 65536;
17546 	void *buf;
17547 	bool cont_flag;
17548 	BUF *ip_list_buf = NewBuf();
17549 	// Validate arguments
17550 	if (thread == NULL || param == NULL)
17551 	{
17552 		return;
17553 	}
17554 
17555 	buf = Malloc(buf_size);
17556 
17557 	// Initializing the socket list
17558 	u->SockList = NewList(NULL);
17559 
17560 	u->LastCheckTick = 0;
17561 
17562 //	u->PollMyIpAndPort = true;
17563 
17564 	// Main loop
17565 	while (u->Halt == false)
17566 	{
17567 		LIST *recv_list;
17568 		UINT64 now = Tick64();
17569 		UINT interval;
17570 		bool stage_changed = false;
17571 		IP nat_t_ip;
17572 
17573 		Zero(&nat_t_ip, sizeof(nat_t_ip));
17574 
17575 
17576 		if (u->LastCheckTick == 0 || (now >= (u->LastCheckTick + UDPLISTENER_CHECK_INTERVAL)))
17577 		{
17578 			LIST *iplist;
17579 			LIST *del_us_list = NewListFast(NULL);
17580 			BUF *ip_list_buf_new = NewBuf();
17581 
17582 			u->LastCheckTick = now;
17583 
17584 			// Obtain an IP address list
17585 			iplist = GetHostIPAddressList();
17586 
17587 			LockList(u->PortList);
17588 			{
17589 				for (k = 0; k < LIST_NUM(u->SockList); k++)
17590 				{
17591 					UDPLISTENER_SOCK *us = LIST_DATA(u->SockList, k);
17592 
17593 					us->Mark = false;
17594 				}
17595 
17596 				// If the combination of the IP address and the port number doesn't exist in the list, add it to the list
17597 				for (i = 0; i < LIST_NUM(iplist); i++)
17598 				{
17599 					IP *ip = LIST_DATA(iplist, i);
17600 
17601 					if (CmpIpAddr(ip, &u->ListenIP) != 0)
17602 					{
17603 						continue;
17604 					}
17605 
17606 					WriteBuf(ip_list_buf_new, ip, sizeof(IP));
17607 
17608 					for (j = 0; j < LIST_NUM(u->PortList); j++)
17609 					{
17610 						UINT k;
17611 						UINT *port = LIST_DATA(u->PortList, j);
17612 						bool existing = false;
17613 
17614 						if (IsZeroIP(ip) && (IS_SPECIAL_PORT(*port)))
17615 						{
17616 							continue;
17617 						}
17618 
17619 
17620 						for (k = 0; k < LIST_NUM(u->SockList); k++)
17621 						{
17622 							UDPLISTENER_SOCK *us = LIST_DATA(u->SockList, k);
17623 
17624 							if (CmpIpAddr(&us->IpAddress, ip) == 0 && us->Port == *port)
17625 							{
17626 								existing = true;
17627 
17628 								us->Mark = true;
17629 
17630 								break;
17631 							}
17632 						}
17633 
17634 						if (existing == false)
17635 						{
17636 							UDPLISTENER_SOCK *us = ZeroMalloc(sizeof(UDPLISTENER_SOCK));
17637 
17638 							Copy(&us->IpAddress, ip, sizeof(IP));
17639 							us->Port = *port;
17640 
17641 							us->Mark = true;
17642 
17643 							Add(u->SockList, us);
17644 						}
17645 					}
17646 				}
17647 
17648 				// If any errors suspected or the combination of IP address and port number
17649 				// has been regarded to delete already, delete it
17650 				for (k = 0; k < LIST_NUM(u->SockList); k++)
17651 				{
17652 					UDPLISTENER_SOCK *us = LIST_DATA(u->SockList, k);
17653 
17654 					if (us->Mark == false || us->HasError)
17655 					{
17656 						Debug("mark=%u error=%u\n", us->Mark, us->HasError);
17657 						Add(del_us_list, us);
17658 					}
17659 				}
17660 
17661 				for (i = 0; i < LIST_NUM(del_us_list); i++)
17662 				{
17663 					UDPLISTENER_SOCK *us = LIST_DATA(del_us_list, i);
17664 
17665 					char ipstr[MAX_SIZE];
17666 
17667 					IPToStr(ipstr, sizeof(ipstr), &us->IpAddress);
17668 					Debug("Closed UDP Port %u at %s.\n", us->Port, ipstr);
17669 
17670 					Delete(u->SockList, us);
17671 
17672 					if (us->Sock != NULL)
17673 					{
17674 						Disconnect(us->Sock);
17675 						ReleaseSock(us->Sock);
17676 					}
17677 
17678 					Free(us);
17679 				}
17680 			}
17681 			UnlockList(u->PortList);
17682 
17683 			// Open the UDP sockets which is not opend yet
17684 			for (k = 0; k < LIST_NUM(u->SockList); k++)
17685 			{
17686 				UDPLISTENER_SOCK *us = LIST_DATA(u->SockList, k);
17687 
17688 				if (us->Sock == NULL)
17689 				{
17690 					char ipstr[MAX_SIZE];
17691 
17692 					IPToStr(ipstr, sizeof(ipstr), &us->IpAddress);
17693 
17694 					if (us->ErrorDebugDisplayed == false)
17695 					{
17696 						Debug("Opening UDP Port %u at %s ...", us->Port, ipstr);
17697 					}
17698 
17699 					us->Sock = NewUDPEx2(us->Port, IsIP6(&us->IpAddress), &us->IpAddress);
17700 
17701 					if (us->Sock != NULL)
17702 					{
17703 						if (us->ErrorDebugDisplayed == false)
17704 						{
17705 							Debug("Ok.\n");
17706 						}
17707 						else
17708 						{
17709 							Debug("Opening UDP Port %u at %s ...", us->Port, ipstr);
17710 							Debug("Ok.\n");
17711 						}
17712 						JoinSockToSockEvent(us->Sock, u->Event);
17713 
17714 						us->ErrorDebugDisplayed = false;
17715 					}
17716 					else
17717 					{
17718 						if (us->ErrorDebugDisplayed == false)
17719 						{
17720 							Debug("Error.\n");
17721 						}
17722 
17723 						us->ErrorDebugDisplayed = true;
17724 					}
17725 				}
17726 			}
17727 
17728 			FreeHostIPAddressList(iplist);
17729 
17730 			ReleaseList(del_us_list);
17731 
17732 			if (CompareBuf(ip_list_buf, ip_list_buf_new) == false)
17733 			{
17734 				u->HostIPAddressListChanged = true;
17735 			}
17736 
17737 			FreeBuf(ip_list_buf);
17738 			ip_list_buf = ip_list_buf_new;
17739 		}
17740 
17741 LABEL_RESTART:
17742 
17743 		stage_changed = false;
17744 
17745 		recv_list = NewListFast(NULL);
17746 
17747 		if (u->PollMyIpAndPort)
17748 		{
17749 			// Create a thread to get a NAT-T IP address if necessary
17750 			if (u->GetNatTIpThread == NULL)
17751 			{
17752 				char natt_hostname[MAX_SIZE];
17753 				RUDPGetRegisterHostNameByIP(natt_hostname, sizeof(natt_hostname), NULL);
17754 				u->GetNatTIpThread = NewQueryIpThread(natt_hostname, QUERYIPTHREAD_INTERVAL_LAST_OK, QUERYIPTHREAD_INTERVAL_LAST_NG);
17755 				GetQueryIpThreadResult(u->GetNatTIpThread, &nat_t_ip);
17756 			}
17757 		}
17758 
17759 		// Receive the data that is arriving at the socket
17760 		for (k = 0; k < LIST_NUM(u->SockList); k++)
17761 		{
17762 			UDPLISTENER_SOCK *us = LIST_DATA(u->SockList, k);
17763 
17764 			if (us->Sock != NULL)
17765 			{
17766 				UINT num_ignore_errors = 0;
17767 
17768 				if (u->PollMyIpAndPort && IsIP4(&us->IpAddress))
17769 				{
17770 					if (us->NextMyIpAndPortPollTick == 0 || us->NextMyIpAndPortPollTick <= now)
17771 					{
17772 						// Examine the self IP address and the self port number by using NAT-T server
17773 						us->NextMyIpAndPortPollTick = now + (UINT64)GenRandInterval(UDP_NAT_T_NAT_STATUS_CHECK_INTERVAL_MIN, UDP_NAT_T_NAT_STATUS_CHECK_INTERVAL_MAX);
17774 
17775 						if (IsZeroIP(&nat_t_ip) == false
17776 						   )
17777 						{
17778 							UCHAR c = 'A';
17779 
17780 							SendTo(us->Sock, &nat_t_ip, UDP_NAT_T_PORT, &c, 1);
17781 						}
17782 					}
17783 				}
17784 
17785 				while (true)
17786 				{
17787 					IP src_addr;
17788 					UINT src_port;
17789 					UDPPACKET *p;
17790 
17791 					UINT size = RecvFrom(us->Sock, &src_addr, &src_port, buf, buf_size);
17792 					if (size == 0)
17793 					{
17794 						// Socket failure
17795 						if (us->Sock->IgnoreRecvErr == false)
17796 						{
17797 LABEL_FATAL_ERROR:
17798 							Debug("RecvFrom has Error.\n");
17799 							us->HasError = true;
17800 						}
17801 						else
17802 						{
17803 							if ((num_ignore_errors++) >= MAX_NUM_IGNORE_ERRORS)
17804 							{
17805 								goto LABEL_FATAL_ERROR;
17806 							}
17807 						}
17808 						break;
17809 					}
17810 					else if (size == SOCK_LATER)
17811 					{
17812 						// No packet
17813 						break;
17814 					}
17815 					//Debug("UDP %u\n", size);
17816 
17817 					if (src_port == UDP_NAT_T_PORT && CmpIpAddr(&src_addr, &nat_t_ip) == 0)
17818 					{
17819 						// Receive a packet in which the IP address and the port number are written from the NAT-T server
17820 						if (size >= 8)
17821 						{
17822 							IP my_ip;
17823 							UINT my_port;
17824 
17825 							if (RUDPParseIPAndPortStr(buf, size, &my_ip, &my_port))
17826 							{
17827 								Copy(&us->PublicIpAddress, &my_ip, sizeof(IP));
17828 								us->PublicPort = my_port;
17829 							}
17830 						}
17831 					}
17832 					else
17833 					{
17834 						// Receive a regular packet
17835 						p = NewUdpPacket(&src_addr, src_port, &us->Sock->LocalIP, us->Sock->LocalPort,
17836 						                 Clone(buf, size), size);
17837 
17838 						if (p->SrcPort == MAKE_SPECIAL_PORT(52))
17839 						{
17840 							p->SrcPort = p->DestPort = MAKE_SPECIAL_PORT(50);
17841 						}
17842 
17843 						p->Type = u->PacketType;
17844 
17845 						Add(recv_list, p);
17846 					}
17847 
17848 					stage_changed = true;
17849 				}
17850 			}
17851 		}
17852 
17853 		// Pass the received packet to the procedure
17854 		u->RecvProc(u, recv_list);
17855 
17856 		// Release the packet
17857 		for (i = 0; i < LIST_NUM(recv_list); i++)
17858 		{
17859 			UDPPACKET *p = LIST_DATA(recv_list, i);
17860 
17861 			FreeUdpPacket(p);
17862 		}
17863 
17864 		ReleaseList(recv_list);
17865 
17866 		cont_flag = true;
17867 
17868 		do
17869 		{
17870 			// When there are packets to be transmitted, transmit it
17871 			LockList(u->SendPacketList);
17872 			{
17873 				UDPLISTENER_SOCK *last_us = NULL;
17874 				IP last_src_ip;
17875 				UINT last_src_port;
17876 
17877 				Zero(&last_src_ip, sizeof(IP));
17878 				last_src_port = 0;
17879 
17880 				for (i = 0; i < LIST_NUM(u->SendPacketList); i++)
17881 				{
17882 					UDPPACKET *p = LIST_DATA(u->SendPacketList, i);
17883 					UDPLISTENER_SOCK *us;
17884 
17885 					if (last_us != NULL && last_src_port == p->SrcPort && CmpIpAddr(&last_src_ip, &p->SrcIP) == 0)
17886 					{
17887 						us = last_us;
17888 					}
17889 					else
17890 					{
17891 						// Search for a good interface for the transmission
17892 						us = DetermineUdpSocketForSending(u, p);
17893 
17894 						if (us != NULL)
17895 						{
17896 							last_us = us;
17897 							last_src_port = p->SrcPort;
17898 							Copy(&last_src_ip, &p->SrcIP, sizeof(IP));
17899 						}
17900 					}
17901 
17902 					if (us != NULL)
17903 					{
17904 						// Send
17905 						UINT ret = SendTo(us->Sock, &p->DstIP, p->DestPort, p->Data, p->Size);
17906 
17907 						if (ret == 0)
17908 						{
17909 							if (us->Sock->IgnoreSendErr == false)
17910 							{
17911 								// Socket failure
17912 								Debug("SendTo has Error.\n");
17913 								us->HasError = true;
17914 								last_us = NULL;
17915 							}
17916 						}
17917 						else
17918 						{
17919 							if (ret != SOCK_LATER)
17920 							{
17921 								stage_changed = true;
17922 							}
17923 						}
17924 					}
17925 
17926 					FreeUdpPacket(p);
17927 				}
17928 				DeleteAll(u->SendPacketList);
17929 			}
17930 			UnlockList(u->SendPacketList);
17931 
17932 			if (LIST_NUM(u->SendPacketList) == 0)
17933 			{
17934 				cont_flag = false;
17935 			}
17936 		}
17937 		while (cont_flag);
17938 
17939 		if (stage_changed && u->Halt == false)
17940 		{
17941 			goto LABEL_RESTART;
17942 		}
17943 
17944 		// Timing adjustment
17945 		interval = GetNextIntervalForInterrupt(u->Interrupts);
17946 
17947 		if (interval == INFINITE)
17948 		{
17949 			interval = UDPLISTENER_WAIT_INTERVAL;
17950 		}
17951 		else
17952 		{
17953 			interval = MIN(UDPLISTENER_WAIT_INTERVAL, interval);
17954 		}
17955 
17956 		if (interval >= 1)
17957 		{
17958 			WaitSockEvent(u->Event, interval);
17959 		}
17960 	}
17961 
17962 	if (u->GetNatTIpThread != NULL)
17963 	{
17964 		FreeQueryIpThread(u->GetNatTIpThread);
17965 	}
17966 
17967 	// Release of the socket list
17968 	for (i = 0; i < LIST_NUM(u->SockList); i++)
17969 	{
17970 		UDPLISTENER_SOCK *us = (UDPLISTENER_SOCK *)LIST_DATA(u->SockList, i);
17971 
17972 		Disconnect(us->Sock);
17973 		ReleaseSock(us->Sock);
17974 
17975 		Free(us);
17976 	}
17977 	ReleaseList(u->SockList);
17978 
17979 	FreeBuf(ip_list_buf);
17980 
17981 	Free(buf);
17982 }
17983 
17984 // Select the best UDP socket to be used for transmission
DetermineUdpSocketForSending(UDPLISTENER * u,UDPPACKET * p)17985 UDPLISTENER_SOCK *DetermineUdpSocketForSending(UDPLISTENER *u, UDPPACKET *p)
17986 {
17987 	UINT i;
17988 	// Validate arguments
17989 	if (u == NULL || p == NULL)
17990 	{
17991 		return NULL;
17992 	}
17993 
17994 	for (i = 0; i < LIST_NUM(u->SockList); i++)
17995 	{
17996 		UDPLISTENER_SOCK *us = LIST_DATA(u->SockList, i);
17997 
17998 		if (us->Sock != NULL && us->HasError == false)
17999 		{
18000 			if (us->Port == p->SrcPort)
18001 			{
18002 				if (CmpIpAddr(&us->IpAddress, &p->SrcIP) == 0)
18003 				{
18004 					return us;
18005 				}
18006 			}
18007 		}
18008 	}
18009 
18010 	for (i = 0; i < LIST_NUM(u->SockList); i++)
18011 	{
18012 		UDPLISTENER_SOCK *us = LIST_DATA(u->SockList, i);
18013 
18014 		if (us->Sock != NULL && us->HasError == false)
18015 		{
18016 			if (us->Port == p->SrcPort)
18017 			{
18018 				if (IsZeroIP(&us->IpAddress))
18019 				{
18020 					if ((IsIP4(&p->DstIP) && IsIP4(&us->IpAddress)) ||
18021 					        (IsIP6(&p->DstIP) && IsIP6(&us->IpAddress)))
18022 					{
18023 						return us;
18024 					}
18025 				}
18026 			}
18027 		}
18028 	}
18029 
18030 	return NULL;
18031 }
18032 
FreeTcpRawData(TCP_RAW_DATA * trd)18033 void FreeTcpRawData(TCP_RAW_DATA *trd)
18034 {
18035 	// Validate arguments
18036 	if (trd == NULL)
18037 	{
18038 		return;
18039 	}
18040 
18041 	ReleaseFifo(trd->Data);
18042 	Free(trd);
18043 }
18044 
NewTcpRawData(IP * src_ip,UINT src_port,IP * dst_ip,UINT dst_port)18045 TCP_RAW_DATA *NewTcpRawData(IP *src_ip, UINT src_port, IP *dst_ip, UINT dst_port)
18046 {
18047 	TCP_RAW_DATA *trd;
18048 	// Validate arguments
18049 	if (dst_ip == NULL || dst_port == 0)
18050 	{
18051 		return NULL;
18052 	}
18053 
18054 	trd = ZeroMalloc(sizeof(TCP_RAW_DATA));
18055 
18056 	Copy(&trd->SrcIP, src_ip, sizeof(IP));
18057 	trd->SrcPort = src_port;
18058 
18059 	Copy(&trd->DstIP, dst_ip, sizeof(IP));
18060 	trd->DstPort = dst_port;
18061 
18062 	trd->Data = NewFifoFast();
18063 
18064 	return trd;
18065 }
18066 
18067 // Release of the UDP packet
FreeUdpPacket(UDPPACKET * p)18068 void FreeUdpPacket(UDPPACKET *p)
18069 {
18070 	// Validate arguments
18071 	if (p == NULL)
18072 	{
18073 		return;
18074 	}
18075 
18076 	Free(p->Data);
18077 	Free(p);
18078 }
18079 
18080 // Create a new UDP packet
NewUdpPacket(IP * src_ip,UINT src_port,IP * dst_ip,UINT dst_port,void * data,UINT size)18081 UDPPACKET *NewUdpPacket(IP *src_ip, UINT src_port, IP *dst_ip, UINT dst_port, void *data, UINT size)
18082 {
18083 	UDPPACKET *p;
18084 	// Validate arguments
18085 	if (data == NULL || size == 0 || dst_ip == NULL || dst_port == 0)
18086 	{
18087 		return NULL;
18088 	}
18089 
18090 	p = ZeroMalloc(sizeof(UDPPACKET));
18091 
18092 	p->Data = data;
18093 	p->Size = size;
18094 
18095 	Copy(&p->SrcIP, src_ip, sizeof(IP));
18096 	p->SrcPort = src_port;
18097 
18098 	Copy(&p->DstIP, dst_ip, sizeof(IP));
18099 	p->DestPort = dst_port;
18100 
18101 	return p;
18102 }
18103 
18104 // Transmit the packets via UDP Listener
UdpListenerSendPackets(UDPLISTENER * u,LIST * packet_list)18105 void UdpListenerSendPackets(UDPLISTENER *u, LIST *packet_list)
18106 {
18107 	UINT num = 0;
18108 	// Validate arguments
18109 	if (u == NULL || packet_list == NULL)
18110 	{
18111 		return;
18112 	}
18113 
18114 	LockList(u->SendPacketList);
18115 	{
18116 		UINT i;
18117 
18118 		num = LIST_NUM(packet_list);
18119 
18120 		for (i = 0; i < LIST_NUM(packet_list); i++)
18121 		{
18122 			UDPPACKET *p = LIST_DATA(packet_list, i);
18123 
18124 			Add(u->SendPacketList, p);
18125 		}
18126 	}
18127 	UnlockList(u->SendPacketList);
18128 
18129 	if (num >= 1)
18130 	{
18131 		SetSockEvent(u->Event);
18132 	}
18133 }
18134 
18135 // Creating a UDP listener
NewUdpListener(UDPLISTENER_RECV_PROC * recv_proc,void * param,IP * listen_ip)18136 UDPLISTENER *NewUdpListener(UDPLISTENER_RECV_PROC *recv_proc, void *param, IP *listen_ip)
18137 {
18138 	return NewUdpListenerEx(recv_proc, param, listen_ip, INFINITE);
18139 }
18140 
NewUdpListenerEx(UDPLISTENER_RECV_PROC * recv_proc,void * param,IP * listen_ip,UINT packet_type)18141 UDPLISTENER *NewUdpListenerEx(UDPLISTENER_RECV_PROC *recv_proc, void *param, IP *listen_ip, UINT packet_type)
18142 {
18143 	UDPLISTENER *u;
18144 	// Validate arguments
18145 	if (recv_proc == NULL)
18146 	{
18147 		return NULL;
18148 	}
18149 
18150 	u = ZeroMalloc(sizeof(UDPLISTENER));
18151 
18152 	u->Param = param;
18153 	u->PacketType = packet_type;
18154 
18155 	u->PortList = NewList(NULL);
18156 	u->Event = NewSockEvent();
18157 
18158 	if (listen_ip)
18159 	{
18160 		Copy(&u->ListenIP, listen_ip, sizeof(IP));
18161 	}
18162 
18163 	u->RecvProc = recv_proc;
18164 	u->SendPacketList = NewList(NULL);
18165 
18166 	u->Interrupts = NewInterruptManager();
18167 
18168 	u->Thread = NewThread(UdpListenerThread, u);
18169 
18170 	return u;
18171 }
18172 
18173 // Stop the UDP listener
StopUdpListener(UDPLISTENER * u)18174 void StopUdpListener(UDPLISTENER *u)
18175 {
18176 	if (u == NULL)
18177 	{
18178 		return;
18179 	}
18180 
18181 	u->Halt = true;
18182 	SetSockEvent(u->Event);
18183 	WaitThread(u->Thread, INFINITE);
18184 }
18185 
18186 // Release the UDP listener
FreeUdpListener(UDPLISTENER * u)18187 void FreeUdpListener(UDPLISTENER *u)
18188 {
18189 	UINT i;
18190 	// Validate arguments
18191 	if (u == NULL)
18192 	{
18193 		return;
18194 	}
18195 
18196 	StopUdpListener(u);
18197 
18198 	ReleaseThread(u->Thread);
18199 	ReleaseSockEvent(u->Event);
18200 
18201 	ReleaseIntList(u->PortList);
18202 
18203 	for (i = 0; i < LIST_NUM(u->SendPacketList); i++)
18204 	{
18205 		UDPPACKET *p = LIST_DATA(u->SendPacketList, i);
18206 
18207 		FreeUdpPacket(p);
18208 	}
18209 
18210 	ReleaseList(u->SendPacketList);
18211 
18212 	FreeInterruptManager(u->Interrupts);
18213 
18214 	Free(u);
18215 }
18216 
18217 // Add the UDP port
AddPortToUdpListener(UDPLISTENER * u,UINT port)18218 void AddPortToUdpListener(UDPLISTENER *u, UINT port)
18219 {
18220 	// Validate arguments
18221 	if (u == NULL || port == 0)
18222 	{
18223 		return;
18224 	}
18225 
18226 	LockList(u->PortList);
18227 	{
18228 		AddIntDistinct(u->PortList, port);
18229 	}
18230 	UnlockList(u->PortList);
18231 
18232 	SetSockEvent(u->Event);
18233 }
18234 
18235 // Delete all the UDP ports
DeleteAllPortFromUdpListener(UDPLISTENER * u)18236 void DeleteAllPortFromUdpListener(UDPLISTENER *u)
18237 {
18238 	// Validate arguments
18239 	if (u == NULL)
18240 	{
18241 		return;
18242 	}
18243 
18244 	LockList(u->PortList);
18245 	{
18246 		UINT num_ports = LIST_NUM(u->PortList);
18247 		UINT *ports = ZeroMalloc(sizeof(UINT) * num_ports);
18248 		UINT i;
18249 
18250 		for (i = 0; i < num_ports; i++)
18251 		{
18252 			ports[i] = *((UINT *)(LIST_DATA(u->PortList, i)));
18253 		}
18254 
18255 		for (i = 0; i < num_ports; i++)
18256 		{
18257 			UINT port = ports[i];
18258 
18259 			DelInt(u->PortList, port);
18260 		}
18261 
18262 		Free(ports);
18263 	}
18264 	UnlockList(u->PortList);
18265 
18266 	SetSockEvent(u->Event);
18267 }
18268 
18269 // Delete the UDP port
DeletePortFromUdpListener(UDPLISTENER * u,UINT port)18270 void DeletePortFromUdpListener(UDPLISTENER *u, UINT port)
18271 {
18272 	// Validate arguments
18273 	if (u == NULL || port == 0)
18274 	{
18275 		return;
18276 	}
18277 
18278 	LockList(u->PortList);
18279 	{
18280 		DelInt(u->PortList, port);
18281 	}
18282 	UnlockList(u->PortList);
18283 
18284 	SetSockEvent(u->Event);
18285 }
18286 
18287 // Sort function of the interrupt management list
CmpInterruptManagerTickList(void * p1,void * p2)18288 int CmpInterruptManagerTickList(void *p1, void *p2)
18289 {
18290 	UINT64 *v1, *v2;
18291 	if (p1 == NULL || p2 == NULL)
18292 	{
18293 		return 0;
18294 	}
18295 
18296 	v1 = *(UINT64 **)p1;
18297 	v2 = *(UINT64 **)p2;
18298 	if (v1 == NULL || v2 == NULL)
18299 	{
18300 		return 0;
18301 	}
18302 
18303 	if (*v1 > *v2)
18304 	{
18305 		return 1;
18306 	}
18307 	else if (*v1 < *v2)
18308 	{
18309 		return -1;
18310 	}
18311 	else
18312 	{
18313 		return 0;
18314 	}
18315 }
18316 
18317 // Initialization of the interrupt management
NewInterruptManager()18318 INTERRUPT_MANAGER *NewInterruptManager()
18319 {
18320 	INTERRUPT_MANAGER *m = ZeroMalloc(sizeof(INTERRUPT_MANAGER));
18321 
18322 	m->TickList = NewList(CmpInterruptManagerTickList);
18323 
18324 	return m;
18325 }
18326 
18327 // Release of the interrupt management
FreeInterruptManager(INTERRUPT_MANAGER * m)18328 void FreeInterruptManager(INTERRUPT_MANAGER *m)
18329 {
18330 	UINT i;
18331 	// Validate arguments
18332 	if (m == NULL)
18333 	{
18334 		return;
18335 	}
18336 
18337 	for (i = 0; i < LIST_NUM(m->TickList); i++)
18338 	{
18339 		UINT64 *v = LIST_DATA(m->TickList, i);
18340 
18341 		Free(v);
18342 	}
18343 
18344 	ReleaseList(m->TickList);
18345 
18346 	Free(m);
18347 }
18348 
18349 // Add a number to the interrupt management
AddInterrupt(INTERRUPT_MANAGER * m,UINT64 tick)18350 void AddInterrupt(INTERRUPT_MANAGER *m, UINT64 tick)
18351 {
18352 	// Validate arguments
18353 	if (tick == 0)
18354 	{
18355 		return;
18356 	}
18357 
18358 	LockList(m->TickList);
18359 	{
18360 		if (Search(m->TickList, &tick) == NULL)
18361 		{
18362 			Insert(m->TickList, Clone(&tick, sizeof(UINT64)));
18363 		}
18364 	}
18365 	UnlockList(m->TickList);
18366 }
18367 
18368 // Get the interval to the next calling
GetNextIntervalForInterrupt(INTERRUPT_MANAGER * m)18369 UINT GetNextIntervalForInterrupt(INTERRUPT_MANAGER *m)
18370 {
18371 	UINT ret = INFINITE;
18372 	UINT i;
18373 	LIST *o = NULL;
18374 	UINT64 now = Tick64();
18375 	// Validate arguments
18376 	if (m == NULL)
18377 	{
18378 		return 0;
18379 	}
18380 
18381 	LockList(m->TickList);
18382 	{
18383 		// Remove entries older than now already
18384 		for (i = 0; i < LIST_NUM(m->TickList); i++)
18385 		{
18386 			UINT64 *v = LIST_DATA(m->TickList, i);
18387 
18388 			if (now >= *v)
18389 			{
18390 				ret = 0;
18391 
18392 				if (o == NULL)
18393 				{
18394 					o = NewListFast(NULL);
18395 				}
18396 
18397 				Add(o, v);
18398 			}
18399 			else
18400 			{
18401 				break;
18402 			}
18403 		}
18404 
18405 		for (i = 0; i < LIST_NUM(o); i++)
18406 		{
18407 			UINT64 *v = LIST_DATA(o, i);
18408 
18409 			Free(v);
18410 
18411 			Delete(m->TickList, v);
18412 		}
18413 
18414 		if (o != NULL)
18415 		{
18416 			ReleaseList(o);
18417 		}
18418 
18419 		if (ret == INFINITE)
18420 		{
18421 			if (LIST_NUM(m->TickList) >= 1)
18422 			{
18423 				UINT64 *v = LIST_DATA(m->TickList, 0);
18424 
18425 				ret = (UINT)(*v - now);
18426 			}
18427 		}
18428 	}
18429 	UnlockList(m->TickList);
18430 
18431 	return ret;
18432 }
18433 
18434 // 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)18435 void InjectNewReverseSocketToAccept(SOCK *listen_sock, SOCK *s, IP *client_ip, UINT client_port)
18436 {
18437 	bool ok = false;
18438 	// Validate arguments
18439 	if (listen_sock == NULL || s == NULL)
18440 	{
18441 		return;
18442 	}
18443 
18444 	LockQueue(listen_sock->ReverseAcceptQueue);
18445 	{
18446 		if (listen_sock->CancelAccept == false && listen_sock->Disconnecting == false)
18447 		{
18448 			InsertQueue(listen_sock->ReverseAcceptQueue, s);
18449 
18450 			ok = true;
18451 
18452 			s->ServerMode = true;
18453 			s->IsReverseAcceptedSocket = true;
18454 
18455 			Copy(&s->RemoteIP, client_ip, sizeof(IP));
18456 			s->RemotePort = client_port;
18457 		}
18458 	}
18459 	UnlockQueue(listen_sock->ReverseAcceptQueue);
18460 
18461 	if (ok == false)
18462 	{
18463 		Disconnect(s);
18464 		ReleaseSock(s);
18465 	}
18466 	else
18467 	{
18468 		Set(listen_sock->ReverseAcceptEvent);
18469 	}
18470 }
18471 
18472 // Create a listening socket for the reverse socket
ListenReverse()18473 SOCK *ListenReverse()
18474 {
18475 	SOCK *s = NewSock();
18476 
18477 	s->Type = SOCK_REVERSE_LISTEN;
18478 	s->ListenMode = true;
18479 	s->ReverseAcceptQueue = NewQueue();
18480 	s->ReverseAcceptEvent = NewEvent();
18481 	s->Connected = true;
18482 
18483 	return s;
18484 }
18485 
18486 // Accept on the reverse socket
AcceptReverse(SOCK * s)18487 SOCK *AcceptReverse(SOCK *s)
18488 {
18489 	// Validate arguments
18490 	if (s == NULL || s->Type != SOCK_REVERSE_LISTEN || s->ListenMode == false)
18491 	{
18492 		return NULL;
18493 	}
18494 
18495 	while (true)
18496 	{
18497 		SOCK *ret;
18498 		if (s->Disconnecting || s->CancelAccept)
18499 		{
18500 			return NULL;
18501 		}
18502 
18503 		LockQueue(s->ReverseAcceptQueue);
18504 		{
18505 			ret = GetNext(s->ReverseAcceptQueue);
18506 		}
18507 		UnlockQueue(s->ReverseAcceptQueue);
18508 
18509 		if (ret != NULL)
18510 		{
18511 			StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_AZURE);
18512 
18513 			AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails), "VPN Azure");
18514 
18515 			return ret;
18516 		}
18517 
18518 		Wait(s->ReverseAcceptEvent, INFINITE);
18519 	}
18520 }
18521 
18522 // Start listening on the in-process socket
ListenInProc()18523 SOCK *ListenInProc()
18524 {
18525 	SOCK *s = NewSock();
18526 
18527 	s->Type = SOCK_INPROC;
18528 	s->ListenMode = true;
18529 	s->InProcAcceptQueue = NewQueue();
18530 	s->InProcAcceptEvent = NewEvent();
18531 	s->Connected = true;
18532 
18533 	return s;
18534 }
18535 
18536 // Accept at the in-process socket
AcceptInProc(SOCK * s)18537 SOCK *AcceptInProc(SOCK *s)
18538 {
18539 	// Validate arguments
18540 	if (s == NULL || s->Type != SOCK_INPROC || s->ListenMode == false)
18541 	{
18542 		return NULL;
18543 	}
18544 
18545 	while (true)
18546 	{
18547 		SOCK *ret;
18548 		if (s->Disconnecting || s->CancelAccept)
18549 		{
18550 			return NULL;
18551 		}
18552 
18553 		LockQueue(s->InProcAcceptQueue);
18554 		{
18555 			ret = GetNext(s->InProcAcceptQueue);
18556 		}
18557 		UnlockQueue(s->InProcAcceptQueue);
18558 
18559 		if (ret != NULL)
18560 		{
18561 			StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_INPROC);
18562 
18563 			AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails), "InProc");
18564 
18565 			return ret;
18566 		}
18567 
18568 		Wait(s->InProcAcceptEvent, INFINITE);
18569 	}
18570 }
18571 
18572 // Connect by the in-process socket
ConnectInProc(SOCK * listen_sock,IP * client_ip,UINT client_port,IP * server_ip,UINT server_port)18573 SOCK *ConnectInProc(SOCK *listen_sock, IP *client_ip, UINT client_port, IP *server_ip, UINT server_port)
18574 {
18575 	SOCK *ss, *sc;
18576 	bool ok = false;
18577 	// Validate arguments
18578 	if (listen_sock == NULL || listen_sock->Type != SOCK_INPROC || listen_sock->ListenMode == false)
18579 	{
18580 		return NULL;
18581 	}
18582 
18583 	NewSocketPair(&sc, &ss, client_ip, client_port, server_ip, server_port);
18584 
18585 	LockQueue(listen_sock->InProcAcceptQueue);
18586 	{
18587 		if (listen_sock->CancelAccept == false && listen_sock->Disconnecting == false)
18588 		{
18589 			InsertQueue(listen_sock->InProcAcceptQueue, ss);
18590 
18591 			ok = true;
18592 		}
18593 	}
18594 	UnlockQueue(listen_sock->InProcAcceptQueue);
18595 
18596 	if (ok == false)
18597 	{
18598 		ReleaseSock(ss);
18599 		ReleaseSock(sc);
18600 		return NULL;
18601 	}
18602 
18603 	Set(listen_sock->InProcAcceptEvent);
18604 
18605 	return sc;
18606 }
18607 
18608 // Creating a new socket pair
NewSocketPair(SOCK ** client,SOCK ** server,IP * client_ip,UINT client_port,IP * server_ip,UINT server_port)18609 void NewSocketPair(SOCK **client, SOCK **server, IP *client_ip, UINT client_port, IP *server_ip, UINT server_port)
18610 {
18611 	IP iptmp;
18612 	TUBE *t1, *t2;
18613 	SOCK *sc, *ss;
18614 	SOCK_EVENT *e1, *e2;
18615 	// Validate arguments
18616 	if (client == NULL || server == NULL)
18617 	{
18618 		return;
18619 	}
18620 
18621 	SetIP(&iptmp, 127, 0, 0, 1);
18622 	if (client_ip == NULL)
18623 	{
18624 		client_ip = &iptmp;
18625 	}
18626 	if (server_ip == NULL)
18627 	{
18628 		server_ip = &iptmp;
18629 	}
18630 
18631 	// Creating a tube
18632 	NewTubePair(&t1, &t2, 0);	// t1: C -> S,  t2: S -> C
18633 
18634 	// Creating a socket event
18635 	e1 = NewSockEvent();
18636 	e2 = NewSockEvent();
18637 
18638 	SetTubeSockEvent(t1, e1);
18639 	SetTubeSockEvent(t2, e2);
18640 
18641 	sc = NewInProcSocket(t1, t2);
18642 	ss = NewInProcSocket(t2, t1);
18643 
18644 	Copy(&sc->LocalIP, client_ip, sizeof(IP));
18645 	sc->LocalPort = client_port;
18646 	Copy(&sc->RemoteIP, server_ip, sizeof(IP));
18647 	sc->RemotePort = server_port;
18648 
18649 	Copy(&ss->LocalIP, server_ip, sizeof(IP));
18650 	ss->LocalPort = server_port;
18651 	Copy(&ss->RemoteIP, client_ip, sizeof(IP));
18652 	ss->RemotePort = client_port;
18653 
18654 	sc->Connected = true;
18655 	sc->ServerMode = false;
18656 
18657 	ss->Connected = true;
18658 	ss->ServerMode = true;
18659 
18660 	SetTimeout(sc, INFINITE);
18661 	SetTimeout(ss, INFINITE);
18662 
18663 	QuerySocketInformation(sc);
18664 	QuerySocketInformation(ss);
18665 
18666 	ReleaseSockEvent(e1);
18667 	ReleaseSockEvent(e2);
18668 
18669 	ReleaseTube(t1);
18670 	ReleaseTube(t2);
18671 
18672 	*client = sc;
18673 	*server = ss;
18674 }
18675 
18676 // Creating a new in-process socket
NewInProcSocket(TUBE * tube_send,TUBE * tube_recv)18677 SOCK *NewInProcSocket(TUBE *tube_send, TUBE *tube_recv)
18678 {
18679 	SOCK *s;
18680 	// Validate arguments
18681 	if (tube_recv == NULL || tube_send == NULL)
18682 	{
18683 		return NULL;
18684 	}
18685 
18686 	s = NewSock();
18687 
18688 	s->Type = SOCK_INPROC;
18689 
18690 	s->SendTube = tube_send;
18691 	s->RecvTube = tube_recv;
18692 
18693 	AddRef(tube_send->Ref);
18694 	AddRef(tube_recv->Ref);
18695 
18696 	s->InProcRecvFifo = NewFifo();
18697 
18698 	s->Connected = true;
18699 
18700 	return s;
18701 }
18702 
18703 // Transmission process for the in-process socket
SendInProc(SOCK * sock,void * data,UINT size)18704 UINT SendInProc(SOCK *sock, void *data, UINT size)
18705 {
18706 	if (sock == NULL || sock->Type != SOCK_INPROC || sock->Disconnecting || sock->Connected == false)
18707 	{
18708 		return 0;
18709 	}
18710 
18711 	if (IsTubeConnected(sock->SendTube) == false)
18712 	{
18713 		return 0;
18714 	}
18715 
18716 	if (TubeSend(sock->SendTube, data, size, NULL) == false)
18717 	{
18718 		return 0;
18719 	}
18720 
18721 	return size;
18722 }
18723 
18724 // Receiving process for the in-process socket
RecvInProc(SOCK * sock,void * data,UINT size)18725 UINT RecvInProc(SOCK *sock, void *data, UINT size)
18726 {
18727 	FIFO *f;
18728 	UINT ret;
18729 	UINT timeout;
18730 	UINT64 giveup_time;
18731 	TUBEDATA *d = NULL;
18732 	if (sock == NULL || sock->Type != SOCK_INPROC || sock->Disconnecting || sock->Connected == false)
18733 	{
18734 		return 0;
18735 	}
18736 
18737 	if (IsTubeConnected(sock->SendTube) == false)
18738 	{
18739 		return 0;
18740 	}
18741 
18742 	f = sock->InProcRecvFifo;
18743 	if (f == NULL)
18744 	{
18745 		return 0;
18746 	}
18747 
18748 	// If there is data in the FIFO, return it immediately
18749 	ret = ReadFifo(f, data, size);
18750 	if (ret != 0)
18751 	{
18752 		return ret;
18753 	}
18754 
18755 	timeout = GetTimeout(sock);
18756 
18757 	giveup_time = Tick64() + (UINT)timeout;
18758 
18759 	// When there is no data in the FIFO, read the next data from the tube
18760 	d = NULL;
18761 
18762 	while (true)
18763 	{
18764 		UINT64 now = 0;
18765 		UINT interval;
18766 
18767 		if (sock->AsyncMode == false)
18768 		{
18769 			now = Tick64();
18770 
18771 			if (now >= giveup_time)
18772 			{
18773 				break;
18774 			}
18775 		}
18776 
18777 		d = TubeRecvAsync(sock->RecvTube);
18778 
18779 		if (d != NULL)
18780 		{
18781 			break;
18782 		}
18783 
18784 		if (IsTubeConnected(sock->RecvTube) == false)
18785 		{
18786 			break;
18787 		}
18788 
18789 		if (sock->AsyncMode)
18790 		{
18791 			break;
18792 		}
18793 
18794 		interval = (UINT)(giveup_time - now);
18795 
18796 		Wait(sock->RecvTube->Event, interval);
18797 	}
18798 
18799 	if (d == NULL)
18800 	{
18801 		if (IsTubeConnected(sock->RecvTube) == false)
18802 		{
18803 			return 0;
18804 		}
18805 
18806 		if (sock->AsyncMode == false)
18807 		{
18808 			// If a timeout occurs in synchronous mode, disconnect ir
18809 			Disconnect(sock);
18810 
18811 			return 0;
18812 		}
18813 		else
18814 		{
18815 			// If a timeout occurs in asynchronous mode, returns the blocking error
18816 			return SOCK_LATER;
18817 		}
18818 	}
18819 	else
18820 	{
18821 		// If the received data is larger than the requested size, write the rest to FIFO
18822 		if (d->DataSize > size)
18823 		{
18824 			WriteFifo(f, ((UCHAR *)d->Data) + size, d->DataSize - size);
18825 			ret = size;
18826 		}
18827 		else
18828 		{
18829 			ret = d->DataSize;
18830 		}
18831 
18832 		Copy(data, d->Data, ret);
18833 
18834 		FreeTubeData(d);
18835 
18836 		return ret;
18837 	}
18838 }
18839 
18840 // Wait for the arrival of data on multiple tubes
WaitForTubes(TUBE ** tubes,UINT num,UINT timeout)18841 void WaitForTubes(TUBE **tubes, UINT num, UINT timeout)
18842 {
18843 	// Validate arguments
18844 	if (num != 0 && tubes == NULL)
18845 	{
18846 		return;
18847 	}
18848 	if (timeout == 0)
18849 	{
18850 		return;
18851 	}
18852 	if (num == 0)
18853 	{
18854 		SleepThread(timeout);
18855 		return;
18856 	}
18857 
18858 #ifdef	OS_WIN32
18859 	Win32WaitForTubes(tubes, num, timeout);
18860 #else	// OS_WIN32
18861 	UnixWaitForTubes(tubes, num, timeout);
18862 #endif	// OS_WIN32
18863 }
18864 
18865 #ifdef	OS_WIN32
Win32WaitForTubes(TUBE ** tubes,UINT num,UINT timeout)18866 void Win32WaitForTubes(TUBE **tubes, UINT num, UINT timeout)
18867 {
18868 	HANDLE array[MAXIMUM_WAIT_OBJECTS];
18869 	UINT i;
18870 
18871 	Zero(array, sizeof(array));
18872 
18873 	for (i = 0; i < num; i++)
18874 	{
18875 		TUBE *t = tubes[i];
18876 
18877 		array[i] = t->Event->pData;
18878 	}
18879 
18880 	if (num == 1)
18881 	{
18882 		WaitForSingleObject(array[0], timeout);
18883 	}
18884 	else
18885 	{
18886 		WaitForMultipleObjects(num, array, false, timeout);
18887 	}
18888 }
18889 #else	// OS_WIN32
UnixWaitForTubes(TUBE ** tubes,UINT num,UINT timeout)18890 void UnixWaitForTubes(TUBE **tubes, UINT num, UINT timeout)
18891 {
18892 	int *fds;
18893 	UINT i;
18894 	char tmp[MAX_SIZE];
18895 	bool any_of_tubes_are_readable = false;
18896 
18897 	fds = ZeroMalloc(sizeof(int) * num);
18898 
18899 	for (i = 0; i < num; i++)
18900 	{
18901 		fds[i] = tubes[i]->SockEvent->pipe_read;
18902 
18903 		if (tubes[i]->SockEvent->current_pipe_data != 0)
18904 		{
18905 			any_of_tubes_are_readable = true;
18906 		}
18907 	}
18908 
18909 	if (any_of_tubes_are_readable == false)
18910 	{
18911 		UnixSelectInner(num, fds, 0, NULL, timeout);
18912 	}
18913 
18914 	for (i = 0; i < num; i++)
18915 	{
18916 		int fd = fds[i];
18917 		int readret;
18918 
18919 		tubes[i]->SockEvent->current_pipe_data = 0;
18920 
18921 		do
18922 		{
18923 			readret = read(fd, tmp, sizeof(tmp));
18924 		}
18925 		while (readret >= 1);
18926 	}
18927 
18928 	Free(fds);
18929 }
18930 #endif	// OS_WIN32
18931 
18932 // Creating a Tube Flush List
NewTubeFlushList()18933 TUBE_FLUSH_LIST *NewTubeFlushList()
18934 {
18935 	TUBE_FLUSH_LIST *f = ZeroMalloc(sizeof(TUBE_FLUSH_LIST));
18936 
18937 	f->List = NewListFast(NULL);
18938 
18939 	return f;
18940 }
18941 
18942 // Release of the Tube Flush List
FreeTubeFlushList(TUBE_FLUSH_LIST * f)18943 void FreeTubeFlushList(TUBE_FLUSH_LIST *f)
18944 {
18945 	UINT i;
18946 	// Validate arguments
18947 	if (f == NULL)
18948 	{
18949 		return;
18950 	}
18951 
18952 	for (i = 0; i < LIST_NUM(f->List); i++)
18953 	{
18954 		TUBE *t = LIST_DATA(f->List, i);
18955 
18956 		ReleaseTube(t);
18957 	}
18958 
18959 	ReleaseList(f->List);
18960 
18961 	Free(f);
18962 }
18963 
18964 // Add a Tube to the Tube Flush List
AddTubeToFlushList(TUBE_FLUSH_LIST * f,TUBE * t)18965 void AddTubeToFlushList(TUBE_FLUSH_LIST *f, TUBE *t)
18966 {
18967 	// Validate arguments
18968 	if (f == NULL || t == NULL)
18969 	{
18970 		return;
18971 	}
18972 
18973 	if (t->IsInFlushList)
18974 	{
18975 		return;
18976 	}
18977 
18978 	if (IsInList(f->List, t) == false)
18979 	{
18980 		Add(f->List, t);
18981 
18982 		AddRef(t->Ref);
18983 
18984 		t->IsInFlushList = true;
18985 	}
18986 }
18987 
18988 // Flush the all tubes in the Tube Flush List
FlushTubeFlushList(TUBE_FLUSH_LIST * f)18989 void FlushTubeFlushList(TUBE_FLUSH_LIST *f)
18990 {
18991 	UINT i;
18992 	// Validate arguments
18993 	if (f == NULL)
18994 	{
18995 		return;
18996 	}
18997 
18998 	for (i = 0; i < LIST_NUM(f->List); i++)
18999 	{
19000 		TUBE *t = LIST_DATA(f->List, i);
19001 
19002 		TubeFlush(t);
19003 		t->IsInFlushList = false;
19004 
19005 		ReleaseTube(t);
19006 	}
19007 
19008 	DeleteAll(f->List);
19009 }
19010 
19011 // Store the error value into PACK
PackError(UINT error)19012 PACK *PackError(UINT error)
19013 {
19014 	PACK *p;
19015 
19016 	p = NewPack();
19017 	PackAddInt(p, "error", error);
19018 
19019 	return p;
19020 }
19021 
19022 // Get the error value from PACK
GetErrorFromPack(PACK * p)19023 UINT GetErrorFromPack(PACK *p)
19024 {
19025 	// Validate arguments
19026 	if (p == NULL)
19027 	{
19028 		return 0;
19029 	}
19030 
19031 	return PackGetInt(p, "error");
19032 }
19033 
19034 // Create an entry to PACK for the dummy
CreateDummyValue(PACK * p)19035 void CreateDummyValue(PACK *p)
19036 {
19037 	UINT size;
19038 	UCHAR *buf;
19039 	// Validate arguments
19040 	if (p == NULL)
19041 	{
19042 		return;
19043 	}
19044 
19045 	size = Rand32() % HTTP_PACK_RAND_SIZE_MAX;
19046 	buf = Malloc(size);
19047 	Rand(buf, size);
19048 
19049 	PackAddData(p, "pencore", buf, size);
19050 
19051 	Free(buf);
19052 }
19053 
19054 // Receive a line
RecvLine(SOCK * s,UINT max_size)19055 char *RecvLine(SOCK *s, UINT max_size)
19056 {
19057 	BUF *b;
19058 	char c;
19059 	char *str;
19060 	// Validate arguments
19061 	if (s == NULL || max_size == 0)
19062 	{
19063 		return NULL;
19064 	}
19065 
19066 	b = NewBuf();
19067 	while (true)
19068 	{
19069 		UCHAR *buf;
19070 		if (RecvAll(s, &c, sizeof(c), s->SecureMode) == false)
19071 		{
19072 			FreeBuf(b);
19073 			return NULL;
19074 		}
19075 		WriteBuf(b, &c, sizeof(c));
19076 		buf = (UCHAR *)b->Buf;
19077 		if (b->Size > max_size)
19078 		{
19079 			FreeBuf(b);
19080 			return NULL;
19081 		}
19082 		if (b->Size >= 1)
19083 		{
19084 			if (buf[b->Size - 1] == '\n')
19085 			{
19086 				b->Size--;
19087 				if (b->Size >= 1)
19088 				{
19089 					if (buf[b->Size - 1] == '\r')
19090 					{
19091 						b->Size--;
19092 					}
19093 				}
19094 				str = Malloc(b->Size + 1);
19095 				Copy(str, b->Buf, b->Size);
19096 				str[b->Size] = 0;
19097 				FreeBuf(b);
19098 
19099 				return str;
19100 			}
19101 		}
19102 	}
19103 }
19104 
19105 // Receive a PACK
RecvPack(SOCK * s)19106 PACK *RecvPack(SOCK *s)
19107 {
19108 	PACK *p;
19109 	BUF *b;
19110 	void *data;
19111 	UINT sz;
19112 	// Validate arguments
19113 	if (s == NULL || s->Type != SOCK_TCP)
19114 	{
19115 		return false;
19116 	}
19117 
19118 	if (RecvAll(s, &sz, sizeof(UINT), s->SecureMode) == false)
19119 	{
19120 		return false;
19121 	}
19122 	sz = Endian32(sz);
19123 	if (sz > MAX_PACK_SIZE)
19124 	{
19125 		return false;
19126 	}
19127 	data = MallocEx(sz, true);
19128 	if (RecvAll(s, data, sz, s->SecureMode) == false)
19129 	{
19130 		Free(data);
19131 		return false;
19132 	}
19133 
19134 	b = NewBuf();
19135 	WriteBuf(b, data, sz);
19136 	SeekBuf(b, 0, 0);
19137 	p = BufToPack(b);
19138 	FreeBuf(b);
19139 	Free(data);
19140 
19141 	return p;
19142 }
19143 
19144 // Receive a PACK (with checking the hash)
RecvPackWithHash(SOCK * s)19145 PACK *RecvPackWithHash(SOCK *s)
19146 {
19147 	PACK *p;
19148 	BUF *b;
19149 	void *data;
19150 	UINT sz;
19151 	UCHAR hash1[SHA1_SIZE];
19152 	UCHAR hash2[SHA1_SIZE];
19153 	// Validate arguments
19154 	if (s == NULL || s->Type != SOCK_TCP)
19155 	{
19156 		return false;
19157 	}
19158 
19159 	if (RecvAll(s, &sz, sizeof(UINT), s->SecureMode) == false)
19160 	{
19161 		return false;
19162 	}
19163 	sz = Endian32(sz);
19164 	if (sz > MAX_PACK_SIZE)
19165 	{
19166 		return false;
19167 	}
19168 	data = MallocEx(sz, true);
19169 	if (RecvAll(s, data, sz, s->SecureMode) == false)
19170 	{
19171 		Free(data);
19172 		return false;
19173 	}
19174 
19175 	Sha1(hash1, data, sz);
19176 	if (RecvAll(s, hash2, sizeof(hash2), s->SecureMode) == false)
19177 	{
19178 		Free(data);
19179 		return false;
19180 	}
19181 
19182 	if (Cmp(hash1, hash2, SHA1_SIZE) != 0)
19183 	{
19184 		Free(data);
19185 		return false;
19186 	}
19187 
19188 	b = NewBuf();
19189 	WriteBuf(b, data, sz);
19190 	SeekBuf(b, 0, 0);
19191 	p = BufToPack(b);
19192 	FreeBuf(b);
19193 	Free(data);
19194 
19195 	return p;
19196 }
19197 
19198 // Send a PACK
SendPack(SOCK * s,PACK * p)19199 bool SendPack(SOCK *s, PACK *p)
19200 {
19201 	BUF *b;
19202 	UINT sz;
19203 	// Validate arguments
19204 	if (s == NULL || p == NULL || s->Type != SOCK_TCP)
19205 	{
19206 		return false;
19207 	}
19208 
19209 	b = PackToBuf(p);
19210 	sz = Endian32(b->Size);
19211 
19212 	SendAdd(s, &sz, sizeof(UINT));
19213 	SendAdd(s, b->Buf, b->Size);
19214 	FreeBuf(b);
19215 
19216 	return SendNow(s, s->SecureMode);
19217 }
19218 
19219 // Send a Pack (with adding a hash)
SendPackWithHash(SOCK * s,PACK * p)19220 bool SendPackWithHash(SOCK *s, PACK *p)
19221 {
19222 	BUF *b;
19223 	UINT sz;
19224 	UCHAR hash[SHA1_SIZE];
19225 	// Validate arguments
19226 	if (s == NULL || p == NULL || s->Type != SOCK_TCP)
19227 	{
19228 		return false;
19229 	}
19230 
19231 	b = PackToBuf(p);
19232 	sz = Endian32(b->Size);
19233 
19234 	SendAdd(s, &sz, sizeof(UINT));
19235 	SendAdd(s, b->Buf, b->Size);
19236 	Sha1(hash, b->Buf, b->Size);
19237 	SendAdd(s, hash, sizeof(hash));
19238 
19239 	FreeBuf(b);
19240 
19241 	return SendNow(s, s->SecureMode);
19242 }
19243 
19244 // Get SNI name from the SSL packet
GetSniNameFromSslPacket(UCHAR * packet_buf,UINT packet_size,char * sni,UINT sni_size)19245 bool GetSniNameFromSslPacket(UCHAR *packet_buf, UINT packet_size, char *sni, UINT sni_size)
19246 {
19247 	BUF *buf;
19248 	bool ret = false;
19249 	UCHAR content_type;
19250 	USHORT version;
19251 	USHORT handshake_length;
19252 
19253 	// Validate arguments
19254 	if (packet_buf == NULL || packet_size <= 11)
19255 	{
19256 		return false;
19257 	}
19258 
19259 	if (!(packet_buf[0] == 0x16 && packet_buf[1] >= 0x03 &&
19260 	        packet_buf[5] == 0x01 && packet_buf[6] == 0x00 &&
19261 	        packet_buf[9] >= 0x03))
19262 	{
19263 		return false;
19264 	}
19265 
19266 	buf = NewBufFromMemory(packet_buf, packet_size);
19267 
19268 	if (ReadBuf(buf, &content_type, sizeof(UCHAR)) == sizeof(UCHAR) &&
19269 	        ReadBuf(buf, &version, sizeof(USHORT)) == sizeof(USHORT) &&
19270 	        ReadBuf(buf, &handshake_length, sizeof(USHORT)) == sizeof(USHORT))
19271 	{
19272 		version = Endian16(version);
19273 		handshake_length = Endian16(handshake_length);
19274 
19275 		if (content_type == 0x16 && version >= 0x0301)
19276 		{
19277 			UCHAR *handshake_data = Malloc(handshake_length);
19278 
19279 			if (ReadBuf(buf, handshake_data, handshake_length) == handshake_length)
19280 			{
19281 				BUF *buf2 = NewBufFromMemory(handshake_data, handshake_length);
19282 				USHORT handshake_type;
19283 				USHORT handshake_length_2;
19284 
19285 				if (ReadBuf(buf2, &handshake_type, sizeof(USHORT)) == sizeof(USHORT) &&
19286 				        ReadBuf(buf2, &handshake_length_2, sizeof(USHORT)) == sizeof(USHORT))
19287 				{
19288 					handshake_type = Endian16(handshake_type);
19289 					handshake_length_2 = Endian16(handshake_length_2);
19290 
19291 					if (handshake_type == 0x0100 && handshake_length_2 <= (handshake_length - 4))
19292 					{
19293 						USHORT version2;
19294 
19295 						if (ReadBuf(buf2, &version2, sizeof(USHORT)) == sizeof(USHORT))
19296 						{
19297 							version2 = Endian16(version2);
19298 
19299 							if (version2 >= 0x0301)
19300 							{
19301 								UCHAR rand[32];
19302 
19303 								if (ReadBuf(buf2, rand, sizeof(rand)) == sizeof(rand))
19304 								{
19305 									UCHAR session_id_len;
19306 
19307 									if (ReadBuf(buf2, &session_id_len, sizeof(UCHAR)) == sizeof(UCHAR))
19308 									{
19309 										if (ReadBuf(buf2, NULL, session_id_len) == session_id_len)
19310 										{
19311 											USHORT cipher_len;
19312 
19313 											if (ReadBuf(buf2, &cipher_len, sizeof(USHORT)) == sizeof(USHORT))
19314 											{
19315 												cipher_len = Endian16(cipher_len);
19316 
19317 												if (ReadBuf(buf2, NULL, cipher_len) == cipher_len)
19318 												{
19319 													UCHAR comps_len;
19320 
19321 													if (ReadBuf(buf2, &comps_len, sizeof(UCHAR)) == sizeof(UCHAR))
19322 													{
19323 														if (ReadBuf(buf2, NULL, comps_len) == comps_len)
19324 														{
19325 															USHORT ext_length;
19326 
19327 															if (ReadBuf(buf2, &ext_length, sizeof(USHORT)) == sizeof(USHORT))
19328 															{
19329 																UCHAR *ext_buf;
19330 
19331 																ext_length = Endian16(ext_length);
19332 
19333 																ext_buf = Malloc(ext_length);
19334 
19335 																if (ReadBuf(buf2, ext_buf, ext_length) == ext_length)
19336 																{
19337 																	BUF *ebuf = NewBufFromMemory(ext_buf, ext_length);
19338 
19339 																	while (ret == false)
19340 																	{
19341 																		USHORT type;
19342 																		USHORT data_len;
19343 																		UCHAR *data;
19344 
19345 																		if (ReadBuf(ebuf, &type, sizeof(USHORT)) != sizeof(USHORT))
19346 																		{
19347 																			break;
19348 																		}
19349 
19350 																		if (ReadBuf(ebuf, &data_len, sizeof(USHORT)) != sizeof(USHORT))
19351 																		{
19352 																			break;
19353 																		}
19354 
19355 																		type = Endian16(type);
19356 																		data_len = Endian16(data_len);
19357 
19358 																		data = Malloc(data_len);
19359 
19360 																		if (ReadBuf(ebuf, data, data_len) != data_len)
19361 																		{
19362 																			Free(data);
19363 																			break;
19364 																		}
19365 
19366 																		if (type == 0x0000)
19367 																		{
19368 																			BUF *dbuf = NewBufFromMemory(data, data_len);
19369 
19370 																			USHORT total_len;
19371 
19372 																			if (ReadBuf(dbuf, &total_len, sizeof(USHORT)) == sizeof(USHORT))
19373 																			{
19374 																				UCHAR c;
19375 																				total_len = Endian16(total_len);
19376 
19377 																				if (ReadBuf(dbuf, &c, sizeof(UCHAR)) == sizeof(UCHAR))
19378 																				{
19379 																					if (c == 0)
19380 																					{
19381 																						USHORT name_len;
19382 
19383 																						if (ReadBuf(dbuf, &name_len, sizeof(USHORT)) == sizeof(USHORT))
19384 																						{
19385 																							char *name_buf;
19386 																							name_len = Endian16(name_len);
19387 
19388 																							name_buf = ZeroMalloc(name_len + 1);
19389 
19390 																							if (ReadBuf(dbuf, name_buf, name_len) == name_len)
19391 																							{
19392 																								if (StrLen(name_buf) >= 1)
19393 																								{
19394 																									ret = true;
19395 
19396 																									StrCpy(sni, sni_size, name_buf);
19397 																								}
19398 																							}
19399 
19400 																							Free(name_buf);
19401 																						}
19402 																					}
19403 																				}
19404 																			}
19405 
19406 																			FreeBuf(dbuf);
19407 																		}
19408 
19409 																		Free(data);
19410 																	}
19411 
19412 																	FreeBuf(ebuf);
19413 																}
19414 
19415 																Free(ext_buf);
19416 															}
19417 														}
19418 													}
19419 												}
19420 											}
19421 										}
19422 									}
19423 								}
19424 							}
19425 						}
19426 					}
19427 				}
19428 
19429 				FreeBuf(buf2);
19430 			}
19431 
19432 			Free(handshake_data);
19433 		}
19434 	}
19435 
19436 	FreeBuf(buf);
19437 
19438 	if (ret)
19439 	{
19440 		Trim(sni);
19441 
19442 		if (IsEmptyStr(sni))
19443 		{
19444 			ret = false;
19445 		}
19446 	}
19447 
19448 	return ret;
19449 }
19450 
SetDhParam(DH_CTX * dh)19451 void SetDhParam(DH_CTX *dh)
19452 {
19453 	if (dh_param)
19454 	{
19455 		DhFree(dh_param);
19456 	}
19457 
19458 	dh_param = dh;
19459 }
19460