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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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), ¤t_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(¤t_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, ¤t_glocal_ipv4, sizeof(IP));
15650 }
15651 else
15652 {
15653 Copy(ip, ¤t_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(¤t_glocal_ipv4, ip, sizeof(IP));
15990 }
15991 else
15992 {
15993 Copy(¤t_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