1 // SoftEther VPN Source Code - Stable Edition Repository
2 // Mayaqua Kernel
3 //
4 // SoftEther VPN Server, Client and Bridge are free software under the Apache License, Version 2.0.
5 //
6 // Copyright (c) Daiyuu Nobori.
7 // Copyright (c) SoftEther VPN Project, University of Tsukuba, Japan.
8 // Copyright (c) SoftEther Corporation.
9 // Copyright (c) all contributors on SoftEther VPN project in GitHub.
10 //
11 // All Rights Reserved.
12 //
13 // http://www.softether.org/
14 //
15 // This stable branch is officially managed by Daiyuu Nobori, the owner of SoftEther VPN Project.
16 // Pull requests should be sent to the Developer Edition Master Repository on https://github.com/SoftEtherVPN/SoftEtherVPN
17 // Contributors:
18 // - nattoheaven (https://github.com/nattoheaven)
19 //
20 // License: The Apache License, Version 2.0
21 // https://www.apache.org/licenses/LICENSE-2.0
22 //
23 // DISCLAIMER
24 // ==========
25 //
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
29 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
30 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
31 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32 // SOFTWARE.
33 //
34 // THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN, UNDER
35 // JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY, MERGE, PUBLISH,
36 // DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS SOFTWARE, THAT ANY
37 // JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS SOFTWARE OR ITS CONTENTS,
38 // AGAINST US (SOFTETHER PROJECT, SOFTETHER CORPORATION, DAIYUU NOBORI OR OTHER
39 // SUPPLIERS), OR ANY JURIDICAL DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND
40 // OF USING, COPYING, MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING,
41 // AND/OR SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
42 // CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO EXCLUSIVE
43 // JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO, JAPAN. YOU MUST WAIVE
44 // ALL DEFENSES OF LACK OF PERSONAL JURISDICTION AND FORUM NON CONVENIENS.
45 // PROCESS MAY BE SERVED ON EITHER PARTY IN THE MANNER AUTHORIZED BY APPLICABLE
46 // LAW OR COURT RULE.
47 //
48 // USE ONLY IN JAPAN. DO NOT USE THIS SOFTWARE IN ANOTHER COUNTRY UNLESS YOU HAVE
49 // A CONFIRMATION THAT THIS SOFTWARE DOES NOT VIOLATE ANY CRIMINAL LAWS OR CIVIL
50 // RIGHTS IN THAT PARTICULAR COUNTRY. USING THIS SOFTWARE IN OTHER COUNTRIES IS
51 // COMPLETELY AT YOUR OWN RISK. THE SOFTETHER VPN PROJECT HAS DEVELOPED AND
52 // DISTRIBUTED THIS SOFTWARE TO COMPLY ONLY WITH THE JAPANESE LAWS AND EXISTING
53 // CIVIL RIGHTS INCLUDING PATENTS WHICH ARE SUBJECTS APPLY IN JAPAN. OTHER
54 // COUNTRIES' LAWS OR CIVIL RIGHTS ARE NONE OF OUR CONCERNS NOR RESPONSIBILITIES.
55 // WE HAVE NEVER INVESTIGATED ANY CRIMINAL REGULATIONS, CIVIL LAWS OR
56 // INTELLECTUAL PROPERTY RIGHTS INCLUDING PATENTS IN ANY OF OTHER 200+ COUNTRIES
57 // AND TERRITORIES. BY NATURE, THERE ARE 200+ REGIONS IN THE WORLD, WITH
58 // DIFFERENT LAWS. IT IS IMPOSSIBLE TO VERIFY EVERY COUNTRIES' LAWS, REGULATIONS
59 // AND CIVIL RIGHTS TO MAKE THE SOFTWARE COMPLY WITH ALL COUNTRIES' LAWS BY THE
60 // PROJECT. EVEN IF YOU WILL BE SUED BY A PRIVATE ENTITY OR BE DAMAGED BY A
61 // PUBLIC SERVANT IN YOUR COUNTRY, THE DEVELOPERS OF THIS SOFTWARE WILL NEVER BE
62 // LIABLE TO RECOVER OR COMPENSATE SUCH DAMAGES, CRIMINAL OR CIVIL
63 // RESPONSIBILITIES. NOTE THAT THIS LINE IS NOT LICENSE RESTRICTION BUT JUST A
64 // STATEMENT FOR WARNING AND DISCLAIMER.
65 //
66 // READ AND UNDERSTAND THE 'WARNING.TXT' FILE BEFORE USING THIS SOFTWARE.
67 // SOME SOFTWARE PROGRAMS FROM THIRD PARTIES ARE INCLUDED ON THIS SOFTWARE WITH
68 // LICENSE CONDITIONS WHICH ARE DESCRIBED ON THE 'THIRD_PARTY.TXT' FILE.
69 //
70 //
71 // SOURCE CODE CONTRIBUTION
72 // ------------------------
73 //
74 // Your contribution to SoftEther VPN Project is much appreciated.
75 // Please send patches to us through GitHub.
76 // Read the SoftEther VPN Patch Acceptance Policy in advance:
77 // http://www.softether.org/5-download/src/9.patch
78 //
79 //
80 // DEAR SECURITY EXPERTS
81 // ---------------------
82 //
83 // If you find a bug or a security vulnerability please kindly inform us
84 // about the problem immediately so that we can fix the security problem
85 // to protect a lot of users around the world as soon as possible.
86 //
87 // Our e-mail address for security reports is:
88 // softether-vpn-security [at] softether.org
89 //
90 // Please note that the above e-mail address is not a technical support
91 // inquiry address. If you need technical assistance, please visit
92 // http://www.softether.org/ and ask your question on the users forum.
93 //
94 // Thank you for your cooperation.
95 //
96 //
97 // NO MEMORY OR RESOURCE LEAKS
98 // ---------------------------
99 //
100 // The memory-leaks and resource-leaks verification under the stress
101 // test has been passed before release this source code.
102
103
104 // Network.c
105 // Network communication module
106
107 #include <GlobalConst.h>
108
109 #define ENCRYPT_C
110 #define NETWORK_C
111
112 #define __WINCRYPT_H__
113
114 #ifdef WIN32
115 // Include windows.h for Socket API
116 #define _WIN32_WINNT 0x0502
117 #define WINVER 0x0502
118 #include <Ws2tcpip.h>
119 #include <Wspiapi.h>
120 #include <winsock2.h>
121 #include <windows.h>
122 #include <Iphlpapi.h>
123 #include <ws2ipdef.h>
124 #include <netioapi.h>
125 #include <Icmpapi.h>
126 #endif // WIN32
127
128 #include <stdio.h>
129 #include <stdlib.h>
130 #include <string.h>
131 #include <wchar.h>
132 #include <stdarg.h>
133 #include <time.h>
134 #include <openssl/ssl.h>
135 #include <openssl/err.h>
136 #include <openssl/rand.h>
137 #include <openssl/engine.h>
138 #include <openssl/bio.h>
139 #include <openssl/x509.h>
140 #include <openssl/pkcs7.h>
141 #include <openssl/pkcs12.h>
142 #include <openssl/rc4.h>
143 #include <openssl/md5.h>
144 #include <openssl/sha.h>
145 #include <Mayaqua/Mayaqua.h>
146 #ifdef UNIX_MACOS
147 #include <sys/event.h>
148 #endif // UNIX_MACOS
149
150 #ifdef OS_WIN32
151 NETWORK_WIN32_FUNCTIONS *w32net;
152 struct ROUTE_CHANGE_DATA
153 {
154 OVERLAPPED Overlapped;
155 HANDLE Handle;
156 UINT NumCalled;
157 };
158 #endif // OS_WIN32
159
160 // Whether the blocking occurs in SSL
161 #if defined(UNIX_BSD) || defined(UNIX_MACOS)
162 #define FIX_SSL_BLOCKING
163 #endif
164
165 // IPV6_V6ONLY constant
166 #ifdef UNIX_LINUX
167 #ifndef IPV6_V6ONLY
168 #define IPV6_V6ONLY 26
169 #endif // IPV6_V6ONLY
170 #endif // UNIX_LINUX
171
172 #ifdef UNIX_SOLARIS
173 #ifndef IPV6_V6ONLY
174 #define IPV6_V6ONLY 0x27
175 #endif // IPV6_V6ONLY
176 #endif // UNIX_SOLARIS
177
178
179
180 // HTTP constant
181 static char http_404_str[] = "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n<HTML><HEAD>\r\n<TITLE>404 Not Found</TITLE>\r\n</HEAD><BODY>\r\n<H1>Not Found</H1>\r\nThe requested URL $TARGET$ was not found on this server.<P>\r\n<HR>\r\n<ADDRESS>HTTP Server at $HOST$ Port $PORT$</ADDRESS>\r\n</BODY></HTML>\r\n";
182 static char http_403_str[] = "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n<HTML><HEAD>\r\n<TITLE>403 Forbidden</TITLE>\r\n</HEAD><BODY>\r\n<H1>Forbidden</H1>\r\nYou don't have permission to access $TARGET$\r\non this server.<P>\r\n<HR>\r\n<ADDRESS>HTTP Server at $HOST$ Port $PORT$</ADDRESS>\r\n</BODY></HTML>\r\n";
183 static char http_500_str[] = "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n<HTML><HEAD>\r\n<TITLE>500 Server Error</TITLE>\r\n</HEAD><BODY>\r\n<H1>Server Error</H1>\r\nServer Error<P>\r\n<HR>\r\n<ADDRESS>HTTP Server at $HOST$ Port $PORT$</ADDRESS>\r\n</BODY></HTML>\r\n";
184 static char http_501_str[] = "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n<HTML><HEAD>\r\n<TITLE>501 Method Not Implemented</TITLE>\r\n</HEAD><BODY>\r\n<H1>Method Not Implemented</H1>\r\n$METHOD$ to $TARGET$ not supported.<P>\r\nInvalid method in request $METHOD$ $TARGET$ $VERSION$<P>\r\n<HR>\r\n<ADDRESS>HTTP Server at $HOST$ Port $PORT$</ADDRESS>\r\n</BODY></HTML>\r\n";
185 static char http_detect_server_startwith[] = "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n<HTML><HEAD>\r\n<TITLE>403 Forbidden</TITLE>\r\n</HEAD><BODY>\r\n<H1>Forbidden</H1>\r\nYou don't have permission to access ";
186 static char http_detect_server_tag_future[] = "9C37197CA7C2428388C2E6E59B829B30";
187
188 // DNS cache list
189 static LIST *DnsCache;
190
191 // Lock related
192 static LOCK *machine_name_lock = NULL;
193 static LOCK *disconnect_function_lock = NULL;
194 static LOCK *aho = NULL;
195 static LOCK *socket_library_lock = NULL;
196 extern LOCK *openssl_lock;
197 static LOCK *ssl_accept_lock = NULL;
198 static LOCK *ssl_connect_lock = NULL;
199 static TOKEN_LIST *cipher_list_token = NULL;
200 static COUNTER *num_tcp_connections = NULL;
201 static LOCK *dns_lock = NULL;
202 static LOCK *unix_dns_server_addr_lock = NULL;
203 static IP unix_dns_server;
204 static LIST *HostCacheList = NULL;
205 static LIST *WaitThreadList = NULL;
206 static bool disable_cache = false;
207 static bool NetworkReleaseMode = false; // Network release mode
208 static UCHAR machine_ip_process_hash[SHA1_SIZE];
209 static LOCK *machine_ip_process_hash_lock = NULL;
210 static LOCK *current_global_ip_lock = NULL;
211 static LOCK *current_fqdn_lock = NULL;
212 static bool current_global_ip_set = false;
213 static IP current_glocal_ipv4 = {0};
214 static IP current_glocal_ipv6 = {0};
215 static char current_fqdn[MAX_SIZE];
216 static bool g_no_rudp_server = false;
217 static bool g_no_rudp_register = false;
218 static bool g_natt_low_priority = false;
219 static LOCK *host_ip_address_list_cache_lock = NULL;
220 static UINT64 host_ip_address_list_cache_last = 0;
221 static LIST *host_ip_address_cache = NULL;
222 static bool disable_gethostname_by_accept = false;
223 static COUNTER *getip_thread_counter = NULL;
224 static UINT max_getip_thread = 0;
225
226
227 static char *cipher_list = "RC4-MD5 RC4-SHA AES128-SHA AES256-SHA DES-CBC-SHA DES-CBC3-SHA DHE-RSA-AES128-SHA DHE-RSA-AES256-SHA AES128-GCM-SHA256 AES128-SHA256 AES256-GCM-SHA384 AES256-SHA256 DHE-RSA-AES128-GCM-SHA256 DHE-RSA-AES128-SHA256 DHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES256-SHA256 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-SHA256 ECDHE-RSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-SHA384"
228 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
229 " DHE-RSA-CHACHA20-POLY1305 ECDHE-RSA-CHACHA20-POLY1305";
230 #endif
231 ;
232
233 static LIST *ip_clients = NULL;
234
235 static LIST *local_mac_list = NULL;
236 static LOCK *local_mac_list_lock = NULL;
237
238 static UINT rand_port_numbers[256] = {0};
239
240
241 static bool g_use_privateip_file = false;
242 static bool g_source_ip_validation_force_disable = false;
243
244 static DH_CTX *dh_2048 = NULL;
245
246 typedef struct PRIVATE_IP_SUBNET
247 {
248 UINT Ip, Mask, Ip2;
249 } PRIVATE_IP_SUBNET;
250
251 static LIST *g_private_ip_list = NULL;
252
253
254 static LIST *g_dyn_value_list = NULL;
255
256
257
258 //#define RUDP_DETAIL_LOG
259
260
261
262
263 // Get a value from a dynamic value list (Returns a default value if the value is not found)
GetDynValueOrDefault(char * name,UINT64 default_value,UINT64 min_value,UINT64 max_value)264 UINT64 GetDynValueOrDefault(char *name, UINT64 default_value, UINT64 min_value, UINT64 max_value)
265 {
266 UINT64 ret = GetDynValue(name);
267
268 if (ret == 0)
269 {
270 return default_value;
271 }
272
273 if (ret < min_value)
274 {
275 ret = min_value;
276 }
277
278 if (ret > max_value)
279 {
280 ret = max_value;
281 }
282
283 return ret;
284 }
285
286 // Get a value from a dynamic value list (Returns a default value if the value is not found)
287 // The value is limited to 1/5 to 50 times of the default value for safety
GetDynValueOrDefaultSafe(char * name,UINT64 default_value)288 UINT64 GetDynValueOrDefaultSafe(char *name, UINT64 default_value)
289 {
290 return GetDynValueOrDefault(name, default_value, default_value / (UINT64)5, default_value * (UINT64)50);
291 }
292
293 // Get a value from a dynamic value list
GetDynValue(char * name)294 UINT64 GetDynValue(char *name)
295 {
296 UINT64 ret = 0;
297 // Validate arguments
298 if (name == NULL)
299 {
300 return 0;
301 }
302
303 if (g_dyn_value_list == NULL)
304 {
305 return 0;
306 }
307
308 LockList(g_dyn_value_list);
309 {
310 UINT i;
311
312 for (i = 0; i < LIST_NUM(g_dyn_value_list);i++)
313 {
314 DYN_VALUE *vv = LIST_DATA(g_dyn_value_list, i);
315
316 if (StrCmpi(vv->Name, name) == 0)
317 {
318 ret = vv->Value;
319 break;
320 }
321 }
322 }
323 UnlockList(g_dyn_value_list);
324
325 return ret;
326 }
327
328 // Set the value to the dynamic value list
SetDynListValue(char * name,UINT64 value)329 void SetDynListValue(char *name, UINT64 value)
330 {
331 // Validate arguments
332 if (name == NULL)
333 {
334 return;
335 }
336
337 if (g_dyn_value_list == NULL)
338 {
339 return;
340 }
341
342 LockList(g_dyn_value_list);
343 {
344 UINT i;
345 DYN_VALUE *v = NULL;
346
347 for (i = 0; i < LIST_NUM(g_dyn_value_list);i++)
348 {
349 DYN_VALUE *vv = LIST_DATA(g_dyn_value_list, i);
350
351 if (StrCmpi(vv->Name, name) == 0)
352 {
353 v = vv;
354 break;
355 }
356 }
357
358 if (v == NULL)
359 {
360 v = ZeroMalloc(sizeof(DYN_VALUE));
361 StrCpy(v->Name, sizeof(v->Name), name);
362
363 Add(g_dyn_value_list, v);
364 }
365
366 v->Value = value;
367 }
368 UnlockList(g_dyn_value_list);
369 }
370
371 // Apply by extracting dynamic value list from the specified PACK
ExtractAndApplyDynList(PACK * p)372 void ExtractAndApplyDynList(PACK *p)
373 {
374 BUF *b;
375 // Validate arguments
376 if (p == NULL)
377 {
378 return;
379 }
380
381 b = PackGetBuf(p, "DynList");
382 if (b == NULL)
383 {
384 return;
385 }
386
387 AddDynList(b);
388
389 FreeBuf(b);
390 }
391
392 // Insert the data to the dynamic value list
AddDynList(BUF * b)393 void AddDynList(BUF *b)
394 {
395 PACK *p;
396 TOKEN_LIST *t;
397 // Validate arguments
398 if (b == NULL)
399 {
400 return;
401 }
402
403 SeekBufToBegin(b);
404
405 p = BufToPack(b);
406 if (p == NULL)
407 {
408 return;
409 }
410
411 t = GetPackElementNames(p);
412 if (t != NULL)
413 {
414 UINT i;
415
416 for (i = 0;i < t->NumTokens;i++)
417 {
418 char *name = t->Token[i];
419 UINT64 v = PackGetInt64(p, name);
420
421 SetDynListValue(name, v);
422 }
423
424 FreeToken(t);
425 }
426
427 FreePack(p);
428 }
429
430 // Initialization of the dynamic value list
InitDynList()431 void InitDynList()
432 {
433 g_dyn_value_list = NewList(NULL);
434 }
435
436 // Solution of dynamic value list
FreeDynList()437 void FreeDynList()
438 {
439 UINT i;
440 if (g_dyn_value_list == NULL)
441 {
442 return;
443 }
444
445 for (i = 0;i < LIST_NUM(g_dyn_value_list);i++)
446 {
447 DYN_VALUE *d = LIST_DATA(g_dyn_value_list, i);
448
449 Free(d);
450 }
451
452 ReleaseList(g_dyn_value_list);
453
454 g_dyn_value_list = NULL;
455 }
456
457 // Check whether the string in the string list appears in the specified string
IsInStrByStrList(char * str,char * str_list)458 bool IsInStrByStrList(char *str, char *str_list)
459 {
460 TOKEN_LIST *t;
461 bool ret = false;
462 // Validate arguments
463 if (str == NULL || str_list == NULL)
464 {
465 return false;
466 }
467
468 t = ParseTokenWithoutNullStr(str_list, ", \t\r\n");
469 if (t != NULL)
470 {
471 UINT i;
472
473 for (i = 0;i < t->NumTokens;i++)
474 {
475 char *s = t->Token[i];
476
477 if (StrLen(s) >= 1)
478 {
479 if (InStrEx(str, s, true))
480 {
481 ret = true;
482 break;
483 }
484 }
485 }
486 }
487
488 FreeToken(t);
489
490 return ret;
491 }
492
493
494 // Search whether the IP address exists on the IP address list string
IsIpInStrList(IP * ip,char * ip_list)495 bool IsIpInStrList(IP *ip, char *ip_list)
496 {
497 char ip_str[128];
498 TOKEN_LIST *t;
499 bool ret = false;
500 // Validate arguments
501 if (ip == NULL || ip_list == NULL)
502 {
503 return false;
504 }
505
506 Zero(ip_str, sizeof(ip_str));
507 IPToStr(ip_str, sizeof(ip_str), ip);
508
509 t = ParseTokenWithoutNullStr(ip_list, ", \t\r\n");
510
511 if (t != NULL)
512 {
513 UINT i;
514
515 for (i = 0;i < t->NumTokens;i++)
516 {
517 char *s = t->Token[i];
518
519 if (StrCmpi(s, ip_str) == 0)
520 {
521 ret = true;
522 break;
523 }
524 }
525 }
526
527 FreeToken(t);
528
529 return ret;
530 }
531
532
533 // Disable NAT-T function globally
DisableRDUPServerGlobally()534 void DisableRDUPServerGlobally()
535 {
536 g_no_rudp_server = true;
537 }
538
539 // Disable NAT-T registration globally
DisableRUDPRegisterGlobally()540 void DisableRUDPRegisterGlobally()
541 {
542 g_no_rudp_register = true;
543 }
544
545 // Lower the priority of the host at NAT-T
SetNatTLowPriority()546 void SetNatTLowPriority()
547 {
548 g_natt_low_priority = true;
549 }
550
551 // Extract only the host name part from FQDN
GetSimpleHostname(char * hostname,UINT hostname_size,char * fqdn)552 void GetSimpleHostname(char *hostname, UINT hostname_size, char *fqdn)
553 {
554 UINT i;
555 ClearStr(hostname, hostname_size);
556 // Validate arguments
557 if (hostname == NULL || fqdn == NULL)
558 {
559 return;
560 }
561
562 StrCpy(hostname, hostname_size, fqdn);
563 Trim(hostname);
564
565 i = SearchStrEx(hostname, ".", 0, true);
566 if (i != INFINITE)
567 {
568 hostname[i] = 0;
569 }
570 }
571
572 // Get the current time zone
GetCurrentTimezone()573 int GetCurrentTimezone()
574 {
575 int ret = 0;
576
577 #ifdef OS_WIN32
578 ret = GetCurrentTimezoneWin32();
579 #else // OS_WIN32
580 {
581 #if defined(UNIX_MACOS) || defined(UNIX_BSD)
582 struct timeval tv;
583 struct timezone tz;
584
585 Zero(&tv, sizeof(tv));
586 Zero(&tz, sizeof(tz));
587
588 gettimeofday(&tv, &tz);
589
590 ret = tz.tz_minuteswest;
591
592 #else // defined(UNIX_MACOS) || defined(UNIX_BSD)
593 tzset();
594
595 ret = timezone / 60;
596 #endif // defined(UNIX_MACOS) || defined(UNIX_BSD)
597 }
598 #endif // OS_WIN32
599
600 return ret;
601 }
602
603 // Flag of whether to use the DNS proxy
IsUseDnsProxy()604 bool IsUseDnsProxy()
605 {
606 return false;
607 }
608
609 // Flag of whether to use an alternate host name
IsUseAlternativeHostname()610 bool IsUseAlternativeHostname()
611 {
612
613 return false;
614 }
615
616 #ifdef OS_WIN32
617 // Get the current time zone (Win32)
GetCurrentTimezoneWin32()618 int GetCurrentTimezoneWin32()
619 {
620 TIME_ZONE_INFORMATION info;
621 Zero(&info, sizeof(info));
622
623 if (GetTimeZoneInformation(&info) == TIME_ZONE_ID_INVALID)
624 {
625 return 0;
626 }
627
628 return info.Bias;
629 }
630 #endif // OS_WIN32
631
632
633 // Set the current FQDN of the DDNS
SetCurrentDDnsFqdn(char * name)634 void SetCurrentDDnsFqdn(char *name)
635 {
636 // Validate arguments
637 if (name == NULL)
638 {
639 return;
640 }
641
642 Lock(current_fqdn_lock);
643 {
644 StrCpy(current_fqdn, sizeof(current_fqdn), name);
645 }
646 Unlock(current_fqdn_lock);
647 }
648
649 // Get the current DDNS FQDN hash
GetCurrentDDnsFqdnHash()650 UINT GetCurrentDDnsFqdnHash()
651 {
652 UINT ret;
653 UCHAR hash[SHA1_SIZE];
654 char name[MAX_SIZE];
655
656 ClearStr(name, sizeof(name));
657 GetCurrentDDnsFqdn(name, sizeof(name));
658
659 Trim(name);
660 StrUpper(name);
661
662 HashSha1(hash, name, StrLen(name));
663
664 Copy(&ret, hash, sizeof(UINT));
665
666 return ret;
667 }
668
669 // Get the current DDNS FQDN
GetCurrentDDnsFqdn(char * name,UINT size)670 void GetCurrentDDnsFqdn(char *name, UINT size)
671 {
672 ClearStr(name, size);
673 // Validate arguments
674 if (name == NULL || size == 0)
675 {
676 return;
677 }
678
679 Lock(current_fqdn_lock);
680 {
681 StrCpy(name, size, current_fqdn);
682 }
683 Unlock(current_fqdn_lock);
684
685 Trim(name);
686 }
687
688 // Check whether the specified MAC address exists on the local host (high speed)
IsMacAddressLocalFast(void * addr)689 bool IsMacAddressLocalFast(void *addr)
690 {
691 bool ret = false;
692 // Validate arguments
693 if (addr == NULL)
694 {
695 return false;
696 }
697
698 Lock(local_mac_list_lock);
699 {
700 if (local_mac_list == NULL)
701 {
702 // First enumeration
703 RefreshLocalMacAddressList();
704 }
705
706 ret = IsMacAddressLocalInner(local_mac_list, addr);
707 }
708 Unlock(local_mac_list_lock);
709
710 return ret;
711 }
712
713 // Update the local MAC address list
RefreshLocalMacAddressList()714 void RefreshLocalMacAddressList()
715 {
716 Lock(local_mac_list_lock);
717 {
718 if (local_mac_list != NULL)
719 {
720 FreeNicList(local_mac_list);
721 }
722
723 local_mac_list = GetNicList();
724 }
725 Unlock(local_mac_list_lock);
726 }
727
728 // Check whether the specified MAC address exists on the local host
IsMacAddressLocal(void * addr)729 bool IsMacAddressLocal(void *addr)
730 {
731 LIST *o;
732 bool ret;
733 // Validate arguments
734 if (addr == NULL)
735 {
736 return false;
737 }
738
739 o = GetNicList();
740
741 ret = IsMacAddressLocalInner(o, addr);
742
743 FreeNicList(o);
744
745 return ret;
746 }
IsMacAddressLocalInner(LIST * o,void * addr)747 bool IsMacAddressLocalInner(LIST *o, void *addr)
748 {
749 bool ret = false;
750 UINT i;
751 // Validate arguments
752 if (o == NULL || addr == NULL)
753 {
754 return false;
755 }
756
757 for (i = 0;i < LIST_NUM(o);i++)
758 {
759 NIC_ENTRY *e = LIST_DATA(o, i);
760
761 if (Cmp(e->MacAddress, addr, 6) == 0)
762 {
763 ret = true;
764 break;
765 }
766 }
767
768 return ret;
769 }
770
771 // Get a list of the NICs on the computer
GetNicList()772 LIST *GetNicList()
773 {
774 LIST *o = NULL;
775
776 #ifdef OS_WIN32
777 o = Win32GetNicList();
778 #endif // OS_WIN32
779
780 #ifdef UNIX_LINUX
781 #endif // UNIX_LINUX
782
783 if (o == NULL)
784 {
785 return NewListFast(NULL);
786 }
787
788 return o;
789 }
790
791 #ifdef OS_WIN32
Win32GetNicList()792 LIST *Win32GetNicList()
793 {
794 UINT i;
795 LIST *o = NewListFast(NULL);
796 MS_ADAPTER_LIST *al = MsCreateAdapterList();
797
798 if (al == NULL)
799 {
800 return NULL;
801 }
802
803 for (i = 0;i < al->Num;i++)
804 {
805 MS_ADAPTER *a = al->Adapters[i];
806
807 if (a->Type == 6 && a->AddressSize == 6)
808 {
809 NIC_ENTRY *e = ZeroMalloc(sizeof(NIC_ENTRY));
810
811 StrCpy(e->IfName, sizeof(e->IfName), a->Title);
812 Copy(e->MacAddress, a->Address, 6);
813
814 Add(o, e);
815 }
816 }
817
818 MsFreeAdapterList(al);
819
820 return o;
821 }
822 #endif // OS_WIN32
823
824 // Release the NIC list
FreeNicList(LIST * o)825 void FreeNicList(LIST *o)
826 {
827 UINT i;
828 // Validate arguments
829 if (o == NULL)
830 {
831 return;
832 }
833
834 for (i = 0;i < LIST_NUM(o);i++)
835 {
836 NIC_ENTRY *e = LIST_DATA(o, i);
837
838 Free(e);
839 }
840
841 ReleaseList(o);
842 }
843
844 // If the computer is connected to the FLET'S line currently, detect the type of the line (obsolete)
DetectFletsType()845 UINT DetectFletsType()
846 {
847 UINT ret = 0;
848 //LIST *o = GetHostIPAddressList();
849 // UINT i;
850
851 /*
852 for (i = 0;i < LIST_NUM(o);i++)
853 {
854 IP *ip = LIST_DATA(o, i);
855
856 if (IsIP6(ip))
857 {
858 char ip_str[MAX_SIZE];
859
860 IPToStr(ip_str, sizeof(ip_str), ip);
861
862 if (IsInSameNetwork6ByStr(ip_str, "2001:c90::", "/32"))
863 {
864 // NTT East B-FLETs
865 ret |= FLETS_DETECT_TYPE_EAST_BFLETS_PRIVATE;
866 }
867
868 if (IsInSameNetwork6ByStr(ip_str, "2408:200::", "/23"))
869 {
870 // Wrapping in network of NTT East NGN
871 ret |= FLETS_DETECT_TYPE_EAST_NGN_PRIVATE;
872 }
873
874 if (IsInSameNetwork6ByStr(ip_str, "2001:a200::", "/23"))
875 {
876 // Wrapping in network of NTT West NGN
877 ret |= FLETS_DETECT_TYPE_WEST_NGN_PRIVATE;
878 }
879 }
880 }
881
882 FreeHostIPAddressList(o);
883 */
884 return ret;
885 }
886
887 // Query for the IP address using the DNS proxy for the B FLETs
GetIPViaDnsProxyForJapanFlets(IP * ip_ret,char * hostname,bool ipv6,UINT timeout,bool * cancel,char * dns_proxy_hostname)888 bool GetIPViaDnsProxyForJapanFlets(IP *ip_ret, char *hostname, bool ipv6, UINT timeout, bool *cancel, char *dns_proxy_hostname)
889 {
890 SOCK *s;
891 char connect_hostname[MAX_SIZE];
892 char connect_hostname2[MAX_SIZE];
893 IP dns_proxy_ip;
894 bool ret = false;
895 bool dummy_flag = false;
896 char request_str[512];
897 // Validate arguments
898 if (ip_ret == NULL || hostname == NULL)
899 {
900 return false;
901 }
902 if (timeout == 0)
903 {
904 timeout = BFLETS_DNS_PROXY_TIMEOUT_FOR_QUERY;
905 }
906 if (cancel == NULL)
907 {
908 cancel = &dummy_flag;
909 }
910
911 // Get the IP address of the DNS proxy server
912 if (IsEmptyStr(dns_proxy_hostname))
913 {
914 // B FLETs
915 if (GetDnsProxyIPAddressForJapanBFlets(&dns_proxy_ip, BFLETS_DNS_PROXY_TIMEOUT_FOR_GET_F, cancel) == false)
916 {
917 return false;
918 }
919 }
920 else
921 {
922 // FLET'S NEXT
923 if (GetIP4Ex6Ex2(&dns_proxy_ip, dns_proxy_hostname, FLETS_NGN_DNS_QUERY_TIMEOUT, true, cancel, true) == false)
924 {
925 return false;
926 }
927 }
928
929 if (*cancel)
930 {
931 return false;
932 }
933
934 IPToStr(connect_hostname, sizeof(connect_hostname), &dns_proxy_ip);
935
936 /*{
937 StrCpy(connect_hostname, sizeof(connect_hostname), "2409:250:62c0:100:6a05:caff:fe09:5158");
938 }*/
939
940 StrCpy(connect_hostname2, sizeof(connect_hostname2), connect_hostname);
941 if (IsIP6(&dns_proxy_ip))
942 {
943 Format(connect_hostname2, sizeof(connect_hostname2), "[%s]", connect_hostname);
944 }
945
946 s = ConnectEx3(connect_hostname, BFLETS_DNS_PROXY_PORT, timeout, cancel, NULL, NULL, false, false, false);
947
948 if (s == NULL)
949 {
950 return false;
951 }
952
953 if (*cancel)
954 {
955 Disconnect(s);
956 ReleaseSock(s);
957
958 return false;
959 }
960
961 SetTimeout(s, timeout);
962
963 // Start the SSL
964 if (StartSSLEx(s, NULL, NULL, true, 0, NULL) && (*cancel == false))
965 {
966 UCHAR hash[SHA1_SIZE];
967 BUF *hash2 = StrToBin(BFLETS_DNS_PROXY_CERT_HASH);
968
969 Zero(hash, sizeof(hash));
970 GetXDigest(s->RemoteX, hash, true);
971
972 if (Cmp(hash, hash2->Buf, SHA1_SIZE) == 0)
973 {
974 // Send the HTTP Request
975 Format(request_str, sizeof(request_str),
976 "GET " BFLETS_DNS_PROXY_PATH "?q=%s&ipv6=%u\r\n"
977 "\r\n",
978 hostname, ipv6, connect_hostname2);
979
980 if (SendAll(s, request_str, StrLen(request_str), true))
981 {
982 if (*cancel == false)
983 {
984 BUF *recv_buf = NewBuf();
985 UINT port_ret;
986
987 while (true)
988 {
989 UCHAR tmp[MAX_SIZE];
990 UINT r;
991
992 r = Recv(s, tmp, sizeof(tmp), true);
993
994 if (r == 0 || (recv_buf->Size > 65536))
995 {
996 break;
997 }
998 else
999 {
1000 WriteBuf(recv_buf, tmp, r);
1001 }
1002 }
1003
1004 ret = RUDPParseIPAndPortStr(recv_buf->Buf, recv_buf->Size, ip_ret, &port_ret);
1005
1006 FreeBuf(recv_buf);
1007 }
1008 }
1009 }
1010
1011 FreeBuf(hash2);
1012 }
1013
1014 Disconnect(s);
1015 ReleaseSock(s);
1016
1017 if (ret)
1018 {
1019 NewDnsCache(hostname, ip_ret);
1020 }
1021
1022 return ret;
1023 }
1024
1025 // Get the IP address of the available DNS proxy in B-FLET'S service that is provided by NTT East of Japan
GetDnsProxyIPAddressForJapanBFlets(IP * ip_ret,UINT timeout,bool * cancel)1026 bool GetDnsProxyIPAddressForJapanBFlets(IP *ip_ret, UINT timeout, bool *cancel)
1027 {
1028 BUF *b;
1029 LIST *o;
1030 bool ret = false;
1031 // Validate arguments
1032 if (ip_ret == NULL)
1033 {
1034 return false;
1035 }
1036 if (timeout == 0)
1037 {
1038 timeout = BFLETS_DNS_PROXY_TIMEOUT_FOR_GET_F;
1039 }
1040
1041 b = QueryFileByUdpForJapanBFlets(timeout, cancel);
1042
1043 if (b == NULL)
1044 {
1045 return false;
1046 }
1047
1048 o = ReadIni(b);
1049
1050 if (o != NULL)
1051 {
1052 INI_ENTRY *e = GetIniEntry(o, "DDnsServerForBFlets");
1053
1054 if (e != NULL)
1055 {
1056 char *s = e->Value;
1057
1058 if (IsEmptyStr(s) == false)
1059 {
1060 IP ip;
1061
1062 if (StrToIP(&ip, s))
1063 {
1064 if (IsZeroIp(&ip) == false)
1065 {
1066 Copy(ip_ret, &ip, sizeof(IP));
1067 ret = true;
1068 }
1069 }
1070 }
1071 }
1072 }
1073
1074 FreeIni(o);
1075 FreeBuf(b);
1076
1077 return ret;
1078 }
1079
1080 // Get a valid F.txt file in B-FLET'S service that is provided by NTT East of Japan
QueryFileByUdpForJapanBFlets(UINT timeout,bool * cancel)1081 BUF *QueryFileByUdpForJapanBFlets(UINT timeout, bool *cancel)
1082 {
1083 bool dummy_flag = false;
1084 BUF *txt_buf = NULL;
1085 BUF *ret = NULL;
1086 LIST *ip_list = NULL;
1087 UINT i;
1088 // Validate arguments
1089 if (cancel == NULL)
1090 {
1091 cancel = &dummy_flag;
1092 }
1093 if (timeout == 0)
1094 {
1095 timeout = BFLETS_DNS_PROXY_TIMEOUT_FOR_GET_F;
1096 }
1097
1098 txt_buf = ReadDump(UDP_FILE_QUERY_BFLETS_TXT_FILENAME);
1099 if (txt_buf == NULL)
1100 {
1101 return NULL;
1102 }
1103
1104 ip_list = NewListFast(NULL);
1105
1106 while (true)
1107 {
1108 char *line = CfgReadNextLine(txt_buf);
1109 if (line == NULL)
1110 {
1111 break;
1112 }
1113
1114 Trim(line);
1115
1116 if (IsEmptyStr(line) == false && StartWith(line, "#") == false)
1117 {
1118 IP ip;
1119
1120 if (StrToIP6(&ip, line))
1121 {
1122 if (IsZeroIp(&ip) == false)
1123 {
1124 if (IsIPv6LocalNetworkAddress(&ip) == false)
1125 {
1126 Add(ip_list, Clone(&ip, sizeof(IP)));
1127 }
1128 }
1129 }
1130 }
1131
1132 Free(line);
1133 }
1134
1135 FreeBuf(txt_buf);
1136
1137 ret = QueryFileByIPv6Udp(ip_list, timeout, cancel);
1138
1139 for (i = 0;i < LIST_NUM(ip_list);i++)
1140 {
1141 IP *ip = LIST_DATA(ip_list, i);
1142
1143 Free(ip);
1144 }
1145
1146 ReleaseList(ip_list);
1147
1148 return ret;
1149 }
1150
1151 // Request a file by UDP (send the requests to the multiple IP addresses at the same time)
QueryFileByIPv6Udp(LIST * ip_list,UINT timeout,bool * cancel)1152 BUF *QueryFileByIPv6Udp(LIST *ip_list, UINT timeout, bool *cancel)
1153 {
1154 bool dummy_flag = false;
1155 UINT64 start_tick, giveup_tick;
1156 UINT64 next_send_tick;
1157 SOCK *s;
1158 INTERRUPT_MANAGER *interrupt;
1159 BUF *buf = NULL;
1160 SOCK_EVENT *se;
1161 UCHAR *tmp_buf;
1162 UINT tmp_buf_size = 65535;
1163 // Validate arguments
1164 if (cancel == NULL)
1165 {
1166 cancel = &dummy_flag;
1167 }
1168 if (ip_list == NULL)
1169 {
1170 return NULL;
1171 }
1172
1173 s = NewUDP6(0, NULL);
1174 if (s == NULL)
1175 {
1176 return NULL;
1177 }
1178
1179 tmp_buf = Malloc(tmp_buf_size);
1180
1181 start_tick = Tick64();
1182 giveup_tick = start_tick + (UINT64)timeout;
1183 next_send_tick = 0;
1184
1185 interrupt = NewInterruptManager();
1186
1187 AddInterrupt(interrupt, giveup_tick);
1188
1189 se = NewSockEvent();
1190 JoinSockToSockEvent(s, se);
1191
1192 while (true)
1193 {
1194 UINT64 now = Tick64();
1195
1196 if (now >= giveup_tick)
1197 {
1198 // Time-out
1199 break;
1200 }
1201
1202 if (*cancel)
1203 {
1204 // User canceled
1205 break;
1206 }
1207
1208 // Receive
1209 while (true)
1210 {
1211 IP src_ip;
1212 UINT src_port;
1213 UINT r;
1214
1215 r = RecvFrom(s, &src_ip, &src_port, tmp_buf, tmp_buf_size);
1216
1217 if (r == SOCK_LATER || r == 0)
1218 {
1219 break;
1220 }
1221
1222 if (src_port == UDP_FILE_QUERY_DST_PORT)
1223 {
1224 if (r >= 40)
1225 {
1226 if (Cmp(tmp_buf, UDP_FILE_QUERY_MAGIC_NUMBER, StrLen(UDP_FILE_QUERY_MAGIC_NUMBER)) == 0)
1227 {
1228 // Successful reception
1229 buf = NewBuf();
1230 WriteBuf(buf, tmp_buf, r);
1231 SeekBuf(buf, 0, 0);
1232 break;
1233 }
1234 }
1235 }
1236 }
1237
1238 if (buf != NULL)
1239 {
1240 // Successful reception
1241 break;
1242 }
1243
1244 if (next_send_tick == 0 || (now >= next_send_tick))
1245 {
1246 // Transmission
1247 UINT i;
1248 for (i = 0;i < LIST_NUM(ip_list);i++)
1249 {
1250 IP *ip = LIST_DATA(ip_list, i);
1251 UCHAR c = 'F';
1252
1253 SendTo(s, ip, UDP_FILE_QUERY_DST_PORT, &c, 1);
1254 }
1255
1256 next_send_tick = now + (UINT64)UDP_FILE_QUERY_RETRY_INTERVAL;
1257 AddInterrupt(interrupt, next_send_tick);
1258 }
1259
1260 WaitSockEvent(se, GetNextIntervalForInterrupt(interrupt));
1261 }
1262
1263 FreeInterruptManager(interrupt);
1264
1265 Disconnect(s);
1266 ReleaseSock(s);
1267
1268 ReleaseSockEvent(se);
1269
1270 Free(tmp_buf);
1271
1272 return buf;
1273 }
1274
1275 // Parse the user name of the NT
ParseNtUsername(char * src_username,char * dst_username,UINT dst_username_size,char * dst_domain,UINT dst_domain_size,bool do_not_parse_atmark)1276 void ParseNtUsername(char *src_username, char *dst_username, UINT dst_username_size, char *dst_domain, UINT dst_domain_size, bool do_not_parse_atmark)
1277 {
1278 char tmp_username[MAX_SIZE];
1279 char tmp_domain[MAX_SIZE];
1280 TOKEN_LIST *t;
1281
1282 if (src_username != dst_username)
1283 {
1284 ClearStr(dst_username, dst_username_size);
1285 }
1286
1287 ClearStr(dst_domain, dst_domain_size);
1288 // Validate arguments
1289 if (src_username == NULL || dst_username == NULL || dst_domain == NULL)
1290 {
1291 return;
1292 }
1293
1294 StrCpy(tmp_username, sizeof(tmp_username), src_username);
1295 ClearStr(tmp_domain, sizeof(tmp_domain));
1296
1297 // Analysis of username@domain.name format
1298 if (do_not_parse_atmark == false)
1299 {
1300 t = ParseTokenWithNullStr(tmp_username, "@");
1301 if (t->NumTokens >= 1)
1302 {
1303 StrCpy(tmp_username, sizeof(tmp_username), t->Token[0]);
1304 }
1305 if (t->NumTokens >= 2)
1306 {
1307 StrCpy(tmp_domain, sizeof(tmp_domain), t->Token[1]);
1308 }
1309 FreeToken(t);
1310 }
1311
1312 // If the username part is in "domain\username" format, split it
1313 t = ParseTokenWithNullStr(tmp_username, "\\");
1314 if (t->NumTokens >= 2)
1315 {
1316 if (IsEmptyStr(tmp_domain))
1317 {
1318 StrCpy(tmp_domain, sizeof(tmp_domain), t->Token[0]);
1319 }
1320
1321 StrCpy(tmp_username, sizeof(tmp_username), t->Token[1]);
1322 }
1323 FreeToken(t);
1324
1325 StrCpy(dst_username, dst_username_size, tmp_username);
1326 StrCpy(dst_domain, dst_domain_size, tmp_domain);
1327 }
1328
1329 // The calculation of the optimum MSS value for use in TCP/IP packet in the payload of bulk transfer in R-UDP session
RUDPCalcBestMssForBulk(RUDP_STACK * r,RUDP_SESSION * se)1330 UINT RUDPCalcBestMssForBulk(RUDP_STACK *r, RUDP_SESSION *se)
1331 {
1332 UINT ret;
1333 // Validate arguments
1334 if (r == NULL || se == NULL)
1335 {
1336 return 0;
1337 }
1338
1339 ret = MTU_FOR_PPPOE;
1340
1341 // IPv4
1342 if (IsIP6(&se->YourIp) == false)
1343 {
1344 ret -= 20;
1345 }
1346 else
1347 {
1348 ret -= 40;
1349 }
1350
1351 if (r->Protocol == RUDP_PROTOCOL_ICMP)
1352 {
1353 // ICMP
1354 ret -= 8;
1355
1356 ret -= SHA1_SIZE;
1357 }
1358 else if (r->Protocol == RUDP_PROTOCOL_DNS)
1359 {
1360 // UDP
1361 ret -= 8;
1362
1363 // DNS
1364 ret -= 42;
1365 }
1366
1367 // IV
1368 ret -= SHA1_SIZE;
1369
1370 // Sign
1371 ret -= SHA1_SIZE;
1372
1373 // SEQ_NO
1374 ret -= sizeof(UINT64);
1375
1376 // Padding Max
1377 ret -= 31;
1378
1379 // Ethernet header (target packets of communication)
1380 ret -= 14;
1381
1382 // IPv4 Header (target packet of communication)
1383 ret -= 20;
1384
1385 // TCP header (target packet of communication)
1386 ret -= 20;
1387
1388 // I don't know well, but subtract 24 bytes
1389 ret -= 24;
1390
1391 return ret;
1392 }
1393
1394 // Processing of the reply packet from the NAT-T server
RUDPProcess_NatT_Recv(RUDP_STACK * r,UDPPACKET * udp)1395 void RUDPProcess_NatT_Recv(RUDP_STACK *r, UDPPACKET *udp)
1396 {
1397 BUF *b;
1398 PACK *p;
1399 // Validate arguments
1400 if (r == NULL || udp == NULL)
1401 {
1402 return;
1403 }
1404
1405 if (udp->Size >= 8)
1406 {
1407 char tmp[128];
1408
1409 Zero(tmp, sizeof(tmp));
1410 Copy(tmp, udp->Data, MIN(udp->Size, sizeof(tmp) - 1));
1411
1412 if (StartWith(tmp, "IP="))
1413 {
1414 IP my_ip;
1415 UINT my_port;
1416
1417 // There was a response to the packet to determine the NAT state
1418 if (IsEmptyStr(r->NatT_Registered_IPAndPort) == false)
1419 {
1420 if (StrCmpi(r->NatT_Registered_IPAndPort, tmp) != 0)
1421 {
1422 // Redo getting the token and registration because the NAT state is changed
1423 ClearStr(r->NatT_Registered_IPAndPort, sizeof(r->NatT_Registered_IPAndPort));
1424
1425 r->NatT_GetTokenNextTick = 0;
1426 r->NatT_GetTokenFailNum = 0;
1427 r->NatT_Token_Ok = false;
1428 Zero(r->NatT_Token, sizeof(r->NatT_Token));
1429
1430 r->NatT_RegisterNextTick = 0;
1431 r->NatT_RegisterFailNum = 0;
1432 r->NatT_Register_Ok = false;
1433 }
1434 }
1435
1436 if (RUDPParseIPAndPortStr(udp->Data, udp->Size, &my_ip, &my_port))
1437 {
1438 if (r->NatTGlobalUdpPort != NULL)
1439 {
1440 *r->NatTGlobalUdpPort = my_port;
1441 }
1442 }
1443
1444 return;
1445 }
1446 }
1447
1448 // Interpret the UDP packet
1449 b = NewBuf();
1450 WriteBuf(b, udp->Data, udp->Size);
1451 SeekBuf(b, 0, 0);
1452
1453 p = BufToPack(b);
1454
1455 if (p != NULL)
1456 {
1457 bool is_ok = PackGetBool(p, "ok");
1458 UINT64 tran_id = PackGetInt64(p, "tran_id");
1459
1460 ExtractAndApplyDynList(p);
1461
1462 if (r->ServerMode)
1463 {
1464 if (PackCmpStr(p, "opcode", "get_token"))
1465 {
1466 // Get the Token
1467 if (is_ok && (tran_id == r->NatT_TranId))
1468 {
1469 char tmp[MAX_SIZE];
1470
1471 if (PackGetStr(p, "token", tmp, sizeof(tmp)) && IsEmptyStr(tmp) == false)
1472 {
1473 char myip[MAX_SIZE];
1474 // Acquisition success
1475 StrCpy(r->NatT_Token, sizeof(r->NatT_Token), tmp);
1476 r->NatT_Token_Ok = true;
1477 r->NatT_GetTokenNextTick = r->Now + (UINT64)GenRandInterval(UDP_NAT_T_GET_TOKEN_INTERVAL_2_MIN, UDP_NAT_T_GET_TOKEN_INTERVAL_2_MAX);
1478 r->NatT_GetTokenFailNum = 0;
1479
1480 // Since success to obtain the self global IPv4 address,
1481 // re-obtain the destination NAT-T host from this IPv4 address
1482 if (PackGetStr(p, "your_ip", myip, sizeof(myip)))
1483 {
1484 IP ip;
1485 char new_hostname[MAX_SIZE];
1486
1487 StrToIP(&ip, myip);
1488
1489 SetCurrentGlobalIP(&ip, false);
1490
1491 RUDPGetRegisterHostNameByIP(new_hostname,
1492 sizeof(new_hostname), &ip);
1493
1494 Lock(r->Lock);
1495 {
1496 if (StrCmpi(r->CurrentRegisterHostname, new_hostname) != 0)
1497 {
1498 r->NumChangedHostname++;
1499
1500 if (r->NumChangedHostname <= RUDP_NATT_MAX_CONT_CHANGE_HOSTNAME)
1501 {
1502 if (r->NumChangedHostnameValueResetTick == 0)
1503 {
1504 r->NumChangedHostnameValueResetTick = r->Now + (UINT64)RUDP_NATT_CONT_CHANGE_HOSTNAME_RESET_INTERVAL;
1505 }
1506
1507 // Change the host name
1508 Debug("CurrentRegisterHostname Changed: New=%s\n", new_hostname);
1509 StrCpy(r->CurrentRegisterHostname, sizeof(r->CurrentRegisterHostname), new_hostname);
1510
1511 Zero(&r->NatT_IP, sizeof(r->NatT_IP));
1512 //Zero(&r->NatT_IP_Safe, sizeof(r->NatT_IP_Safe));
1513
1514 Set(r->HaltEvent);
1515 }
1516 else
1517 {
1518 if (r->NumChangedHostnameValueResetTick == 0)
1519 {
1520 r->NumChangedHostnameValueResetTick = r->Now + (UINT64)RUDP_NATT_CONT_CHANGE_HOSTNAME_RESET_INTERVAL;
1521 }
1522
1523 if (r->Now >= r->NumChangedHostnameValueResetTick)
1524 {
1525 r->NumChangedHostname = 0;
1526 r->NumChangedHostnameValueResetTick = 0;
1527 }
1528 }
1529 }
1530 else
1531 {
1532 r->NumChangedHostname = 0;
1533 r->NumChangedHostnameValueResetTick = 0;
1534 }
1535 }
1536 Unlock(r->Lock);
1537 }
1538
1539 AddInterrupt(r->Interrupt, r->NatT_GetTokenNextTick);
1540 }
1541 }
1542 }
1543 else if (PackCmpStr(p, "opcode", "nat_t_register"))
1544 {
1545 // NAT-T server registration result
1546 if (is_ok && (tran_id == r->NatT_TranId))
1547 {
1548 UINT my_global_port;
1549 // Successful registration
1550 r->NatT_Register_Ok = true;
1551 r->NatT_RegisterNextTick = r->Now + (UINT64)GenRandInterval(UDP_NAT_T_REGISTER_INTERVAL_MIN, UDP_NAT_T_REGISTER_INTERVAL_MAX);
1552 r->NatT_RegisterFailNum = 0;
1553
1554 Debug("NAT-T Registered.\n");
1555
1556 // Save the IP address and port number at the time of registration
1557 PackGetStr(p, "your_ip_and_port", r->NatT_Registered_IPAndPort, sizeof(r->NatT_Registered_IPAndPort));
1558
1559 if (g_source_ip_validation_force_disable == false)
1560 {
1561 // Enable the source IP address validation mechanism
1562 r->NatT_EnableSourceIpValidation = PackGetBool(p, "enable_source_ip_validation");
1563
1564 }
1565 else
1566 {
1567 // Force disable the source IP address validation mechanism
1568 r->NatT_EnableSourceIpValidation = false;
1569 }
1570
1571 // Global port of itself
1572 my_global_port = PackGetInt(p, "your_port");
1573
1574 if (my_global_port != 0)
1575 {
1576 if (r->NatTGlobalUdpPort != NULL)
1577 {
1578 *r->NatTGlobalUdpPort = my_global_port;
1579 }
1580 }
1581
1582 AddInterrupt(r->Interrupt, r->NatT_RegisterNextTick);
1583 }
1584 }
1585 else if (PackCmpStr(p, "opcode", "nat_t_connect_relay"))
1586 {
1587 // Connection request from the client via the NAT-T server
1588 if (is_ok && (PackGetInt64(p, "session_key") == r->NatT_SessionKey))
1589 {
1590 char client_ip_str[MAX_SIZE];
1591 UINT client_port;
1592 IP client_ip;
1593
1594 PackGetStr(p, "client_ip", client_ip_str, sizeof(client_ip_str));
1595 client_port = PackGetInt(p, "client_port");
1596 StrToIP(&client_ip, client_ip_str);
1597
1598 if (IsZeroIp(&client_ip) == false && client_port != 0)
1599 {
1600 UCHAR *rand_data;
1601 UINT rand_size;
1602
1603 if (r->NatT_EnableSourceIpValidation)
1604 {
1605 RUDPAddIpToValidateList(r, &client_ip);
1606 }
1607
1608 rand_size = Rand32() % 19;
1609 rand_data = Malloc(rand_size);
1610
1611 Rand(rand_data, rand_size);
1612
1613 RUDPSendPacket(r, &client_ip, client_port, rand_data, rand_size, 0);
1614
1615 Free(rand_data);
1616 }
1617 }
1618 }
1619 }
1620
1621 FreePack(p);
1622 }
1623
1624 FreeBuf(b);
1625 }
1626
1627 // Set the flag of the source IP address validation function
RUDPSetSourceIpValidationForceDisable(bool b)1628 void RUDPSetSourceIpValidationForceDisable(bool b)
1629 {
1630 g_source_ip_validation_force_disable = b;
1631 }
1632
1633 // Process such as packet transmission for NAT-T server
RUDPDo_NatT_Interrupt(RUDP_STACK * r)1634 void RUDPDo_NatT_Interrupt(RUDP_STACK *r)
1635 {
1636 // Validate arguments
1637 if (r == NULL)
1638 {
1639 return;
1640 }
1641
1642 if (r->ServerMode)
1643 {
1644
1645 if (g_no_rudp_register == false && IsZeroIp(&r->NatT_IP_Safe) == false)
1646 {
1647 if (r->NatT_GetTokenNextTick == 0 || r->Now >= r->NatT_GetTokenNextTick)
1648 {
1649 // Try to get a token from the NAT-T server periodically
1650 PACK *p = NewPack();
1651 BUF *b;
1652
1653 PackAddStr(p, "opcode", "get_token");
1654 PackAddInt64(p, "tran_id", r->NatT_TranId);
1655 PackAddInt(p, "nat_traversal_version", UDP_NAT_TRAVERSAL_VERSION);
1656
1657 b = PackToBuf(p);
1658 FreePack(p);
1659
1660 RUDPSendPacket(r, &r->NatT_IP_Safe, UDP_NAT_T_PORT, b->Buf, b->Size, 0);
1661
1662 FreeBuf(b);
1663
1664 // Determine the next acquisition time
1665 r->NatT_GetTokenFailNum++;
1666 r->NatT_GetTokenNextTick = r->Now + (UINT64)(UDP_NAT_T_GET_TOKEN_INTERVAL_1 * (UINT64)MIN(r->NatT_GetTokenFailNum, UDP_NAT_T_GET_TOKEN_INTERVAL_FAIL_MAX));
1667 AddInterrupt(r->Interrupt, r->NatT_GetTokenNextTick);
1668 r->NatT_Token_Ok = false;
1669 }
1670 }
1671
1672 {
1673 if (IsZeroIp(&r->NatT_IP_Safe) == false)
1674 {
1675 // Normal servers: Send request packets to the NAT-T server
1676 if (r->NatT_NextNatStatusCheckTick == 0 || r->Now >= r->NatT_NextNatStatusCheckTick)
1677 {
1678 UCHAR a = 'A';
1679 UINT ddns_hash;
1680 // Check of the NAT state
1681 RUDPSendPacket(r, &r->NatT_IP_Safe, UDP_NAT_T_PORT, &a, 1, 0);
1682
1683 // Execution time of the next
1684 r->NatT_NextNatStatusCheckTick = r->Now + (UINT64)GenRandInterval(UDP_NAT_T_NAT_STATUS_CHECK_INTERVAL_MIN, UDP_NAT_T_NAT_STATUS_CHECK_INTERVAL_MAX);
1685 AddInterrupt(r->Interrupt, r->NatT_NextNatStatusCheckTick);
1686
1687 // Check whether the DDNS host name changing have not occurred
1688 ddns_hash = GetCurrentDDnsFqdnHash();
1689
1690 if (r->LastDDnsFqdnHash != ddns_hash)
1691 {
1692 r->LastDDnsFqdnHash = ddns_hash;
1693 // Do the Register immediately if there is a change in the DDNS host name
1694 r->NatT_RegisterNextTick = 0;
1695 }
1696 }
1697 }
1698 }
1699
1700 if (r->NatT_Token_Ok && g_no_rudp_register == false && IsZeroIp(&r->NatT_IP_Safe) == false)
1701 {
1702 if (r->NatT_RegisterNextTick == 0 || r->Now >= r->NatT_RegisterNextTick)
1703 {
1704 // Try to register itself periodically for NAT-T server
1705 PACK *p = NewPack();
1706 BUF *b;
1707 char private_ip_str[MAX_SIZE];
1708 char machine_key[MAX_SIZE];
1709 char machine_name[MAX_SIZE];
1710 UCHAR hash[SHA1_SIZE];
1711 char ddns_fqdn[MAX_SIZE];
1712
1713 Debug("NAT-T Registering...\n");
1714
1715 GetCurrentDDnsFqdn(ddns_fqdn, sizeof(ddns_fqdn));
1716
1717 PackAddStr(p, "opcode", "nat_t_register");
1718 PackAddInt64(p, "tran_id", r->NatT_TranId);
1719 PackAddStr(p, "token", r->NatT_Token);
1720 PackAddStr(p, "svc_name", r->SvcName);
1721 PackAddStr(p, "product_str", CEDAR_PRODUCT_STR);
1722 PackAddInt64(p, "session_key", r->NatT_SessionKey);
1723 PackAddInt(p, "nat_traversal_version", UDP_NAT_TRAVERSAL_VERSION);
1724
1725
1726 if (g_natt_low_priority)
1727 {
1728 PackAddBool(p, "low_priority", g_natt_low_priority);
1729 }
1730
1731 Zero(private_ip_str, sizeof(private_ip_str));
1732 if (IsZeroIp(&r->My_Private_IP_Safe) == false)
1733 {
1734 IPToStr(private_ip_str, sizeof(private_ip_str), &r->My_Private_IP_Safe);
1735 PackAddStr(p, "private_ip", private_ip_str);
1736 }
1737
1738 PackAddInt(p, "private_port", r->UdpSock->LocalPort);
1739
1740 Zero(hash, sizeof(hash));
1741 GetCurrentMachineIpProcessHash(hash);
1742 BinToStr(machine_key, sizeof(machine_key), hash, sizeof(hash));
1743 PackAddStr(p, "machine_key", machine_key);
1744
1745 Zero(machine_name, sizeof(machine_name));
1746 GetMachineName(machine_name, sizeof(machine_name));
1747 PackAddStr(p, "host_name", machine_name);
1748 PackAddStr(p, "ddns_fqdn", ddns_fqdn);
1749
1750 b = PackToBuf(p);
1751 FreePack(p);
1752
1753 RUDPSendPacket(r, &r->NatT_IP_Safe, UDP_NAT_T_PORT, b->Buf, b->Size, 0);
1754 //RUDPSendPacket(r, &r->NatT_IP_Safe, UDP_NAT_T_PORT, "a", 1);
1755
1756 FreeBuf(b);
1757
1758 // Determine the next acquisition time
1759 r->NatT_RegisterFailNum++;
1760 r->NatT_RegisterNextTick = r->Now + (UINT64)UDP_NAT_T_REGISTER_INTERVAL_INITIAL * (UINT64)MIN(r->NatT_RegisterFailNum, UDP_NAT_T_REGISTER_INTERVAL_FAIL_MAX);
1761 AddInterrupt(r->Interrupt, r->NatT_RegisterNextTick);
1762 r->NatT_Register_Ok = false;
1763 }
1764 }
1765 }
1766 }
1767
1768 // R-UDP packet reception procedure
RUDPRecvProc(RUDP_STACK * r,UDPPACKET * p)1769 void RUDPRecvProc(RUDP_STACK *r, UDPPACKET *p)
1770 {
1771 RUDP_SESSION *se = NULL;
1772 // Validate arguments
1773 if (r == NULL || p == NULL)
1774 {
1775 return;
1776 }
1777
1778 if (r->ServerMode)
1779 {
1780 if (g_no_rudp_server)
1781 {
1782 return;
1783 }
1784 }
1785
1786 if (r->ServerMode && r->NoNatTRegister == false)
1787 {
1788
1789 if (p->SrcPort == UDP_NAT_T_PORT && CmpIpAddr(&p->SrcIP, &r->NatT_IP_Safe) == 0)
1790 {
1791 // There was a response from the NAT-T server
1792 RUDPProcess_NatT_Recv(r, p);
1793 return;
1794 }
1795 }
1796
1797 if (r->ServerMode)
1798 {
1799 if (r->ProcRpcRecv != NULL)
1800 {
1801 if (r->ProcRpcRecv(r, p))
1802 {
1803 return;
1804 }
1805 }
1806 }
1807
1808 if (r->ServerMode)
1809 {
1810 // Search the session by the end-point information if in the server mode
1811 se = RUDPSearchSession(r, &p->DstIP, p->DestPort, &p->SrcIP, p->SrcPort);
1812 }
1813 else
1814 {
1815 // Session should exist only one in the case of client mode
1816 if (LIST_NUM(r->SessionList) >= 1)
1817 {
1818 se = LIST_DATA(r->SessionList, 0);
1819 }
1820 else
1821 {
1822 se = NULL;
1823 }
1824 }
1825
1826 if (p->Size < 20)
1827 {
1828 // The received packet is too small
1829 if (r->ServerMode == false)
1830 {
1831 if (se != NULL && se->Status == RUDP_SESSION_STATUS_CONNECT_SENT)
1832 {
1833 if (CmpIpAddr(&se->YourIp, &p->SrcIP) == 0)
1834 {
1835 // If the connection initialization packet which is shorter than 20 bytes
1836 // has been received from the server side, overwrite the source port number
1837 // of the packet to the client-side session information (for some NAT)
1838 se->YourPort = p->SrcPort;
1839 }
1840 }
1841 }
1842 return;
1843 }
1844
1845 if (se == NULL && r->ServerMode && p->Size >= 40)
1846 {
1847 // Corresponding to a sudden change of port number on the client side.
1848 // The target session is a session which matches the client side IP address
1849 // and the key and the signature is verified
1850 UINT i;
1851 for (i = 0; i < LIST_NUM(r->SessionList);i++)
1852 {
1853 RUDP_SESSION *s = LIST_DATA(r->SessionList, i);
1854
1855 if (CmpIpAddr(&s->YourIp, &p->SrcIP) == 0)
1856 {
1857 if (RUDPCheckSignOfRecvPacket(r, s, p->Data, p->Size))
1858 {
1859 // Signature matched
1860 se = s;
1861 break;
1862 }
1863 }
1864 }
1865 }
1866
1867 if (se == NULL)
1868 {
1869 // There is no session
1870 if (r->ServerMode)
1871 {
1872 if (p->Size < 40)
1873 {
1874 bool ok = true;
1875 UCHAR ctoken_hash[SHA1_SIZE];
1876
1877 Zero(ctoken_hash, sizeof(ctoken_hash));
1878
1879 // Examine the quota of new session creation
1880 if (LIST_NUM(r->SessionList) >= RUDP_QUOTA_MAX_NUM_SESSIONS)
1881 {
1882 // Entire number of sessions exceeds the limit
1883 ok = false;
1884 }
1885 else if (r->NatT_EnableSourceIpValidation && RUDPIsIpInValidateList(r, &p->SrcIP) == false)
1886 {
1887 // Invalid source IP address, which is not registered on the validated source IP address list
1888 ok = false;
1889 }
1890 else
1891 {
1892 UINT i;
1893 // Check the number of sessions per IP address
1894 UINT num = 0;
1895
1896 for (i = 0;i < LIST_NUM(r->SessionList);i++)
1897 {
1898 RUDP_SESSION *se = LIST_DATA(r->SessionList, i);
1899
1900 if (CmpIpAddr(&se->YourIp, &p->SrcIP) == 0)
1901 {
1902 num++;
1903 }
1904 }
1905
1906 if (num >= RUDP_QUOTA_MAX_NUM_SESSIONS_PER_IP)
1907 {
1908 // Limit exceeded the number of sessions per IP address
1909 ok = false;
1910 }
1911 }
1912
1913
1914 if (ok)
1915 {
1916 char ip_str[64];
1917
1918 // Create a session since a new session creation request packet was received
1919 se = RUDPNewSession(true, &p->DstIP, p->DestPort, &p->SrcIP, p->SrcPort, p->Data);
1920 se->Status = RUDP_SESSION_STATUS_ESTABLISHED;
1921 Insert(r->SessionList, se);
1922
1923 IPToStr(ip_str, sizeof(ip_str), &p->SrcIP);
1924 Debug("RUDPNewSession %X %s:%u\n", se, ip_str, p->SrcPort);
1925
1926 if (r->Protocol == RUDP_PROTOCOL_ICMP)
1927 {
1928 // In case of ICMP, save the ICMP TYPE number to use
1929 se->Icmp_Type = (p->Type == ICMP_TYPE_INFORMATION_REQUEST ? ICMP_TYPE_INFORMATION_REPLY : p->Type);
1930 }
1931 else if (r->Protocol == RUDP_PROTOCOL_DNS)
1932 {
1933 // Save the Tran ID to be used if it's a DNS
1934 se->Dns_TranId = (USHORT)p->Type;
1935 }
1936 }
1937 }
1938 }
1939 }
1940 else
1941 {
1942 if (p->Size < 40)
1943 {
1944 if (r->ServerMode)
1945 {
1946 if (Cmp(se->Key_Init, p->Data, SHA1_SIZE) == 0)
1947 {
1948 // New session creation request packet have received more than once. reply an ACK immediately for second and subsequent
1949 se->LastSentTick = 0;
1950
1951 // Update the endpoint information
1952 Copy(&se->YourIp, &p->SrcIP, sizeof(IP));
1953 se->YourPort = p->SrcPort;
1954
1955 if (r->Protocol == RUDP_PROTOCOL_ICMP)
1956 {
1957 // In case of ICMP, save the ICMP TYPE number to use
1958 se->Icmp_Type = (p->Type == ICMP_TYPE_INFORMATION_REQUEST ? ICMP_TYPE_INFORMATION_REPLY : p->Type);
1959 }
1960 else if (r->Protocol == RUDP_PROTOCOL_DNS)
1961 {
1962 // Save the Tran ID to be used if it's a DNS
1963 se->Dns_TranId = (USHORT)p->Type;
1964 }
1965 }
1966 else
1967 {
1968 // Since the different session creation request packet have been received from the same end point, ignore it
1969 }
1970 }
1971 }
1972 else
1973 {
1974 // Process the received packet
1975 if (RUDPProcessRecvPacket(r, se, p->Data, p->Size) || RUDPProcessBulkRecvPacket(r, se, p->Data, p->Size))
1976 {
1977 // Update endpoint information (only the port number)
1978 //Copy(&se->YourIp, &p->SrcIP, sizeof(IP));
1979 se->YourPort = p->SrcPort;
1980
1981 if (r->Protocol == RUDP_PROTOCOL_ICMP)
1982 {
1983 // In case of ICMP, save the ICMP TYPE number to use
1984 if (r->ServerMode)
1985 {
1986 se->Icmp_Type = (p->Type == ICMP_TYPE_INFORMATION_REQUEST ? ICMP_TYPE_INFORMATION_REPLY : p->Type);
1987 }
1988 else
1989 {
1990 se->Icmp_Type = (p->Type == ICMP_TYPE_INFORMATION_REPLY ? ICMP_TYPE_INFORMATION_REQUEST : p->Type);
1991 }
1992 }
1993 else if (r->Protocol == RUDP_PROTOCOL_DNS)
1994 {
1995 if (r->ServerMode)
1996 {
1997 // Save the Tran ID to be used if it's a DNS
1998 se->Dns_TranId = (USHORT)p->Type;
1999 }
2000 }
2001 }
2002 }
2003 }
2004 }
2005
2006 // Check whether the specificed IP address is in the validated source IP address list
RUDPIsIpInValidateList(RUDP_STACK * r,IP * ip)2007 bool RUDPIsIpInValidateList(RUDP_STACK *r, IP *ip)
2008 {
2009 UINT i;
2010 UINT64 now = Tick64();
2011 LIST *o = NULL;
2012 bool ret = false;
2013 // Validate arguments
2014 if (r == NULL || ip == NULL)
2015 {
2016 return false;
2017 }
2018
2019 // Always allow private IP addresses
2020 if (IsIPPrivate(ip))
2021 {
2022 return true;
2023 }
2024
2025 if (IsIPAddressInSameLocalNetwork(ip))
2026 {
2027 return true;
2028 }
2029
2030 for (i = 0;i < LIST_NUM(r->NatT_SourceIpList);i++)
2031 {
2032 RUDP_SOURCE_IP *s = (RUDP_SOURCE_IP *)LIST_DATA(r->NatT_SourceIpList, i);
2033
2034 if (s->ExpiresTick <= now)
2035 {
2036 if (o == NULL)
2037 {
2038 o = NewListFast(NULL);
2039 }
2040
2041 Add(o, s);
2042 }
2043 }
2044
2045 if (o != NULL)
2046 {
2047 for (i = 0;i < LIST_NUM(o);i++)
2048 {
2049 RUDP_SOURCE_IP *s = (RUDP_SOURCE_IP *)LIST_DATA(o, i);
2050
2051 Delete(r->NatT_SourceIpList, s);
2052
2053 Free(s);
2054 }
2055
2056 ReleaseList(o);
2057 }
2058
2059 for (i = 0;i < LIST_NUM(r->NatT_SourceIpList);i++)
2060 {
2061 RUDP_SOURCE_IP *s = (RUDP_SOURCE_IP *)LIST_DATA(r->NatT_SourceIpList, i);
2062
2063 if (CmpIpAddr(&s->ClientIP, ip) == 0)
2064 {
2065 ret = true;
2066 break;
2067 }
2068 }
2069
2070 Debug("RUDP: NAT-T: Validate IP: %r, ret=%u (current list len = %u)\n", ip, ret, LIST_NUM(r->NatT_SourceIpList));
2071
2072 return ret;
2073 }
2074
2075 // Add an IP address to the validated source IP address list
RUDPAddIpToValidateList(RUDP_STACK * r,IP * ip)2076 void RUDPAddIpToValidateList(RUDP_STACK *r, IP *ip)
2077 {
2078 UINT i;
2079 RUDP_SOURCE_IP *sip;
2080 UINT64 now = Tick64();
2081 LIST *o = NULL;
2082 // Validate arguments
2083 if (r == NULL || ip == NULL)
2084 {
2085 return;
2086 }
2087
2088 if (LIST_NUM(r->NatT_SourceIpList) >= RUDP_MAX_VALIDATED_SOURCE_IP_ADDRESSES)
2089 {
2090 return;
2091 }
2092
2093 for (i = 0;i < LIST_NUM(r->NatT_SourceIpList);i++)
2094 {
2095 RUDP_SOURCE_IP *s = (RUDP_SOURCE_IP *)LIST_DATA(r->NatT_SourceIpList, i);
2096
2097 if (s->ExpiresTick <= now)
2098 {
2099 if (o == NULL)
2100 {
2101 o = NewListFast(NULL);
2102 }
2103
2104 Add(o, s);
2105 }
2106 }
2107
2108 if (o != NULL)
2109 {
2110 for (i = 0;i < LIST_NUM(o);i++)
2111 {
2112 RUDP_SOURCE_IP *s = (RUDP_SOURCE_IP *)LIST_DATA(o, i);
2113
2114 Delete(r->NatT_SourceIpList, s);
2115
2116 Free(s);
2117 }
2118
2119 ReleaseList(o);
2120 }
2121
2122 sip = NULL;
2123
2124 for (i = 0;i < LIST_NUM(r->NatT_SourceIpList);i++)
2125 {
2126 RUDP_SOURCE_IP *s = (RUDP_SOURCE_IP *)LIST_DATA(r->NatT_SourceIpList, i);
2127
2128 if (CmpIpAddr(&s->ClientIP, ip) == 0)
2129 {
2130 sip = s;
2131 break;
2132 }
2133 }
2134
2135 if (sip == NULL)
2136 {
2137 sip = ZeroMalloc(sizeof(RUDP_SOURCE_IP));
2138
2139 Copy(&sip->ClientIP, ip, sizeof(IP));
2140
2141 Add(r->NatT_SourceIpList, sip);
2142 }
2143
2144 sip->ExpiresTick = now + (UINT64)RUDP_VALIDATED_SOURCE_IP_ADDRESS_EXPIRES;
2145
2146 Debug("RUDP: NAT-T: Src IP added: %r (current list len = %u)\n", ip, LIST_NUM(r->NatT_SourceIpList));
2147 }
2148
2149 // R-UDP interrupt processing procedure
RUDPInterruptProc(RUDP_STACK * r)2150 void RUDPInterruptProc(RUDP_STACK *r)
2151 {
2152 UINT i;
2153 LIST *o;
2154 // Validate arguments
2155 if (r == NULL)
2156 {
2157 return;
2158 }
2159
2160 // Packet transmission and other process for NAT-T server
2161 if (r->NoNatTRegister == false)
2162 {
2163 RUDPDo_NatT_Interrupt(r);
2164 }
2165
2166 if (r->ServerMode == false)
2167 {
2168 if (r->ClientInitiated == false)
2169 {
2170 bool client_target_inited = false;
2171 Lock(r->Lock);
2172 {
2173 client_target_inited = r->TargetIpAndPortInited;
2174 }
2175 Unlock(r->Lock);
2176
2177 if (client_target_inited)
2178 {
2179 // Start a connection when there is the end point information of the destination server to connect as a client
2180 RUDP_SESSION *se;
2181 UCHAR init_key[SHA1_SIZE];
2182 char ip_str[128];
2183 UINT64 ui;
2184
2185 Rand(init_key, SHA1_SIZE);
2186
2187 se = RUDPNewSession(false, &r->UdpSock->LocalIP, r->UdpSock->LocalPort,
2188 &r->TargetIp, r->TargetPort, init_key);
2189
2190 IPToStr(ip_str, sizeof(ip_str), &r->TargetIp);
2191 Debug("RUDPNewSession %X %s:%u\n", se, ip_str, r->TargetPort);
2192
2193 Insert(r->SessionList, se);
2194
2195 ui = Endian64(se->Magic_Disconnect);
2196 WriteFifo(se->SendFifo, &ui, sizeof(UINT64));
2197
2198 r->ClientInitiated = true;
2199 }
2200 }
2201 }
2202
2203 // Process for all the sessions
2204 for (i = 0;i < LIST_NUM(r->SessionList);i++)
2205 {
2206 RUDP_SESSION *se = LIST_DATA(r->SessionList, i);
2207
2208 if (r->Halt)
2209 {
2210 // Disconnect all the sessions if the R-UDP stack stopped
2211 RUDPDisconnectSession(r, se, false);
2212 }
2213
2214 if (se->FlushBulkSendTube)
2215 {
2216 if (se->TcpSock != NULL && se->TcpSock->BulkSendTube != NULL)
2217 {
2218 TubeFlush(se->TcpSock->BulkSendTube);
2219 }
2220
2221 se->FlushBulkSendTube = false;
2222 }
2223
2224 if (se->Status == RUDP_SESSION_STATUS_ESTABLISHED)
2225 {
2226 // Process for all of the sessions which is established a connection
2227 UINT j;
2228
2229 if (r->Now >= (se->LatestRecvMyTick + (UINT64)RUDP_TIMEOUT))
2230 {
2231 // Disconnect the session because the fully communication failure is detected for a while
2232 Debug("R-UDP Session %X Timed Out.\n", se);
2233
2234 RUDPDisconnectSession(r, se, false);
2235 }
2236
2237 // If there are received segments, read to the part that has arrived in succession
2238 if (FifoSize(se->RecvFifo) <= RUDP_MAX_FIFO_SIZE)
2239 {
2240 LIST *o;
2241 UINT64 current_seq_no;
2242
2243 o = NULL;
2244 current_seq_no = se->LastRecvCompleteSeqNo;
2245 for (j = 0;j < LIST_NUM(se->RecvSegmentList);j++)
2246 {
2247 RUDP_SEGMENT *s;
2248
2249 current_seq_no++;
2250
2251 s = LIST_DATA(se->RecvSegmentList, j);
2252
2253 if (s->SeqNo == current_seq_no)
2254 {
2255 #ifdef RUDP_DETAIL_LOG
2256 Debug("%X s->SeqNo = %I64u, current_seq_no = %I64u\n", se, s->SeqNo, current_seq_no);
2257 #endif // RUDP_DETAIL_LOG
2258
2259 if (s->Size == sizeof(se->Magic_KeepAliveRequest) && Cmp(s->Data, se->Magic_KeepAliveRequest, sizeof(se->Magic_KeepAliveRequest)) == 0)
2260 {
2261 // Receive the KeepAlive Request
2262 #ifdef RUDP_DETAIL_LOG
2263 Debug("Recv KeepAlive Request\n");
2264 #endif // RUDP_DETAIL_LOG
2265
2266 // Send a KeepAlive Response if the transmisson queue is empty
2267 if (LIST_NUM(se->SendSegmentList) == 0)
2268 {
2269 #ifdef RUDP_DETAIL_LOG
2270 Debug("Send KeepAlive Response\n");
2271 #endif // RUDP_DETAIL_LOG
2272
2273 RUDPSendSegment(r, se, se->Magic_KeepAliveResponse, sizeof(se->Magic_KeepAliveResponse));
2274 }
2275 }
2276 else if (s->Size == sizeof(se->Magic_KeepAliveResponse) && Cmp(s->Data, se->Magic_KeepAliveResponse, sizeof(se->Magic_KeepAliveResponse)) == 0)
2277 {
2278 // Receive the KeepAlive Response
2279 #ifdef RUDP_DETAIL_LOG
2280 Debug("Recv KeepAlive Response\n");
2281 #endif // RUDP_DETAIL_LOG
2282 }
2283 else
2284 {
2285 // Write to the receive FIFO
2286 WriteFifo(se->RecvFifo, s->Data, s->Size);
2287 }
2288 r->TotalLogicalReceived += s->Size;
2289
2290 // Advance the SEQ NO which has been received completely
2291 se->LastRecvCompleteSeqNo = s->SeqNo;
2292
2293 // Add to the Delete list
2294 if (o == NULL)
2295 {
2296 o = NewListFast(NULL);
2297 }
2298 Add(o, s);
2299 }
2300 else
2301 {
2302 // Continuous reading is interrupted
2303 #ifdef RUDP_DETAIL_LOG
2304 Debug("%X s->SeqNo = %I64u, current_seq_no = %I64u\n", se, s->SeqNo, current_seq_no);
2305 WHERE;
2306 #endif // RUDP_DETAIL_LOG
2307 break;
2308 }
2309 }
2310
2311 // Delete the segment which has been received completely
2312 if (o != NULL)
2313 {
2314 for (j = 0;j < LIST_NUM(o);j++)
2315 {
2316 RUDP_SEGMENT *s = LIST_DATA(o, j);
2317
2318 Delete(se->RecvSegmentList, s);
2319 Free(s);
2320 }
2321 ReleaseList(o);
2322 }
2323 }
2324
2325 if (r->ServerMode && se->Magic_Disconnect == 0)
2326 {
2327 if (FifoSize(se->RecvFifo) >= sizeof(UINT64))
2328 {
2329 UINT64 ui;
2330
2331 if (ReadFifo(se->RecvFifo, &ui, sizeof(UINT64)) == sizeof(UINT64))
2332 {
2333 ui = Endian64(ui);
2334
2335 if ((ui & 0xffffffff00000000ULL) != 0ULL)
2336 {
2337 se->Magic_Disconnect = ui;
2338 }
2339 }
2340 }
2341 }
2342
2343 // If the data remains in FIFO, write it to the TCP socket as possible
2344 if (r->ServerMode == false || se->Magic_Disconnect != 0)
2345 {
2346 while (FifoSize(se->RecvFifo) >= 1)
2347 {
2348 UINT ret;
2349
2350 RUDPInitSock(r, se);
2351
2352 ret = Send(se->TcpSock, FifoPtr(se->RecvFifo), FifoSize(se->RecvFifo), false);
2353
2354 if (ret == SOCK_LATER)
2355 {
2356 // Can not write any more
2357 break;
2358 }
2359 else if (ret == 0)
2360 {
2361 // Disconnected
2362 Disconnect(se->TcpSock);
2363 RUDPDisconnectSession(r, se, false);
2364 break;
2365 }
2366 else
2367 {
2368 // Writing success
2369 ReadFifo(se->RecvFifo, NULL, ret);
2370 }
2371 }
2372 }
2373
2374 // Read the data as much as possible from the TCP socket and store it to FIFO
2375 if (se->TcpSock != NULL)
2376 {
2377 SetNoNeedToRead(se->TcpSock);
2378
2379 while (FifoSize(se->SendFifo) <= RUDP_MAX_FIFO_SIZE)
2380 {
2381 UINT ret = Recv(se->TcpSock, r->TmpBuf, sizeof(r->TmpBuf), false);
2382
2383 if (ret == SOCK_LATER)
2384 {
2385 // Can not read any more
2386 break;
2387 }
2388 else if (ret == 0)
2389 {
2390 // Disconnected
2391 Disconnect(se->TcpSock);
2392 RUDPDisconnectSession(r, se, false);
2393 break;
2394 }
2395 else
2396 {
2397 // Reading success
2398 WriteFifo(se->SendFifo, r->TmpBuf, ret);
2399 }
2400 }
2401 }
2402
2403 // Attempt to send a divided segment
2404 while (true)
2405 {
2406 UINT64 seq_no_min, seq_no_max;
2407
2408 seq_no_min = RUDPGetCurrentSendingMinSeqNo(se);
2409 seq_no_max = RUDPGetCurrentSendingMaxSeqNo(se);
2410
2411 #ifdef RUDP_DETAIL_LOG
2412 Debug("min=%I64u max=%I64u\n", seq_no_min, seq_no_max);
2413 #endif // RUDP_DETAIL_LOG
2414
2415 if (seq_no_min == 0 || ((seq_no_min + RUDP_MAX_NUM_ACK - 1) >= se->NextSendSeqNo))
2416 {
2417 // Because there is a room to send a new segment, send a segment
2418 UINT size = MIN(FifoSize(se->SendFifo), RUDP_MAX_SEGMENT_SIZE);
2419
2420 if (size == 0)
2421 {
2422 // There is no more data to send in FIFO
2423 break;
2424 }
2425
2426 // Transmission
2427 RUDPSendSegment(r, se, FifoPtr(se->SendFifo), size);
2428
2429 r->TotalLogicalSent += size;
2430
2431 // Advance the FIFO
2432 ReadFifo(se->SendFifo, NULL, size);
2433 }
2434 else
2435 {
2436 // There is no room to send a new segment further
2437 break;
2438 }
2439 }
2440
2441 if (se->DisconnectFlag == false)
2442 {
2443 UINT64 seq_no_min;
2444
2445 if (se->LastSentTick == 0 || (r->Now >= (se->LastSentTick + (UINT64)se->NextKeepAliveInterval)))
2446 {
2447 if (LIST_NUM(se->SendSegmentList) == 0)
2448 {
2449 // Send a Keep-Alive if no data was sent for a while and the transmission queue is empty
2450 RUDPSendSegment(r, se, se->Magic_KeepAliveRequest, sizeof(se->Magic_KeepAliveRequest));
2451
2452 #ifdef RUDP_DETAIL_LOG
2453 Debug("Sent KeepAlive Request\n");
2454 #endif // RUDP_DETAIL_LOG
2455 }
2456
2457 se->NextKeepAliveInterval = RUDP_KEEPALIVE_INTERVAL_MIN + (Rand32() % (RUDP_KEEPALIVE_INTERVAL_MAX - RUDP_KEEPALIVE_INTERVAL_MIN));
2458
2459 AddInterrupt(r->Interrupt, r->Now + se->NextKeepAliveInterval);
2460 }
2461
2462 seq_no_min = RUDPGetCurrentSendingMinSeqNo(se);
2463 for (j = 0;j < LIST_NUM(se->SendSegmentList);j++)
2464 {
2465 RUDP_SEGMENT *s = LIST_DATA(se->SendSegmentList, j);
2466
2467 if (s->SeqNo <= (seq_no_min + RUDP_MAX_NUM_ACK - 1))
2468 {
2469 if (s->NextSendTick == 0 || r->Now >= s->NextSendTick)
2470 {
2471 UINT next_interval;
2472 // Transmits a segment which has not been sent even once yet, or whose retransmission time has arrived
2473 RUDPSendSegmentNow(r, se, s->SeqNo, s->Data, s->Size);
2474
2475 if (se->CurrentRtt != 0)
2476 {
2477 next_interval = (se->CurrentRtt * 120 / 100) * Power(2, MIN(s->NumSent, 10));
2478 }
2479 else
2480 {
2481 next_interval = RUDP_RESEND_TIMER * Power(2, MIN(s->NumSent, 10));
2482 }
2483
2484 next_interval = MIN(next_interval, RUDP_RESEND_TIMER_MAX);
2485
2486 s->NumSent++;
2487
2488 s->NextSendTick = r->Now + next_interval;
2489
2490 AddInterrupt(r->Interrupt, s->NextSendTick);
2491 }
2492 }
2493 }
2494
2495 while (LIST_NUM(se->ReplyAckList) >= 1)
2496 {
2497 // If there are ACKs which is not responded yet in the list, send all of them
2498 RUDPSendSegmentNow(r, se, se->NextSendSeqNo, NULL, 0);
2499 }
2500
2501 // Send all if there are bulk transfer data
2502 if (se->TcpSock != NULL)
2503 {
2504 SOCK *s = se->TcpSock;
2505
2506 if (s->BulkRecvTube != NULL)
2507 {
2508 TUBE *t = s->BulkRecvTube;
2509
2510 while (true)
2511 {
2512 TUBEDATA *d = TubeRecvAsync(t);
2513
2514 if (d == NULL)
2515 {
2516 break;
2517 }
2518
2519 if (d->Header != NULL && d->HeaderSize == sizeof(TCP_PAIR_HEADER))
2520 {
2521 TCP_PAIR_HEADER *h = d->Header;
2522
2523 if (h->EnableHMac)
2524 {
2525 se->UseHMac = true;
2526 }
2527 }
2528
2529 RUDPBulkSend(r, se, d->Data, d->DataSize);
2530
2531 FreeTubeData(d);
2532 }
2533 }
2534 }
2535 }
2536 }
2537
2538 if (r->ServerMode == false)
2539 {
2540 if (se->Status == RUDP_SESSION_STATUS_CONNECT_SENT)
2541 {
2542 // Send a connection request periodically from the client side
2543 if (se->LastSentTick == 0 || ((se->LastSentTick + (UINT64)RUDP_RESEND_TIMER) <= r->Now))
2544 {
2545 UCHAR tmp[40];
2546 UINT size_of_padding = 19;
2547 UINT size = size_of_padding + SHA1_SIZE;
2548
2549 se->LastSentTick = r->Now;
2550
2551 Copy(tmp, se->Key_Init, SHA1_SIZE);
2552 Rand(tmp + SHA1_SIZE, size_of_padding);
2553
2554 if (r->Protocol == RUDP_PROTOCOL_ICMP)
2555 {
2556 // ICMP packet
2557 UCHAR *rand_data;
2558 UINT rand_size;
2559
2560 rand_size = Rand32() % 64 + 64;
2561 rand_data = Malloc(rand_size);
2562 Rand(rand_data, rand_size);
2563
2564 RUDPSendPacket(r, &se->YourIp, se->YourPort, rand_data, rand_size, ICMP_TYPE_ECHO_REQUEST);
2565 Free(rand_data);
2566
2567 se->Client_Icmp_NextSendEchoRequest = r->Now + GenRandInterval(RUDP_CLIENT_ECHO_REQUEST_SEND_INTERVAL_MIN, RUDP_CLIENT_ECHO_REQUEST_SEND_INTERVAL_MAX);
2568 AddInterrupt(r->Interrupt, se->Client_Icmp_NextSendEchoRequest);
2569
2570 // Try in both INFORMATION_REQUEST and ECHO_RESPONSE from the client side first
2571 RUDPSendPacket(r, &se->YourIp, se->YourPort, tmp, size, ICMP_TYPE_ECHO_RESPONSE);
2572 RUDPSendPacket(r, &se->YourIp, se->YourPort, tmp, size, ICMP_TYPE_INFORMATION_REQUEST);
2573 }
2574 else if (r->Protocol == RUDP_PROTOCOL_DNS)
2575 {
2576 // DNS
2577 RUDPSendPacket(r, &se->YourIp, se->YourPort, tmp, size, se->Dns_TranId);
2578 }
2579 else
2580 {
2581 // Normal UDP
2582 RUDPSendPacket(r, &se->YourIp, se->YourPort, tmp, size, 0);
2583 }
2584
2585 AddInterrupt(r->Interrupt, r->Now + (UINT64)RUDP_RESEND_TIMER);
2586 }
2587 }
2588
2589 if (r->Protocol == RUDP_PROTOCOL_ICMP)
2590 {
2591 if (se->Client_Icmp_NextSendEchoRequest == 0 || (r->Now >= se->Client_Icmp_NextSendEchoRequest))
2592 {
2593 // Periodic ICMP Echo transmission from the client side when R-UDP used in ICMP mode
2594 // (To maintain the mapping table of the NAT)
2595 UCHAR *rand_data;
2596 UINT rand_size;
2597
2598 rand_size = Rand32() % 64 + 64;
2599 rand_data = Malloc(rand_size);
2600 Rand(rand_data, rand_size);
2601
2602 RUDPSendPacket(r, &se->YourIp, se->YourPort, rand_data, rand_size, ICMP_TYPE_ECHO_REQUEST);
2603 Free(rand_data);
2604
2605 se->Client_Icmp_NextSendEchoRequest = r->Now + GenRandInterval(RUDP_CLIENT_ECHO_REQUEST_SEND_INTERVAL_MIN, RUDP_CLIENT_ECHO_REQUEST_SEND_INTERVAL_MAX);
2606 AddInterrupt(r->Interrupt, se->Client_Icmp_NextSendEchoRequest);
2607 }
2608 }
2609 }
2610 }
2611
2612 // Release the disconnected sessions
2613 o = NULL;
2614 for (i = 0;i < LIST_NUM(r->SessionList);i++)
2615 {
2616 RUDP_SESSION *se = LIST_DATA(r->SessionList, i);
2617
2618 if (se->DisconnectFlag)
2619 {
2620 if (o == NULL)
2621 {
2622 o = NewListFast(NULL);
2623 }
2624
2625 Add(o, se);
2626 }
2627 }
2628 if (o != NULL)
2629 {
2630 for (i = 0;i < LIST_NUM(o);i++)
2631 {
2632 RUDP_SESSION *se = LIST_DATA(o, i);
2633
2634 Delete(r->SessionList, se);
2635
2636 RUDPFreeSession(se);
2637 }
2638
2639 ReleaseList(o);
2640 }
2641 }
2642
2643 // Do the bulk send
RUDPBulkSend(RUDP_STACK * r,RUDP_SESSION * se,void * data,UINT data_size)2644 void RUDPBulkSend(RUDP_STACK *r, RUDP_SESSION *se, void *data, UINT data_size)
2645 {
2646 UCHAR *buf;
2647 UINT buf_size;
2648 UINT padding_size;
2649 UINT i;
2650 CRYPT *c;
2651 UCHAR crypt_key_src[SHA1_SIZE * 2];
2652 UCHAR crypt_key[SHA1_SIZE];
2653 UINT icmp_type;
2654 // Validate arguments
2655 if (r == NULL || se == NULL || (data == NULL && data_size != 0))
2656 {
2657 return;
2658 }
2659
2660 if (se->BulkSendKey->Size == RUDP_BULK_KEY_SIZE_V2)
2661 {
2662 // Ver 2
2663 UCHAR iv[RUDP_BULK_IV_SIZE_V2];
2664
2665 padding_size = Rand32() % 31 + 1;
2666
2667 // Packet: IV + Encrypted(SEQ_NO + Data + padding) + MAC
2668 buf_size = RUDP_BULK_IV_SIZE_V2 + sizeof(UINT64) + data_size + padding_size + RUDP_BULK_MAC_SIZE_V2;
2669 buf = Malloc(buf_size);
2670
2671 // IV
2672 Copy(iv, se->BulkNextIv_V2, RUDP_BULK_IV_SIZE_V2);
2673 Copy(buf, iv, RUDP_BULK_IV_SIZE_V2);
2674
2675 // SEQ NO
2676 WRITE_UINT64(buf + RUDP_BULK_IV_SIZE_V2, se->BulkNextSeqNo);
2677 se->BulkNextSeqNo++;
2678
2679 // Data
2680 Copy(buf + RUDP_BULK_IV_SIZE_V2 + sizeof(UINT64), data, data_size);
2681
2682 // Padding
2683 for (i = 0;i < padding_size;i++)
2684 {
2685 buf[RUDP_BULK_IV_SIZE_V2 + sizeof(UINT64) + data_size + i] = (UCHAR)padding_size;
2686 }
2687
2688 // Encryption
2689 Aead_ChaCha20Poly1305_Ietf_Encrypt(buf + RUDP_BULK_IV_SIZE_V2,
2690 buf + RUDP_BULK_IV_SIZE_V2,
2691 sizeof(UINT64) + data_size + padding_size,
2692 se->BulkSendKey->Data,
2693 iv,
2694 NULL,
2695 0);
2696
2697 // Next IV
2698 Copy(se->BulkNextIv_V2, buf + RUDP_BULK_IV_SIZE_V2 + sizeof(UINT64) + data_size + padding_size - RUDP_BULK_IV_SIZE_V2,
2699 RUDP_BULK_IV_SIZE_V2);
2700
2701 if (r->Protocol == RUDP_PROTOCOL_ICMP)
2702 {
2703 icmp_type = se->Icmp_Type;
2704 }
2705 else if (r->Protocol == RUDP_PROTOCOL_DNS)
2706 {
2707 icmp_type = se->Dns_TranId;
2708 }
2709 RUDPSendPacket(r, &se->YourIp, se->YourPort, buf, buf_size, icmp_type);
2710
2711 Free(buf);
2712 }
2713 else
2714 {
2715 UCHAR sign[SHA1_SIZE];
2716 UCHAR iv[SHA1_SIZE];
2717
2718 // Ver 1
2719 padding_size = Rand32() % 31 + 1;
2720
2721 buf_size = SHA1_SIZE + SHA1_SIZE + sizeof(UINT64) + data_size + padding_size;
2722 buf = Malloc(buf_size);
2723
2724 // SEQ NO
2725 WRITE_UINT64(buf + SHA1_SIZE + SHA1_SIZE, se->BulkNextSeqNo);
2726 se->BulkNextSeqNo++;
2727
2728 // Data
2729 Copy(buf + SHA1_SIZE + SHA1_SIZE + sizeof(UINT64), data, data_size);
2730
2731 // Padding
2732 for (i = 0;i < padding_size;i++)
2733 {
2734 buf[SHA1_SIZE + SHA1_SIZE + sizeof(UINT64) + data_size + i] = (UCHAR)padding_size;
2735 }
2736
2737 // Encryption
2738 Copy(iv, se->BulkNextIv, SHA1_SIZE);
2739 Copy(crypt_key_src + 0, se->BulkSendKey->Data, SHA1_SIZE);
2740 Copy(crypt_key_src + SHA1_SIZE, iv, SHA1_SIZE);
2741 HashSha1(crypt_key, crypt_key_src, SHA1_SIZE * 2);
2742 c = NewCrypt(crypt_key, sizeof(crypt_key));
2743 Encrypt(c, buf + SHA1_SIZE + SHA1_SIZE, buf + SHA1_SIZE + SHA1_SIZE, sizeof(UINT64) + data_size + padding_size);
2744 FreeCrypt(c);
2745
2746 // IV
2747 Copy(buf + SHA1_SIZE, iv, SHA1_SIZE);
2748
2749 // Sign
2750 if (se->UseHMac == false)
2751 {
2752 Copy(buf + 0, se->BulkSendKey->Data, SHA1_SIZE);
2753 HashSha1(sign, buf, SHA1_SIZE + SHA1_SIZE + sizeof(UINT64) + data_size + padding_size);
2754 Copy(buf + 0, sign, SHA1_SIZE);
2755 }
2756 else
2757 {
2758 HMacSha1(buf + 0, se->BulkSendKey->Data, SHA1_SIZE, buf + SHA1_SIZE, SHA1_SIZE + sizeof(UINT64) + data_size + padding_size);
2759 }
2760
2761 // Next IV
2762 Copy(se->BulkNextIv, buf + buf_size - SHA1_SIZE, SHA1_SIZE);
2763
2764 if (r->Protocol == RUDP_PROTOCOL_ICMP)
2765 {
2766 icmp_type = se->Icmp_Type;
2767 }
2768 else if (r->Protocol == RUDP_PROTOCOL_DNS)
2769 {
2770 icmp_type = se->Dns_TranId;
2771 }
2772 RUDPSendPacket(r, &se->YourIp, se->YourPort, buf, buf_size, icmp_type);
2773
2774 Free(buf);
2775 }
2776 }
2777
2778 // Start a socket for R-UDP Listening
ListenRUDP(char * svc_name,RUDP_STACK_INTERRUPTS_PROC * proc_interrupts,RUDP_STACK_RPC_RECV_PROC * proc_rpc_recv,void * param,UINT port,bool no_natt_register,bool over_dns_mode)2779 SOCK *ListenRUDP(char *svc_name, RUDP_STACK_INTERRUPTS_PROC *proc_interrupts, RUDP_STACK_RPC_RECV_PROC *proc_rpc_recv, void *param, UINT port, bool no_natt_register, bool over_dns_mode)
2780 {
2781 return ListenRUDPEx(svc_name, proc_interrupts, proc_rpc_recv, param, port, no_natt_register, over_dns_mode, NULL, 0);
2782 }
ListenRUDPEx(char * svc_name,RUDP_STACK_INTERRUPTS_PROC * proc_interrupts,RUDP_STACK_RPC_RECV_PROC * proc_rpc_recv,void * param,UINT port,bool no_natt_register,bool over_dns_mode,volatile UINT * natt_global_udp_port,UCHAR rand_port_id)2783 SOCK *ListenRUDPEx(char *svc_name, RUDP_STACK_INTERRUPTS_PROC *proc_interrupts, RUDP_STACK_RPC_RECV_PROC *proc_rpc_recv, void *param, UINT port, bool no_natt_register, bool over_dns_mode,
2784 volatile UINT *natt_global_udp_port, UCHAR rand_port_id)
2785 {
2786 SOCK *s;
2787 RUDP_STACK *r;
2788
2789 // Creating a R-UDP stack
2790 r = NewRUDPServer(svc_name, proc_interrupts, proc_rpc_recv, param, port, no_natt_register, over_dns_mode, natt_global_udp_port, rand_port_id);
2791 if (r == NULL)
2792 {
2793 return NULL;
2794 }
2795
2796 s = NewSock();
2797
2798 s->Type = SOCK_RUDP_LISTEN;
2799 s->ListenMode = true;
2800 s->Connected = true;
2801
2802 s->LocalPort = r->UdpSock->LocalPort;
2803
2804 s->R_UDP_Stack = r;
2805
2806 return s;
2807 }
2808
2809 // Accept on the R-UDP socket
AcceptRUDP(SOCK * s)2810 SOCK *AcceptRUDP(SOCK *s)
2811 {
2812 // Validate arguments
2813 if (s == NULL || s->Type != SOCK_RUDP_LISTEN || s->ListenMode == false)
2814 {
2815 return NULL;
2816 }
2817
2818 while (true)
2819 {
2820 RUDP_STACK *r = s->R_UDP_Stack;
2821 SOCK *ret;
2822
2823 if (s->Disconnecting || s->CancelAccept)
2824 {
2825 return NULL;
2826 }
2827
2828 ret = GetNextWithLock(r->NewSockQueue);
2829
2830 if (ret != NULL)
2831 {
2832 switch (r->Protocol)
2833 {
2834 case RUDP_PROTOCOL_UDP:
2835 StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_NAT_T);
2836 AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails),
2837 "RUDP/UDP");
2838 break;
2839
2840 case RUDP_PROTOCOL_DNS:
2841 StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_DNS);
2842 AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails),
2843 "RUDP/DNS");
2844 break;
2845
2846 case RUDP_PROTOCOL_ICMP:
2847 StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_ICMP);
2848 AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails),
2849 "RUDP/ICMP");
2850 break;
2851 }
2852
2853 return ret;
2854 }
2855
2856 Wait(r->NewSockConnectEvent, INFINITE);
2857 }
2858 }
2859
2860 // Verify the signature of the received packet
RUDPCheckSignOfRecvPacket(RUDP_STACK * r,RUDP_SESSION * se,void * recv_data,UINT recv_size)2861 bool RUDPCheckSignOfRecvPacket(RUDP_STACK *r, RUDP_SESSION *se, void *recv_data, UINT recv_size)
2862 {
2863 UCHAR sign[SHA1_SIZE];
2864 UCHAR sign2[SHA1_SIZE];
2865 UCHAR *p;
2866 UINT size;
2867 // Validate arguments
2868 if (r == NULL || se == NULL || recv_data == NULL || recv_size == 0)
2869 {
2870 return false;
2871 }
2872
2873 p = (UCHAR *)recv_data;
2874 size = recv_size;
2875 if (size < SHA1_SIZE)
2876 {
2877 return false;
2878 }
2879
2880 // Verification the signature (segment packet)
2881 Copy(sign, p, SHA1_SIZE);
2882 Copy(p, se->Key_Recv, SHA1_SIZE);
2883 HashSha1(sign2, p, recv_size);
2884
2885 if (r->Protocol == RUDP_PROTOCOL_DNS || r->Protocol == RUDP_PROTOCOL_ICMP)
2886 {
2887 XorData(sign2, sign2, r->SvcNameHash, SHA1_SIZE);
2888 }
2889
2890 Copy(p, sign, SHA1_SIZE);
2891 if (Cmp(sign, sign2, SHA1_SIZE) == 0)
2892 {
2893 return true;
2894 }
2895
2896 if (se->BulkRecvKey == NULL)
2897 {
2898 return false;
2899 }
2900
2901 // Verification signature (bulk packet)
2902 if (se->BulkRecvKey->Size == RUDP_BULK_KEY_SIZE_V2)
2903 {
2904 // Ver 2
2905 UCHAR *iv = p;
2906 // Packet: IV + Encrypted(SEQ_NO + Data + padding) + MAC
2907 // IV
2908 if (size < RUDP_BULK_IV_SIZE_V2)
2909 {
2910 return false;
2911 }
2912 iv = p;
2913 p += RUDP_BULK_IV_SIZE_V2;
2914 size -= RUDP_BULK_IV_SIZE_V2;
2915
2916 // Decrypt
2917 if (size < (RUDP_BULK_MAC_SIZE_V2 + 1))
2918 {
2919 return false;
2920 }
2921 if (Aead_ChaCha20Poly1305_Ietf_Decrypt(r->TmpBuf, p, size, se->BulkRecvKey->Data, iv, NULL, 0) == false)
2922 {
2923 return false;
2924 }
2925 return true;
2926 }
2927 else
2928 {
2929 // Ver 1
2930 if (se->UseHMac == false)
2931 {
2932 Copy(sign, p, SHA1_SIZE);
2933 Copy(p, se->BulkRecvKey->Data, SHA1_SIZE);
2934 HashSha1(sign2, p, recv_size);
2935 Copy(p, sign, SHA1_SIZE);
2936
2937 if (Cmp(sign, sign2, SHA1_SIZE) == 0)
2938 {
2939 return true;
2940 }
2941 }
2942
2943 HMacSha1(sign2, se->BulkRecvKey->Data, SHA1_SIZE, p + SHA1_SIZE, size - SHA1_SIZE);
2944 if (Cmp(p, sign2, SHA1_SIZE) == 0)
2945 {
2946 se->UseHMac = true;
2947 return true;
2948 }
2949 }
2950
2951 return false;
2952 }
2953
2954 // Process the received packet (bulk)
RUDPProcessBulkRecvPacket(RUDP_STACK * r,RUDP_SESSION * se,void * recv_data,UINT recv_size)2955 bool RUDPProcessBulkRecvPacket(RUDP_STACK *r, RUDP_SESSION *se, void *recv_data, UINT recv_size)
2956 {
2957 UCHAR sign[SHA1_SIZE];
2958 UCHAR sign2[SHA1_SIZE];
2959 UCHAR *p;
2960 UCHAR *iv;
2961 UINT size;
2962 UCHAR keygen[SHA1_SIZE * 2];
2963 UCHAR key[SHA1_SIZE];
2964 CRYPT *c;
2965 UCHAR padlen;
2966 UINT64 seq_no;
2967 UCHAR *payload;
2968 UINT payload_size;
2969 // Validate arguments
2970 if (r == NULL || se == NULL || recv_data == NULL || recv_size == 0 || se->BulkRecvKey == NULL)
2971 {
2972 return false;
2973 }
2974
2975 p = (UCHAR *)recv_data;
2976 size = recv_size;
2977 if (size < SHA1_SIZE)
2978 {
2979 return false;
2980 }
2981
2982 if (se->BulkRecvKey->Size == RUDP_BULK_KEY_SIZE_V2)
2983 {
2984 // Ver 2
2985 // Packet: IV + Encrypted(SEQ_NO + Data + padding) + MAC
2986 // IV
2987 if (size < RUDP_BULK_IV_SIZE_V2)
2988 {
2989 WHERE;
2990 return false;
2991 }
2992 iv = p;
2993 p += RUDP_BULK_IV_SIZE_V2;
2994 size -= RUDP_BULK_IV_SIZE_V2;
2995
2996 // Decrypt
2997 if (size < (RUDP_BULK_MAC_SIZE_V2 + 1))
2998 {
2999 WHERE;
3000 return false;
3001 }
3002 if (Aead_ChaCha20Poly1305_Ietf_Decrypt(p, p, size, se->BulkRecvKey->Data, iv, NULL, 0) == false)
3003 {
3004 WHERE;
3005 return false;
3006 }
3007
3008 size -= RUDP_BULK_MAC_SIZE_V2;
3009
3010 // padlen
3011 padlen = p[size - 1];
3012 if (padlen == 0)
3013 {
3014 WHERE;
3015 return false;
3016 }
3017 if (size < padlen)
3018 {
3019 WHERE;
3020 return false;
3021 }
3022 size -= padlen;
3023 }
3024 else
3025 {
3026 // Validate the signature
3027 if (se->UseHMac == false)
3028 {
3029 Copy(sign, p, SHA1_SIZE);
3030 Copy(p, se->BulkRecvKey->Data, SHA1_SIZE);
3031 HashSha1(sign2, p, recv_size);
3032 Copy(p, sign, SHA1_SIZE);
3033
3034 if (Cmp(sign, sign2, SHA1_SIZE) != 0)
3035 {
3036 HMacSha1(sign2, se->BulkRecvKey->Data, SHA1_SIZE, p + SHA1_SIZE, recv_size - SHA1_SIZE);
3037
3038 if (Cmp(p, sign2, SHA1_SIZE) != 0)
3039 {
3040 return false;
3041 }
3042 else
3043 {
3044 se->UseHMac = true;
3045 }
3046 }
3047 else
3048 {
3049 }
3050 }
3051 else
3052 {
3053 HMacSha1(sign2, se->BulkRecvKey->Data, SHA1_SIZE, p + SHA1_SIZE, recv_size - SHA1_SIZE);
3054
3055 if (Cmp(p, sign2, SHA1_SIZE) != 0)
3056 {
3057 return false;
3058 }
3059 }
3060
3061 p += SHA1_SIZE;
3062 size -= SHA1_SIZE;
3063
3064 // IV
3065 if (size < SHA1_SIZE)
3066 {
3067 return false;
3068 }
3069 iv = p;
3070 p += SHA1_SIZE;
3071 size -= SHA1_SIZE;
3072
3073 // Decrypt
3074 if (size < 1)
3075 {
3076 return false;
3077 }
3078 Copy(keygen + 0, se->BulkRecvKey->Data, SHA1_SIZE);
3079 Copy(keygen + SHA1_SIZE, iv, SHA1_SIZE);
3080 HashSha1(key, keygen, sizeof(keygen));
3081
3082 c = NewCrypt(key, sizeof(key));
3083 Encrypt(c, p, p, size);
3084 FreeCrypt(c);
3085
3086 // padlen
3087 padlen = p[size - 1];
3088 if (padlen == 0)
3089 {
3090 return false;
3091 }
3092 if (size < padlen)
3093 {
3094 return false;
3095 }
3096 size -= padlen;
3097 }
3098
3099 // SEQ NO
3100 seq_no = READ_UINT64(p);
3101 p += sizeof(UINT64);
3102 size -= sizeof(UINT64);
3103
3104 if (seq_no == 0 || seq_no >= (0xF000000000000000ULL))
3105 {
3106 // Sequence number is invalid
3107 return false;
3108 }
3109
3110 if ((seq_no + RUDP_BULK_SEQ_NO_RANGE) < se->BulkRecvSeqNoMax)
3111 {
3112 // Sequence number is too small
3113 return false;
3114 }
3115
3116 se->LastRecvTick = r->Now;
3117
3118 payload = p;
3119 payload_size = size;
3120
3121 se->BulkRecvSeqNoMax = MAX(seq_no, se->BulkRecvSeqNoMax);
3122
3123 // Send the received bulk packet to the Tube of the socket
3124 RUDPInitSock(r, se);
3125
3126 if (se->TcpSock != NULL)
3127 {
3128 SOCK *s = se->TcpSock;
3129 TUBE *t = s->BulkSendTube;
3130
3131 if (t != NULL)
3132 {
3133 TubeSendEx2(t, payload, payload_size, NULL, true, RUDP_BULK_MAX_RECV_PKTS_IN_QUEUE);
3134
3135 se->FlushBulkSendTube = true;
3136 }
3137 }
3138
3139 return true;
3140 }
3141
3142 // Process the received packet (segment)
RUDPProcessRecvPacket(RUDP_STACK * r,RUDP_SESSION * se,void * recv_data,UINT recv_size)3143 bool RUDPProcessRecvPacket(RUDP_STACK *r, RUDP_SESSION *se, void *recv_data, UINT recv_size)
3144 {
3145 UCHAR sign[SHA1_SIZE];
3146 UCHAR sign2[SHA1_SIZE];
3147 UCHAR *p;
3148 UCHAR *iv;
3149 UINT size;
3150 UCHAR keygen[SHA1_SIZE * 2];
3151 UCHAR key[SHA1_SIZE];
3152 CRYPT *c;
3153 UCHAR padlen;
3154 UINT num_ack;
3155 UINT i;
3156 UINT64 seq_no;
3157 UCHAR *payload;
3158 UINT payload_size;
3159 UINT64 max_ack;
3160 UINT64 my_tick, your_tick;
3161 // Validate arguments
3162 if (r == NULL || se == NULL || recv_data == NULL || recv_size == 0)
3163 {
3164 return false;
3165 }
3166
3167 p = (UCHAR *)recv_data;
3168 size = recv_size;
3169 if (size < SHA1_SIZE)
3170 {
3171 return false;
3172 }
3173
3174 // Validate the signature
3175 Copy(sign, p, SHA1_SIZE);
3176 Copy(p, se->Key_Recv, SHA1_SIZE);
3177 HashSha1(sign2, p, recv_size);
3178 Copy(p, sign, SHA1_SIZE);
3179
3180 if (r->Protocol == RUDP_PROTOCOL_DNS || r->Protocol == RUDP_PROTOCOL_ICMP)
3181 {
3182 XorData(sign2, sign2, r->SvcNameHash, SHA1_SIZE);
3183 }
3184
3185 if (Cmp(sign, sign2, SHA1_SIZE) != 0)
3186 {
3187 //WHERE;
3188 return false;
3189 }
3190 p += SHA1_SIZE;
3191 size -= SHA1_SIZE;
3192
3193 // IV
3194 if (size < SHA1_SIZE)
3195 {
3196 return false;
3197 }
3198 iv = p;
3199 p += SHA1_SIZE;
3200 size -= SHA1_SIZE;
3201
3202 // Decrypt
3203 if (size < 1)
3204 {
3205 return false;
3206 }
3207 Copy(keygen + 0, iv, SHA1_SIZE);
3208 Copy(keygen + SHA1_SIZE, se->Key_Recv, SHA1_SIZE);
3209 HashSha1(key, keygen, sizeof(keygen));
3210
3211 c = NewCrypt(key, sizeof(key));
3212 Encrypt(c, p, p, size);
3213 FreeCrypt(c);
3214
3215 // padlen
3216 padlen = p[size - 1];
3217 if (padlen == 0)
3218 {
3219 return false;
3220 }
3221 if (size < padlen)
3222 {
3223 return false;
3224 }
3225 size -= padlen;
3226
3227 // MyTick
3228 if (size < sizeof(UINT64))
3229 {
3230 return false;
3231 }
3232 my_tick = READ_UINT64(p);
3233 p += sizeof(UINT64);
3234 size -= sizeof(UINT64);
3235
3236 // YourTick
3237 if (size < sizeof(UINT64))
3238 {
3239 return false;
3240 }
3241 your_tick = READ_UINT64(p);
3242 p += sizeof(UINT64);
3243 size -= sizeof(UINT64);
3244
3245 if (your_tick > r->Now)
3246 {
3247 return false;
3248 }
3249
3250 // MAX_ACK
3251 if (size < sizeof(UINT64))
3252 {
3253 return false;
3254 }
3255 max_ack = READ_UINT64(p);
3256 p += sizeof(UINT64);
3257 size -= sizeof(UINT64);
3258
3259 // num_ack
3260 if (size < sizeof(UINT))
3261 {
3262 return false;
3263 }
3264
3265 num_ack = READ_UINT(p);
3266 if (num_ack > RUDP_MAX_NUM_ACK)
3267 {
3268 return false;
3269 }
3270 p += sizeof(UINT);
3271 size -= sizeof(UINT);
3272
3273 // ACKs
3274 if (size < (sizeof(UINT64) * num_ack + sizeof(UINT64)))
3275 {
3276 return false;
3277 }
3278
3279 if (max_ack >= 1)
3280 {
3281 RUDPProcessAck2(r, se, max_ack);
3282 }
3283
3284 for (i = 0;i < num_ack;i++)
3285 {
3286 UINT64 seq = READ_UINT64(p);
3287
3288 RUDPProcessAck(r, se, seq);
3289
3290 p += sizeof(UINT64);
3291 size -= sizeof(UINT64);
3292 }
3293
3294 // Processing of the Tick (Calculation of RTT)
3295 if (my_tick >= 2)
3296 {
3297 my_tick--;
3298 }
3299 se->YourTick = MAX(se->YourTick, my_tick);
3300
3301 se->LatestRecvMyTick = MAX(se->LatestRecvMyTick, your_tick);
3302
3303 if (se->LatestRecvMyTick2 != se->LatestRecvMyTick)
3304 {
3305 se->LatestRecvMyTick2 = se->LatestRecvMyTick;
3306 se->CurrentRtt = (UINT)(r->Now - se->LatestRecvMyTick);
3307
3308 #ifdef RUDP_DETAIL_LOG
3309 Debug("CurrentRTT = %u\n", se->CurrentRtt);
3310 #endif // RUDP_DETAIL_LOG
3311 }
3312
3313 // SEQ NO
3314 seq_no = READ_UINT64(p);
3315 p += sizeof(UINT64);
3316 size -= sizeof(UINT64);
3317
3318 if (seq_no == 0)
3319 {
3320 // Sequence number of 0 is a invalid packet
3321 return true;
3322 }
3323
3324 if (seq_no == se->Magic_Disconnect)
3325 {
3326 // Disconnected from opponent
3327 RUDPDisconnectSession(r, se, true);
3328 return true;
3329 }
3330
3331 // Update the last reception date and time
3332 se->LastRecvTick = r->Now;
3333
3334 payload = p;
3335 payload_size = size;
3336
3337 #ifdef RUDP_DETAIL_LOG
3338 Debug("RUDP %X Segment Recv: %I64u (num_ack=%u, size=%u)\n", se, seq_no, num_ack, size);
3339 #endif // RUDP_DETAIL_LOG
3340
3341 if (payload_size >= 1 && payload_size <= RUDP_MAX_SEGMENT_SIZE)
3342 {
3343 // Received one or more bytes of data
3344
3345 #ifdef RUDP_DETAIL_LOG
3346 Debug("Recv Size: %X %I64u %u %u\n", se, seq_no, payload_size, recv_size);
3347 #endif // RUDP_DETAIL_LOG
3348
3349 RUDPProcessRecvPayload(r, se, seq_no, payload, payload_size);
3350 }
3351
3352 if (r->ServerMode == false)
3353 {
3354 if (se->Status == RUDP_SESSION_STATUS_CONNECT_SENT)
3355 {
3356 // Shift to the established state if the connection is not yet in established state
3357 se->Status = RUDP_SESSION_STATUS_ESTABLISHED;
3358
3359 RUDPInitSock(r, se);
3360 }
3361 }
3362
3363 return true;
3364 }
3365
3366 // Disconnect the session
RUDPDisconnectSession(RUDP_STACK * r,RUDP_SESSION * se,bool disconnected_by_you)3367 void RUDPDisconnectSession(RUDP_STACK *r, RUDP_SESSION *se, bool disconnected_by_you)
3368 {
3369 // Validate arguments
3370 if (r == NULL || se == NULL)
3371 {
3372 return;
3373 }
3374
3375 if (se->DisconnectFlag == false)
3376 {
3377 UINT i;
3378
3379 se->DisconnectFlag = true;
3380 se->DisconnectedByYou = disconnected_by_you;
3381
3382 Debug("R-UDP Session %X Disconnected. by you flag: %u\n", se, disconnected_by_you);
3383
3384 if (se->TcpSock != NULL)
3385 {
3386 // Disconnect a TCP socket
3387 Disconnect(se->TcpSock);
3388 ReleaseSock(se->TcpSock);
3389
3390 se->TcpSock = NULL;
3391 }
3392
3393 // Send 5 disconnect signals serially if to disconnect from here
3394 if (disconnected_by_you == false)
3395 {
3396 for (i = 0;i < 5;i++)
3397 {
3398 RUDPSendSegmentNow(r, se, se->Magic_Disconnect, NULL, 0);
3399 }
3400 }
3401 }
3402 }
3403
3404 // Initialize the TCP socket for the session
RUDPInitSock(RUDP_STACK * r,RUDP_SESSION * se)3405 void RUDPInitSock(RUDP_STACK *r, RUDP_SESSION *se)
3406 {
3407 SOCK *s1, *s2;
3408 UINT mss;
3409 // Validate arguments
3410 if (r == NULL || se == NULL || se->DisconnectFlag)
3411 {
3412 return;
3413 }
3414
3415 if (se->TcpSock != NULL)
3416 {
3417 // It has already been created
3418 return;
3419 }
3420
3421 // Creating a TCP socket pair
3422 if (NewTcpPair(&s1, &s2) == false)
3423 {
3424 // Failed to create. Disconnect the session
3425 RUDPDisconnectSession(r, se, false);
3426 return;
3427 }
3428
3429 // Calculate the optimal MSS
3430 mss = RUDPCalcBestMssForBulk(r, se);
3431
3432 if (r->ServerMode)
3433 {
3434 // Server mode
3435 se->TcpSock = s2;
3436
3437 JoinSockToSockEvent(s2, r->SockEvent);
3438
3439 // Update the end point information of the socket s1
3440 ZeroIP4(&s1->LocalIP);
3441 s1->LocalPort = se->MyPort;
3442 Copy(&s1->RemoteIP, &se->YourIp, sizeof(IP));
3443 s1->RemotePort = se->YourPort;
3444 if (IsLocalHostIP(&s1->RemoteIP) == false)
3445 {
3446 AddIpClient(&s1->RemoteIP);
3447 s1->IpClientAdded = true;
3448 }
3449 s1->IsRUDPSocket = true;
3450
3451 s1->BulkSendKey = se->BulkSendKey;
3452 s1->BulkRecvKey = se->BulkRecvKey;
3453
3454 AddRef(s1->BulkSendKey->Ref);
3455 AddRef(s1->BulkRecvKey->Ref);
3456
3457 s1->RUDP_OptimizedMss = mss;
3458
3459 // Enqueue the newly created socket, and set the event
3460 InsertQueueWithLock(r->NewSockQueue, s1);
3461 Set(r->NewSockConnectEvent);
3462 }
3463 else
3464 {
3465 // Client mode
3466 Lock(r->Lock);
3467 {
3468 if (r->TargetConnectedSock == NULL && r->DoNotSetTargetConnectedSock == false)
3469 {
3470 // Update the end point information of the socket s2
3471 Copy(&s2->LocalIP, &r->UdpSock->LocalIP, sizeof(IP));
3472 s2->LocalPort = se->MyPort;
3473 Copy(&s2->RemoteIP, &se->YourIp, sizeof(IP));
3474 s2->RemotePort = se->YourPort;
3475 if (IsLocalHostIP(&s2->RemoteIP) == false)
3476 {
3477 AddIpClient(&s2->RemoteIP);
3478 s2->IpClientAdded = true;
3479 }
3480 s2->IsRUDPSocket = true;
3481
3482 s2->BulkSendKey = se->BulkSendKey;
3483 s2->BulkRecvKey = se->BulkRecvKey;
3484
3485 AddRef(s2->BulkSendKey->Ref);
3486 AddRef(s2->BulkRecvKey->Ref);
3487
3488 s2->RUDP_OptimizedMss = mss;
3489
3490 // Register the socket to the RUDP stack
3491 r->TargetConnectedSock = s2;
3492 s2->R_UDP_Stack = r;
3493 se->TcpSock = s1;
3494
3495 JoinSockToSockEvent(s1, r->SockEvent);
3496
3497 // Set the event to be set when the connection is successful
3498 Set(r->TargetConnectedEvent);
3499 }
3500 else
3501 {
3502 Disconnect(s1);
3503 Disconnect(s2);
3504 ReleaseSock(s1);
3505 ReleaseSock(s2);
3506 }
3507 }
3508 Unlock(r->Lock);
3509 }
3510 }
3511
3512 // Process the received payload
RUDPProcessRecvPayload(RUDP_STACK * r,RUDP_SESSION * se,UINT64 seq,void * payload_data,UINT payload_size)3513 void RUDPProcessRecvPayload(RUDP_STACK *r, RUDP_SESSION *se, UINT64 seq, void *payload_data, UINT payload_size)
3514 {
3515 RUDP_SEGMENT t;
3516 RUDP_SEGMENT *s;
3517 // Validate arguments
3518 if (r == NULL || se == NULL || seq == 0 || payload_data == NULL || payload_size == 0 || payload_size > RUDP_MAX_SEGMENT_SIZE)
3519 {
3520 return;
3521 }
3522
3523 if (seq > (se->LastRecvCompleteSeqNo + RUDP_MAX_NUM_ACK))
3524 {
3525 // Ignore the segment which have sequence number beyond the window size, and also not to reply an ACK
3526 return;
3527 }
3528
3529 if (seq <= se->LastRecvCompleteSeqNo)
3530 {
3531 // Do not receive the segment which have the sequence number that has been already received. However, reply an ACK for it
3532 AddInt64Distinct(se->ReplyAckList, seq);
3533 return;
3534 }
3535
3536 Zero(&t, sizeof(t));
3537 t.SeqNo = seq;
3538
3539 s = Search(se->RecvSegmentList, &t);
3540 if (s != NULL)
3541 {
3542 // Do not receive the segment which have the sequence number that has been already received. However, reply an ACK for it
3543 AddInt64Distinct(se->ReplyAckList, seq);
3544 return;
3545 }
3546
3547 // Received a segment of the new sequence number
3548 s = ZeroMalloc(sizeof(RUDP_SEGMENT));
3549 s->SeqNo = seq;
3550 Copy(s->Data, payload_data, payload_size);
3551 s->Size = payload_size;
3552 Insert(se->RecvSegmentList, s);
3553
3554 // Reply an ACK
3555 AddInt64Distinct(se->ReplyAckList, seq);
3556
3557 // Create a socket for session if it have not been created yet
3558 //RUDPInitSock(r, se);
3559 }
3560
3561 // Process the incoming ACK
RUDPProcessAck(RUDP_STACK * r,RUDP_SESSION * se,UINT64 seq)3562 void RUDPProcessAck(RUDP_STACK *r, RUDP_SESSION *se, UINT64 seq)
3563 {
3564 RUDP_SEGMENT t;
3565 RUDP_SEGMENT *s;
3566 // Validate arguments
3567 if (r == NULL || se == NULL || seq == 0)
3568 {
3569 return;
3570 }
3571
3572 Zero(&t, sizeof(t));
3573 t.SeqNo = seq;
3574
3575 s = Search(se->SendSegmentList, &t);
3576 if (s == NULL)
3577 {
3578 return;
3579 }
3580
3581 Delete(se->SendSegmentList, s);
3582 Free(s);
3583 }
3584
3585 // Remove all segments which are preceding max_seq as already delivered
RUDPProcessAck2(RUDP_STACK * r,RUDP_SESSION * se,UINT64 max_seq)3586 void RUDPProcessAck2(RUDP_STACK *r, RUDP_SESSION *se, UINT64 max_seq)
3587 {
3588 LIST *o;
3589 UINT i;
3590 // Validate arguments
3591 if (r == NULL || se == NULL || max_seq == 0)
3592 {
3593 return;
3594 }
3595
3596 o = NULL;
3597
3598 for (i = 0;i < LIST_NUM(se->SendSegmentList);i++)
3599 {
3600 RUDP_SEGMENT *s = LIST_DATA(se->SendSegmentList, i);
3601
3602 if (s->SeqNo <= max_seq)
3603 {
3604 if (o == NULL)
3605 {
3606 o = NewListFast(NULL);
3607 }
3608
3609 Add(o, s);
3610 }
3611 }
3612
3613 if (o != NULL)
3614 {
3615 for (i = 0;i < LIST_NUM(o);i++)
3616 {
3617 RUDP_SEGMENT *s = LIST_DATA(o, i);
3618
3619 Delete(se->SendSegmentList, s);
3620
3621 Free(s);
3622 }
3623
3624 ReleaseList(o);
3625 }
3626 }
3627
3628 // Get the minimum sequence number which is trying to send
RUDPGetCurrentSendingMinSeqNo(RUDP_SESSION * se)3629 UINT64 RUDPGetCurrentSendingMinSeqNo(RUDP_SESSION *se)
3630 {
3631 RUDP_SEGMENT *s;
3632 // Validate arguments
3633 if (se == NULL)
3634 {
3635 return 0;
3636 }
3637
3638 if (LIST_NUM(se->SendSegmentList) == 0)
3639 {
3640 return 0;
3641 }
3642
3643 s = LIST_DATA(se->SendSegmentList, 0);
3644
3645 return s->SeqNo;
3646 }
3647
3648 // Get the maximum sequence number which is trying to send
RUDPGetCurrentSendingMaxSeqNo(RUDP_SESSION * se)3649 UINT64 RUDPGetCurrentSendingMaxSeqNo(RUDP_SESSION *se)
3650 {
3651 RUDP_SEGMENT *s;
3652 // Validate arguments
3653 if (se == NULL)
3654 {
3655 return 0;
3656 }
3657
3658 if (LIST_NUM(se->SendSegmentList) == 0)
3659 {
3660 return 0;
3661 }
3662
3663 s = LIST_DATA(se->SendSegmentList, (LIST_NUM(se->SendSegmentList) - 1));
3664
3665 return s->SeqNo;
3666 }
3667
3668 // R-UDP segment transmission
RUDPSendSegmentNow(RUDP_STACK * r,RUDP_SESSION * se,UINT64 seq_no,void * data,UINT size)3669 void RUDPSendSegmentNow(RUDP_STACK *r, RUDP_SESSION *se, UINT64 seq_no, void *data, UINT size)
3670 {
3671 UCHAR dst[RUDP_MAX_PACKET_SIZE];
3672 UCHAR *p;
3673 UCHAR *iv;
3674 LIST *o = NULL;
3675 UINT i;
3676 UCHAR padlen;
3677 UINT current_size;
3678 UCHAR sign[SHA1_SIZE];
3679 UCHAR key[SHA1_SIZE];
3680 UCHAR keygen[SHA1_SIZE * 2];
3681 CRYPT *c;
3682 UINT next_iv_pos;
3683 UINT num_ack;
3684 UINT icmp_type = 0;
3685 // Validate arguments
3686 if (r == NULL || se == NULL || (size != 0 && data == NULL) || (size > RUDP_MAX_SEGMENT_SIZE))
3687 {
3688 return;
3689 }
3690
3691 Zero(dst, sizeof(dst));
3692 p = dst;
3693
3694 // SIGN
3695 Copy(p, se->Key_Send, SHA1_SIZE);
3696 p += SHA1_SIZE;
3697
3698 // IV
3699 iv = p;
3700 Copy(iv, se->NextIv, SHA1_SIZE);
3701 p += SHA1_SIZE;
3702
3703 for (i = 0;i < MIN(LIST_NUM(se->ReplyAckList), RUDP_MAX_NUM_ACK);i++)
3704 {
3705 UINT64 *seq = LIST_DATA(se->ReplyAckList, i);
3706
3707 if (o == NULL)
3708 {
3709 o = NewListFast(NULL);
3710 }
3711
3712 Add(o, seq);
3713 }
3714
3715 // MyTick
3716 WRITE_UINT64(p, r->Now);
3717 p += sizeof(UINT64);
3718
3719 // YourTick
3720 WRITE_UINT64(p, se->YourTick);
3721 p += sizeof(UINT64);
3722
3723 // MAX_ACK
3724 WRITE_UINT64(p, se->LastRecvCompleteSeqNo);
3725 p += sizeof(UINT64);
3726
3727 // NUM_ACK
3728 num_ack = LIST_NUM(o);
3729 WRITE_UINT(p, num_ack);
3730 p += sizeof(UINT);
3731
3732 if (o != NULL)
3733 {
3734 // ACK body
3735 for (i = 0;i < LIST_NUM(o);i++)
3736 {
3737 UINT64 *seq = LIST_DATA(o, i);
3738
3739 WRITE_UINT64(p, *seq);
3740 p += sizeof(UINT64);
3741
3742 Delete(se->ReplyAckList, seq);
3743
3744 Free(seq);
3745 }
3746 ReleaseList(o);
3747 }
3748
3749 // SEQ
3750 WRITE_UINT64(p, seq_no);
3751 p += sizeof(UINT64);
3752
3753 // data
3754 Copy(p, data, size);
3755 p += size;
3756
3757 // padding
3758 padlen = Rand8();
3759 padlen = MAX(padlen, 1);
3760
3761 for (i = 0;i < padlen;i++)
3762 {
3763 *p = padlen;
3764 p++;
3765 }
3766
3767 current_size = (UINT)(p - dst);
3768
3769 // Encrypt
3770 Copy(keygen + 0, iv, SHA1_SIZE);
3771 Copy(keygen + SHA1_SIZE, se->Key_Send, SHA1_SIZE);
3772 HashSha1(key, keygen, sizeof(keygen));
3773 c = NewCrypt(key, sizeof(key));
3774 Encrypt(c, dst + SHA1_SIZE * 2, dst + SHA1_SIZE * 2, current_size - (SHA1_SIZE * 2));
3775 FreeCrypt(c);
3776
3777 // Sign
3778 HashSha1(sign, dst, current_size);
3779 if (r->Protocol == RUDP_PROTOCOL_DNS || r->Protocol == RUDP_PROTOCOL_ICMP)
3780 {
3781 XorData(sign, sign, r->SvcNameHash, SHA1_SIZE);
3782 }
3783 Copy(dst, sign, SHA1_SIZE);
3784
3785 if (r->Protocol == RUDP_PROTOCOL_ICMP)
3786 {
3787 icmp_type = se->Icmp_Type;
3788 }
3789 else if (r->Protocol == RUDP_PROTOCOL_DNS)
3790 {
3791 icmp_type = se->Dns_TranId;
3792 }
3793 RUDPSendPacket(r, &se->YourIp, se->YourPort, dst, current_size, icmp_type);
3794
3795 if (size >= 1)
3796 {
3797 se->LastSentTick = r->Now;
3798 }
3799
3800 // Next IV
3801 next_iv_pos = Rand32() % (current_size - SHA1_SIZE);
3802 Copy(se->NextIv, dst + next_iv_pos, SHA1_SIZE);
3803
3804 #ifdef RUDP_DETAIL_LOG
3805 Debug("RUDP %X Segment Sent: %I64u (num_ack=%u, size=%u)\n", se, seq_no, num_ack, size);
3806 #endif // RUDP_DETAIL_LOG
3807
3808 if (size >= 1)
3809 {
3810 #ifdef RUDP_DETAIL_LOG
3811 Debug("Send Size: %X %I64u %u %u\n", se, seq_no, size, current_size);
3812 #endif // RUDP_DETAIL_LOG
3813 }
3814 }
3815
3816 // R-UDP segment transmission (only put into the queue)
RUDPSendSegment(RUDP_STACK * r,RUDP_SESSION * se,void * data,UINT size)3817 void RUDPSendSegment(RUDP_STACK *r, RUDP_SESSION *se, void *data, UINT size)
3818 {
3819 RUDP_SEGMENT *s;
3820 // Validate arguments
3821 if (r == NULL || se == NULL || (size != 0 && data == NULL) || (size > RUDP_MAX_SEGMENT_SIZE))
3822 {
3823 return;
3824 }
3825
3826 s = ZeroMalloc(sizeof(RUDP_SEGMENT));
3827
3828 Copy(s->Data, data, size);
3829 s->Size = size;
3830
3831 s->SeqNo = se->NextSendSeqNo++;
3832
3833 Insert(se->SendSegmentList, s);
3834 }
3835
3836 // Search for a session
RUDPSearchSession(RUDP_STACK * r,IP * my_ip,UINT my_port,IP * your_ip,UINT your_port)3837 RUDP_SESSION *RUDPSearchSession(RUDP_STACK *r, IP *my_ip, UINT my_port, IP *your_ip, UINT your_port)
3838 {
3839 RUDP_SESSION t;
3840 RUDP_SESSION *se;
3841 // Validate arguments
3842 if (r == NULL || my_ip == NULL || your_ip == NULL)
3843 {
3844 return NULL;
3845 }
3846
3847 Copy(&t.MyIp, my_ip, sizeof(IP));
3848 t.MyPort = my_port;
3849 Copy(&t.YourIp, your_ip, sizeof(IP));
3850 t.YourPort = your_port;
3851
3852 se = Search(r->SessionList, &t);
3853
3854 return se;
3855 }
3856
3857 // Release of the session
RUDPFreeSession(RUDP_SESSION * se)3858 void RUDPFreeSession(RUDP_SESSION *se)
3859 {
3860 UINT i;
3861 // Validate arguments
3862 if (se == NULL)
3863 {
3864 return;
3865 }
3866
3867 Debug("RUDPFreeSession %X\n", se);
3868
3869 for (i = 0;i < LIST_NUM(se->SendSegmentList);i++)
3870 {
3871 RUDP_SEGMENT *s = LIST_DATA(se->SendSegmentList, i);
3872
3873 Free(s);
3874 }
3875
3876 ReleaseList(se->SendSegmentList);
3877
3878 for (i = 0;i < LIST_NUM(se->RecvSegmentList);i++)
3879 {
3880 RUDP_SEGMENT *s = LIST_DATA(se->RecvSegmentList, i);
3881
3882 Free(s);
3883 }
3884
3885 ReleaseList(se->RecvSegmentList);
3886
3887 if (se->TcpSock != NULL)
3888 {
3889 Disconnect(se->TcpSock);
3890 ReleaseSock(se->TcpSock);
3891 }
3892
3893 ReleaseInt64List(se->ReplyAckList);
3894
3895 ReleaseFifo(se->RecvFifo);
3896 ReleaseFifo(se->SendFifo);
3897
3898 ReleaseSharedBuffer(se->BulkSendKey);
3899 ReleaseSharedBuffer(se->BulkRecvKey);
3900
3901 Free(se);
3902 }
3903
3904 // Create a new session
RUDPNewSession(bool server_mode,IP * my_ip,UINT my_port,IP * your_ip,UINT your_port,UCHAR * init_key)3905 RUDP_SESSION *RUDPNewSession(bool server_mode, IP *my_ip, UINT my_port, IP *your_ip, UINT your_port, UCHAR *init_key)
3906 {
3907 RUDP_SESSION *se;
3908 UCHAR key1[SHA1_SIZE];
3909 UCHAR key2[SHA1_SIZE];
3910 UCHAR bulk_send_key[RUDP_BULK_KEY_SIZE_MAX];
3911 UCHAR bulk_recv_key[RUDP_BULK_KEY_SIZE_MAX];
3912 BUF *b;
3913
3914 se = ZeroMalloc(sizeof(RUDP_SESSION));
3915
3916 Copy(&se->MyIp, my_ip, sizeof(IP));
3917 se->MyPort = my_port;
3918
3919 Copy(&se->YourIp, your_ip, sizeof(IP));
3920 se->YourPort = your_port;
3921
3922 Copy(se->Key_Init, init_key, SHA1_SIZE);
3923 se->LastSentTick = 0;
3924 se->LastRecvTick = Tick64();
3925 se->LatestRecvMyTick = Tick64();
3926
3927 se->NextSendSeqNo = 1;
3928
3929 se->ServerMode = server_mode;
3930
3931 se->SendSegmentList = NewList(RUDPCompareSegmentList);
3932 se->RecvSegmentList = NewList(RUDPCompareSegmentList);
3933
3934 // Generate the two keys
3935 b = NewBuf();
3936 WriteBuf(b, init_key, SHA1_SIZE);
3937 WriteBufStr(b, "zurukko");
3938 HashSha1(key1, b->Buf, b->Size);
3939 FreeBuf(b);
3940
3941 b = NewBuf();
3942 WriteBuf(b, init_key, SHA1_SIZE);
3943 WriteBuf(b, key1, SHA1_SIZE);
3944 WriteBufStr(b, "yasushineko");
3945 HashSha1(key2, b->Buf, b->Size);
3946 FreeBuf(b);
3947
3948 // Generate the magic number for the KeepAlive
3949 b = NewBuf();
3950 WriteBuf(b, init_key, SHA1_SIZE);
3951 WriteBufStr(b, "Magic_KeepAliveRequest");
3952 HashSha1(se->Magic_KeepAliveRequest, b->Buf, b->Size);
3953 FreeBuf(b);
3954 b = NewBuf();
3955 WriteBuf(b, init_key, SHA1_SIZE);
3956 WriteBufStr(b, "Magic_KeepAliveResponse");
3957 HashSha1(se->Magic_KeepAliveResponse, b->Buf, b->Size);
3958 FreeBuf(b);
3959
3960 if (server_mode == false)
3961 {
3962 se->Magic_Disconnect = 0xffffffff00000000ULL | (UINT64)(Rand32());
3963 }
3964
3965 Copy(se->Key_Init, init_key, SHA1_SIZE);
3966
3967 if (se->ServerMode)
3968 {
3969 Copy(se->Key_Send, key1, SHA1_SIZE);
3970 Copy(se->Key_Recv, key2, SHA1_SIZE);
3971 }
3972 else
3973 {
3974 Copy(se->Key_Send, key2, SHA1_SIZE);
3975 Copy(se->Key_Recv, key1, SHA1_SIZE);
3976 }
3977
3978 Rand(se->NextIv, sizeof(se->NextIv));
3979
3980 se->ReplyAckList = NewInt64List(true);
3981
3982 se->NextKeepAliveInterval = RUDP_KEEPALIVE_INTERVAL_MIN + (Rand32() % (RUDP_KEEPALIVE_INTERVAL_MAX - RUDP_KEEPALIVE_INTERVAL_MIN));
3983
3984 se->RecvFifo = NewFifo();
3985 se->SendFifo = NewFifo();
3986
3987 se->Dns_TranId = Rand16() % 65535 + 1;
3988
3989 // Generate the bulk transfer key
3990 Rand(bulk_send_key, sizeof(bulk_send_key));
3991 Rand(bulk_recv_key, sizeof(bulk_recv_key));
3992
3993 se->BulkSendKey = NewSharedBuffer(bulk_send_key, sizeof(bulk_send_key));
3994 se->BulkRecvKey = NewSharedBuffer(bulk_recv_key, sizeof(bulk_recv_key));
3995
3996 Rand(se->BulkNextIv, sizeof(se->BulkNextIv));
3997 Rand(se->BulkNextIv_V2, sizeof(se->BulkNextIv_V2));
3998
3999 se->BulkNextSeqNo = 1;
4000
4001 return se;
4002 }
4003
4004 // Comparison function of the segment list items
RUDPCompareSegmentList(void * p1,void * p2)4005 int RUDPCompareSegmentList(void *p1, void *p2)
4006 {
4007 RUDP_SEGMENT *s1, *s2;
4008 UINT r;
4009 // Validate arguments
4010 if (p1 == NULL || p2 == NULL)
4011 {
4012 return 0;
4013 }
4014 s1 = *((RUDP_SEGMENT **)p1);
4015 s2 = *((RUDP_SEGMENT **)p2);
4016 if (s1 == NULL || s2 == NULL)
4017 {
4018 return 0;
4019 }
4020
4021 r = COMPARE_RET(s1->SeqNo, s2->SeqNo);
4022
4023 return r;
4024 }
4025
4026 // Send a UDP packet
RUDPSendPacket(RUDP_STACK * r,IP * dest_ip,UINT dest_port,void * data,UINT size,UINT icmp_type)4027 void RUDPSendPacket(RUDP_STACK *r, IP *dest_ip, UINT dest_port, void *data, UINT size, UINT icmp_type)
4028 {
4029 UDPPACKET *p;
4030 // Validate arguments
4031 if (r == NULL || dest_ip == NULL || dest_port == 0 || data == NULL || size == 0)
4032 {
4033 return;
4034 }
4035
4036 p = NewUdpPacket(&r->UdpSock->LocalIP, r->UdpSock->LocalPort,
4037 dest_ip, dest_port,
4038 Clone(data, size), size);
4039
4040 if (r->Protocol == RUDP_PROTOCOL_ICMP || r->Protocol == RUDP_PROTOCOL_DNS)
4041 {
4042 // ICMP Type / DNS Tran ID
4043 p->Type = icmp_type;
4044 }
4045
4046 Add(r->SendPacketList, p);
4047 }
4048
4049 // R-UDP main thread
RUDPMainThread(THREAD * thread,void * param)4050 void RUDPMainThread(THREAD *thread, void *param)
4051 {
4052 RUDP_STACK *r;
4053 bool halt_flag = false;
4054 // Validate arguments
4055 if (thread == NULL || param == NULL)
4056 {
4057 return;
4058 }
4059
4060 r = (RUDP_STACK *)param;
4061
4062 AddWaitThread(thread);
4063 NoticeThreadInit(thread);
4064
4065 while (true)
4066 {
4067 UINT wait_interval;
4068 UINT i;
4069 UINT min_wait_interval;
4070 UINT num_ignore_errors = 0;
4071
4072 r->Now = Tick64();
4073
4074 Lock(r->Lock);
4075 {
4076 Copy(&r->NatT_IP_Safe, &r->NatT_IP, sizeof(IP));
4077 Copy(&r->My_Private_IP_Safe, &r->My_Private_IP, sizeof(IP));
4078 }
4079 Unlock(r->Lock);
4080
4081 // Receive the data from the UDP socket
4082 while (true)
4083 {
4084 UINT ret;
4085 IP ip_src;
4086 UINT port_src;
4087
4088 ret = RecvFrom(r->UdpSock, &ip_src, &port_src, r->TmpBuf, sizeof(r->TmpBuf));
4089
4090 if (ret == SOCK_LATER)
4091 {
4092 // There is no packet more
4093 break;
4094 }
4095 else if (ret != 0)
4096 {
4097 // Receive a Packet
4098 bool ok = false;
4099 UDPPACKET *p = NewUdpPacket(&ip_src, port_src,
4100 &r->UdpSock->LocalIP, r->UdpSock->LocalPort,
4101 Clone(r->TmpBuf, ret), ret);
4102
4103 if (r->Protocol == RUDP_PROTOCOL_ICMP)
4104 {
4105 // Analyse the incoming ICMP packet
4106 UINT ip_header_size = GetIpHeaderSize(p->Data, p->Size);
4107
4108 if (ip_header_size >= sizeof(IPV4_HEADER))
4109 {
4110 if (p->Size >= (ip_header_size + sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO) + SHA1_SIZE))
4111 {
4112 IPV4_HEADER *ip_header = (IPV4_HEADER *)(((UCHAR *)p->Data) + 0);
4113 ICMP_HEADER *icmp_header = (ICMP_HEADER *)(((UCHAR *)p->Data) + ip_header_size);
4114 ICMP_ECHO *echo_header = (ICMP_ECHO *)(((UCHAR *)p->Data) + ip_header_size + sizeof(ICMP_HEADER));
4115
4116 if (icmp_header->Type == ICMP_TYPE_ECHO_RESPONSE ||
4117 icmp_header->Type == (r->ServerMode ? ICMP_TYPE_INFORMATION_REQUEST : ICMP_TYPE_INFORMATION_REPLY))
4118 {
4119 UCHAR hash[SHA1_SIZE];
4120
4121 HashSha1(hash, ((UCHAR *)p->Data) + ip_header_size + sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO) + SHA1_SIZE,
4122 p->Size - (ip_header_size + sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO) + SHA1_SIZE));
4123
4124 if (Cmp(hash, ((UCHAR *)p->Data) + ip_header_size + sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO), SHA1_SIZE) == 0)
4125 {
4126 UCHAR *new_data;
4127 UINT new_data_size;
4128 if (r->ServerMode)
4129 {
4130 // On the server side, the ICMP ID and the SEQ NO of received messages are treated as a source port number
4131 Copy(&p->SrcPort, echo_header, sizeof(UINT));
4132 }
4133
4134 // Record the Type
4135 p->Type = icmp_header->Type;
4136
4137 // Erase the header part
4138 new_data_size = p->Size - (ip_header_size + sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO) + SHA1_SIZE);
4139 new_data = Clone(((UCHAR *)p->Data) + ip_header_size + sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO) + SHA1_SIZE, new_data_size);
4140 Free(p->Data);
4141 p->Data = new_data;
4142 p->Size = new_data_size;
4143
4144 ok = true;
4145 }
4146 }
4147 }
4148 }
4149 }
4150 else if (r->Protocol == RUDP_PROTOCOL_DNS)
4151 {
4152 // Analyse the incoming DNS packet
4153 UINT offset;
4154
4155 if (r->ServerMode == false)
4156 {
4157 offset = 42;
4158 }
4159 else
4160 {
4161 offset = 37;
4162 }
4163
4164 if (p->Size > offset)
4165 {
4166 UCHAR *new_data;
4167 UINT new_size = p->Size - offset;
4168
4169 p->Type = *((USHORT *)p->Data);
4170
4171 new_data = Clone(((UCHAR *)p->Data) + offset, new_size);
4172
4173 Free(p->Data);
4174 p->Data = new_data;
4175 p->Size = new_size;
4176
4177 ok = true;
4178 }
4179 }
4180 else
4181 {
4182 // Don't do anything for ordinary UDP packet
4183 ok = true;
4184 }
4185
4186 if (ok)
4187 {
4188 // Process the received packet
4189 RUDPRecvProc(r, p);
4190
4191 r->TotalPhysicalReceived += ret;
4192 }
4193
4194 FreeUdpPacket(p);
4195 }
4196 else
4197 {
4198 if (r->UdpSock->IgnoreRecvErr)
4199 {
4200 // An ignorable reception error occurs
4201 if ((num_ignore_errors++) >= MAX_NUM_IGNORE_ERRORS)
4202 {
4203 break;
4204 }
4205 }
4206 else
4207 {
4208 // A non-ignorable reception error occurs
4209 break;
4210 }
4211 }
4212 }
4213
4214 // Call the interrupt notification callback function
4215 if (r->ProcInterrupts != NULL)
4216 {
4217 r->ProcInterrupts(r);
4218 }
4219
4220 RUDPInterruptProc(r);
4221
4222 // Send all packets in the transmission packet list
4223 for (i = 0;i < LIST_NUM(r->SendPacketList);i++)
4224 {
4225 UDPPACKET *p = LIST_DATA(r->SendPacketList, i);
4226
4227 if (r->Protocol == RUDP_PROTOCOL_ICMP)
4228 {
4229 // In case of the ICMP protocol, assemble an ICMP header
4230 UINT dst_size = sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO) + SHA1_SIZE + p->Size;
4231 UCHAR *dst_data = ZeroMalloc(dst_size);
4232
4233 ICMP_HEADER *icmp_header = (ICMP_HEADER *)dst_data;
4234 ICMP_ECHO *icmp_echo = (ICMP_ECHO *)(dst_data + sizeof(ICMP_HEADER));
4235 UCHAR *hash = dst_data + sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO);
4236 UCHAR *icmp_data = dst_data + sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO) + SHA1_SIZE;
4237
4238 // Header
4239 icmp_header->Type = (UCHAR)p->Type;
4240 icmp_header->Code = 0;
4241 icmp_header->Checksum = 0;
4242
4243 if (r->ServerMode)
4244 {
4245 // On the server side, use the port number in the opponent internal data as ICMP ID and SEQ NO
4246 Copy(icmp_echo, &p->DestPort, 4);
4247 }
4248 else
4249 {
4250 // Use the fixed ICMP ID and SEQ NO on the client side
4251 icmp_echo->Identifier = Endian16(r->Client_IcmpId);
4252 icmp_echo->SeqNo = Endian16(r->Client_IcmpSeqNo);
4253 }
4254
4255 // Data body
4256 Copy(icmp_data, p->Data, p->Size);
4257
4258 // Hash
4259 HashSha1(hash, icmp_data, p->Size);
4260
4261 // Checksum calculation
4262 icmp_header->Checksum = IpChecksum(dst_data, dst_size);
4263
4264 // Replacement
4265 Free(p->Data);
4266 p->Data = dst_data;
4267 p->Size = dst_size;
4268 }
4269 else if (r->Protocol == RUDP_PROTOCOL_DNS)
4270 {
4271 BUF *b = NewBuf();
4272 // In case of over DNS protocol, assemble a header that conforms to the DNS protocol
4273 if (r->ServerMode == false)
4274 {
4275 // DNS query header
4276 USHORT us = Rand16() % 65535 + 1;
4277 static UCHAR dns_query_header_1[] =
4278 {
4279 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08,
4280 };
4281 static UCHAR dns_query_header_2[] =
4282 {
4283 0x00, 0x00, 0x30, 0x00, 0x01, 0x00, 0x00, 0x29, 0x10,
4284 0x00, 0x00, 0x00, 0x80, 0x00,
4285 };
4286 UCHAR rand_data[4];
4287 char rand_str[MAX_SIZE];
4288
4289 Rand(rand_data, sizeof(rand_data));
4290 BinToStr(rand_str, sizeof(rand_str), rand_data, sizeof(rand_data));
4291 StrLower(rand_str);
4292
4293 WriteBuf(b, &us, sizeof(USHORT));
4294 WriteBuf(b, dns_query_header_1, sizeof(dns_query_header_1));
4295 WriteBuf(b, rand_str, 8);
4296 WriteBuf(b, dns_query_header_2, sizeof(dns_query_header_2));
4297 us = Endian16((USHORT)p->Size);
4298 WriteBuf(b, &us, sizeof(USHORT));
4299 WriteBuf(b, p->Data, p->Size);
4300 }
4301 else
4302 {
4303 // DNS response header
4304 USHORT us = p->Type;
4305 UINT ui;
4306 static UCHAR dns_response_header_1[] =
4307 {
4308 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00,
4309 0x00, 0x00, 0x08,
4310 };
4311 static UCHAR dns_response_header_2[] =
4312 {
4313 0x00, 0x00, 0x30, 0x00, 0x01,
4314 0xc0, 0x0c, 0x00, 0x30, 0x00, 0x01, 0x00, 0x00, 0xa4, 0x5b,
4315 };
4316 static UCHAR dns_response_header_3[] =
4317 {
4318 0x01, 0x00, 0x03, 0x08,
4319 };
4320 UCHAR rand_data[4];
4321 char rand_str[MAX_SIZE];
4322
4323 Rand(rand_data, sizeof(rand_data));
4324 BinToStr(rand_str, sizeof(rand_str), rand_data, sizeof(rand_data));
4325 StrLower(rand_str);
4326
4327 WriteBuf(b, &us, sizeof(USHORT));
4328 WriteBuf(b, dns_response_header_1, sizeof(dns_response_header_1));
4329 WriteBuf(b, rand_str, 8);
4330 WriteBuf(b, dns_response_header_2, sizeof(dns_response_header_2));
4331 us = Endian16((USHORT)(p->Size + 4));
4332 WriteBuf(b, &us, sizeof(USHORT));
4333 WriteBuf(b, dns_response_header_3, sizeof(dns_response_header_3));
4334 WriteBuf(b, p->Data, p->Size);
4335
4336 ui = Rand16() % (60 * 60 * 12) + (60 * 60 * 12);
4337 WRITE_UINT(((UCHAR *)b->Buf) + 0x20, ui);
4338 }
4339 Free(p->Data);
4340 p->Data = b->Buf;
4341 p->Size = b->Size;
4342 Free(b);
4343 }
4344
4345 SendTo(r->UdpSock, &p->DstIP, p->DestPort, p->Data, p->Size);
4346
4347 r->TotalPhysicalSent += p->Size;
4348
4349 FreeUdpPacket(p);
4350 }
4351 DeleteAll(r->SendPacketList);
4352
4353 if (r->Halt)
4354 {
4355 // If it is necessary to stop, stop it after cycling through a loop
4356 if (halt_flag == false)
4357 {
4358 halt_flag = true;
4359 continue;
4360 }
4361 else
4362 {
4363 break;
4364 }
4365 }
4366
4367 // Rest the CPU until the next event
4368 wait_interval = GetNextIntervalForInterrupt(r->Interrupt);
4369 if (r->ServerMode)
4370 {
4371 min_wait_interval = RUDP_LOOP_WAIT_INTERVAL_S;
4372 }
4373 else
4374 {
4375 min_wait_interval = RUDP_LOOP_WAIT_INTERVAL_C;
4376 }
4377
4378 if (wait_interval == INFINITE)
4379 {
4380 wait_interval = min_wait_interval;
4381 }
4382 else
4383 {
4384 wait_interval = MIN(min_wait_interval, wait_interval);
4385 }
4386
4387 #ifdef RUDP_DETAIL_LOG
4388 Debug("wait_interval = %u\n", wait_interval);
4389 #endif // RUDP_DETAIL_LOG
4390
4391 if (wait_interval >= 1)
4392 {
4393 WaitSockEvent(r->SockEvent, wait_interval);
4394 }
4395
4396 #ifdef RUDP_DETAIL_LOG
4397 if (r->ServerMode)
4398 {
4399 char str1[MAX_SIZE];
4400 char str2[MAX_SIZE];
4401 double rate = 0.0;
4402
4403 ToStr64(str1, r->TotalPhysicalReceived);
4404 ToStr64(str2, r->TotalLogicalReceived);
4405
4406 if (r->TotalPhysicalReceived >= 1)
4407 {
4408 rate = (double)r->TotalLogicalReceived / (double)r->TotalPhysicalReceived;
4409 }
4410
4411 Debug("%s / %s %.4f\n", str1, str2, rate);
4412 }
4413 #endif // RUDP_DETAIL_LOG
4414 }
4415
4416 Disconnect(r->UdpSock);
4417
4418 DelWaitThread(thread);
4419 }
4420
4421 // Generate a appropriate register host name from the IP address
RUDPGetRegisterHostNameByIP(char * dst,UINT size,IP * ip)4422 void RUDPGetRegisterHostNameByIP(char *dst, UINT size, IP *ip)
4423 {
4424 char tmp[16];
4425 // Validate arguments
4426 if (dst == NULL)
4427 {
4428 return;
4429 }
4430
4431 if (ip != NULL && IsIP4(ip))
4432 {
4433 UCHAR hash[SHA1_SIZE];
4434
4435 HashSha1(hash, ip->addr, 4);
4436 BinToStr(tmp, sizeof(tmp), hash, 2);
4437 }
4438 else
4439 {
4440 UCHAR rand[2];
4441 Rand(rand, 2);
4442 BinToStr(tmp, sizeof(tmp), rand, 2);
4443 }
4444
4445 StrLower(tmp);
4446 Format(dst, size,
4447 (IsUseAlternativeHostname() ? UDP_NAT_T_SERVER_TAG_ALT : UDP_NAT_T_SERVER_TAG),
4448 tmp[2], tmp[3]);
4449
4450
4451 if (false)
4452 {
4453 Debug("Hash Src IP: %r\n"
4454 "Hash Dst HN: %s\n",
4455 ip,
4456 dst);
4457 }
4458 }
4459
4460 // Analyze the IP address and port number from the string
RUDPParseIPAndPortStr(void * data,UINT data_size,IP * ip,UINT * port)4461 bool RUDPParseIPAndPortStr(void *data, UINT data_size, IP *ip, UINT *port)
4462 {
4463 char tmp[MAX_SIZE];
4464 UINT i;
4465 char ipstr[MAX_SIZE];
4466 char *portstr;
4467 // Validate arguments
4468 if (data == NULL || ip == NULL || port == NULL)
4469 {
4470 return false;
4471 }
4472
4473 Zero(tmp, sizeof(tmp));
4474
4475 Copy(tmp, data, MIN(data_size, sizeof(tmp) - 1));
4476
4477 if (StartWith(tmp, "IP=") == false)
4478 {
4479 return false;
4480 }
4481
4482 i = SearchStrEx(tmp, "#", 0, true);
4483 if (i != INFINITE)
4484 {
4485 tmp[i] = 0;
4486 }
4487
4488 StrCpy(ipstr, sizeof(ipstr), tmp + 3);
4489
4490 i = SearchStrEx(ipstr, ",PORT=", 0, true);
4491 if (i == INFINITE)
4492 {
4493 return false;
4494 }
4495
4496 ipstr[i] = 0;
4497 portstr = ipstr + i + 6;
4498
4499 StrToIP(ip, ipstr);
4500 *port = ToInt(portstr);
4501
4502 return true;
4503 }
4504
4505 // R-UDP NAT-T IP address acquisition thread
RUDPIpQueryThread(THREAD * thread,void * param)4506 void RUDPIpQueryThread(THREAD *thread, void *param)
4507 {
4508 RUDP_STACK *r;
4509 UINT64 next_getip_tick = 0;
4510 UINT64 next_getprivate_ip_tick = 0;
4511 UINT last_ip_hash = 0;
4512 void *route_change_poller = NULL;
4513 char current_hostname[MAX_SIZE];
4514 bool last_time_ip_changed = false;
4515 UINT num_retry = 0;
4516 // Validate arguments
4517 if (thread == NULL || param == NULL)
4518 {
4519 return;
4520 }
4521
4522 r = (RUDP_STACK *)param;
4523
4524 last_ip_hash = GetHostIPAddressHash32();
4525
4526 route_change_poller = NewRouteChange();
4527 IsRouteChanged(route_change_poller);
4528
4529 Zero(current_hostname, sizeof(current_hostname));
4530
4531 while (r->Halt == false)
4532 {
4533 UINT ip_hash = GetHostIPAddressHash32();
4534 UINT64 now = Tick64();
4535 bool ip_changed = false;
4536
4537 if (ip_hash != last_ip_hash)
4538 {
4539 last_time_ip_changed = false;
4540 }
4541
4542 if ((ip_hash != last_ip_hash) || (IsRouteChanged(route_change_poller)))
4543 {
4544 if (last_time_ip_changed == false)
4545 {
4546 // Call all getting functions from the beginning
4547 // if the routing table or the IP address of this host has changed
4548 next_getip_tick = 0;
4549 next_getprivate_ip_tick = 0;
4550 ip_changed = true;
4551
4552 last_ip_hash = ip_hash;
4553
4554 last_time_ip_changed = true;
4555 }
4556 }
4557 else
4558 {
4559 last_time_ip_changed = false;
4560 }
4561
4562 Lock(r->Lock);
4563 {
4564 if (StrCmpi(current_hostname, r->CurrentRegisterHostname) != 0)
4565 {
4566 // The target host name has changed
4567 next_getip_tick = 0;
4568 StrCpy(current_hostname, sizeof(current_hostname), r->CurrentRegisterHostname);
4569 }
4570 }
4571 Unlock(r->Lock);
4572
4573 // Get the IP address of the NAT-T server with DNS
4574 if (next_getip_tick == 0 || now >= next_getip_tick)
4575 {
4576 IP ip;
4577
4578 if (GetIP4(&ip, current_hostname) && IsZeroIp(&ip) == false)
4579 {
4580 Lock(r->Lock);
4581 {
4582 // Debug("%r %r\n",&r->NatT_IP, &ip);
4583 if (CmpIpAddr(&r->NatT_IP, &ip) != 0)
4584 {
4585 // WHERE;
4586 ip_changed = true;
4587 Copy(&r->NatT_IP, &ip, sizeof(IP));
4588 }
4589 }
4590 Unlock(r->Lock);
4591 }
4592
4593 if (IsZeroIp(&r->NatT_IP))
4594 {
4595 num_retry++;
4596
4597 next_getip_tick = now + MIN((UINT64)UDP_NAT_T_GET_IP_INTERVAL * (UINT64)num_retry, (UINT64)UDP_NAT_T_GET_IP_INTERVAL_MAX);
4598 }
4599 else
4600 {
4601 next_getip_tick = now + (UINT64)UDP_NAT_T_GET_IP_INTERVAL_AFTER;
4602 }
4603
4604 if (ip_changed)
4605 {
4606 Debug("NAT-T: NAT-T Server IP (%s): %r\n", current_hostname, &r->NatT_IP);
4607
4608 r->NatT_GetTokenNextTick = 0;
4609 r->NatT_RegisterNextTick = 0;
4610 r->NatT_GetTokenFailNum = 0;
4611 r->NatT_RegisterFailNum = 0;
4612
4613 r->NatT_TranId = Rand64();
4614
4615 SetSockEvent(r->SockEvent);
4616 }
4617 }
4618
4619 // Get a private IP address of this host using TCP
4620 if (next_getprivate_ip_tick == 0 || now >= next_getprivate_ip_tick)
4621 {
4622 IP ip;
4623
4624 if (GetMyPrivateIP(&ip, false))
4625 {
4626 Lock(r->Lock);
4627 {
4628 Copy(&r->My_Private_IP, &ip, sizeof(IP));
4629 }
4630 Unlock(r->Lock);
4631 }
4632
4633 if (IsZeroIp(&r->My_Private_IP))
4634 {
4635 next_getprivate_ip_tick = now + (UINT64)UDP_NAT_T_GET_PRIVATE_IP_INTERVAL;
4636 }
4637 else
4638 {
4639 next_getprivate_ip_tick = now + (UINT64)GenRandInterval(UDP_NAT_T_GET_PRIVATE_IP_INTERVAL_AFTER_MIN, UDP_NAT_T_GET_PRIVATE_IP_INTERVAL_AFTER_MAX);
4640 }
4641
4642 Debug("NAT-T: My Private IP: %r\n", &r->My_Private_IP);
4643 }
4644
4645 if (r->Halt)
4646 {
4647 break;
4648 }
4649
4650 Wait(r->HaltEvent, RUDP_LOOP_WAIT_INTERVAL_S);
4651 }
4652
4653 FreeRouteChange(route_change_poller);
4654 }
4655
4656 // Generate a random intervals
GenRandInterval(UINT min,UINT max)4657 UINT GenRandInterval(UINT min, UINT max)
4658 {
4659 UINT a, b;
4660
4661 a = MIN(min, max);
4662 b = MAX(min, max);
4663
4664 if (a == b)
4665 {
4666 return a;
4667 }
4668
4669 return (Rand32() % (b - a)) + a;
4670 }
4671
4672 // Identify the private IP of the interface which is used to connect to the Internet currently
GetMyPrivateIP(IP * ip,bool from_vg)4673 bool GetMyPrivateIP(IP *ip, bool from_vg)
4674 {
4675 SOCK *s;
4676 IP t;
4677 char *hostname = UDP_NAT_T_GET_PRIVATE_IP_TCP_SERVER;
4678 // Validate arguments
4679 if (ip == NULL)
4680 {
4681 return false;
4682 }
4683
4684 s = ConnectEx(hostname, UDP_NAT_T_PORT_FOR_TCP_1, UDP_NAT_T_GET_PRIVATE_IP_CONNECT_TIMEOUT);
4685
4686 if (s == NULL)
4687 {
4688 s = ConnectEx(hostname, UDP_NAT_T_PORT_FOR_TCP_2, UDP_NAT_T_GET_PRIVATE_IP_CONNECT_TIMEOUT);
4689
4690 if (s == NULL)
4691 {
4692 s = ConnectEx(GetRandHostNameForGetMyPrivateIP(), UDP_NAT_T_PORT_FOR_TCP_1, UDP_NAT_T_GET_PRIVATE_IP_CONNECT_TIMEOUT);
4693
4694 if (s == NULL)
4695 {
4696 return false;
4697 }
4698 }
4699 }
4700
4701 Copy(&t, &s->LocalIP, sizeof(IP));
4702
4703 Disconnect(s);
4704 ReleaseSock(s);
4705
4706 if (IsZeroIp(&t))
4707 {
4708 return false;
4709 }
4710
4711 Copy(ip, &t, sizeof(IP));
4712
4713 return true;
4714 }
GetRandHostNameForGetMyPrivateIP()4715 char *GetRandHostNameForGetMyPrivateIP()
4716 {
4717 char *hosts[] =
4718 {
4719 "www.microsoft.com",
4720 "www.yahoo.com",
4721 "www.bing.com",
4722 };
4723 UINT num_hosts = 3;
4724
4725 return hosts[Rand32() % num_hosts];
4726 }
4727
4728 // Function to wait until changing any IP address of the host or expiring the specified time or waking the event
WaitUntilHostIPAddressChanged(void * p,EVENT * event,UINT timeout,UINT ip_check_interval)4729 void WaitUntilHostIPAddressChanged(void *p, EVENT *event, UINT timeout, UINT ip_check_interval)
4730 {
4731 UINT64 start, end;
4732 UINT last_hash;
4733 // Validate arguments
4734 if (timeout == 0x7FFFFFFF)
4735 {
4736 timeout = 0xFFFFFFFF;
4737 }
4738 if (ip_check_interval == 0)
4739 {
4740 ip_check_interval = 0xFFFFFFFF;
4741 }
4742 if (event == NULL || timeout == 0)
4743 {
4744 return;
4745 }
4746
4747 start = Tick64();
4748 end = start + (UINT64)timeout;
4749 last_hash = GetHostIPAddressHash32();
4750
4751 while (true)
4752 {
4753 UINT64 now = Tick64();
4754 UINT next_interval;
4755
4756 if (now >= end)
4757 {
4758 break;
4759 }
4760
4761 if (p != NULL)
4762 {
4763 if (IsRouteChanged(p))
4764 {
4765 break;
4766 }
4767 }
4768
4769 if (last_hash != GetHostIPAddressHash32())
4770 {
4771 break;
4772 }
4773
4774 next_interval = (UINT)(end - now);
4775 next_interval = MIN(next_interval, ip_check_interval);
4776
4777 if (Wait(event, next_interval))
4778 {
4779 break;
4780 }
4781 }
4782 }
InitWaitUntilHostIPAddressChanged()4783 void *InitWaitUntilHostIPAddressChanged()
4784 {
4785 void *p = NewRouteChange();
4786
4787 if (p != NULL)
4788 {
4789 IsRouteChanged(p);
4790 }
4791
4792 return p;
4793 }
FreeWaitUntilHostIPAddressChanged(void * p)4794 void FreeWaitUntilHostIPAddressChanged(void *p)
4795 {
4796 FreeRouteChange(p);
4797 }
4798
4799 // Get whether the specified IPv6 address is on the local network
IsIPv6LocalNetworkAddress(IP * ip)4800 bool IsIPv6LocalNetworkAddress(IP *ip)
4801 {
4802 UINT type;
4803 LIST *o;
4804 UINT i;
4805 bool ret = false;
4806 IP mask64;
4807 // Validate arguments
4808 if (ip == NULL)
4809 {
4810 return false;
4811 }
4812 if (IsIP6(ip) == false)
4813 {
4814 return false;
4815 }
4816 if (IsZeroIp(ip))
4817 {
4818 return false;
4819 }
4820
4821 type = GetIPAddrType6(ip);
4822
4823 if (type & IPV6_ADDR_LOCAL_UNICAST)
4824 {
4825 return true;
4826 }
4827
4828 if ((type & IPV6_ADDR_GLOBAL_UNICAST) == 0)
4829 {
4830 return false;
4831 }
4832
4833 IntToSubnetMask6(&mask64, 64);
4834
4835 o = GetHostIPAddressList();
4836
4837 ret = false;
4838
4839 for (i = 0;i < LIST_NUM(o);i++)
4840 {
4841 IP *p = LIST_DATA(o, i);
4842
4843 if (IsIP6(p))
4844 {
4845 if (IsZeroIp(p) == false)
4846 {
4847 if (IsLocalHostIP6(p) == false)
4848 {
4849 if (IsInSameNetwork6(p, ip, &mask64))
4850 {
4851 ret = true;
4852 }
4853 }
4854 }
4855 }
4856 }
4857
4858 FreeHostIPAddressList(o);
4859
4860 return ret;
4861 }
4862
4863 // Check whether the specified IP address is localhost or the IP address of the local interface of itself
IsIPLocalHostOrMySelf(IP * ip)4864 bool IsIPLocalHostOrMySelf(IP *ip)
4865 {
4866 LIST *o;
4867 bool ret = false;
4868 UINT i;
4869 // Validate arguments
4870 if (ip == NULL)
4871 {
4872 return false;
4873 }
4874
4875 o = GetHostIPAddressList();
4876 if (o == NULL)
4877 {
4878 return false;
4879 }
4880
4881 for (i = 0;i < LIST_NUM(o);i++)
4882 {
4883 IP *p = LIST_DATA(o, i);
4884
4885 if (CmpIpAddr(p, ip) == 0)
4886 {
4887 ret = true;
4888
4889 break;
4890 }
4891 }
4892
4893 FreeHostIPAddressList(o);
4894
4895 if (IsLocalHostIP4(ip) || IsLocalHostIP6(ip))
4896 {
4897 ret = true;
4898 }
4899
4900 return ret;
4901 }
4902
4903 // Get the results of the port number that is determined at random
RUDPGetRandPortNumber(UCHAR rand_port_id)4904 UINT RUDPGetRandPortNumber(UCHAR rand_port_id)
4905 {
4906 UINT ret;
4907 // Validate arguments
4908 if (rand_port_id == 0)
4909 {
4910 return 0;
4911 }
4912
4913 ret = rand_port_numbers[rand_port_id];
4914
4915 Debug("rand_port_id[%u] = %u\n", rand_port_id, ret);
4916 return ret;
4917 }
4918
4919 // Obtain the hash value of combining all of the IP address assigned to the host
GetHostIPAddressHash32()4920 UINT GetHostIPAddressHash32()
4921 {
4922 BUF *b;
4923 UINT i;
4924 UCHAR hash[SHA1_SIZE];
4925 UINT ret;
4926 LIST *o = GetHostIPAddressList();
4927
4928 if (o == NULL)
4929 {
4930 return 0;
4931 }
4932
4933 b = NewBuf();
4934 for (i = 0;i < LIST_NUM(o);i++)
4935 {
4936 IP *ip = LIST_DATA(o, i);
4937
4938 WriteBuf(b, ip, sizeof(IP));
4939
4940 WriteBufStr(b, ":-) yas (-:");
4941 }
4942 FreeHostIPAddressList(o);
4943
4944 WriteBuf(b, rand_port_numbers, sizeof(rand_port_numbers));
4945
4946 HashSha1(hash, b->Buf, b->Size);
4947
4948 FreeBuf(b);
4949
4950 Copy(&ret, hash, sizeof(UINT));
4951
4952 return ret;
4953 }
4954
4955 // Create an IPv4 UDP socket destined for a particular target
NewUDP4ForSpecificIp(IP * target_ip,UINT port)4956 SOCK *NewUDP4ForSpecificIp(IP *target_ip, UINT port)
4957 {
4958 SOCK *s;
4959 IP local_ip;
4960 // Validate arguments
4961 if (target_ip == NULL || IsZeroIP(target_ip) || IsIP4(target_ip) == false)
4962 {
4963 target_ip = NULL;
4964 }
4965
4966 Zero(&local_ip, sizeof(local_ip));
4967 GetBestLocalIpForTarget(&local_ip, target_ip);
4968
4969 s = NewUDP4(port, &local_ip);
4970
4971 if (s == NULL)
4972 {
4973 s = NewUDP4(port, NULL);
4974 }
4975
4976 return s;
4977 }
4978
4979 // Get the best self IPv4 address to connect to the target IPv4 address
GetBestLocalIpForTarget(IP * local_ip,IP * target_ip)4980 bool GetBestLocalIpForTarget(IP *local_ip, IP *target_ip)
4981 {
4982 bool ret = false;
4983 ROUTE_ENTRY *e;
4984 IP ip2;
4985 UINT n = 0;
4986 IP zero_ip;
4987 // Validate arguments
4988 Zero(local_ip, sizeof(IP));
4989 ZeroIP4(&zero_ip);
4990 if (target_ip == NULL)
4991 {
4992 target_ip = &zero_ip;
4993 }
4994 if (local_ip == NULL || IsIP4(target_ip) == false)
4995 {
4996 return false;
4997 }
4998
4999 Copy(&ip2, target_ip, sizeof(IP));
5000
5001 while (true)
5002 {
5003 n++;
5004 if (n >= 64)
5005 {
5006 break;
5007 }
5008
5009 e = GetBestRouteEntry(&ip2);
5010 if (e != NULL)
5011 {
5012 if (IsZeroIp(&e->GatewayIP))
5013 {
5014 Free(e);
5015 break;
5016 }
5017
5018 if (e->LocalRouting)
5019 {
5020 ret = true;
5021 Copy(local_ip, &e->GatewayIP, sizeof(IP));
5022 Free(e);
5023 break;
5024 }
5025 else
5026 {
5027 Copy(&ip2, &e->GatewayIP, sizeof(IP));
5028 }
5029
5030 Free(e);
5031 }
5032 }
5033
5034 if (ret == false)
5035 {
5036 if (IsLocalHostIP4(target_ip))
5037 {
5038 GetLocalHostIP4(local_ip);
5039 ret = true;
5040 }
5041 }
5042
5043 return ret;
5044 }
5045
5046 // Create a R-UDP client (Connection via NAT-T gateway)
NewRUDPClientNatT(char * svc_name,IP * ip,UINT * error_code,UINT timeout,bool * cancel,char * hint_str,char * target_hostname)5047 SOCK *NewRUDPClientNatT(char *svc_name, IP *ip, UINT *error_code, UINT timeout, bool *cancel, char *hint_str, char *target_hostname)
5048 {
5049 IP nat_t_ip;
5050 UINT dummy_int = 0;
5051 UINT64 giveup_tick;
5052 bool dummy_bool = false;
5053 SOCK_EVENT *sock_event;
5054 SOCK *sock;
5055 bool same_lan = false;
5056 char hostname[MAX_SIZE];
5057
5058
5059
5060 if (timeout == 0)
5061 {
5062 timeout = RUDP_TIMEOUT;
5063 }
5064 if (error_code == NULL)
5065 {
5066 error_code = &dummy_int;
5067 }
5068 if (cancel == NULL)
5069 {
5070 cancel = &dummy_bool;
5071 }
5072 *error_code = RUDP_ERROR_UNKNOWN;
5073 if (svc_name == NULL || ip == NULL)
5074 {
5075 return NULL;
5076 }
5077
5078 ListenTcpForPopupFirewallDialog();
5079
5080 giveup_tick = Tick64() + (UINT64)timeout;
5081
5082 // Get the IP address of the NAT-T server
5083 RUDPGetRegisterHostNameByIP(hostname, sizeof(hostname), ip);
5084 if (GetIP4Ex(&nat_t_ip, hostname, 0, cancel) == false)
5085 {
5086 *error_code = RUDP_ERROR_NAT_T_NO_RESPONSE;
5087 return NULL;
5088 }
5089
5090 if (Tick64() >= giveup_tick)
5091 {
5092 *error_code = RUDP_ERROR_TIMEOUT;
5093 return NULL;
5094 }
5095 if (*cancel)
5096 {
5097 *error_code = RUDP_ERROR_USER_CANCELED;
5098 return NULL;
5099 }
5100
5101 sock = NewUDP4ForSpecificIp(&nat_t_ip, 0);
5102 if (sock == NULL)
5103 {
5104 *error_code = RUDP_ERROR_UNKNOWN;
5105 return NULL;
5106 }
5107 else
5108 {
5109 UINT64 next_send_request_tick = 0;
5110 INTERRUPT_MANAGER *interrupt = NewInterruptManager();
5111 UINT64 tran_id = Rand64();
5112 UINT tmp_size = 65536;
5113 UCHAR *tmp = Malloc(tmp_size);
5114 char result_ip_str[MAX_SIZE];
5115 IP result_ip;
5116 UINT result_port;
5117 SOCK *ret = NULL;
5118 UINT num_tries = 0;
5119 UINT64 current_cookie = 0;
5120
5121 AddInterrupt(interrupt, giveup_tick);
5122
5123 sock_event = NewSockEvent();
5124 JoinSockToSockEvent(sock, sock_event);
5125
5126 // Communication with the NAT-T server
5127 while (true)
5128 {
5129 UINT64 now = Tick64();
5130 UINT interval;
5131 UINT r;
5132 IP src_ip;
5133 UINT src_port;
5134 UINT err;
5135 UINT num_ignore_errors = 0;
5136
5137 if (now >= giveup_tick)
5138 {
5139 // Time-out
5140 LABEL_TIMEOUT:
5141 *error_code = RUDP_ERROR_NAT_T_NO_RESPONSE;
5142 break;
5143 }
5144
5145 if (*cancel)
5146 {
5147 // User canceled
5148 *error_code = RUDP_ERROR_USER_CANCELED;
5149 break;
5150 }
5151
5152 err = INFINITE;
5153
5154 // Receive a response packet from the NAT-T server
5155 while (err == INFINITE)
5156 {
5157 r = RecvFrom(sock, &src_ip, &src_port, tmp, tmp_size);
5158 if (r == SOCK_LATER)
5159 {
5160 // No packet
5161 break;
5162 }
5163 else if (r == 0)
5164 {
5165 if (sock->IgnoreRecvErr == false)
5166 {
5167 // Communication error
5168 goto LABEL_TIMEOUT;
5169 }
5170 else
5171 {
5172 if ((num_ignore_errors++) >= MAX_NUM_IGNORE_ERRORS)
5173 {
5174 goto LABEL_TIMEOUT;
5175 }
5176 }
5177 }
5178 else
5179 {
5180 // Check the source IP address and the port number
5181 if (CmpIpAddr(&src_ip, &nat_t_ip) == 0 && src_port == UDP_NAT_T_PORT)
5182 {
5183 BUF *b = NewBuf();
5184 PACK *p;
5185
5186 WriteBuf(b, tmp, r);
5187 SeekBuf(b, 0, 0);
5188
5189
5190 p = BufToPack(b);
5191
5192 if (p != NULL)
5193 {
5194 UINT64 cookie = PackGetInt64(p, "cookie");
5195 if (cookie != 0)
5196 {
5197 current_cookie = cookie;
5198 }
5199
5200 // Compare tran_id
5201 if (PackGetInt64(p, "tran_id") == tran_id)
5202 {
5203 // Compare opcode
5204 if (PackCmpStr(p, "opcode", "nat_t_connect_request"))
5205 {
5206 bool ok = PackGetBool(p, "ok");
5207 bool multi_candidate = PackGetBool(p, "multi_candidates");
5208
5209 if (ok)
5210 {
5211 // Success
5212 PackGetStr(p, "result_ip", result_ip_str, sizeof(result_ip_str));
5213 StrToIP(&result_ip, result_ip_str);
5214
5215 result_port = PackGetInt(p, "result_port");
5216
5217 same_lan = PackGetBool(p, "same_lan");
5218
5219 if (result_port != 0)
5220 {
5221 if (IsZeroIp(&result_ip) == false)
5222 {
5223 if ((sock->IPv6 == false && IsIP4(&result_ip)) ||
5224 (sock->IPv6 && IsIP6(&result_ip)))
5225 {
5226 err = RUDP_ERROR_OK;
5227 }
5228 }
5229 }
5230 }
5231 else if (multi_candidate)
5232 {
5233 // There are two or more computers behind the specified IP address
5234 err = RUDP_ERROR_NAT_T_TWO_OR_MORE;
5235 }
5236 else
5237 {
5238 // Failure
5239 err = RUDP_ERROR_NAT_T_NOT_FOUND;
5240 }
5241 }
5242 }
5243
5244 FreePack(p);
5245 }
5246
5247 FreeBuf(b);
5248 }
5249 }
5250 }
5251
5252 if (err != INFINITE)
5253 {
5254 *error_code = err;
5255 break;
5256 }
5257
5258 if (next_send_request_tick == 0 || now >= next_send_request_tick)
5259 {
5260 // Send a connection request to the NAT-T server
5261 BUF *b;
5262 char ip_str[MAX_SIZE];
5263 PACK *p = NewPack();
5264
5265 PackAddStr(p, "opcode", "nat_t_connect_request");
5266 PackAddInt64(p, "tran_id", tran_id);
5267 IPToStr(ip_str, sizeof(ip_str), ip);
5268 PackAddStr(p, "dest_ip", ip_str);
5269 PackAddInt64(p, "cookie", current_cookie);
5270 if (IsEmptyStr(hint_str) == false)
5271 {
5272 PackAddStr(p, "hint", hint_str);
5273 }
5274 if (IsEmptyStr(target_hostname) == false)
5275 {
5276 PackAddStr(p, "target_hostname", target_hostname);
5277 }
5278 PackAddStr(p, "svc_name", svc_name);
5279
5280 PackAddInt(p, "nat_traversal_version", UDP_NAT_TRAVERSAL_VERSION);
5281
5282 b = PackToBuf(p);
5283 FreePack(p);
5284
5285 SendTo(sock, &nat_t_ip, UDP_NAT_T_PORT, b->Buf, b->Size);
5286 FreeBuf(b);
5287
5288 // Determine the next transmission time
5289 next_send_request_tick = now + (UINT64)UDP_NAT_T_CONNECT_INTERVAL * (UINT64)(Power(2, MAX(num_tries, 6)));
5290 num_tries++;
5291 AddInterrupt(interrupt, next_send_request_tick);
5292 }
5293
5294 interval = GetNextIntervalForInterrupt(interrupt);
5295 interval = MIN(interval, 50);
5296
5297 WaitSockEvent(sock_event, interval);
5298 }
5299
5300 Free(tmp);
5301 FreeInterruptManager(interrupt);
5302
5303 if (*error_code == RUDP_ERROR_OK)
5304 {
5305 UINT remain_timeout;
5306 UINT64 now = Tick64();
5307 // Success to get the IP address and the port number of the target
5308
5309 // Get the rest timeout tolerance
5310 if (now <= giveup_tick)
5311 {
5312 remain_timeout = (UINT)(giveup_tick - now);
5313 }
5314 else
5315 {
5316 remain_timeout = 0;
5317 }
5318
5319 remain_timeout = MAX(remain_timeout, 2000);
5320
5321 if (same_lan)
5322 {
5323 // Discard current UDP socket and create a new UDP socket in NewRUDPClientDirect().
5324 // Because using a UDP socket which used for communication with the NAT-T server
5325 // can cause trouble when the client and the server exists in the same LAN.
5326 ReleaseSockEvent(sock_event);
5327 ReleaseSock(sock);
5328
5329 sock = NULL;
5330 sock_event = NULL;
5331 }
5332
5333 ret = NewRUDPClientDirect(svc_name, &result_ip, result_port, error_code, remain_timeout, cancel,
5334 sock, sock_event, 0, false);
5335 }
5336
5337 if (sock_event != NULL)
5338 {
5339 ReleaseSockEvent(sock_event);
5340 }
5341
5342 if (sock != NULL)
5343 {
5344 if (ret == NULL)
5345 {
5346 Disconnect(sock);
5347 }
5348
5349 ReleaseSock(sock);
5350 }
5351
5352 return ret;
5353 }
5354 }
5355
5356 // Listen to the TCP for a moment to show the firewall dialog
ListenTcpForPopupFirewallDialog()5357 void ListenTcpForPopupFirewallDialog()
5358 {
5359 #ifdef OS_WIN32
5360 static bool tried = false;
5361
5362 if (tried == false)
5363 {
5364 SOCK *s;
5365 tried = true;
5366 s = ListenAnyPortEx2(false, true);
5367
5368 if (s != NULL)
5369 {
5370 Disconnect(s);
5371 ReleaseSock(s);
5372 }
5373 }
5374 #endif // OS_WIN32
5375 }
5376
5377 // Create a R-UDP client (direct connection)
NewRUDPClientDirect(char * svc_name,IP * ip,UINT port,UINT * error_code,UINT timeout,bool * cancel,SOCK * sock,SOCK_EVENT * sock_event,UINT local_port,bool over_dns_mode)5378 SOCK *NewRUDPClientDirect(char *svc_name, IP *ip, UINT port, UINT *error_code, UINT timeout, bool *cancel, SOCK *sock, SOCK_EVENT *sock_event, UINT local_port, bool over_dns_mode)
5379 {
5380 RUDP_STACK *r;
5381 UINT dummy_int = 0;
5382 SOCK *ret = NULL;
5383 // Validate arguments
5384 if (error_code == NULL)
5385 {
5386 error_code = &dummy_int;
5387 }
5388 if (timeout == 0)
5389 {
5390 timeout = RUDP_TIMEOUT;
5391 }
5392 *error_code = RUDP_ERROR_UNKNOWN;
5393 if (svc_name == NULL || ip == NULL || port == 0)
5394 {
5395 return NULL;
5396 }
5397
5398 r = NewRUDP(false, svc_name, NULL, NULL, NULL, local_port, sock, sock_event, false, over_dns_mode, ip, NULL, 0);
5399 if (r == NULL)
5400 {
5401 *error_code = RUDP_ERROR_UNKNOWN;
5402 return NULL;
5403 }
5404
5405 // Set the port number and the target IP address
5406 Lock(r->Lock);
5407 {
5408 Copy(&r->TargetIp, ip, sizeof(IP));
5409 r->TargetPort = port;
5410 r->TargetIpAndPortInited = true;
5411 }
5412 Unlock(r->Lock);
5413 SetSockEvent(r->SockEvent);
5414
5415 // Wait for a connection success/failure to the target IP address
5416 WaitEx(r->TargetConnectedEvent, timeout, cancel);
5417 Lock(r->Lock);
5418 {
5419 if (r->TargetConnectedSock != NULL)
5420 {
5421 // The connection succeeded
5422 ret = r->TargetConnectedSock;
5423 r->TargetConnectedSock = NULL;
5424 }
5425 else
5426 {
5427 r->DoNotSetTargetConnectedSock = true;
5428 }
5429 }
5430 Unlock(r->Lock);
5431
5432 if (ret == NULL)
5433 {
5434 // Stop the R-UDP stack if the connection has failed
5435 *error_code = RUDP_ERROR_TIMEOUT;
5436 FreeRUDP(r);
5437 }
5438 else if (cancel != NULL && (*cancel))
5439 {
5440 // User canceled
5441 *error_code = RUDP_ERROR_USER_CANCELED;
5442
5443 Disconnect(ret);
5444 ReleaseSock(ret);
5445
5446 ret = NULL;
5447 }
5448 else
5449 {
5450 *error_code = RUDP_ERROR_OK;
5451 }
5452
5453 return ret;
5454 }
5455
5456 // Creating a R-UDP server
NewRUDPServer(char * svc_name,RUDP_STACK_INTERRUPTS_PROC * proc_interrupts,RUDP_STACK_RPC_RECV_PROC * proc_rpc_recv,void * param,UINT port,bool no_natt_register,bool over_dns_mode,volatile UINT * natt_global_udp_port,UCHAR rand_port_id)5457 RUDP_STACK *NewRUDPServer(char *svc_name, RUDP_STACK_INTERRUPTS_PROC *proc_interrupts, RUDP_STACK_RPC_RECV_PROC *proc_rpc_recv, void *param, UINT port, bool no_natt_register, bool over_dns_mode, volatile UINT *natt_global_udp_port, UCHAR rand_port_id)
5458 {
5459 RUDP_STACK *r;
5460 // Validate arguments
5461 if (IsEmptyStr(svc_name))
5462 {
5463 return NULL;
5464 }
5465
5466 if (g_no_rudp_server)
5467 {
5468 return NULL;
5469 }
5470
5471 ListenTcpForPopupFirewallDialog();
5472
5473 r = NewRUDP(true, svc_name, proc_interrupts, proc_rpc_recv, param, port, NULL, NULL, no_natt_register, over_dns_mode, NULL, natt_global_udp_port, rand_port_id);
5474
5475 if (r == NULL)
5476 {
5477 return NULL;
5478 }
5479
5480 return r;
5481 }
5482
5483 // Creating a R-UDP
NewRUDP(bool server_mode,char * svc_name,RUDP_STACK_INTERRUPTS_PROC * proc_interrupts,RUDP_STACK_RPC_RECV_PROC * proc_rpc_recv,void * param,UINT port,SOCK * sock,SOCK_EVENT * sock_event,bool server_no_natt_register,bool over_dns_mode,IP * client_target_ip,volatile UINT * natt_global_udp_port,UCHAR rand_port_id)5484 RUDP_STACK *NewRUDP(bool server_mode, char *svc_name, RUDP_STACK_INTERRUPTS_PROC *proc_interrupts, RUDP_STACK_RPC_RECV_PROC *proc_rpc_recv, void *param, UINT port, SOCK *sock, SOCK_EVENT *sock_event, bool server_no_natt_register, bool over_dns_mode, IP *client_target_ip, volatile UINT *natt_global_udp_port, UCHAR rand_port_id)
5485 {
5486 RUDP_STACK *r;
5487 char tmp[MAX_SIZE];
5488 UCHAR pid_hash[SHA1_SIZE];
5489 UINT pid;
5490 USHORT pid_us;
5491
5492 // Validate arguments
5493 if (IsEmptyStr(svc_name))
5494 {
5495 return NULL;
5496 }
5497
5498 ListenTcpForPopupFirewallDialog();
5499
5500 if (sock == NULL)
5501 {
5502 if (server_mode == false && client_target_ip != NULL)
5503 {
5504 sock = NewUDP4ForSpecificIp(client_target_ip, port);
5505 }
5506 else
5507 {
5508 if (rand_port_id == 0)
5509 {
5510 sock = NewUDP(port);
5511 }
5512 else
5513 {
5514 sock = NewUDPEx2RandMachineAndExePath(false, NULL, 0, rand_port_id);
5515 }
5516 }
5517
5518 if (sock == NULL)
5519 {
5520 return NULL;
5521 }
5522 }
5523 else
5524 {
5525 AddRef(sock->ref);
5526 }
5527
5528 if (port == 0)
5529 {
5530 port = sock->LocalPort;
5531 }
5532
5533 if (rand_port_id != 0)
5534 {
5535 rand_port_numbers[rand_port_id] = port;
5536 }
5537
5538 if (sock_event == NULL)
5539 {
5540 sock_event = NewSockEvent();
5541 }
5542 else
5543 {
5544 AddRef(sock_event->ref);
5545 }
5546
5547 r = ZeroMalloc(sizeof(RUDP_STACK));
5548
5549 r->NatT_SessionKey = Rand64();
5550
5551 StrCpy(r->SvcName, sizeof(r->SvcName), svc_name);
5552 r->RandPortId = rand_port_id;
5553 r->NatTGlobalUdpPort = natt_global_udp_port;
5554 r->ServerMode = server_mode;
5555 r->Interrupt = NewInterruptManager();
5556 r->SessionList = NewList(RUDPCompareSessionList);
5557 r->UdpSock = sock;
5558 r->Port = port;
5559 r->SockEvent = sock_event;
5560 r->HaltEvent = NewEvent();
5561 r->Now = Tick64();
5562 r->Lock = NewLock();
5563 r->Param = param;
5564 r->TargetConnectedEvent = NewEvent();
5565 r->SendPacketList = NewList(NULL);
5566 r->NewSockConnectEvent = NewEvent();
5567 r->NewSockQueue = NewQueue();
5568 r->NatT_TranId = Rand64();
5569
5570 r->NatT_SourceIpList = NewListFast(NULL);
5571
5572 StrCpy(tmp, sizeof(tmp), r->SvcName);
5573 Trim(tmp);
5574 StrLower(tmp);
5575
5576 HashSha1(r->SvcNameHash, tmp, StrLen(tmp));
5577
5578 r->Client_IcmpId = (USHORT)(Rand32() % 65534 + 1);
5579 r->Client_IcmpSeqNo = (USHORT)(Rand32() % 65534 + 1);
5580
5581 // Determination of the type of the protocol
5582 r->Protocol = RUDP_PROTOCOL_UDP;
5583 if (r->Port == MAKE_SPECIAL_PORT(IP_PROTO_ICMPV4))
5584 {
5585 r->Protocol = RUDP_PROTOCOL_ICMP;
5586
5587 // Generate the ICMP ID based on the process ID
5588 #ifdef OS_WIN32
5589 pid = (UINT)MsGetProcessId();
5590 #else // OS_WIN32
5591 pid = (UINT)getpid();
5592 #endif // OS_WIN32
5593
5594 pid = Endian32(pid);
5595 HashSha1(pid_hash, &pid, sizeof(UINT));
5596
5597 pid_us = READ_USHORT(pid_hash);
5598 if (pid_us == 0 || pid_us == 0xFFFF)
5599 {
5600 pid_us = 1;
5601 }
5602
5603 r->Client_IcmpId = pid_us;
5604 }
5605 else if (over_dns_mode)
5606 {
5607 r->Protocol = RUDP_PROTOCOL_DNS;
5608 }
5609
5610 if (r->ServerMode)
5611 {
5612 r->NoNatTRegister = server_no_natt_register;
5613
5614 if (r->Protocol == RUDP_PROTOCOL_ICMP || r->Protocol == RUDP_PROTOCOL_DNS)
5615 {
5616 // Never register to the NAT-T server in case of using the DNS or the ICMP
5617 r->NoNatTRegister = true;
5618 }
5619 }
5620
5621 if (true
5622 )
5623 {
5624 RUDPGetRegisterHostNameByIP(r->CurrentRegisterHostname, sizeof(r->CurrentRegisterHostname), NULL);
5625 }
5626
5627 if (r->ServerMode)
5628 {
5629 r->ProcInterrupts = proc_interrupts;
5630 r->ProcRpcRecv = proc_rpc_recv;
5631 }
5632
5633 if (r->ServerMode && r->NoNatTRegister == false
5634 )
5635 {
5636 r->IpQueryThread = NewThread(RUDPIpQueryThread, r);
5637 }
5638
5639 JoinSockToSockEvent(r->UdpSock, r->SockEvent);
5640
5641 r->Thread = NewThread(RUDPMainThread, r);
5642 WaitThreadInit(r->Thread);
5643
5644 return r;
5645 }
5646
5647 // R-UDP session comparison function
RUDPCompareSessionList(void * p1,void * p2)5648 int RUDPCompareSessionList(void *p1, void *p2)
5649 {
5650 RUDP_SESSION *s1, *s2;
5651 UINT r;
5652 // Validate arguments
5653 if (p1 == NULL || p2 == NULL)
5654 {
5655 return 0;
5656 }
5657 s1 = *((RUDP_SESSION **)p1);
5658 s2 = *((RUDP_SESSION **)p2);
5659 if (s1 == NULL || s2 == NULL)
5660 {
5661 return 0;
5662 }
5663
5664 r = CmpIpAddr(&s1->YourIp, &s2->YourIp);
5665 if (r != 0)
5666 {
5667 return r;
5668 }
5669
5670 r = COMPARE_RET(s1->YourPort, s2->YourPort);
5671 if (r != 0)
5672 {
5673 return r;
5674 }
5675
5676 r = CmpIpAddr(&s1->MyIp, &s2->MyIp);
5677 if (r != 0)
5678 {
5679 return r;
5680 }
5681
5682 r = COMPARE_RET(s1->MyPort, s2->MyPort);
5683 if (r != 0)
5684 {
5685 return r;
5686 }
5687
5688 return 0;
5689 }
5690
5691 // Release of the R-UDP
FreeRUDP(RUDP_STACK * r)5692 void FreeRUDP(RUDP_STACK *r)
5693 {
5694 UINT i;
5695 // Validate arguments
5696 if (r == NULL)
5697 {
5698 return;
5699 }
5700
5701 r->Halt = true;
5702 Set(r->HaltEvent);
5703 SetSockEvent(r->SockEvent);
5704
5705 if (r->ServerMode && r->NoNatTRegister == false)
5706 {
5707 if (r->IpQueryThread != NULL)
5708 {
5709 WaitThread(r->IpQueryThread, INFINITE);
5710 ReleaseThread(r->IpQueryThread);
5711 }
5712 }
5713
5714 WaitThread(r->Thread, INFINITE);
5715 ReleaseThread(r->Thread);
5716
5717 for (i = 0;i < LIST_NUM(r->SessionList);i++)
5718 {
5719 RUDP_SESSION *se = LIST_DATA(r->SessionList, i);
5720
5721 RUDPFreeSession(se);
5722 }
5723
5724 ReleaseList(r->SessionList);
5725
5726 for (i = 0;i < LIST_NUM(r->SendPacketList);i++)
5727 {
5728 UDPPACKET *p = LIST_DATA(r->SendPacketList, i);
5729
5730 FreeUdpPacket(p);
5731 }
5732
5733 while (true)
5734 {
5735 SOCK *s = GetNext(r->NewSockQueue);
5736 if (s == NULL)
5737 {
5738 break;
5739 }
5740
5741 Disconnect(s);
5742 ReleaseSock(s);
5743 }
5744
5745 for (i = 0;i < LIST_NUM(r->NatT_SourceIpList);i++)
5746 {
5747 RUDP_SOURCE_IP *sip = (RUDP_SOURCE_IP *)LIST_DATA(r->NatT_SourceIpList, i);
5748
5749 Free(sip);
5750 }
5751
5752 ReleaseList(r->NatT_SourceIpList);
5753
5754 ReleaseQueue(r->NewSockQueue);
5755
5756 ReleaseList(r->SendPacketList);
5757
5758 FreeInterruptManager(r->Interrupt);
5759
5760 Disconnect(r->UdpSock);
5761 ReleaseSock(r->UdpSock);
5762 ReleaseSockEvent(r->SockEvent);
5763 ReleaseEvent(r->HaltEvent);
5764 ReleaseEvent(r->TargetConnectedEvent);
5765
5766 ReleaseEvent(r->NewSockConnectEvent);
5767
5768 Disconnect(r->TargetConnectedSock);
5769 ReleaseSock(r->TargetConnectedSock);
5770
5771 DeleteLock(r->Lock);
5772
5773 if (r->RandPortId != 0)
5774 {
5775 rand_port_numbers[r->RandPortId] = 0;
5776 }
5777
5778 Free(r);
5779 }
5780
5781 // Generate a hash from the current computer name and the process name
GetCurrentMachineIpProcessHash(void * hash)5782 void GetCurrentMachineIpProcessHash(void *hash)
5783 {
5784 // Validate arguments
5785 if (hash == NULL)
5786 {
5787 return;
5788 }
5789
5790 Lock(machine_ip_process_hash_lock);
5791 {
5792 if (IsZero(machine_ip_process_hash, SHA1_SIZE))
5793 {
5794 GetCurrentMachineIpProcessHashInternal(machine_ip_process_hash);
5795 }
5796
5797 Copy(hash, machine_ip_process_hash, SHA1_SIZE);
5798 }
5799 Unlock(machine_ip_process_hash_lock);
5800 }
GetCurrentMachineIpProcessHashInternal(void * hash)5801 void GetCurrentMachineIpProcessHashInternal(void *hash)
5802 {
5803 BUF *b;
5804 LIST *ip_list;
5805 char machine_name[MAX_SIZE];
5806 wchar_t exe_path[MAX_PATH];
5807 char *product_id = NULL;
5808 // Validate arguments
5809 if (hash == NULL)
5810 {
5811 return;
5812 }
5813
5814 #ifdef OS_WIN32
5815 product_id = MsRegReadStr(REG_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "ProductId");
5816 if (product_id == NULL)
5817 {
5818 product_id = MsRegReadStr(REG_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion", "ProductId");
5819 }
5820 #endif // OS_WIN32
5821
5822 b = NewBuf();
5823
5824 GetMachineHostName(machine_name, sizeof(machine_name));
5825 Trim(machine_name);
5826 StrUpper(machine_name);
5827
5828 GetExeNameW(exe_path, sizeof(exe_path));
5829 UniTrim(exe_path);
5830 UniStrUpper(exe_path);
5831
5832 WriteBuf(b, machine_name, StrSize(machine_name));
5833 WriteBuf(b, exe_path, UniStrSize(exe_path));
5834 WriteBuf(b, product_id, StrSize(product_id));
5835
5836 ip_list = GetHostIPAddressList();
5837 if (ip_list != NULL)
5838 {
5839 UINT i;
5840 for (i = 0;i < LIST_NUM(ip_list);i++)
5841 {
5842 IP *ip = LIST_DATA(ip_list, i);
5843
5844 WriteBuf(b, ip, sizeof(IP));
5845 }
5846 }
5847 FreeHostIPAddressList(ip_list);
5848
5849 HashSha1(hash, b->Buf, b->Size);
5850
5851 FreeBuf(b);
5852
5853 Free(product_id);
5854 }
5855
5856 // Create a pair of pre-bound TCP sockets
NewTcpPair(SOCK ** s1,SOCK ** s2)5857 bool NewTcpPair(SOCK **s1, SOCK **s2)
5858 {
5859 SOCK *a;
5860 SOCK *s, *c;
5861 TUBE *t1, *t2;
5862 SOCK_EVENT *e1, *e2;
5863 // Validate arguments
5864 if (s1 == NULL || s2 == NULL)
5865 {
5866 return false;
5867 }
5868
5869 a = ListenAnyPortEx2(true, true);
5870 if (a == NULL)
5871 {
5872 return false;
5873 }
5874
5875 c = Connect("127.0.0.1", a->LocalPort);
5876 if (c == NULL)
5877 {
5878 ReleaseSock(a);
5879 return false;
5880 }
5881
5882 s = Accept(a);
5883 if (s == NULL)
5884 {
5885 ReleaseSock(c);
5886 ReleaseSock(a);
5887 return false;
5888 }
5889
5890 ReleaseSock(a);
5891
5892 if ((s->LocalPort != c->RemotePort) || (s->RemotePort != c->LocalPort))
5893 {
5894 ReleaseSock(s);
5895 ReleaseSock(c);
5896 return false;
5897 }
5898
5899 NewTubePair(&t1, &t2, sizeof(TCP_PAIR_HEADER));
5900
5901 // Creating a socket event
5902 e1 = NewSockEvent();
5903 e2 = NewSockEvent();
5904
5905 SetTubeSockEvent(t1, e1);
5906 SetTubeSockEvent(t2, e2);
5907
5908 AddRef(t1->Ref);
5909 AddRef(t2->Ref);
5910 s->BulkRecvTube = c->BulkSendTube = t1;
5911 s->BulkSendTube = c->BulkRecvTube = t2;
5912
5913 ReleaseSockEvent(e1);
5914 ReleaseSockEvent(e2);
5915
5916 *s1 = s;
5917 *s2 = c;
5918
5919 return true;
5920 }
5921
5922 // Listen in any available port
ListenAnyPortEx(bool local_only)5923 SOCK *ListenAnyPortEx(bool local_only)
5924 {
5925 return ListenAnyPortEx2(local_only, false);
5926 }
ListenAnyPortEx2(bool local_only,bool disable_ca)5927 SOCK *ListenAnyPortEx2(bool local_only, bool disable_ca)
5928 {
5929 UINT i;
5930 SOCK *s;
5931 for (i = 40000;i < 65536;i++)
5932 {
5933 s = ListenEx(i, local_only);
5934 if (s != NULL)
5935 {
5936 return s;
5937 }
5938 }
5939
5940 return NULL;
5941 }
5942
cb_test(int a,X509_STORE_CTX * ctx)5943 int cb_test(int a, X509_STORE_CTX *ctx)
5944 {
5945 WHERE;
5946 return 1;
5947 }
5948
5949 #if OPENSSL_VERSION_NUMBER < 0x10100000L
5950 #define X509_STORE_CTX_get0_cert(o) ((o)->cert)
5951 #endif
5952
5953 // Verify client SSL certificate during TLS handshake.
5954 //
5955 // (actually, only save the certificate for later authentication in Protocol.c)
SslCertVerifyCallback(int preverify_ok,X509_STORE_CTX * ctx)5956 int SslCertVerifyCallback(int preverify_ok, X509_STORE_CTX *ctx)
5957 {
5958 SSL *ssl;
5959 struct SslClientCertInfo *clientcert;
5960 X509 *cert;
5961
5962 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
5963 clientcert = SSL_get_ex_data(ssl, GetSslClientCertIndex());
5964
5965 if (clientcert != NULL)
5966 {
5967 clientcert->PreverifyErr = X509_STORE_CTX_get_error(ctx);
5968 clientcert->PreverifyErrMessage[0] = '\0';
5969 if (!preverify_ok)
5970 {
5971 const char *msg = X509_verify_cert_error_string(clientcert->PreverifyErr);
5972 StrCpy(clientcert->PreverifyErrMessage, PREVERIFY_ERR_MESSAGE_SIZE, (char *)msg);
5973 Debug("SslCertVerifyCallback preverify error: '%s'\n", msg);
5974 }
5975 else
5976 {
5977 cert = X509_STORE_CTX_get0_cert(ctx);
5978 if (cert != NULL)
5979 {
5980 X *tmpX = X509ToX(cert); // this only wraps cert, but we need to make a copy
5981 X *copyX = CloneX(tmpX);
5982 tmpX->do_not_free = true; // do not release inner X509 object
5983 FreeX(tmpX);
5984 clientcert->X = copyX;
5985 }
5986 }
5987 }
5988
5989 return 1; /* allow the verification process to continue */
5990 }
5991
5992 // Create a new SSL pipe
NewSslPipe(bool server_mode,X * x,K * k,DH_CTX * dh)5993 SSL_PIPE *NewSslPipe(bool server_mode, X *x, K *k, DH_CTX *dh)
5994 {
5995 return NewSslPipeEx(server_mode, x, k, dh, false, NULL);
5996 }
5997
5998 // Create a new SSL pipe with extended options
NewSslPipeEx(bool server_mode,X * x,K * k,DH_CTX * dh,bool verify_peer,struct SslClientCertInfo * clientcert)5999 SSL_PIPE *NewSslPipeEx(bool server_mode, X *x, K *k, DH_CTX *dh, bool verify_peer, struct SslClientCertInfo *clientcert)
6000 {
6001 SSL_PIPE *s;
6002 SSL *ssl;
6003 SSL_CTX *ssl_ctx = NewSSLCtx(server_mode);
6004
6005 Lock(openssl_lock);
6006 {
6007 if (server_mode)
6008 {
6009 SSL_CTX_set_ssl_version(ssl_ctx, SSLv23_method());
6010 SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSLv2);
6011
6012 AddChainSslCertOnDirectory(ssl_ctx);
6013
6014 if (dh != NULL)
6015 {
6016 SSL_CTX_set_tmp_dh(ssl_ctx, dh->dh);
6017 }
6018 }
6019 else
6020 {
6021 SSL_CTX_set_ssl_version(ssl_ctx, SSLv23_client_method());
6022 }
6023
6024 if (verify_peer)
6025 {
6026 SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, SslCertVerifyCallback);
6027 }
6028
6029 if (dh != NULL)
6030 {
6031 SSL_CTX_set_options(ssl_ctx, SSL_OP_SINGLE_DH_USE);
6032 }
6033
6034 if (server_mode == false)
6035 {
6036 SSL_CTX_set_options(ssl_ctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
6037 }
6038
6039 ssl = SSL_new(ssl_ctx);
6040
6041 // Set the OpenSSL default cipher algorithms
6042 SSL_set_cipher_list(ssl, OPENSSL_DEFAULT_CIPHER_LIST);
6043
6044 SSL_set_ex_data(ssl, GetSslClientCertIndex(), clientcert);
6045 }
6046 Unlock(openssl_lock);
6047
6048 s = ZeroMalloc(sizeof(SSL_PIPE));
6049
6050 s->ssl = ssl;
6051 s->ssl_ctx = ssl_ctx;
6052 s->ServerMode = server_mode;
6053
6054 s->SslInOut = NewSslBioSsl();
6055 s->RawIn = NewSslBioMem();
6056 s->RawOut = NewSslBioMem();
6057
6058 if (x != NULL && k != NULL)
6059 {
6060 Lock(openssl_lock);
6061 {
6062 SSL_use_certificate(s->ssl, x->x509);
6063 SSL_use_PrivateKey(s->ssl, k->pkey);
6064 }
6065 Unlock(openssl_lock);
6066 }
6067
6068 if (s->ServerMode == false)
6069 {
6070 SSL_set_connect_state(s->ssl);
6071 }
6072 else
6073 {
6074 SSL_set_accept_state(s->ssl);
6075 }
6076
6077 SSL_set_bio(s->ssl, s->RawIn->bio, s->RawOut->bio);
6078 BIO_set_ssl(s->SslInOut->bio, s->ssl, BIO_NOCLOSE);
6079
6080 //s->RawIn->NoFree = true;
6081 s->RawOut->NoFree = true;
6082
6083 return s;
6084 }
6085
6086 // Synchronization of the SSL pipe
SyncSslPipe(SSL_PIPE * s)6087 bool SyncSslPipe(SSL_PIPE *s)
6088 {
6089 UINT i;
6090 // Validate arguments
6091 if (s == NULL || s->IsDisconnected)
6092 {
6093 return false;
6094 }
6095
6096 for (i = 0;i < 2;i++)
6097 {
6098 if (SslBioSync(s->RawIn, true, false) == false)
6099 {
6100 s->IsDisconnected = true;
6101 Debug("SyncSslPipe: s->RawIn error.\n");
6102 return false;
6103 }
6104
6105 if (SslBioSync(s->RawOut, false, true) == false)
6106 {
6107 s->IsDisconnected = true;
6108 Debug("SyncSslPipe: s->RawOut error.\n");
6109 return false;
6110 }
6111
6112 if (SslBioSync(s->SslInOut, true, true) == false)
6113 {
6114 s->IsDisconnected = true;
6115 Debug("SyncSslPipe: s->SslInOut error.\n");
6116 return false;
6117 }
6118 }
6119
6120 return true;
6121 }
6122
6123 // Release of the SSL pipe
FreeSslPipe(SSL_PIPE * s)6124 void FreeSslPipe(SSL_PIPE *s)
6125 {
6126 // Validate arguments
6127 if (s == NULL)
6128 {
6129 return;
6130 }
6131
6132 FreeSslBio(s->SslInOut);
6133 FreeSslBio(s->RawIn);
6134 FreeSslBio(s->RawOut);
6135
6136 SSL_free(s->ssl);
6137 SSL_CTX_free(s->ssl_ctx);
6138
6139 Free(s);
6140 }
6141
6142 // Release of the SSL BIO
FreeSslBio(SSL_BIO * b)6143 void FreeSslBio(SSL_BIO *b)
6144 {
6145 // Validate arguments
6146 if (b == NULL)
6147 {
6148 return;
6149 }
6150
6151 if (b->NoFree == false)
6152 {
6153 BIO_free(b->bio);
6154 }
6155
6156 ReleaseFifo(b->RecvFifo);
6157 ReleaseFifo(b->SendFifo);
6158
6159 Free(b);
6160 }
6161
6162 // Create a new SSL BIO (SSL)
NewSslBioSsl()6163 SSL_BIO *NewSslBioSsl()
6164 {
6165 SSL_BIO *b = ZeroMalloc(sizeof(SSL_BIO));
6166
6167 b->bio = BIO_new(BIO_f_ssl());
6168
6169 b->RecvFifo = NewFifo();
6170 b->SendFifo = NewFifo();
6171
6172 return b;
6173 }
6174
6175 // Create a new SSL BIO (memory)
NewSslBioMem()6176 SSL_BIO *NewSslBioMem()
6177 {
6178 SSL_BIO *b = ZeroMalloc(sizeof(SSL_BIO));
6179
6180 b->bio = BIO_new(BIO_s_mem());
6181
6182 b->RecvFifo = NewFifo();
6183 b->SendFifo = NewFifo();
6184
6185 return b;
6186 }
6187
6188 // Synchronize memory contents of the SSL BIO with the FIFO
SslBioSync(SSL_BIO * b,bool sync_send,bool sync_recv)6189 bool SslBioSync(SSL_BIO *b, bool sync_send, bool sync_recv)
6190 {
6191 // Validate arguments
6192 if (b == NULL)
6193 {
6194 return false;
6195 }
6196
6197 if (b->IsDisconnected)
6198 {
6199 return false;
6200 }
6201
6202 // Write the contents of the SendFifo to the BIO
6203 if (sync_send)
6204 {
6205 while (b->SendFifo->size >= 1)
6206 {
6207 int r = BIO_write(b->bio, GetFifoPointer(b->SendFifo), FifoSize(b->SendFifo));
6208
6209 if (r == 0)
6210 {
6211 b->IsDisconnected = true;
6212 WHERE;
6213 return false;
6214 }
6215 else
6216 {
6217 if (r < 0)
6218 {
6219 if (BIO_should_retry(b->bio))
6220 {
6221 break;
6222 }
6223 else
6224 {
6225 b->IsDisconnected = true;
6226 WHERE;
6227 return false;
6228 }
6229 }
6230 else
6231 {
6232 ReadFifo(b->SendFifo, NULL, (UINT)r);
6233 }
6234 }
6235 }
6236 }
6237
6238 // Save to the RecvFifo by reading from the BIO
6239 if (sync_recv)
6240 {
6241 while (true)
6242 {
6243 UCHAR tmp[4096];
6244 int r;
6245
6246 r = BIO_read(b->bio, tmp, sizeof(tmp));
6247
6248 if (r == 0)
6249 {
6250 b->IsDisconnected = true;
6251 WHERE;
6252 return false;
6253 }
6254 else
6255 {
6256 if (r < 0)
6257 {
6258 if (BIO_should_retry(b->bio))
6259 {
6260 break;
6261 }
6262 else
6263 {
6264 b->IsDisconnected = true;
6265 WHERE;
6266 Debug("OpenSSL Error: %s\n", ERR_error_string(ERR_peek_last_error(), NULL));
6267 return false;
6268 }
6269 }
6270 else
6271 {
6272 WriteFifo(b->RecvFifo, tmp, (UINT)r);
6273 }
6274 }
6275 }
6276 }
6277
6278 return true;
6279 }
6280
6281 // Release the memory for the return value of the ICMP API
IcmpApiFreeResult(ICMP_RESULT * ret)6282 void IcmpApiFreeResult(ICMP_RESULT *ret)
6283 {
6284 // Validate arguments
6285 if (ret == NULL)
6286 {
6287 return;
6288 }
6289
6290 if (ret->Data != NULL)
6291 {
6292 Free(ret->Data);
6293 }
6294
6295 Free(ret);
6296 }
6297
6298 // Send an ICMP Echo using ICMP API
IcmpApiEchoSend(IP * dest_ip,UCHAR ttl,UCHAR * data,UINT size,UINT timeout)6299 ICMP_RESULT *IcmpApiEchoSend(IP *dest_ip, UCHAR ttl, UCHAR *data, UINT size, UINT timeout)
6300 {
6301 #ifdef OS_WIN32
6302 // Validate arguments
6303 if (dest_ip == NULL || IsIP4(dest_ip) == false || (size != 0 && data == NULL))
6304 {
6305 return NULL;
6306 }
6307 if (ttl == 0)
6308 {
6309 ttl = 127;
6310 }
6311
6312 if (IsIcmpApiSupported())
6313 {
6314 HANDLE h;
6315 DWORD dw;
6316 IPAddr dest_addr;
6317 UINT reply_size;
6318 ICMP_ECHO_REPLY *reply;
6319 ICMP_RESULT *ret = NULL;
6320 IP_OPTION_INFORMATION opt;
6321
6322 h = w32net->IcmpCreateFile();
6323
6324 if (h == INVALID_HANDLE_VALUE)
6325 {
6326 return NULL;
6327 }
6328
6329 Zero(&opt, sizeof(opt));
6330 opt.Ttl = ttl;
6331
6332 IPToInAddr((struct in_addr *)&dest_addr, dest_ip);
6333
6334 reply_size = sizeof(*reply) + size + 64;
6335 reply = ZeroMalloc(reply_size);
6336
6337 dw = w32net->IcmpSendEcho(h, dest_addr, data, size, &opt, reply, reply_size, timeout);
6338
6339 ret = ZeroMalloc(sizeof(ICMP_RESULT));
6340
6341 if (dw >= 1 && reply->Status == IP_SUCCESS)
6342 {
6343 ret->Ok = true;
6344 }
6345 else
6346 {
6347 switch (reply->Status)
6348 {
6349 case IP_DEST_NET_UNREACHABLE:
6350 ret->Type = ICMP_TYPE_DESTINATION_UNREACHABLE;
6351 ret->Code = ICMP_CODE_NET_UNREACHABLE;
6352 break;
6353
6354 case IP_DEST_HOST_UNREACHABLE:
6355 ret->Type = ICMP_TYPE_DESTINATION_UNREACHABLE;
6356 ret->Code = ICMP_CODE_HOST_UNREACHABLE;
6357 break;
6358
6359 case IP_DEST_PROT_UNREACHABLE:
6360 ret->Type = ICMP_TYPE_DESTINATION_UNREACHABLE;
6361 ret->Code = ICMP_CODE_PROTOCOL_UNREACHABLE;
6362 break;
6363
6364 case IP_DEST_PORT_UNREACHABLE:
6365 ret->Type = ICMP_TYPE_DESTINATION_UNREACHABLE;
6366 ret->Code = ICMP_CODE_PORT_UNREACHABLE;
6367 break;
6368
6369 case IP_TTL_EXPIRED_TRANSIT:
6370 ret->Type = ICMP_TYPE_TIME_EXCEEDED;
6371 ret->Code = ICMP_CODE_TTL_EXCEEDED_IN_TRANSIT;
6372 break;
6373
6374 case IP_TTL_EXPIRED_REASSEM:
6375 ret->Type = ICMP_TYPE_TIME_EXCEEDED;
6376 ret->Code = ICMP_CODE_FRAGMENT_REASSEMBLY_TIME_EXCEEDED;
6377 break;
6378
6379 default:
6380 ret->Timeout = true;
6381 break;
6382 }
6383 }
6384
6385 if (ret->Timeout == false)
6386 {
6387 ret->Ttl = reply->Options.Ttl;
6388 ret->Rtt = reply->RoundTripTime;
6389 InAddrToIP(&ret->IpAddress, (struct in_addr *)&reply->Address);
6390
6391 if (reply->DataSize >= 1 && reply->Data != NULL)
6392 {
6393 ret->DataSize = reply->DataSize;
6394 ret->Data = Clone(reply->Data, reply->DataSize);
6395 }
6396 }
6397
6398 Free(reply);
6399
6400 w32net->IcmpCloseHandle(h);
6401
6402 return ret;
6403 }
6404 else
6405 {
6406 return NULL;
6407 }
6408
6409 #else // OS_WIN32
6410 return NULL;
6411 #endif // OS_WIN32
6412 }
6413
6414 // Detect whether the ICMP API is supported
IsIcmpApiSupported()6415 bool IsIcmpApiSupported()
6416 {
6417 #ifdef OS_WIN32
6418 if (w32net->IcmpCloseHandle != NULL &&
6419 w32net->IcmpCreateFile != NULL &&
6420 w32net->IcmpSendEcho != NULL)
6421 {
6422 return true;
6423 }
6424 #endif // OS_WIN32
6425
6426 return false;
6427 }
6428
6429 // Initialize the routing table change detector
NewRouteChange()6430 ROUTE_CHANGE *NewRouteChange()
6431 {
6432 #ifdef OS_WIN32
6433 return Win32NewRouteChange();
6434 #else // OS_WIN32
6435 return NULL;
6436 #endif // OS_WIN32
6437 }
6438
6439 // Release the routing table change detector
FreeRouteChange(ROUTE_CHANGE * r)6440 void FreeRouteChange(ROUTE_CHANGE *r)
6441 {
6442 #ifdef OS_WIN32
6443 Win32FreeRouteChange(r);
6444 #endif // OS_WIN32
6445 }
6446
6447 // Get whether the routing table has been changed
IsRouteChanged(ROUTE_CHANGE * r)6448 bool IsRouteChanged(ROUTE_CHANGE *r)
6449 {
6450 #ifdef OS_WIN32
6451 return Win32IsRouteChanged(r);
6452 #else // OS_WIN32
6453 return false;
6454 #endif // OS_WIN32
6455 }
6456
6457 // Routing table change detector function (Win32)
6458 #ifdef OS_WIN32
Win32NewRouteChange()6459 ROUTE_CHANGE *Win32NewRouteChange()
6460 {
6461 ROUTE_CHANGE *r;
6462 bool ret;
6463
6464 if (MsIsNt() == false)
6465 {
6466 return NULL;
6467 }
6468
6469 if (w32net->CancelIPChangeNotify == NULL ||
6470 w32net->NotifyRouteChange == NULL)
6471 {
6472 return NULL;
6473 }
6474
6475 r = ZeroMalloc(sizeof(ROUTE_CHANGE));
6476
6477 r->Data = ZeroMalloc(sizeof(ROUTE_CHANGE_DATA));
6478
6479 r->Data->Overlapped.hEvent = CreateEventA(NULL, false, true, NULL);
6480
6481 ret = w32net->NotifyRouteChange(&r->Data->Handle, &r->Data->Overlapped);
6482 if (!(ret == NO_ERROR || ret == WSA_IO_PENDING || WSAGetLastError() == WSA_IO_PENDING))
6483 {
6484 Free(r->Data);
6485 Free(r);
6486
6487 return NULL;
6488 }
6489
6490 return r;
6491 }
6492
Win32FreeRouteChange(ROUTE_CHANGE * r)6493 void Win32FreeRouteChange(ROUTE_CHANGE *r)
6494 {
6495 // Validate arguments
6496 if (r == NULL)
6497 {
6498 return;
6499 }
6500
6501 w32net->CancelIPChangeNotify(&r->Data->Overlapped);
6502 CloseHandle(r->Data->Overlapped.hEvent);
6503
6504 Free(r->Data);
6505 Free(r);
6506 }
6507
Win32IsRouteChanged(ROUTE_CHANGE * r)6508 bool Win32IsRouteChanged(ROUTE_CHANGE *r)
6509 {
6510 // Validate arguments
6511 if (r == NULL)
6512 {
6513 return false;
6514 }
6515
6516 if ((r->Data->NumCalled++) == 0)
6517 {
6518 return true;
6519 }
6520
6521 if (WaitForSingleObject(r->Data->Overlapped.hEvent, 0) == WAIT_OBJECT_0)
6522 {
6523 w32net->NotifyRouteChange(&r->Data->Handle, &r->Data->Overlapped);
6524 return true;
6525 }
6526
6527 return false;
6528 }
6529
6530 typedef struct WIN32_ACCEPT_CHECK_DATA
6531 {
6532 bool IsIPv6;
6533 bool Rejected;
6534 } WIN32_ACCEPT_CHECK_DATA;
6535
6536 // Function for determining whether accept or not in Win32
Win32AcceptCheckCallback_Delay(LPWSABUF lpCallerId,LPWSABUF lpCallerData,LPQOS pQos,LPQOS lpGQOS,LPWSABUF lpCalleeId,LPWSABUF lpCalleeData,GROUP FAR * g,DWORD_PTR dwCallbackData)6537 int CALLBACK Win32AcceptCheckCallback_Delay(LPWSABUF lpCallerId, LPWSABUF lpCallerData, LPQOS pQos,
6538 LPQOS lpGQOS, LPWSABUF lpCalleeId, LPWSABUF lpCalleeData,
6539 GROUP FAR * g, DWORD_PTR dwCallbackData)
6540 {
6541 return CF_DEFER;
6542 }
6543
Win32AcceptCheckCallback(LPWSABUF lpCallerId,LPWSABUF lpCallerData,LPQOS pQos,LPQOS lpGQOS,LPWSABUF lpCalleeId,LPWSABUF lpCalleeData,GROUP FAR * g,DWORD_PTR dwCallbackData)6544 int CALLBACK Win32AcceptCheckCallback(LPWSABUF lpCallerId, LPWSABUF lpCallerData, LPQOS pQos,
6545 LPQOS lpGQOS, LPWSABUF lpCalleeId, LPWSABUF lpCalleeData,
6546 GROUP FAR * g, DWORD_PTR dwCallbackData)
6547 {
6548 return CF_ACCEPT;
6549 }
6550
6551 // Accept function for Win32
Win32Accept_XP(SOCK * sock,SOCKET s,struct sockaddr * addr,int * addrlen,bool ipv6)6552 SOCKET Win32Accept_XP(SOCK *sock, SOCKET s, struct sockaddr *addr, int *addrlen, bool ipv6)
6553 {
6554 SOCKET ret;
6555 WIN32_ACCEPT_CHECK_DATA d;
6556 UINT err;
6557 int initial_addrlen = *addrlen;
6558 UINT num_error = 0;
6559 // Validate arguments
6560 if (s == INVALID_SOCKET)
6561 {
6562 return INVALID_SOCKET;
6563 }
6564
6565 L_LOOP:
6566
6567 Zero(&d, sizeof(d));
6568
6569 d.IsIPv6 = ipv6;
6570
6571 *addrlen = initial_addrlen;
6572 Zero(addr, initial_addrlen);
6573 ret = WSAAccept(s, addr, addrlen, Win32AcceptCheckCallback, (DWORD_PTR)&d);
6574
6575 if (ret == INVALID_SOCKET)
6576 {
6577 err = WSAGetLastError();
6578
6579 num_error++;
6580
6581 Debug("!!! WSAAccept Error: %u rej=%u num=%u tick=%I64u\n", WSAGetLastError(), d.Rejected, num_error, Tick64());
6582
6583 if (d.Rejected && err == WSAECONNREFUSED)
6584 {
6585 goto L_LOOP;
6586 }
6587
6588 if (err == WSAETIMEDOUT)
6589 {
6590 goto L_LOOP;
6591 }
6592 }
6593
6594 return ret;
6595 }
6596
6597 // Accept function for Win32
Win32Accept(SOCK * sock,SOCKET s,struct sockaddr * addr,int * addrlen,bool ipv6)6598 SOCKET Win32Accept(SOCK *sock, SOCKET s, struct sockaddr *addr, int *addrlen, bool ipv6)
6599 {
6600 SOCKET ret;
6601 WIN32_ACCEPT_CHECK_DATA d;
6602 UINT err;
6603 int initial_addrlen = *addrlen;
6604 UINT num_error = 0;
6605 UINT zero = 0;
6606 UINT tmp = 0;
6607 UINT ret_size = 0;
6608 // Validate arguments
6609 if (sock == NULL || s == INVALID_SOCKET)
6610 {
6611 return INVALID_SOCKET;
6612 }
6613
6614 if (sock->hAcceptEvent == NULL)
6615 {
6616 sock->hAcceptEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
6617
6618 WSAEventSelect(s, sock->hAcceptEvent, FD_ACCEPT | FD_CLOSE);
6619 }
6620
6621 L_LOOP:
6622
6623 if (sock->CancelAccept)
6624 {
6625 return INVALID_SOCKET;
6626 }
6627
6628 Zero(&d, sizeof(d));
6629
6630 d.IsIPv6 = ipv6;
6631
6632 *addrlen = initial_addrlen;
6633 Zero(addr, initial_addrlen);
6634 ret = WSAAccept(s, addr, addrlen, Win32AcceptCheckCallback, (DWORD_PTR)&d);
6635
6636 if (ret == INVALID_SOCKET)
6637 {
6638 err = WSAGetLastError();
6639
6640 if (err == WSAEWOULDBLOCK)
6641 {
6642 //Debug("!!! WSAAccept: WSAEWOULDBLOCK\n");
6643 UINT wait_ret = WaitForSingleObject(sock->hAcceptEvent, 1234);
6644
6645 if (wait_ret == WAIT_OBJECT_0 || wait_ret == WAIT_TIMEOUT)
6646 {
6647 goto L_LOOP;
6648 }
6649
6650 Debug("!!! WaitForSingleObject Error. ret=%u GetLastError=%u\n", wait_ret, GetLastError());
6651 }
6652
6653 num_error++;
6654
6655 Debug("!!! WSAAccept Error: %u rej=%u num=%u tick=%I64u\n", err, d.Rejected, num_error, Tick64());
6656
6657 if (d.Rejected && err == WSAECONNREFUSED)
6658 {
6659 goto L_LOOP;
6660 }
6661
6662 if (err == WSAETIMEDOUT)
6663 {
6664 goto L_LOOP;
6665 }
6666 }
6667 else
6668 {
6669 // Remove a new socket from the event
6670 WSAEventSelect(ret, sock->hAcceptEvent, 0);
6671
6672 // Restore the new socket to synchronized
6673 WSAIoctl(ret, FIONBIO, &zero, sizeof(zero), &tmp, sizeof(tmp), &ret_size, NULL, NULL);
6674 }
6675
6676 return ret;
6677 }
6678
6679 #endif // OS_WIN32
6680
6681
6682 // Get whether the aquirement of the Process ID of the TCP connection succeed
CanGetTcpProcessId()6683 bool CanGetTcpProcessId()
6684 {
6685 UINT i;
6686 bool ret = false;
6687 LIST *o = GetTcpTableList();
6688
6689 if (o == NULL)
6690 {
6691 return false;
6692 }
6693
6694 for (i = 0;i < LIST_NUM(o);i++)
6695 {
6696 TCPTABLE *t = LIST_DATA(o, i);
6697
6698 if (t->ProcessId != 0)
6699 {
6700 ret = true;
6701 break;
6702 }
6703 }
6704
6705 FreeTcpTableList(o);
6706
6707 return ret;
6708 }
6709
6710
6711
6712
6713 #define USE_OLD_GETIP
6714
6715 // Set the arp_filter in Linux
SetLinuxArpFilter()6716 void SetLinuxArpFilter()
6717 {
6718 char *filename = "/proc/sys/net/ipv4/conf/all/arp_filter";
6719 char *data = "1\n";
6720 IO *o;
6721
6722 o = FileCreate(filename);
6723 if (o == NULL)
6724 {
6725 return;
6726 }
6727
6728 FileWrite(o, data, StrLen(data));
6729 FileFlush(o);
6730
6731 FileClose(o);
6732 }
6733
6734 // Determine whether the string is a IPv6 mask
IsIpMask6(char * str)6735 bool IsIpMask6(char *str)
6736 {
6737 IP mask;
6738 // Validate arguments
6739 if (str == NULL)
6740 {
6741 return false;
6742 }
6743
6744 return StrToMask6(&mask, str);
6745 }
6746
6747 // Determine whether the string is a IPv6 address
IsStrIPv6Address(char * str)6748 bool IsStrIPv6Address(char *str)
6749 {
6750 IP ip;
6751 // Validate arguments
6752 if (str == NULL)
6753 {
6754 return false;
6755 }
6756
6757 if (StrToIP6(&ip, str) == false)
6758 {
6759 return false;
6760 }
6761
6762 return true;
6763 }
6764
6765 // Convert the subnet mask to an integer
SubnetMaskToInt6(IP * a)6766 UINT SubnetMaskToInt6(IP *a)
6767 {
6768 UINT i;
6769 // Validate arguments
6770 if (IsIP6(a) == false)
6771 {
6772 return 0;
6773 }
6774
6775 for (i = 0;i <= 128;i++)
6776 {
6777 IP tmp;
6778
6779 IntToSubnetMask6(&tmp, i);
6780
6781 if (CmpIpAddr(a, &tmp) == 0)
6782 {
6783 return i;
6784 }
6785 }
6786
6787 return 0;
6788 }
SubnetMaskToInt4(IP * a)6789 UINT SubnetMaskToInt4(IP *a)
6790 {
6791 UINT i;
6792 // Validate arguments
6793 if (IsIP4(a) == false)
6794 {
6795 return 0;
6796 }
6797
6798 for (i = 0;i <= 32;i++)
6799 {
6800 IP tmp;
6801
6802 IntToSubnetMask4(&tmp, i);
6803
6804 if (CmpIpAddr(a, &tmp) == 0)
6805 {
6806 return i;
6807 }
6808 }
6809
6810 return 0;
6811 }
SubnetMaskToInt(IP * a)6812 UINT SubnetMaskToInt(IP *a)
6813 {
6814 if (IsIP6(a))
6815 {
6816 return SubnetMaskToInt6(a);
6817 }
6818 else
6819 {
6820 return SubnetMaskToInt4(a);
6821 }
6822 }
6823
6824 // Determine whether the specified IP address is a subnet mask
IsSubnetMask6(IP * a)6825 bool IsSubnetMask6(IP *a)
6826 {
6827 UINT i;
6828 // Validate arguments
6829 if (IsIP6(a) == false)
6830 {
6831 return false;
6832 }
6833
6834 for (i = 0;i <= 128;i++)
6835 {
6836 IP tmp;
6837
6838 IntToSubnetMask6(&tmp, i);
6839
6840 if (CmpIpAddr(a, &tmp) == 0)
6841 {
6842 return true;
6843 }
6844 }
6845
6846 return false;
6847 }
6848
6849 // Generate a global address from the MAC address
GenerateEui64GlobalAddress(IP * ip,IP * prefix,IP * subnet,UCHAR * mac)6850 void GenerateEui64GlobalAddress(IP *ip, IP *prefix, IP *subnet, UCHAR *mac)
6851 {
6852 UCHAR tmp[8];
6853 IP a;
6854 IP subnet_not;
6855 IP or1, or2;
6856 // Validate arguments
6857 if (ip == NULL || prefix == NULL || subnet == NULL || mac == NULL)
6858 {
6859 return;
6860 }
6861
6862 GenerateEui64Address6(tmp, mac);
6863
6864 ZeroIP6(&a);
6865
6866 Copy(&a.ipv6_addr[8], tmp, 8);
6867
6868 IPNot6(&subnet_not, subnet);
6869 IPAnd6(&or1, &a, &subnet_not);
6870 IPAnd6(&or2, prefix, subnet);
6871
6872 IPOr6(ip, &or1, &or2);
6873 }
6874
6875 // Generate a local address from the MAC address
GenerateEui64LocalAddress(IP * a,UCHAR * mac)6876 void GenerateEui64LocalAddress(IP *a, UCHAR *mac)
6877 {
6878 UCHAR tmp[8];
6879 // Validate arguments
6880 if (a == NULL || mac == NULL)
6881 {
6882 return;
6883 }
6884
6885 GenerateEui64Address6(tmp, mac);
6886
6887 ZeroIP6(a);
6888 a->ipv6_addr[0] = 0xfe;
6889 a->ipv6_addr[1] = 0x80;
6890
6891 Copy(&a->ipv6_addr[8], tmp, 8);
6892 }
6893
6894 // Generate the EUI-64 address from the MAC address
GenerateEui64Address6(UCHAR * dst,UCHAR * mac)6895 void GenerateEui64Address6(UCHAR *dst, UCHAR *mac)
6896 {
6897 // Validate arguments
6898 if (dst == NULL || mac == NULL)
6899 {
6900 return;
6901 }
6902
6903 Copy(dst, mac, 3);
6904 Copy(dst + 5, mac, 3);
6905
6906 dst[3] = 0xff;
6907 dst[4] = 0xfe;
6908 dst[0] = ((~(dst[0] & 0x02)) & 0x02) | (dst[0] & 0xfd);
6909 }
6910
6911 // Examine whether two IP addresses are in the same network
IsInSameNetwork6ByStr(char * ip1,char * ip2,char * subnet)6912 bool IsInSameNetwork6ByStr(char *ip1, char *ip2, char *subnet)
6913 {
6914 IP p1, p2, s;
6915
6916 if (StrToIP6(&p1, ip1) == false)
6917 {
6918 return false;
6919 }
6920
6921 if (StrToIP6(&p2, ip2) == false)
6922 {
6923 return false;
6924 }
6925
6926 if (StrToMask6(&s, subnet) == false)
6927 {
6928 return false;
6929 }
6930
6931 return IsInSameNetwork6(&p1, &p2, &s);
6932 }
IsInSameNetwork6(IP * a1,IP * a2,IP * subnet)6933 bool IsInSameNetwork6(IP *a1, IP *a2, IP *subnet)
6934 {
6935 IP prefix1, prefix2;
6936 // Validate arguments
6937 if (IsIP6(a1) == false || IsIP6(a2) == false || IsIP6(subnet) == false)
6938 {
6939 return false;
6940 }
6941
6942 if (a1->ipv6_scope_id != a2->ipv6_scope_id)
6943 {
6944 return false;
6945 }
6946
6947 GetPrefixAddress6(&prefix1, a1, subnet);
6948 GetPrefixAddress6(&prefix2, a2, subnet);
6949
6950 if (CmpIpAddr(&prefix1, &prefix2) == 0)
6951 {
6952 return true;
6953 }
6954
6955 return false;
6956 }
IsInSameNetwork4(IP * a1,IP * a2,IP * subnet)6957 bool IsInSameNetwork4(IP *a1, IP *a2, IP *subnet)
6958 {
6959 IP net1, net2;
6960 // Validate arguments
6961 if (IsIP4(a1) == false || IsIP4(a2) == false || IsIP4(subnet) == false)
6962 {
6963 return false;
6964 }
6965
6966 IPAnd4(&net1, a1, subnet);
6967 IPAnd4(&net2, a2, subnet);
6968
6969 if (CmpIpAddr(&net1, &net2) == 0)
6970 {
6971 return true;
6972 }
6973
6974 return false;
6975 }
IsInSameNetwork4Standard(IP * a1,IP * a2)6976 bool IsInSameNetwork4Standard(IP *a1, IP *a2)
6977 {
6978 IP subnet;
6979
6980 SetIP(&subnet, 255, 255, 0, 0);
6981
6982 return IsInSameNetwork4(a1, a2, &subnet);
6983 }
IsInSameLocalNetworkToMe4(IP * a)6984 bool IsInSameLocalNetworkToMe4(IP *a)
6985 {
6986 IP g1, g2;
6987
6988 Zero(&g1, sizeof(g1));
6989 Zero(&g2, sizeof(g2));
6990
6991 GetCurrentGlobalIPGuess(&g1, false);
6992
6993 if (IsZeroIp(&g1) == false)
6994 {
6995 if (IsInSameNetwork4Standard(&g1, a))
6996 {
6997 return true;
6998 }
6999 }
7000
7001 if (GetCurrentGlobalIP(&g2, false))
7002 {
7003 if (IsInSameNetwork4Standard(&g2, a))
7004 {
7005 return true;
7006 }
7007 }
7008
7009 if (IsIPAddressInSameLocalNetwork(a))
7010 {
7011 return true;
7012 }
7013
7014 return false;
7015 }
7016
7017 // Check whether it is a network address prefix
IsNetworkAddress6(IP * ip,IP * subnet)7018 bool IsNetworkAddress6(IP *ip, IP *subnet)
7019 {
7020 return IsNetworkPrefixAddress6(ip, subnet);
7021 }
IsNetworkPrefixAddress6(IP * ip,IP * subnet)7022 bool IsNetworkPrefixAddress6(IP *ip, IP *subnet)
7023 {
7024 IP host;
7025 // Validate arguments
7026 if (ip == NULL || subnet == NULL)
7027 {
7028 return false;
7029 }
7030
7031 if (IsIP6(ip) == false || IsIP6(subnet) == false)
7032 {
7033 return false;
7034 }
7035
7036 GetHostAddress6(&host, ip, subnet);
7037
7038 if (IsZeroIp(&host))
7039 {
7040 return true;
7041 }
7042
7043 return false;
7044 }
7045
7046 // Check whether the unicast address is available
CheckUnicastAddress(IP * ip)7047 bool CheckUnicastAddress(IP *ip)
7048 {
7049 // Validate arguments
7050 if (ip == NULL)
7051 {
7052 return false;
7053 }
7054
7055 if ((GetIPAddrType6(ip) & IPV6_ADDR_UNICAST) == 0)
7056 {
7057 return false;
7058 }
7059
7060 return true;
7061 }
7062
7063 // Get the host address
GetHostAddress6(IP * dst,IP * ip,IP * subnet)7064 void GetHostAddress6(IP *dst, IP *ip, IP *subnet)
7065 {
7066 IP not;
7067 // Validate arguments
7068 if (dst == NULL || ip == NULL || subnet == NULL)
7069 {
7070 return;
7071 }
7072
7073 IPNot6(¬, subnet);
7074
7075 IPAnd6(dst, ip, ¬);
7076
7077 dst->ipv6_scope_id = ip->ipv6_scope_id;
7078 }
7079
7080 // Get the prefix address
GetPrefixAddress6(IP * dst,IP * ip,IP * subnet)7081 void GetPrefixAddress6(IP *dst, IP *ip, IP *subnet)
7082 {
7083 // Validate arguments
7084 if (dst == NULL || ip == NULL || subnet == NULL)
7085 {
7086 return;
7087 }
7088
7089 IPAnd6(dst, ip, subnet);
7090
7091 dst->ipv6_scope_id = ip->ipv6_scope_id;
7092 }
7093
7094 // Get the solicited-node multicast address
GetSoliciationMulticastAddr6(IP * dst,IP * src)7095 void GetSoliciationMulticastAddr6(IP *dst, IP *src)
7096 {
7097 IP prefix;
7098 IP mask104;
7099 IP or1, or2;
7100
7101 // Validate arguments
7102 if (dst == NULL || src == NULL)
7103 {
7104 return;
7105 }
7106
7107 ZeroIP6(&prefix);
7108 prefix.ipv6_addr[0] = 0xff;
7109 prefix.ipv6_addr[1] = 0x02;
7110 prefix.ipv6_addr[11] = 0x01;
7111 prefix.ipv6_addr[12] = 0xff;
7112
7113 IntToSubnetMask6(&mask104, 104);
7114
7115 IPAnd6(&or1, &prefix, &mask104);
7116 IPAnd6(&or2, src, &mask104);
7117
7118 IPOr6(dst, &or1, &or2);
7119
7120 dst->ipv6_scope_id = src->ipv6_scope_id;
7121 }
7122
7123 // Generate a MAC address corresponding to the multicast address
GenerateMulticastMacAddress6(UCHAR * mac,IP * ip)7124 void GenerateMulticastMacAddress6(UCHAR *mac, IP *ip)
7125 {
7126 // Validate arguments
7127 if (mac == NULL)
7128 {
7129 return;
7130 }
7131
7132 mac[0] = 0x33;
7133 mac[1] = 0x33;
7134 mac[2] = ip->ipv6_addr[12];
7135 mac[3] = ip->ipv6_addr[13];
7136 mac[4] = ip->ipv6_addr[14];
7137 mac[5] = ip->ipv6_addr[15];
7138 }
7139
7140 // Get the type of the IPv6 address
GetIPv6AddrType(IPV6_ADDR * addr)7141 UINT GetIPv6AddrType(IPV6_ADDR *addr)
7142 {
7143 IP ip;
7144 // Validate arguments
7145 if (addr == NULL)
7146 {
7147 return 0;
7148 }
7149
7150 IPv6AddrToIP(&ip, addr);
7151
7152 return GetIPAddrType6(&ip);
7153 }
GetIPAddrType6(IP * ip)7154 UINT GetIPAddrType6(IP *ip)
7155 {
7156 UINT ret = 0;
7157 // Validate arguments
7158 if (IsIP6(ip) == false)
7159 {
7160 return 0;
7161 }
7162
7163 if (ip->ipv6_addr[0] == 0xff)
7164 {
7165 IP all_node, all_router;
7166
7167 GetAllNodeMulticaseAddress6(&all_node);
7168
7169 GetAllRouterMulticastAddress6(&all_router);
7170
7171 ret |= IPV6_ADDR_MULTICAST;
7172
7173 if (Cmp(ip->ipv6_addr, all_node.ipv6_addr, 16) == 0)
7174 {
7175 ret |= IPV6_ADDR_ALL_NODE_MULTICAST;
7176 }
7177 else if (Cmp(ip->ipv6_addr, all_router.ipv6_addr, 16) == 0)
7178 {
7179 ret |= IPV6_ADDR_ALL_ROUTER_MULTICAST;
7180 }
7181 else
7182 {
7183 if (ip->ipv6_addr[1] == 0x02 && ip->ipv6_addr[2] == 0 && ip->ipv6_addr[3] == 0 &&
7184 ip->ipv6_addr[4] == 0 && ip->ipv6_addr[5] == 0 && ip->ipv6_addr[6] == 0 &&
7185 ip->ipv6_addr[7] == 0 && ip->ipv6_addr[8] == 0 && ip->ipv6_addr[9] == 0 &&
7186 ip->ipv6_addr[10] == 0 && ip->ipv6_addr[11] == 0x01 && ip->ipv6_addr[12] == 0xff)
7187 {
7188 ret |= IPV6_ADDR_SOLICIATION_MULTICAST;
7189 }
7190 }
7191 }
7192 else
7193 {
7194 ret |= IPV6_ADDR_UNICAST;
7195
7196 if (ip->ipv6_addr[0] == 0xfe && (ip->ipv6_addr[1] & 0xc0) == 0x80)
7197 {
7198 ret |= IPV6_ADDR_LOCAL_UNICAST;
7199 }
7200 else
7201 {
7202 ret |= IPV6_ADDR_GLOBAL_UNICAST;
7203
7204 if (IsZero(&ip->ipv6_addr, 16))
7205 {
7206 ret |= IPV6_ADDR_ZERO;
7207 }
7208 else
7209 {
7210 IP loopback;
7211
7212 GetLoopbackAddress6(&loopback);
7213
7214 if (Cmp(ip->ipv6_addr, loopback.ipv6_addr, 16) == 0)
7215 {
7216 ret |= IPV6_ADDR_LOOPBACK;
7217 }
7218 }
7219 }
7220 }
7221
7222 return ret;
7223 }
7224
7225 // Address that all of the bits are set
GetAllFilledAddress6(IP * ip)7226 void GetAllFilledAddress6(IP *ip)
7227 {
7228 UINT i;
7229 // Validate arguments
7230 if (ip == NULL)
7231 {
7232 return;
7233 }
7234
7235 ZeroIP6(ip);
7236
7237 for (i = 0;i < 15;i++)
7238 {
7239 ip->ipv6_addr[i] = 0xff;
7240 }
7241 }
7242
7243 // Loopback address
GetLoopbackAddress6(IP * ip)7244 void GetLoopbackAddress6(IP *ip)
7245 {
7246 // Validate arguments
7247 if (ip == NULL)
7248 {
7249 return;
7250 }
7251
7252 ZeroIP6(ip);
7253
7254 ip->ipv6_addr[15] = 0x01;
7255 }
7256
7257 // All-nodes multicast address
GetAllNodeMulticaseAddress6(IP * ip)7258 void GetAllNodeMulticaseAddress6(IP *ip)
7259 {
7260 // Validate arguments
7261 if (ip == NULL)
7262 {
7263 return;
7264 }
7265
7266 ZeroIP6(ip);
7267
7268 ip->ipv6_addr[0] = 0xff;
7269 ip->ipv6_addr[1] = 0x02;
7270 ip->ipv6_addr[15] = 0x01;
7271 }
7272
7273 // All-routers multicast address
GetAllRouterMulticastAddress6(IP * ip)7274 void GetAllRouterMulticastAddress6(IP *ip)
7275 {
7276 // Validate arguments
7277 if (ip == NULL)
7278 {
7279 return;
7280 }
7281
7282 ZeroIP6(ip);
7283
7284 ip->ipv6_addr[0] = 0xff;
7285 ip->ipv6_addr[1] = 0x02;
7286 ip->ipv6_addr[15] = 0x02;
7287 }
7288
7289 // Logical operation of the IPv4 address
IPNot4(IP * dst,IP * a)7290 void IPNot4(IP *dst, IP *a)
7291 {
7292 UINT i;
7293 // Validate arguments
7294 if (dst == NULL || a == NULL || IsIP4(a) == false)
7295 {
7296 Zero(dst, sizeof(IP));
7297 return;
7298 }
7299
7300 i = IPToUINT(a);
7301 i = ~i;
7302
7303 UINTToIP(dst, i);
7304 }
IPOr4(IP * dst,IP * a,IP * b)7305 void IPOr4(IP *dst, IP *a, IP *b)
7306 {
7307 UINT i;
7308 // Validate arguments
7309 if (dst == NULL || a == NULL || b == NULL || IsIP4(a) == false || IsIP4(b) == false)
7310 {
7311 Zero(dst, sizeof(IP));
7312 return;
7313 }
7314
7315 i = IPToUINT(a) | IPToUINT(b);
7316
7317 UINTToIP(dst, i);
7318 }
IPAnd4(IP * dst,IP * a,IP * b)7319 void IPAnd4(IP *dst, IP *a, IP *b)
7320 {
7321 UINT i;
7322 // Validate arguments
7323 if (dst == NULL || a == NULL || b == NULL || IsIP4(a) == false || IsIP4(b) == false)
7324 {
7325 Zero(dst, sizeof(IP));
7326 return;
7327 }
7328
7329 i = IPToUINT(a) & IPToUINT(b);
7330
7331 UINTToIP(dst, i);
7332 }
7333
7334 // Logical operation of the IPv6 address
IPAnd6(IP * dst,IP * a,IP * b)7335 void IPAnd6(IP *dst, IP *a, IP *b)
7336 {
7337 UINT i;
7338 // Validate arguments
7339 if (dst == NULL || IsIP6(a) == false || IsIP6(b) == false)
7340 {
7341 ZeroIP6(dst);
7342 return;
7343 }
7344
7345 ZeroIP6(dst);
7346 for (i = 0;i < 16;i++)
7347 {
7348 dst->ipv6_addr[i] = a->ipv6_addr[i] & b->ipv6_addr[i];
7349 }
7350 }
IPOr6(IP * dst,IP * a,IP * b)7351 void IPOr6(IP *dst, IP *a, IP *b)
7352 {
7353 UINT i;
7354 // Validate arguments
7355 if (dst == NULL || IsIP6(a) == false || IsIP6(b) == false)
7356 {
7357 ZeroIP6(dst);
7358 return;
7359 }
7360
7361 ZeroIP6(dst);
7362 for (i = 0;i < 16;i++)
7363 {
7364 dst->ipv6_addr[i] = a->ipv6_addr[i] | b->ipv6_addr[i];
7365 }
7366 }
IPNot6(IP * dst,IP * a)7367 void IPNot6(IP *dst, IP *a)
7368 {
7369 UINT i;
7370 // Validate arguments
7371 if (dst == NULL || IsIP6(a) == false)
7372 {
7373 ZeroIP6(dst);
7374 return;
7375 }
7376
7377 ZeroIP6(dst);
7378 for (i = 0;i < 16;i++)
7379 {
7380 dst->ipv6_addr[i] = ~(a->ipv6_addr[i]);
7381 }
7382 }
7383
7384 // Creating a subnet mask
IntToSubnetMask6(IP * ip,UINT i)7385 void IntToSubnetMask6(IP *ip, UINT i)
7386 {
7387 UINT j = i / 8;
7388 UINT k = i % 8;
7389 UINT z;
7390 IP a;
7391
7392 ZeroIP6(&a);
7393
7394 for (z = 0;z < 16;z++)
7395 {
7396 if (z < j)
7397 {
7398 a.ipv6_addr[z] = 0xff;
7399 }
7400 else if (z == j)
7401 {
7402 a.ipv6_addr[z] = ~(0xff >> k);
7403 }
7404 }
7405
7406 Copy(ip, &a, sizeof(IP));
7407 }
7408
7409 // Convert the IP address to a string
IP6AddrToStr(char * str,UINT size,IPV6_ADDR * addr)7410 void IP6AddrToStr(char *str, UINT size, IPV6_ADDR *addr)
7411 {
7412 // Validate arguments
7413 if (str == NULL || addr == NULL)
7414 {
7415 return;
7416 }
7417
7418 IPToStr6Array(str, size, addr->Value);
7419 }
IPToStr6Array(char * str,UINT size,UCHAR * bytes)7420 void IPToStr6Array(char *str, UINT size, UCHAR *bytes)
7421 {
7422 IP ip;
7423 // Validate arguments
7424 if (str == NULL || bytes == NULL)
7425 {
7426 return;
7427 }
7428
7429 SetIP6(&ip, bytes);
7430
7431 IPToStr6(str, size, &ip);
7432 }
IPToStr6(char * str,UINT size,IP * ip)7433 void IPToStr6(char *str, UINT size, IP *ip)
7434 {
7435 char tmp[MAX_SIZE];
7436
7437 IPToStr6Inner(tmp, ip);
7438
7439 StrCpy(str, size, tmp);
7440 }
IPToStr6Inner(char * str,IP * ip)7441 void IPToStr6Inner(char *str, IP *ip)
7442 {
7443 UINT i;
7444 USHORT values[8];
7445 UINT zero_started_index;
7446 UINT max_zero_len;
7447 UINT max_zero_start;
7448 IP a;
7449 // Validate arguments
7450 if (str == NULL || ip == NULL)
7451 {
7452 return;
7453 }
7454
7455 Copy(&a, ip, sizeof(IP));
7456
7457 for (i = 0;i < 8;i++)
7458 {
7459 Copy(&values[i], &a.ipv6_addr[i * 2], sizeof(USHORT));
7460 values[i] = Endian16(values[i]);
7461 }
7462
7463 // Search for omitable part
7464 zero_started_index = INFINITE;
7465 max_zero_len = 0;
7466 max_zero_start = INFINITE;
7467 for (i = 0;i < 9;i++)
7468 {
7469 USHORT v = (i != 8 ? values[i] : 1);
7470
7471 if (v == 0)
7472 {
7473 if (zero_started_index == INFINITE)
7474 {
7475 zero_started_index = i;
7476 }
7477 }
7478 else
7479 {
7480 UINT zero_len;
7481
7482 if (zero_started_index != INFINITE)
7483 {
7484 zero_len = i - zero_started_index;
7485 if (zero_len >= 2)
7486 {
7487 if (max_zero_len < zero_len)
7488 {
7489 max_zero_start = zero_started_index;
7490 max_zero_len = zero_len;
7491 }
7492 }
7493
7494 zero_started_index = INFINITE;
7495 }
7496 }
7497 }
7498
7499 // Format a string
7500 StrCpy(str, 0, "");
7501 for (i = 0;i < 8;i++)
7502 {
7503 char tmp[16];
7504
7505 ToHex(tmp, values[i]);
7506 StrLower(tmp);
7507
7508 if (i == max_zero_start)
7509 {
7510 if (i == 0)
7511 {
7512 StrCat(str, 0, "::");
7513 }
7514 else
7515 {
7516 StrCat(str, 0, ":");
7517 }
7518 i += max_zero_len - 1;
7519 }
7520 else
7521 {
7522 StrCat(str, 0, tmp);
7523 if (i != 7)
7524 {
7525 StrCat(str, 0, ":");
7526 }
7527 }
7528 }
7529
7530 // Scope ID
7531 if (ip->ipv6_scope_id != 0)
7532 {
7533 char tmp[64];
7534
7535 StrCat(str, 0, "%");
7536 ToStr(tmp, ip->ipv6_scope_id);
7537
7538 StrCat(str, 0, tmp);
7539 }
7540 }
7541
7542 // Convert the string to an IP address
StrToIP6(IP * ip,char * str)7543 bool StrToIP6(IP *ip, char *str)
7544 {
7545 TOKEN_LIST *t;
7546 char tmp[MAX_PATH];
7547 IP a;
7548 UINT i;
7549 UINT scope_id = 0;
7550 // Validate arguments
7551 if (str == NULL || ip == NULL)
7552 {
7553 return false;
7554 }
7555
7556 ZeroIP6(&a);
7557
7558 StrCpy(tmp, sizeof(tmp), str);
7559 Trim(tmp);
7560
7561 if (StartWith(tmp, "[") && EndWith(tmp, "]"))
7562 {
7563 // If the string is enclosed in square brackets, remove brackets
7564 StrCpyAllowOverlap(tmp, sizeof(tmp), &tmp[1]);
7565
7566 if (StrLen(tmp) >= 1)
7567 {
7568 tmp[StrLen(tmp) - 1] = 0;
7569 }
7570 }
7571
7572 // Remove the scope ID by analyzing if there is it
7573 i = SearchStrEx(tmp, "%", 0, false);
7574 if (i != INFINITE)
7575 {
7576 char ss[MAX_PATH];
7577
7578 StrCpy(ss, sizeof(ss), &tmp[i + 1]);
7579
7580 tmp[i] = 0;
7581
7582 Trim(tmp);
7583
7584 Trim(ss);
7585
7586 scope_id = ToInt(ss);
7587 }
7588
7589 // Tokenize
7590 t = ParseTokenWithNullStr(tmp, ":");
7591 if (t->NumTokens >= 3 && t->NumTokens <= 8)
7592 {
7593 UINT i, n;
7594 bool b = true;
7595 UINT k = 0;
7596
7597 n = 0;
7598
7599 for (i = 0;i < t->NumTokens;i++)
7600 {
7601 char *str = t->Token[i];
7602
7603 if (i != 0 && i != (t->NumTokens - 1) && StrLen(str) == 0)
7604 {
7605 n++;
7606 if (n == 1)
7607 {
7608 k += 2 * (8 - t->NumTokens + 1);
7609 }
7610 else
7611 {
7612 b = false;
7613 break;
7614 }
7615 }
7616 else
7617 {
7618 UCHAR chars[2];
7619
7620 if (CheckIPItemStr6(str) == false)
7621 {
7622 b = false;
7623 break;
7624 }
7625
7626 IPItemStrToChars6(chars, str);
7627
7628 a.ipv6_addr[k++] = chars[0];
7629 a.ipv6_addr[k++] = chars[1];
7630 }
7631 }
7632
7633 if (n != 0 && n != 1)
7634 {
7635 b = false;
7636 }
7637 else if (n == 0 && t->NumTokens != 8)
7638 {
7639 b = false;
7640 }
7641
7642 if (b == false)
7643 {
7644 FreeToken(t);
7645 return false;
7646 }
7647 }
7648 else
7649 {
7650 FreeToken(t);
7651 return false;
7652 }
7653
7654 FreeToken(t);
7655
7656 Copy(ip, &a, sizeof(IP));
7657
7658 ip->ipv6_scope_id = scope_id;
7659
7660 return true;
7661 }
StrToIP6Addr(IPV6_ADDR * ip,char * str)7662 bool StrToIP6Addr(IPV6_ADDR *ip, char *str)
7663 {
7664 IP ip2;
7665 // Validate arguments
7666 if (ip == NULL || str == NULL)
7667 {
7668 Zero(ip, sizeof(IPV6_ADDR));
7669 return false;
7670 }
7671
7672 if (StrToIP6(&ip2, str) == false)
7673 {
7674 return false;
7675 }
7676
7677 if (IPToIPv6Addr(ip, &ip2) == false)
7678 {
7679 return false;
7680 }
7681
7682 return true;
7683 }
7684
7685 // Convert an IP address character to the UCHAR type
IPItemStrToChars6(UCHAR * chars,char * str)7686 void IPItemStrToChars6(UCHAR *chars, char *str)
7687 {
7688 char tmp[5];
7689 BUF *b;
7690 UINT len;
7691 // Validate arguments
7692 if (chars == NULL)
7693 {
7694 return;
7695 }
7696
7697 Zero(tmp, sizeof(tmp));
7698
7699 len = StrLen(str);
7700 switch (len)
7701 {
7702 case 0:
7703 tmp[0] = tmp[1] = tmp[2] = tmp[3] = '0';
7704 break;
7705
7706 case 1:
7707 tmp[0] = tmp[1] = tmp[2] = '0';
7708 tmp[3] = str[0];
7709 break;
7710
7711 case 2:
7712 tmp[0] = tmp[1] = '0';
7713 tmp[2] = str[0];
7714 tmp[3] = str[1];
7715 break;
7716
7717 case 3:
7718 tmp[0] = '0';
7719 tmp[1] = str[0];
7720 tmp[2] = str[1];
7721 tmp[3] = str[2];
7722 break;
7723
7724 case 4:
7725 tmp[0] = str[0];
7726 tmp[1] = str[1];
7727 tmp[2] = str[2];
7728 tmp[3] = str[3];
7729 break;
7730 }
7731
7732 b = StrToBin(tmp);
7733
7734 chars[0] = ((UCHAR *)b->Buf)[0];
7735 chars[1] = ((UCHAR *)b->Buf)[1];
7736
7737 FreeBuf(b);
7738 }
7739
7740 // Check whether invalid characters are included in the element string of the IP address
CheckIPItemStr6(char * str)7741 bool CheckIPItemStr6(char *str)
7742 {
7743 UINT i, len;
7744 // Validate arguments
7745 if (str == NULL)
7746 {
7747 return false;
7748 }
7749
7750 len = StrLen(str);
7751 if (len >= 5)
7752 {
7753 // Invalid length
7754 return false;
7755 }
7756
7757 for (i = 0;i < len;i++)
7758 {
7759 char c = str[i];
7760
7761 if ((c >= 'a' && c <= 'f') ||
7762 (c >= 'A' && c <= 'F') ||
7763 (c >= '0' && c <= '9'))
7764 {
7765 }
7766 else
7767 {
7768 return false;
7769 }
7770 }
7771
7772 return true;
7773 }
7774
7775 // Create an IPv4 address of all zero
ZeroIP4(IP * ip)7776 void ZeroIP4(IP *ip)
7777 {
7778 // Validate arguments
7779 if (ip == NULL)
7780 {
7781 return;
7782 }
7783
7784 Zero(ip, sizeof(IP));
7785 }
7786
7787 // Create an IPv6 address of all zero
ZeroIP6(IP * ip)7788 void ZeroIP6(IP *ip)
7789 {
7790 // Validate arguments
7791 if (ip == NULL)
7792 {
7793 return;
7794 }
7795
7796 SetIP6(ip, NULL);
7797 }
7798
7799 // Get the IP address of the localhost
GetLocalHostIP6(IP * ip)7800 void GetLocalHostIP6(IP *ip)
7801 {
7802 // Validate arguments
7803 if (ip == NULL)
7804 {
7805 return;
7806 }
7807 ZeroIP6(ip);
7808
7809 ip->ipv6_addr[15] = 1;
7810 }
GetLocalHostIP4(IP * ip)7811 void GetLocalHostIP4(IP *ip)
7812 {
7813 // Validate arguments
7814 if (ip == NULL)
7815 {
7816 return;
7817 }
7818
7819 SetIP(ip, 127, 0, 0, 1);
7820 }
7821
7822 // Check whether the specified address is a localhost
IsLocalHostIP6(IP * ip)7823 bool IsLocalHostIP6(IP *ip)
7824 {
7825 IP local;
7826 // Validate arguments
7827 if (ip == NULL)
7828 {
7829 return false;
7830 }
7831 if (IsIP6(ip) == false)
7832 {
7833 return false;
7834 }
7835
7836 GetLocalHostIP6(&local);
7837
7838 if (CmpIpAddr(&local, ip) == 0)
7839 {
7840 return true;
7841 }
7842
7843 return false;
7844 }
IsLocalHostIP4(IP * ip)7845 bool IsLocalHostIP4(IP *ip)
7846 {
7847 // Validate arguments
7848 if (ip == NULL)
7849 {
7850 return false;
7851 }
7852 if (IsIP4(ip) == false)
7853 {
7854 return false;
7855 }
7856
7857 if (ip->addr[0] == 127)
7858 {
7859 return true;
7860 }
7861
7862 return false;
7863 }
IsLocalHostIP(IP * ip)7864 bool IsLocalHostIP(IP *ip)
7865 {
7866 // Validate arguments
7867 if (ip == NULL)
7868 {
7869 return false;
7870 }
7871
7872 if (IsIP4(ip))
7873 {
7874 return IsLocalHostIP4(ip);
7875 }
7876 else
7877 {
7878 return IsLocalHostIP6(ip);
7879 }
7880 }
7881
7882 // Convert the IPV6_ADDR to an IP
IPv6AddrToIP(IP * ip,IPV6_ADDR * addr)7883 void IPv6AddrToIP(IP *ip, IPV6_ADDR *addr)
7884 {
7885 // Validate arguments
7886 if (ip == NULL || addr == NULL)
7887 {
7888 return;
7889 }
7890
7891 SetIP6(ip, addr->Value);
7892 }
7893
7894 // Convert the IP to an IPV6_ADDR
IPToIPv6Addr(IPV6_ADDR * addr,IP * ip)7895 bool IPToIPv6Addr(IPV6_ADDR *addr, IP *ip)
7896 {
7897 UINT i;
7898 // Validate arguments
7899 if (addr == NULL || ip == NULL)
7900 {
7901 Zero(addr, sizeof(IPV6_ADDR));
7902 return false;
7903 }
7904
7905 if (IsIP6(ip) == false)
7906 {
7907 Zero(addr, sizeof(IPV6_ADDR));
7908 return false;
7909 }
7910
7911 for (i = 0;i < 16;i++)
7912 {
7913 addr->Value[i] = ip->ipv6_addr[i];
7914 }
7915
7916 return true;
7917 }
7918
7919 // Set an IPv6 address
SetIP6(IP * ip,UCHAR * value)7920 void SetIP6(IP *ip, UCHAR *value)
7921 {
7922 // Validate arguments
7923 if (ip == NULL)
7924 {
7925 return;
7926 }
7927
7928 Zero(ip, sizeof(IP));
7929
7930 ip->addr[0] = 223;
7931 ip->addr[1] = 255;
7932 ip->addr[2] = 255;
7933 ip->addr[3] = 254;
7934
7935 if (value != NULL)
7936 {
7937 UINT i;
7938
7939 for (i = 0;i < 16;i++)
7940 {
7941 ip->ipv6_addr[i] = value[i];
7942 }
7943 }
7944 }
7945
7946 // Check whether the specified address is a IPv6 address
IsIP6(IP * ip)7947 bool IsIP6(IP *ip)
7948 {
7949 // Validate arguments
7950 if (ip == NULL)
7951 {
7952 return false;
7953 }
7954
7955 if (ip->addr[0] == 223 && ip->addr[1] == 255 && ip->addr[2] == 255 && ip->addr[3] == 254)
7956 {
7957 return true;
7958 }
7959
7960 return false;
7961 }
IsIP4(IP * ip)7962 bool IsIP4(IP *ip)
7963 {
7964 // Validate arguments
7965 if (ip == NULL)
7966 {
7967 return false;
7968 }
7969
7970 return (IsIP6(ip) ? false : true);
7971 }
7972
7973 // Examine whether the version of the two IP addresses are same
IsSameIPVer(IP * ip1,IP * ip2)7974 bool IsSameIPVer(IP *ip1, IP *ip2)
7975 {
7976 // Validate arguments
7977 if (ip1 == NULL || ip2 == NULL)
7978 {
7979 return false;
7980 }
7981
7982 if (IsIP4(ip1) && IsIP4(ip2))
7983 {
7984 return true;
7985 }
7986
7987 if (IsIP6(ip1) && IsIP6(ip2))
7988 {
7989 return true;
7990 }
7991
7992 return false;
7993 }
7994
7995 // Copy the IP address
CopyIP(IP * dst,IP * src)7996 void CopyIP(IP *dst, IP *src)
7997 {
7998 Copy(dst, src, sizeof(IP));
7999 }
8000
8001 // Check the length of the IPv6 subnet
CheckSubnetLength6(UINT i)8002 bool CheckSubnetLength6(UINT i)
8003 {
8004 if (i >= 1 && i <= 127)
8005 {
8006 return true;
8007 }
8008
8009 return false;
8010 }
8011
8012 // Get the process ID of the corresponding TCP connection by the socket
GetTcpProcessIdFromSocket(SOCK * s)8013 UINT GetTcpProcessIdFromSocket(SOCK *s)
8014 {
8015 LIST *o;
8016 TCPTABLE *t;
8017 UINT pid = 0;
8018 // Validate arguments
8019 if (s == NULL)
8020 {
8021 return 0;
8022 }
8023
8024 o = GetTcpTableList();
8025 if (o == NULL)
8026 {
8027 return 0;
8028 }
8029
8030 t = GetTcpTableFromEndPoint(o, &s->LocalIP, s->LocalPort,
8031 &s->RemoteIP, s->RemotePort);
8032
8033 if (t != NULL)
8034 {
8035 pid = t->ProcessId;
8036 }
8037
8038 FreeTcpTableList(o);
8039
8040 return pid;
8041 }
GetTcpProcessIdFromSocketReverse(SOCK * s)8042 UINT GetTcpProcessIdFromSocketReverse(SOCK *s)
8043 {
8044 LIST *o;
8045 TCPTABLE *t;
8046 UINT pid = 0;
8047 // Validate arguments
8048 if (s == NULL)
8049 {
8050 return 0;
8051 }
8052
8053 o = GetTcpTableList();
8054 if (o == NULL)
8055 {
8056 return 0;
8057 }
8058
8059 t = GetTcpTableFromEndPoint(o, &s->RemoteIP, s->RemotePort,
8060 &s->LocalIP, s->LocalPort);
8061
8062 if (t != NULL)
8063 {
8064 pid = t->ProcessId;
8065 }
8066
8067 FreeTcpTableList(o);
8068
8069 return pid;
8070 }
8071
8072 // Search in the TCP table by the end point
GetTcpTableFromEndPoint(LIST * o,IP * local_ip,UINT local_port,IP * remote_ip,UINT remote_port)8073 TCPTABLE *GetTcpTableFromEndPoint(LIST *o, IP *local_ip, UINT local_port, IP *remote_ip, UINT remote_port)
8074 {
8075 IP local;
8076 UINT i;
8077 // Validate arguments
8078 if (o == NULL)
8079 {
8080 return NULL;
8081 }
8082
8083 SetIP(&local, 127, 0, 0, 1);
8084
8085 if (local_ip == NULL)
8086 {
8087 local_ip = &local;
8088 }
8089
8090 if (remote_ip == NULL)
8091 {
8092 remote_ip = &local;
8093 }
8094
8095 for (i = 0;i < LIST_NUM(o);i++)
8096 {
8097 TCPTABLE *t = LIST_DATA(o, i);
8098
8099 if (t->Status == TCP_STATE_SYN_SENT || t->Status == TCP_STATE_SYN_RCVD ||
8100 t->Status == TCP_STATE_ESTAB)
8101 {
8102 if (CmpIpAddr(&t->LocalIP, local_ip) == 0)
8103 {
8104 if (CmpIpAddr(&t->RemoteIP, remote_ip) == 0)
8105 {
8106 if (t->LocalPort == local_port)
8107 {
8108 if (t->RemotePort == remote_port)
8109 {
8110 return t;
8111 }
8112 }
8113 }
8114 }
8115 }
8116 }
8117
8118 return NULL;
8119 }
8120
8121 // Get the TCP table list (Win32)
8122 #ifdef OS_WIN32
Win32GetTcpTableList()8123 LIST *Win32GetTcpTableList()
8124 {
8125 LIST *o;
8126
8127 // Windows XP SP2 or later
8128 o = Win32GetTcpTableListByGetExtendedTcpTable();
8129 if (o != NULL)
8130 {
8131 return o;
8132 }
8133
8134 // Windows XP or later
8135 o = Win32GetTcpTableListByAllocateAndGetTcpExTableFromStack();
8136 if (o != NULL)
8137 {
8138 return o;
8139 }
8140
8141 // For legacy Windows
8142 return Win32GetTcpTableListByGetTcpTable();
8143 }
8144
8145 // Get the TCP table list (for Windows XP SP2 or later)
Win32GetTcpTableListByGetExtendedTcpTable()8146 LIST *Win32GetTcpTableListByGetExtendedTcpTable()
8147 {
8148 UINT need_size;
8149 UINT i;
8150 MIB_TCPTABLE_OWNER_PID *table;
8151 bool ok = false;
8152 LIST *o;
8153 if (w32net->GetExtendedTcpTable == NULL)
8154 {
8155 return NULL;
8156 }
8157
8158 for (i = 0;i < 128;i++)
8159 {
8160 UINT ret;
8161 table = MallocFast(sizeof(MIB_TCPTABLE_OWNER_PID));
8162 need_size = sizeof(MIB_TCPTABLE_OWNER_PID);
8163 ret = w32net->GetExtendedTcpTable(table, &need_size, true, AF_INET, _TCP_TABLE_OWNER_PID_ALL, 0);
8164 if (ret == NO_ERROR)
8165 {
8166 ok = true;
8167 break;
8168 }
8169 else
8170 {
8171 Free(table);
8172 if (ret != ERROR_INSUFFICIENT_BUFFER)
8173 {
8174 return NULL;
8175 }
8176 }
8177
8178 table = MallocFast(need_size);
8179
8180 ret = w32net->GetExtendedTcpTable(table, &need_size, true, AF_INET, _TCP_TABLE_OWNER_PID_ALL, 0);
8181 if (ret == NO_ERROR)
8182 {
8183 ok = true;
8184 break;
8185 }
8186 else
8187 {
8188 Free(table);
8189
8190 if (ret != ERROR_INSUFFICIENT_BUFFER)
8191 {
8192 return NULL;
8193 }
8194 }
8195 }
8196
8197 if (ok == false)
8198 {
8199 return NULL;
8200 }
8201
8202 o = NewListEx(NULL, true);
8203
8204 for (i = 0;i < table->dwNumEntries;i++)
8205 {
8206 MIB_TCPROW_OWNER_PID *r = &table->table[i];
8207 TCPTABLE *t = ZeroMallocFast(sizeof(TCPTABLE));
8208
8209 UINTToIP(&t->LocalIP, r->dwLocalAddr);
8210 t->LocalPort = Endian16((USHORT)r->dwLocalPort);
8211
8212 if (r->dwState != TCP_STATE_LISTEN)
8213 {
8214 UINTToIP(&t->RemoteIP, r->dwRemoteAddr);
8215 t->RemotePort = Endian16((USHORT)r->dwRemotePort);
8216 }
8217
8218 t->Status = r->dwState;
8219 t->ProcessId = r->dwOwningPid;
8220
8221 Add(o, t);
8222 }
8223
8224 Free(table);
8225
8226 return o;
8227 }
8228
8229 // Get the TCP table list (Windows XP or later)
Win32GetTcpTableListByAllocateAndGetTcpExTableFromStack()8230 LIST *Win32GetTcpTableListByAllocateAndGetTcpExTableFromStack()
8231 {
8232 HANDLE heap;
8233 UINT i;
8234 MIB_TCPTABLE_OWNER_PID *table;
8235 bool ok = false;
8236 LIST *o;
8237 if (w32net->AllocateAndGetTcpExTableFromStack == NULL)
8238 {
8239 return NULL;
8240 }
8241
8242 heap = GetProcessHeap();
8243
8244 if (w32net->AllocateAndGetTcpExTableFromStack(&table, true, heap, HEAP_GROWABLE, AF_INET) != ERROR_SUCCESS)
8245 {
8246 return NULL;
8247 }
8248
8249 o = NewListEx(NULL, true);
8250
8251 for (i = 0;i < table->dwNumEntries;i++)
8252 {
8253 MIB_TCPROW_OWNER_PID *r = &table->table[i];
8254 TCPTABLE *t = ZeroMallocFast(sizeof(TCPTABLE));
8255
8256 UINTToIP(&t->LocalIP, r->dwLocalAddr);
8257 t->LocalPort = Endian16((USHORT)r->dwLocalPort);
8258
8259 if (r->dwState != TCP_STATE_LISTEN)
8260 {
8261 UINTToIP(&t->RemoteIP, r->dwRemoteAddr);
8262 t->RemotePort = Endian16((USHORT)r->dwRemotePort);
8263 }
8264
8265 t->ProcessId = r->dwOwningPid;
8266 t->Status = r->dwState;
8267
8268 Add(o, t);
8269 }
8270
8271 HeapFree(heap, 0, table);
8272
8273 return o;
8274 }
8275
8276 // Get the TCP table list (For legacy Windows)
Win32GetTcpTableListByGetTcpTable()8277 LIST *Win32GetTcpTableListByGetTcpTable()
8278 {
8279 UINT need_size;
8280 UINT i;
8281 MIB_TCPTABLE *table;
8282 bool ok = false;
8283 LIST *o;
8284 if (w32net->GetTcpTable == NULL)
8285 {
8286 return NULL;
8287 }
8288
8289 for (i = 0;i < 128;i++)
8290 {
8291 UINT ret;
8292 table = MallocFast(sizeof(MIB_TCPTABLE));
8293 need_size = sizeof(MIB_TCPTABLE);
8294 ret = w32net->GetTcpTable(table, &need_size, true);
8295 if (ret == NO_ERROR)
8296 {
8297 ok = true;
8298 break;
8299 }
8300 else
8301 {
8302 Free(table);
8303 if (ret != ERROR_INSUFFICIENT_BUFFER)
8304 {
8305 return NULL;
8306 }
8307 }
8308
8309 table = MallocFast(need_size);
8310
8311 ret = w32net->GetTcpTable(table, &need_size, true);
8312 if (ret == NO_ERROR)
8313 {
8314 ok = true;
8315 break;
8316 }
8317 else
8318 {
8319 Free(table);
8320
8321 if (ret != ERROR_INSUFFICIENT_BUFFER)
8322 {
8323 return NULL;
8324 }
8325 }
8326 }
8327
8328 if (ok == false)
8329 {
8330 return NULL;
8331 }
8332
8333 o = NewListEx(NULL, true);
8334
8335 for (i = 0;i < table->dwNumEntries;i++)
8336 {
8337 MIB_TCPROW *r = &table->table[i];
8338 TCPTABLE *t = ZeroMallocFast(sizeof(TCPTABLE));
8339
8340 UINTToIP(&t->LocalIP, r->dwLocalAddr);
8341 t->LocalPort = Endian16((USHORT)r->dwLocalPort);
8342
8343 if (r->dwState != TCP_STATE_LISTEN)
8344 {
8345 UINTToIP(&t->RemoteIP, r->dwRemoteAddr);
8346 t->RemotePort = Endian16((USHORT)r->dwRemotePort);
8347 }
8348
8349 t->Status = r->dwState;
8350
8351 Add(o, t);
8352 }
8353
8354 Free(table);
8355
8356 return o;
8357 }
8358
8359 #endif // OS_WIN32
8360
8361 // Display the TCP table
PrintTcpTableList(LIST * o)8362 void PrintTcpTableList(LIST *o)
8363 {
8364 UINT i;
8365 // Validate arguments
8366 if (o == NULL)
8367 {
8368 Print("o == NULL\n\n");
8369 return;
8370 }
8371
8372 Print("--- TCPTABLE: %u Entries ---\n", LIST_NUM(o));
8373 for (i = 0;i < LIST_NUM(o);i++)
8374 {
8375 char tmp1[MAX_PATH], tmp2[MAX_PATH];
8376 TCPTABLE *t = LIST_DATA(o, i);
8377
8378 IPToStr(tmp1, sizeof(tmp1), &t->LocalIP);
8379 IPToStr(tmp2, sizeof(tmp2), &t->RemoteIP);
8380
8381 Print("%s:%u <--> %s:%u state=%u pid=%u\n",
8382 tmp1, t->LocalPort,
8383 tmp2, t->RemotePort,
8384 t->Status,
8385 t->ProcessId);
8386 }
8387 Print("------\n\n");
8388 }
8389
8390 // Comparison of TCP table items
CompareTcpTable(void * p1,void * p2)8391 int CompareTcpTable(void *p1, void *p2)
8392 {
8393 TCPTABLE *t1, *t2;
8394 if (p1 == NULL || p2 == NULL)
8395 {
8396 return 0;
8397 }
8398 t1 = *(TCPTABLE **)p1;
8399 t2 = *(TCPTABLE **)p2;
8400 if (t1 == NULL || t2 == NULL)
8401 {
8402 return 0;
8403 }
8404
8405 return Cmp(t1, t2, sizeof(TCPTABLE));
8406 }
8407
8408 // Get the TCP table list
GetTcpTableList()8409 LIST *GetTcpTableList()
8410 {
8411 #ifdef OS_WIN32
8412 return Win32GetTcpTableList();
8413 #else // OS_WIN32
8414 return NULL;
8415 #endif // OS_WIN32
8416 }
8417
8418 // Release the TCP table list
FreeTcpTableList(LIST * o)8419 void FreeTcpTableList(LIST *o)
8420 {
8421 UINT i;
8422 // Validate arguments
8423 if (o == NULL)
8424 {
8425 return;
8426 }
8427
8428 for (i = 0;i < LIST_NUM(o);i++)
8429 {
8430 TCPTABLE *t = LIST_DATA(o, i);
8431
8432 Free(t);
8433 }
8434
8435 ReleaseList(o);
8436 }
8437
8438 // Get the number of clients connected from the specified IP address
GetNumIpClient(IP * ip)8439 UINT GetNumIpClient(IP *ip)
8440 {
8441 IP_CLIENT *c;
8442 UINT ret = 0;
8443 // Validate arguments
8444 if (ip == NULL)
8445 {
8446 return 0;
8447 }
8448
8449 LockList(ip_clients);
8450 {
8451 c = SearchIpClient(ip);
8452
8453 if (c != NULL)
8454 {
8455 ret = c->NumConnections;
8456 }
8457 }
8458 UnlockList(ip_clients);
8459
8460 return ret;
8461 }
8462
8463 // Add to the IP client entry
AddIpClient(IP * ip)8464 void AddIpClient(IP *ip)
8465 {
8466 IP_CLIENT *c;
8467 // Validate arguments
8468 if (ip == NULL)
8469 {
8470 return;
8471 }
8472
8473 LockList(ip_clients);
8474 {
8475 c = SearchIpClient(ip);
8476
8477 if (c == NULL)
8478 {
8479 c = ZeroMallocFast(sizeof(IP_CLIENT));
8480 Copy(&c->IpAddress, ip, sizeof(IP));
8481 c->NumConnections = 0;
8482
8483 Add(ip_clients, c);
8484 }
8485
8486 c->NumConnections++;
8487 }
8488 UnlockList(ip_clients);
8489
8490 //Debug("AddIpClient: %r\n", ip);
8491 }
8492
8493 // Remove from the IP client list
DelIpClient(IP * ip)8494 void DelIpClient(IP *ip)
8495 {
8496 IP_CLIENT *c;
8497 // Validate arguments
8498 if (ip == NULL)
8499 {
8500 return;
8501 }
8502
8503 LockList(ip_clients);
8504 {
8505 c = SearchIpClient(ip);
8506
8507 if (c != NULL)
8508 {
8509 c->NumConnections--;
8510
8511 if (c->NumConnections == 0)
8512 {
8513 Delete(ip_clients, c);
8514 Free(c);
8515 }
8516 }
8517 }
8518 UnlockList(ip_clients);
8519
8520 //Debug("DelIpClient: %r\n", ip);
8521 }
8522
8523 // Search for the IP client entry
SearchIpClient(IP * ip)8524 IP_CLIENT *SearchIpClient(IP *ip)
8525 {
8526 IP_CLIENT t;
8527 // Validate arguments
8528 if (ip == NULL)
8529 {
8530 return NULL;
8531 }
8532
8533 Zero(&t, sizeof(t));
8534 Copy(&t.IpAddress, ip, sizeof(IP));
8535
8536 return Search(ip_clients, &t);
8537 }
8538
8539 // Initialization of the client list
InitIpClientList()8540 void InitIpClientList()
8541 {
8542 ip_clients = NewList(CompareIpClientList);
8543 }
8544
8545 // Release of the client list
FreeIpClientList()8546 void FreeIpClientList()
8547 {
8548 UINT i;
8549
8550 for (i = 0;i < LIST_NUM(ip_clients);i++)
8551 {
8552 IP_CLIENT *c = LIST_DATA(ip_clients, i);
8553
8554 Free(c);
8555 }
8556
8557 ReleaseList(ip_clients);
8558 ip_clients = NULL;
8559 }
8560
8561 // Comparison of the client list entries
CompareIpClientList(void * p1,void * p2)8562 int CompareIpClientList(void *p1, void *p2)
8563 {
8564 IP_CLIENT *c1, *c2;
8565 if (p1 == NULL || p2 == NULL)
8566 {
8567 return 0;
8568 }
8569 c1 = *(IP_CLIENT **)p1;
8570 c2 = *(IP_CLIENT **)p2;
8571 if (c1 == NULL || c2 == NULL)
8572 {
8573 return 0;
8574 }
8575
8576 return CmpIpAddr(&c1->IpAddress, &c2->IpAddress);
8577 }
8578
8579 // Normalization of the MAC address
NormalizeMacAddress(char * dst,UINT size,char * src)8580 bool NormalizeMacAddress(char *dst, UINT size, char *src)
8581 {
8582 BUF *b;
8583 bool ret = false;
8584 // Validate arguments
8585 if (dst == NULL || src == NULL)
8586 {
8587 return false;
8588 }
8589
8590 b = StrToBin(src);
8591
8592 if (b != NULL && b->Size == 6)
8593 {
8594 ret = true;
8595
8596 BinToStr(dst, size, b->Buf, b->Size);
8597 }
8598
8599 FreeBuf(b);
8600
8601 return ret;
8602 }
8603
8604 // Identify whether the IP address is empty
IsZeroIP(IP * ip)8605 bool IsZeroIP(IP *ip)
8606 {
8607 return IsZeroIp(ip);
8608 }
IsZeroIp(IP * ip)8609 bool IsZeroIp(IP *ip)
8610 {
8611 // Validate arguments
8612 if (ip == NULL)
8613 {
8614 return true;
8615 }
8616
8617 if (IsIP6(ip) == false)
8618 {
8619 return IsZero(ip->addr, sizeof(ip->addr));
8620 }
8621 else
8622 {
8623 return IsZero(ip->ipv6_addr, sizeof(ip->ipv6_addr));
8624 }
8625 }
IsZeroIP6Addr(IPV6_ADDR * addr)8626 bool IsZeroIP6Addr(IPV6_ADDR *addr)
8627 {
8628 // Validate arguments
8629 if (addr == NULL)
8630 {
8631 return true;
8632 }
8633
8634 return IsZero(addr, sizeof(IPV6_ADDR));
8635 }
8636
8637 // Examine whether the specified IP address is meaningful as a host
IsHostIPAddress4(IP * ip)8638 bool IsHostIPAddress4(IP *ip)
8639 {
8640 UINT a;
8641 // Validate arguments
8642 if (ip == NULL)
8643 {
8644 return false;
8645 }
8646
8647 a = IPToUINT(ip);
8648
8649 if (a == 0 || a == 0xffffffff)
8650 {
8651 return false;
8652 }
8653
8654 return true;
8655 }
IsHostIPAddress32(UINT ip)8656 bool IsHostIPAddress32(UINT ip)
8657 {
8658 IP p;
8659
8660 UINTToIP(&p, ip);
8661
8662 return IsHostIPAddress4(&p);
8663 }
8664
8665 // Check whether the specified IP address and subnet mask indicates a network correctly
IsNetworkAddress(IP * ip,IP * mask)8666 bool IsNetworkAddress(IP *ip, IP *mask)
8667 {
8668 if (IsIP4(ip))
8669 {
8670 return IsNetworkAddress4(ip, mask);
8671 }
8672 else
8673 {
8674 return IsNetworkAddress6(ip, mask);
8675 }
8676 }
IsNetworkAddress4(IP * ip,IP * mask)8677 bool IsNetworkAddress4(IP *ip, IP *mask)
8678 {
8679 UINT a, b;
8680 // Validate arguments
8681 if (ip == NULL || mask == NULL)
8682 {
8683 return false;
8684 }
8685
8686 if (IsIP4(ip) == false || IsIP4(mask) == false)
8687 {
8688 return false;
8689 }
8690
8691 if (IsSubnetMask4(mask) == false)
8692 {
8693 return false;
8694 }
8695
8696 a = IPToUINT(ip);
8697 b = IPToUINT(mask);
8698
8699 if ((a & b) == a)
8700 {
8701 return true;
8702 }
8703
8704 return false;
8705 }
IsNetworkAddress32(UINT ip,UINT mask)8706 bool IsNetworkAddress32(UINT ip, UINT mask)
8707 {
8708 IP a, b;
8709
8710 UINTToIP(&a, ip);
8711 UINTToIP(&b, mask);
8712
8713 return IsNetworkAddress4(&a, &b);
8714 }
8715
8716 // Convert the integer to a subnet mask
IntToSubnetMask32(UINT i)8717 UINT IntToSubnetMask32(UINT i)
8718 {
8719 UINT ret = 0xFFFFFFFF;
8720
8721 switch (i)
8722 {
8723 case 0: ret = 0x00000000; break;
8724 case 1: ret = 0x80000000; break;
8725 case 2: ret = 0xC0000000; break;
8726 case 3: ret = 0xE0000000; break;
8727 case 4: ret = 0xF0000000; break;
8728 case 5: ret = 0xF8000000; break;
8729 case 6: ret = 0xFC000000; break;
8730 case 7: ret = 0xFE000000; break;
8731 case 8: ret = 0xFF000000; break;
8732 case 9: ret = 0xFF800000; break;
8733 case 10: ret = 0xFFC00000; break;
8734 case 11: ret = 0xFFE00000; break;
8735 case 12: ret = 0xFFF00000; break;
8736 case 13: ret = 0xFFF80000; break;
8737 case 14: ret = 0xFFFC0000; break;
8738 case 15: ret = 0xFFFE0000; break;
8739 case 16: ret = 0xFFFF0000; break;
8740 case 17: ret = 0xFFFF8000; break;
8741 case 18: ret = 0xFFFFC000; break;
8742 case 19: ret = 0xFFFFE000; break;
8743 case 20: ret = 0xFFFFF000; break;
8744 case 21: ret = 0xFFFFF800; break;
8745 case 22: ret = 0xFFFFFC00; break;
8746 case 23: ret = 0xFFFFFE00; break;
8747 case 24: ret = 0xFFFFFF00; break;
8748 case 25: ret = 0xFFFFFF80; break;
8749 case 26: ret = 0xFFFFFFC0; break;
8750 case 27: ret = 0xFFFFFFE0; break;
8751 case 28: ret = 0xFFFFFFF0; break;
8752 case 29: ret = 0xFFFFFFF8; break;
8753 case 30: ret = 0xFFFFFFFC; break;
8754 case 31: ret = 0xFFFFFFFE; break;
8755 case 32: ret = 0xFFFFFFFF; break;
8756 }
8757
8758 if (IsLittleEndian())
8759 {
8760 ret = Swap32(ret);
8761 }
8762
8763 return ret;
8764 }
IntToSubnetMask4(IP * ip,UINT i)8765 void IntToSubnetMask4(IP *ip, UINT i)
8766 {
8767 UINT m;
8768 // Validate arguments
8769 if (ip == NULL)
8770 {
8771 return;
8772 }
8773
8774 m = IntToSubnetMask32(i);
8775
8776 UINTToIP(ip, m);
8777 }
8778
8779 // Examine whether the specified IP address is a subnet mask
IsSubnetMask(IP * ip)8780 bool IsSubnetMask(IP *ip)
8781 {
8782 if (IsIP6(ip))
8783 {
8784 return IsSubnetMask6(ip);
8785 }
8786 else
8787 {
8788 return IsSubnetMask4(ip);
8789 }
8790 }
IsSubnetMask4(IP * ip)8791 bool IsSubnetMask4(IP *ip)
8792 {
8793 UINT i;
8794 // Validate arguments
8795 if (ip == NULL)
8796 {
8797 return false;
8798 }
8799
8800 if (IsIP6(ip))
8801 {
8802 return false;
8803 }
8804
8805 i = IPToUINT(ip);
8806
8807 if (IsLittleEndian())
8808 {
8809 i = Swap32(i);
8810 }
8811
8812 switch (i)
8813 {
8814 case 0x00000000:
8815 case 0x80000000:
8816 case 0xC0000000:
8817 case 0xE0000000:
8818 case 0xF0000000:
8819 case 0xF8000000:
8820 case 0xFC000000:
8821 case 0xFE000000:
8822 case 0xFF000000:
8823 case 0xFF800000:
8824 case 0xFFC00000:
8825 case 0xFFE00000:
8826 case 0xFFF00000:
8827 case 0xFFF80000:
8828 case 0xFFFC0000:
8829 case 0xFFFE0000:
8830 case 0xFFFF0000:
8831 case 0xFFFF8000:
8832 case 0xFFFFC000:
8833 case 0xFFFFE000:
8834 case 0xFFFFF000:
8835 case 0xFFFFF800:
8836 case 0xFFFFFC00:
8837 case 0xFFFFFE00:
8838 case 0xFFFFFF00:
8839 case 0xFFFFFF80:
8840 case 0xFFFFFFC0:
8841 case 0xFFFFFFE0:
8842 case 0xFFFFFFF0:
8843 case 0xFFFFFFF8:
8844 case 0xFFFFFFFC:
8845 case 0xFFFFFFFE:
8846 case 0xFFFFFFFF:
8847 return true;
8848 }
8849
8850 return false;
8851 }
IsSubnetMask32(UINT ip)8852 bool IsSubnetMask32(UINT ip)
8853 {
8854 IP p;
8855
8856 UINTToIP(&p, ip);
8857
8858 return IsSubnetMask4(&p);
8859 }
8860
8861 // Network release mode
SetNetworkReleaseMode()8862 void SetNetworkReleaseMode()
8863 {
8864 NetworkReleaseMode = true;
8865 }
8866
8867 #ifdef OS_UNIX // Code for UNIX
8868
8869 // Turn on and off the non-blocking mode of the socket
UnixSetSocketNonBlockingMode(int fd,bool nonblock)8870 void UnixSetSocketNonBlockingMode(int fd, bool nonblock)
8871 {
8872 UINT flag = 0;
8873 // Validate arguments
8874 if (fd == INVALID_SOCKET)
8875 {
8876 return;
8877 }
8878
8879 if (nonblock)
8880 {
8881 flag = 1;
8882 }
8883
8884 #ifdef FIONBIO
8885 ioctl(fd, FIONBIO, &flag);
8886 #else // FIONBIO
8887 {
8888 int flag = fcntl(fd, F_GETFL, 0);
8889 if (flag != -1)
8890 {
8891 if (nonblock)
8892 {
8893 flag |= O_NONBLOCK;
8894 }
8895 else
8896 {
8897 flag = flag & ~O_NONBLOCK;
8898
8899 fcntl(fd, F_SETFL, flag);
8900 }
8901 }
8902 }
8903 #endif // FIONBIO
8904 }
8905
8906 // Do Nothing
UnixIpForwardRowToRouteEntry(ROUTE_ENTRY * entry,void * ip_forward_row)8907 void UnixIpForwardRowToRouteEntry(ROUTE_ENTRY *entry, void *ip_forward_row)
8908 {
8909 }
8910
8911 // Do Nothing
UnixRouteEntryToIpForwardRow(void * ip_forward_row,ROUTE_ENTRY * entry)8912 void UnixRouteEntryToIpForwardRow(void *ip_forward_row, ROUTE_ENTRY *entry)
8913 {
8914 }
8915
8916 // Do Nothing
UnixCompareRouteEntryByMetric(void * p1,void * p2)8917 int UnixCompareRouteEntryByMetric(void *p1, void *p2)
8918 {
8919 return 1;
8920 }
8921
8922 // Do Nothing
UnixGetRouteTable()8923 ROUTE_TABLE *UnixGetRouteTable()
8924 {
8925 ROUTE_TABLE *ret = ZeroMalloc(sizeof(ROUTE_TABLE));
8926 ret->NumEntry = 0;
8927 ret->Entry = ZeroMalloc(0);
8928
8929 return ret;
8930 }
8931
8932 // Do Nothing
UnixAddRouteEntry(ROUTE_ENTRY * e,bool * already_exists)8933 bool UnixAddRouteEntry(ROUTE_ENTRY *e, bool *already_exists)
8934 {
8935 return true;
8936 }
8937
8938 // Do Nothing
UnixDeleteRouteEntry(ROUTE_ENTRY * e)8939 void UnixDeleteRouteEntry(ROUTE_ENTRY *e)
8940 {
8941 return;
8942 }
8943
8944 // Do Nothing
UnixGetVLanInterfaceID(char * instance_name)8945 UINT UnixGetVLanInterfaceID(char *instance_name)
8946 {
8947 return 1;
8948 }
8949
8950 // Do Nothing
UnixEnumVLan(char * tag_name)8951 char **UnixEnumVLan(char *tag_name)
8952 {
8953 char **list;
8954
8955 list = ZeroMalloc(sizeof(char *));
8956
8957 return list;
8958 }
8959
8960 // Do Nothing
UnixRenewDhcp()8961 void UnixRenewDhcp()
8962 {
8963 }
8964
8965 // Get the IP address of the default DNS server
UnixGetDefaultDns(IP * ip)8966 bool UnixGetDefaultDns(IP *ip)
8967 {
8968 BUF *b;
8969 // Validate arguments
8970 if (ip == NULL)
8971 {
8972 return false;
8973 }
8974
8975 Lock(unix_dns_server_addr_lock);
8976 {
8977 if (IsZero(&unix_dns_server, sizeof(IP)) == false)
8978 {
8979 Copy(ip, &unix_dns_server, sizeof(IP));
8980 Unlock(unix_dns_server_addr_lock);
8981 return true;
8982 }
8983
8984 ip->addr[0] = 127;
8985 ip->addr[1] = 0;
8986 ip->addr[2] = 0;
8987 ip->addr[3] = 1;
8988
8989 b = ReadDump("/etc/resolv.conf");
8990 if (b != NULL)
8991 {
8992 char *s;
8993 bool f = false;
8994 while ((s = CfgReadNextLine(b)) != NULL)
8995 {
8996 TOKEN_LIST *t = ParseToken(s, "\" \t,");
8997 if (t->NumTokens == 2)
8998 {
8999 if (StrCmpi(t->Token[0], "nameserver") == 0)
9000 {
9001 StrToIP(ip, t->Token[1]);
9002 f = true;
9003 }
9004 }
9005 FreeToken(t);
9006
9007 Free(s);
9008
9009 if (f)
9010 {
9011 break;
9012 }
9013 }
9014 FreeBuf(b);
9015 }
9016 Copy(&unix_dns_server, ip, sizeof(IP));
9017 }
9018 Unlock(unix_dns_server_addr_lock);
9019
9020 return true;
9021 }
9022
9023
9024 // Select procedure
UnixSelect(SOCKSET * set,UINT timeout,CANCEL * c1,CANCEL * c2)9025 void UnixSelect(SOCKSET *set, UINT timeout, CANCEL *c1, CANCEL *c2)
9026 {
9027 UINT reads[MAXIMUM_WAIT_OBJECTS];
9028 UINT writes[MAXIMUM_WAIT_OBJECTS];
9029 UINT num_read, num_write, i;
9030 UINT p1, p2;
9031 SOCK_EVENT *sock_events[MAXIMUM_WAIT_OBJECTS];
9032 UINT num_sock_events;
9033 SOCK *s;
9034 UCHAR tmp[MAX_SIZE];
9035 int ret;
9036 bool any_of_tubes_are_readable = false;
9037 // Initialization of array
9038 Zero(reads, sizeof(reads));
9039 Zero(writes, sizeof(writes));
9040 Zero(sock_events, sizeof(sock_events));
9041 num_read = num_write = num_sock_events = 0;
9042
9043 // Setting the event array
9044 if (set != NULL)
9045 {
9046 for (i = 0;i < set->NumSocket;i++)
9047 {
9048 s = set->Sock[i];
9049 if (s != NULL)
9050 {
9051 UnixInitAsyncSocket(s);
9052 if (s->Type == SOCK_INPROC)
9053 {
9054 TUBE *t = s->RecvTube;
9055 if (t != NULL)
9056 {
9057 reads[num_read++] = t->SockEvent->pipe_read;
9058
9059 sock_events[num_sock_events++] = t->SockEvent;
9060
9061 if (t->SockEvent->current_pipe_data != 0)
9062 {
9063 any_of_tubes_are_readable = true;
9064 }
9065 }
9066 }
9067 else
9068 {
9069 if (s->NoNeedToRead == false)
9070 {
9071 reads[num_read++] = s->socket;
9072 }
9073 }
9074
9075 if (s->BulkRecvTube != NULL)
9076 {
9077 TUBE *t = s->BulkRecvTube;
9078 if (t != NULL)
9079 {
9080 reads[num_read++] = t->SockEvent->pipe_read;
9081
9082 sock_events[num_sock_events++] = t->SockEvent;
9083
9084 if (t->SockEvent->current_pipe_data != 0)
9085 {
9086 any_of_tubes_are_readable = true;
9087 }
9088 }
9089 }
9090
9091 if (s->WriteBlocked)
9092 {
9093 writes[num_write++] = s->socket;
9094 }
9095 }
9096 }
9097 }
9098
9099 if (timeout == 0)
9100 {
9101 return;
9102 }
9103
9104 p1 = p2 = -1;
9105
9106 if (c1 != NULL)
9107 {
9108 reads[num_read++] = p1 = c1->pipe_read;
9109
9110 if (c1->SpecialFlag)
9111 {
9112 if (c1->pipe_special_read2 != -1 && c1->pipe_special_read2 != 0)
9113 {
9114 reads[num_read++] = c1->pipe_special_read2;
9115 }
9116
9117 if (c1->pipe_special_read3 != -1 && c1->pipe_special_read3 != 0)
9118 {
9119 reads[num_read++] = c1->pipe_special_read3;
9120 }
9121 }
9122 }
9123 if (c2 != NULL)
9124 {
9125 reads[num_read++] = p2 = c2->pipe_read;
9126
9127 if (c2->SpecialFlag)
9128 {
9129 if (c2->pipe_special_read2 != -1 && c2->pipe_special_read2 != 0)
9130 {
9131 reads[num_read++] = c2->pipe_special_read2;
9132 }
9133
9134 if (c2->pipe_special_read3 != -1 && c2->pipe_special_read3 != 0)
9135 {
9136 reads[num_read++] = c2->pipe_special_read3;
9137 }
9138 }
9139 }
9140
9141 // Call the select
9142 if (any_of_tubes_are_readable == false)
9143 {
9144 UnixSelectInner(num_read, reads, num_write, writes, timeout);
9145 }
9146
9147 // Read from the pipe
9148 if (c1 != NULL && c1->SpecialFlag == false && p1 != -1)
9149 {
9150 do
9151 {
9152 ret = read(p1, tmp, sizeof(tmp));
9153 }
9154 while (ret >= 1);
9155 }
9156 if (c2 != NULL && c2->SpecialFlag == false && p2 != -1)
9157 {
9158 do
9159 {
9160 ret = read(p2, tmp, sizeof(tmp));
9161 }
9162 while (ret >= 1);
9163 }
9164
9165 // Read from the pipe of sockevent
9166 for (i = 0;i < num_sock_events;i++)
9167 {
9168 SOCK_EVENT *e = sock_events[i];
9169
9170 e->current_pipe_data = 0;
9171
9172 do
9173 {
9174 ret = read(e->pipe_read, tmp, sizeof(tmp));
9175 }
9176 while (ret >= 1);
9177 }
9178 }
9179
9180 // Cancel
UnixCancel(CANCEL * c)9181 void UnixCancel(CANCEL *c)
9182 {
9183 // Validate arguments
9184 if (c == NULL)
9185 {
9186 return;
9187 }
9188
9189 UnixWritePipe(c->pipe_write);
9190 }
9191
9192 // Release of the cancel object
UnixCleanupCancel(CANCEL * c)9193 void UnixCleanupCancel(CANCEL *c)
9194 {
9195 // Validate arguments
9196 if (c == NULL)
9197 {
9198 return;
9199 }
9200
9201 if (c->SpecialFlag == false)
9202 {
9203 UnixDeletePipe(c->pipe_read, c->pipe_write);
9204 }
9205
9206 Free(c);
9207 }
9208
9209 // Creating a new cancel object
UnixNewCancel()9210 CANCEL *UnixNewCancel()
9211 {
9212 CANCEL *c = ZeroMallocFast(sizeof(CANCEL));
9213
9214 c->ref = NewRef();
9215 c->SpecialFlag = false;
9216
9217 UnixNewPipe(&c->pipe_read, &c->pipe_write);
9218
9219 c->pipe_special_read2 = c->pipe_special_read3 = -1;
9220
9221 return c;
9222 }
9223
9224 // Add the socket to the socket event
UnixJoinSockToSockEvent(SOCK * sock,SOCK_EVENT * event)9225 void UnixJoinSockToSockEvent(SOCK *sock, SOCK_EVENT *event)
9226 {
9227 // Validate arguments
9228 if (sock == NULL || event == NULL || sock->AsyncMode)
9229 {
9230 return;
9231 }
9232 if (sock->ListenMode != false || (sock->Type == SOCK_TCP && sock->Connected == false))
9233 {
9234 return;
9235 }
9236
9237 sock->AsyncMode = true;
9238
9239 LockList(event->SockList);
9240 {
9241 Add(event->SockList, sock);
9242 AddRef(sock->ref);
9243 }
9244 UnlockList(event->SockList);
9245
9246 // Make the socket asynchronous mode
9247 if (sock->Type != SOCK_INPROC)
9248 {
9249 UnixSetSocketNonBlockingMode(sock->socket, true);
9250 }
9251
9252 // Increase the reference count of the SOCK_EVENT
9253 AddRef(event->ref);
9254 sock->SockEvent = event;
9255
9256 // Set the socket event
9257 SetSockEvent(event);
9258 }
9259
9260 // Wait for a socket event
UnixWaitSockEvent(SOCK_EVENT * event,UINT timeout)9261 bool UnixWaitSockEvent(SOCK_EVENT *event, UINT timeout)
9262 {
9263 UINT num_read, num_write;
9264 UINT *reads, *writes;
9265 UINT n;
9266 char tmp[MAX_SIZE];
9267 int readret = 0;
9268 bool event_pipe_is_readable = false;
9269 // Validate arguments
9270 if (event == NULL)
9271 {
9272 return false;
9273 }
9274
9275 LockList(event->SockList);
9276 {
9277 UINT i;
9278 reads = ZeroMallocFast(sizeof(SOCK *) * (LIST_NUM(event->SockList) + 1));
9279
9280 num_write = 0;
9281 num_read = 0;
9282
9283 for (i = 0;i < LIST_NUM(event->SockList);i++)
9284 {
9285 SOCK *s = LIST_DATA(event->SockList, i);
9286
9287 if (s->NoNeedToRead == false)
9288 {
9289 reads[num_read++] = s->socket;
9290 }
9291
9292 if (s->WriteBlocked)
9293 {
9294 num_write++;
9295 }
9296 }
9297
9298 reads[num_read++] = event->pipe_read;
9299
9300 if (event->current_pipe_data != 0)
9301 {
9302 event_pipe_is_readable = true;
9303 }
9304
9305 writes = ZeroMallocFast(sizeof(SOCK *) * num_write);
9306
9307 n = 0;
9308
9309 for (i = 0;i < (num_read - 1);i++)
9310 {
9311 SOCK *s = LIST_DATA(event->SockList, i);
9312 if (s->WriteBlocked)
9313 {
9314 writes[n++] = s->socket;
9315 }
9316 }
9317 }
9318 UnlockList(event->SockList);
9319
9320 if (event_pipe_is_readable == false)
9321 {
9322 UnixSelectInner(num_read, reads, num_write, writes, timeout);
9323 }
9324
9325 event->current_pipe_data = 0;
9326 do
9327 {
9328 readret = read(event->pipe_read, tmp, sizeof(tmp));
9329 }
9330 while (readret >= 1);
9331
9332 Free(reads);
9333 Free(writes);
9334
9335 return true;
9336 }
9337
9338 // Set the socket event
UnixSetSockEvent(SOCK_EVENT * event)9339 void UnixSetSockEvent(SOCK_EVENT *event)
9340 {
9341 // Validate arguments
9342 if (event == NULL)
9343 {
9344 return;
9345 }
9346
9347 if (event->current_pipe_data <= 100)
9348 {
9349 UnixWritePipe(event->pipe_write);
9350 event->current_pipe_data++;
9351 }
9352 }
9353
9354 // This is a helper function for select()
safe_fd_set(int fd,fd_set * fds,int * max_fd)9355 int safe_fd_set(int fd, fd_set* fds, int* max_fd) {
9356 FD_SET(fd, fds);
9357 if (fd > *max_fd) {
9358 *max_fd = fd;
9359 }
9360 return 0;
9361 }
9362
9363 // Execute 'select' for the socket
UnixSelectInner(UINT num_read,UINT * reads,UINT num_write,UINT * writes,UINT timeout)9364 void UnixSelectInner(UINT num_read, UINT *reads, UINT num_write, UINT *writes, UINT timeout)
9365 {
9366 #ifdef UNIX_MACOS
9367 fd_set rfds; //read descriptors
9368 fd_set wfds; //write descriptors
9369 int max_fd = 0; //maximum descriptor id
9370 struct timeval tv; //timeval for timeout
9371 #else // UNIX_MACOS
9372 struct pollfd *p;
9373 #endif // UNIX_MACOS
9374 UINT num;
9375 UINT i;
9376 UINT n;
9377 UINT num_read_total, num_write_total;
9378
9379 if (num_read != 0 && reads == NULL)
9380 {
9381 num_read = 0;
9382 }
9383 if (num_write != 0 && writes == NULL)
9384 {
9385 num_write = 0;
9386 }
9387
9388 if (timeout == 0)
9389 {
9390 return;
9391 }
9392
9393 num_read_total = num_write_total = 0;
9394 for (i = 0;i < num_read;i++)
9395 {
9396 if (reads[i] != INVALID_SOCKET)
9397 {
9398 num_read_total++;
9399 }
9400 }
9401 for (i = 0;i < num_write;i++)
9402 {
9403 if (writes[i] != INVALID_SOCKET)
9404 {
9405 num_write_total++;
9406 }
9407 }
9408
9409 num = num_read_total + num_write_total;
9410 #ifdef UNIX_MACOS
9411 FD_ZERO(&rfds); //zero out descriptor set for read descriptors
9412 FD_ZERO(&wfds); //same for write
9413 #else // UNIX_MACOS
9414 p = ZeroMallocFast(sizeof(struct pollfd) * num);
9415 #endif // UNIX_MACOS
9416
9417 n = 0;
9418
9419 for (i = 0;i < num_read;i++)
9420 {
9421 if (reads[i] != INVALID_SOCKET)
9422 {
9423 #ifdef UNIX_MACOS
9424 safe_fd_set(reads[i], &rfds, &max_fd);
9425 #else // UNIX_MACOS
9426 struct pollfd *pfd = &p[n++];
9427 pfd->fd = reads[i];
9428 pfd->events = POLLIN | POLLPRI | POLLERR | POLLHUP;
9429 #endif // UNIX_MACOS
9430 }
9431 }
9432
9433 for (i = 0;i < num_write;i++)
9434 {
9435 if (writes[i] != INVALID_SOCKET)
9436 {
9437 #ifdef UNIX_MACOS
9438 safe_fd_set(writes[i], &wfds, &max_fd);
9439 #else // UNIX_MACOS
9440 struct pollfd *pfd = &p[n++];
9441 pfd->fd = writes[i];
9442 pfd->events = POLLIN | POLLPRI | POLLERR | POLLHUP | POLLOUT;
9443 #endif // UNIX_MACOS
9444 }
9445 }
9446
9447 if (num != 0)
9448 {
9449 #ifdef UNIX_MACOS
9450 tv.tv_sec = timeout / 1000;
9451 tv.tv_usec = (timeout % 1000) * 1000l;
9452 select(max_fd + 1, &rfds, &wfds, NULL, timeout == INFINITE ? NULL : &tv);
9453 #else // UNIX_MACOS
9454 poll(p, num, timeout == INFINITE ? -1 : (int)timeout);
9455 #endif // UNIX_MACOS
9456 }
9457 else
9458 {
9459 SleepThread(timeout);
9460 }
9461
9462 #ifndef UNIX_MACOS
9463 Free(p);
9464 #endif // not UNIX_MACOS
9465 }
9466
9467 // Clean-up of the socket event
UnixCleanupSockEvent(SOCK_EVENT * event)9468 void UnixCleanupSockEvent(SOCK_EVENT *event)
9469 {
9470 UINT i;
9471 // Validate arguments
9472 if (event == NULL)
9473 {
9474 return;
9475 }
9476
9477 for (i = 0;i < LIST_NUM(event->SockList);i++)
9478 {
9479 SOCK *s = LIST_DATA(event->SockList, i);
9480
9481 ReleaseSock(s);
9482 }
9483
9484 ReleaseList(event->SockList);
9485
9486 UnixDeletePipe(event->pipe_read, event->pipe_write);
9487
9488 Free(event);
9489 }
9490
9491 // Create a socket event
UnixNewSockEvent()9492 SOCK_EVENT *UnixNewSockEvent()
9493 {
9494 SOCK_EVENT *e = ZeroMallocFast(sizeof(SOCK_EVENT));
9495
9496 e->SockList = NewList(NULL);
9497 e->ref = NewRef();
9498
9499 UnixNewPipe(&e->pipe_read, &e->pipe_write);
9500
9501 return e;
9502 }
9503
9504 // Close the pipe
UnixDeletePipe(int p1,int p2)9505 void UnixDeletePipe(int p1, int p2)
9506 {
9507 if (p1 != -1)
9508 {
9509 close(p1);
9510 }
9511
9512 if (p2 != -1)
9513 {
9514 close(p2);
9515 }
9516 }
9517
9518 // Write to the pipe
UnixWritePipe(int pipe_write)9519 void UnixWritePipe(int pipe_write)
9520 {
9521 char c = 1;
9522 write(pipe_write, &c, 1);
9523 }
9524
9525 // Create a new pipe
UnixNewPipe(int * pipe_read,int * pipe_write)9526 void UnixNewPipe(int *pipe_read, int *pipe_write)
9527 {
9528 int fd[2];
9529 // Validate arguments
9530 if (pipe_read == NULL || pipe_write == NULL)
9531 {
9532 return;
9533 }
9534
9535 fd[0] = fd[1] = 0;
9536
9537 pipe(fd);
9538
9539 *pipe_read = fd[0];
9540 *pipe_write = fd[1];
9541
9542 UnixSetSocketNonBlockingMode(*pipe_write, true);
9543 UnixSetSocketNonBlockingMode(*pipe_read, true);
9544 }
9545
9546 // Release the asynchronous socket
UnixFreeAsyncSocket(SOCK * sock)9547 void UnixFreeAsyncSocket(SOCK *sock)
9548 {
9549 UINT p;
9550 // Validate arguments
9551 if (sock == NULL)
9552 {
9553 return;
9554 }
9555
9556 Lock(sock->lock);
9557 {
9558 if (sock->AsyncMode == false)
9559 {
9560 Unlock(sock->lock);
9561 return;
9562 }
9563
9564 sock->AsyncMode = false;
9565
9566 // Examine whether this socket are associated to SockEvent
9567 if (sock->SockEvent != NULL)
9568 {
9569 SOCK_EVENT *e = sock->SockEvent;
9570
9571 AddRef(e->ref);
9572
9573 p = e->pipe_write;
9574 LockList(e->SockList);
9575 {
9576 if (Delete(e->SockList, sock))
9577 {
9578 ReleaseSock(sock);
9579 }
9580 }
9581 UnlockList(e->SockList);
9582
9583 // Release the socket event
9584 ReleaseSockEvent(sock->SockEvent);
9585 sock->SockEvent = NULL;
9586
9587 SetSockEvent(e);
9588
9589 ReleaseSockEvent(e);
9590 }
9591 }
9592 Unlock(sock->lock);
9593 }
9594
9595 // Set the socket to asynchronous mode
UnixInitAsyncSocket(SOCK * sock)9596 void UnixInitAsyncSocket(SOCK *sock)
9597 {
9598 // Validate arguments
9599 if (sock == NULL)
9600 {
9601 return;
9602 }
9603 if (sock->AsyncMode)
9604 {
9605 // The socket has been set in asynchronous mode already
9606 return;
9607 }
9608 if (sock->ListenMode != false || ((sock->Type == SOCK_TCP || sock->Type == SOCK_INPROC) && sock->Connected == false))
9609 {
9610 return;
9611 }
9612
9613 sock->AsyncMode = true;
9614
9615 if (sock->Type != SOCK_INPROC)
9616 {
9617 UnixSetSocketNonBlockingMode(sock->socket, true);
9618 }
9619
9620 #if OPENSSL_VERSION_NUMBER < 0x10100000L
9621 if (sock->ssl != NULL && sock->ssl->s3 != NULL)
9622 {
9623 sock->Ssl_Init_Async_SendAlert[0] = sock->ssl->s3->send_alert[0];
9624 sock->Ssl_Init_Async_SendAlert[1] = sock->ssl->s3->send_alert[1];
9625 }
9626 #endif
9627 }
9628
9629 // Initializing the socket library
UnixInitSocketLibrary()9630 void UnixInitSocketLibrary()
9631 {
9632 // Do not do anything special
9633 }
9634
9635 // Release of the socket library
UnixFreeSocketLibrary()9636 void UnixFreeSocketLibrary()
9637 {
9638 // Do not do anything special
9639 }
9640
9641 #endif // OS_UNIX
9642
9643 #ifdef OS_WIN32 // Code for Windows
9644
9645 NETWORK_WIN32_FUNCTIONS *w32net;
9646
9647 // Comparison of IP_ADAPTER_INDEX_MAP
CompareIpAdapterIndexMap(void * p1,void * p2)9648 int CompareIpAdapterIndexMap(void *p1, void *p2)
9649 {
9650 IP_ADAPTER_INDEX_MAP *a1, *a2;
9651 if (p1 == NULL || p2 == NULL)
9652 {
9653 return 0;
9654 }
9655 a1 = *(IP_ADAPTER_INDEX_MAP **)p1;
9656 a2 = *(IP_ADAPTER_INDEX_MAP **)p2;
9657 if (a1 == NULL || a2 == NULL)
9658 {
9659 return 0;
9660 }
9661
9662 if (a1->Index > a2->Index)
9663 {
9664 return 1;
9665 }
9666 else if (a1->Index < a2->Index)
9667 {
9668 return -1;
9669 }
9670 else
9671 {
9672 return 0;
9673 }
9674 }
9675
9676 // Update the IP address of the adapter
Win32RenewAddressByGuid(char * guid)9677 bool Win32RenewAddressByGuid(char *guid)
9678 {
9679 IP_ADAPTER_INDEX_MAP a;
9680 // Validate arguments
9681 if (guid == NULL)
9682 {
9683 return false;
9684 }
9685
9686 Zero(&a, sizeof(a));
9687 if (Win32GetAdapterFromGuid(&a, guid) == false)
9688 {
9689 return false;
9690 }
9691
9692 return Win32RenewAddress(&a);
9693 }
Win32RenewAddress(void * a)9694 bool Win32RenewAddress(void *a)
9695 {
9696 DWORD ret;
9697 // Validate arguments
9698 if (a == NULL)
9699 {
9700 return false;
9701 }
9702 if (w32net->IpRenewAddress == NULL)
9703 {
9704 return false;
9705 }
9706
9707 ret = w32net->IpRenewAddress(a);
9708
9709 if (ret == NO_ERROR)
9710 {
9711 return true;
9712 }
9713 else
9714 {
9715 Debug("IpRenewAddress: Error: %u\n", ret);
9716 return false;
9717 }
9718 }
9719
9720 // Release the IP address of the adapter
Win32ReleaseAddress(void * a)9721 bool Win32ReleaseAddress(void *a)
9722 {
9723 DWORD ret;
9724 // Validate arguments
9725 if (a == NULL)
9726 {
9727 return false;
9728 }
9729 if (w32net->IpReleaseAddress == NULL)
9730 {
9731 return false;
9732 }
9733
9734 ret = w32net->IpReleaseAddress(a);
9735
9736 if (ret == NO_ERROR)
9737 {
9738 return true;
9739 }
9740 else
9741 {
9742 Debug("IpReleaseAddress: Error: %u\n", ret);
9743 return false;
9744 }
9745 }
Win32ReleaseAddressByGuid(char * guid)9746 bool Win32ReleaseAddressByGuid(char *guid)
9747 {
9748 IP_ADAPTER_INDEX_MAP a;
9749 // Validate arguments
9750 if (guid == NULL)
9751 {
9752 return false;
9753 }
9754
9755 Zero(&a, sizeof(a));
9756 if (Win32GetAdapterFromGuid(&a, guid) == false)
9757 {
9758 return false;
9759 }
9760
9761 return Win32ReleaseAddress(&a);
9762 }
Win32ReleaseAddressByGuidExThread(THREAD * t,void * param)9763 void Win32ReleaseAddressByGuidExThread(THREAD *t, void *param)
9764 {
9765 WIN32_RELEASEADDRESS_THREAD_PARAM *p;
9766 // Validate arguments
9767 if (t == NULL || param == NULL)
9768 {
9769 return;
9770 }
9771
9772 p = (WIN32_RELEASEADDRESS_THREAD_PARAM *)param;
9773
9774 AddRef(p->Ref);
9775
9776 NoticeThreadInit(t);
9777
9778 AddWaitThread(t);
9779
9780 if (p->Renew == false)
9781 {
9782 p->Ok = Win32ReleaseAddressByGuid(p->Guid);
9783 }
9784 else
9785 {
9786 p->Ok = Win32RenewAddressByGuid(p->Guid);
9787 }
9788
9789 ReleaseWin32ReleaseAddressByGuidThreadParam(p);
9790
9791 DelWaitThread(t);
9792 }
Win32RenewAddressByGuidEx(char * guid,UINT timeout)9793 bool Win32RenewAddressByGuidEx(char *guid, UINT timeout)
9794 {
9795 return Win32ReleaseOrRenewAddressByGuidEx(guid, timeout, true);
9796 }
Win32ReleaseAddressByGuidEx(char * guid,UINT timeout)9797 bool Win32ReleaseAddressByGuidEx(char *guid, UINT timeout)
9798 {
9799 return Win32ReleaseOrRenewAddressByGuidEx(guid, timeout, false);
9800 }
Win32ReleaseOrRenewAddressByGuidEx(char * guid,UINT timeout,bool renew)9801 bool Win32ReleaseOrRenewAddressByGuidEx(char *guid, UINT timeout, bool renew)
9802 {
9803 THREAD *t;
9804 WIN32_RELEASEADDRESS_THREAD_PARAM *p;
9805 bool ret = false;
9806 UINT64 start_tick = 0;
9807 UINT64 end_tick = 0;
9808 // Validate arguments
9809 if (guid == NULL)
9810 {
9811 return false;
9812 }
9813 if (timeout == 0)
9814 {
9815 timeout = INFINITE;
9816 }
9817
9818 p = ZeroMalloc(sizeof(WIN32_RELEASEADDRESS_THREAD_PARAM));
9819 p->Ref = NewRef();
9820 StrCpy(p->Guid, sizeof(p->Guid), guid);
9821 p->Timeout = timeout;
9822 p->Renew = renew;
9823
9824 t = NewThread(Win32ReleaseAddressByGuidExThread, p);
9825 WaitThreadInit(t);
9826 start_tick = Tick64();
9827 end_tick = start_tick + (UINT64)timeout;
9828
9829 while (true)
9830 {
9831 UINT64 now = Tick64();
9832 UINT64 remain;
9833 UINT remain32;
9834
9835 if (now >= end_tick)
9836 {
9837 break;
9838 }
9839
9840 remain = end_tick - now;
9841 remain32 = MIN((UINT)remain, 100);
9842
9843 if (WaitThread(t, remain32))
9844 {
9845 break;
9846 }
9847 }
9848
9849 ReleaseThread(t);
9850
9851 if (p->Ok)
9852 {
9853 ret = true;
9854 }
9855
9856 ReleaseWin32ReleaseAddressByGuidThreadParam(p);
9857
9858 return ret;
9859 }
ReleaseWin32ReleaseAddressByGuidThreadParam(WIN32_RELEASEADDRESS_THREAD_PARAM * p)9860 void ReleaseWin32ReleaseAddressByGuidThreadParam(WIN32_RELEASEADDRESS_THREAD_PARAM *p)
9861 {
9862 // Validate arguments
9863 if (p == NULL)
9864 {
9865 return;
9866 }
9867
9868 if (Release(p->Ref) == 0)
9869 {
9870 Free(p);
9871 }
9872 }
9873
9874 // Get the adapter by the GUID
Win32GetAdapterFromGuid(void * a,char * guid)9875 bool Win32GetAdapterFromGuid(void *a, char *guid)
9876 {
9877 bool ret = false;
9878 IP_INTERFACE_INFO *info;
9879 UINT size;
9880 int i;
9881 LIST *o;
9882 wchar_t tmp[MAX_SIZE];
9883
9884 // Validate arguments
9885 if (a == NULL || guid == NULL)
9886 {
9887 return false;
9888 }
9889 if (w32net->GetInterfaceInfo == NULL)
9890 {
9891 return false;
9892 }
9893
9894 UniFormat(tmp, sizeof(tmp), L"\\DEVICE\\TCPIP_%S", guid);
9895
9896 size = sizeof(IP_INTERFACE_INFO);
9897 info = ZeroMallocFast(size);
9898
9899 if (w32net->GetInterfaceInfo(info, &size) == ERROR_INSUFFICIENT_BUFFER)
9900 {
9901 Free(info);
9902 info = ZeroMallocFast(size);
9903 }
9904
9905 if (w32net->GetInterfaceInfo(info, &size) != NO_ERROR)
9906 {
9907 Free(info);
9908 return false;
9909 }
9910
9911 o = NewListFast(CompareIpAdapterIndexMap);
9912
9913 for (i = 0;i < info->NumAdapters;i++)
9914 {
9915 IP_ADAPTER_INDEX_MAP *a = &info->Adapter[i];
9916
9917 Add(o, a);
9918 }
9919
9920 Sort(o);
9921
9922 for (i = 0;i < (int)(LIST_NUM(o));i++)
9923 {
9924 IP_ADAPTER_INDEX_MAP *e = LIST_DATA(o, i);
9925
9926 if (UniStrCmpi(e->Name, tmp) == 0)
9927 {
9928 Copy(a, e, sizeof(IP_ADAPTER_INDEX_MAP));
9929 ret = true;
9930 break;
9931 }
9932 }
9933
9934 ReleaseList(o);
9935
9936 Free(info);
9937
9938 return ret;
9939 }
9940
9941 // Test
Win32NetworkTest()9942 void Win32NetworkTest()
9943 {
9944 IP_INTERFACE_INFO *info;
9945 UINT size;
9946 int i;
9947 LIST *o;
9948
9949 size = sizeof(IP_INTERFACE_INFO);
9950 info = ZeroMallocFast(size);
9951
9952 if (w32net->GetInterfaceInfo(info, &size) == ERROR_INSUFFICIENT_BUFFER)
9953 {
9954 Free(info);
9955 info = ZeroMallocFast(size);
9956 }
9957
9958 if (w32net->GetInterfaceInfo(info, &size) != NO_ERROR)
9959 {
9960 Free(info);
9961 return;
9962 }
9963
9964 o = NewListFast(CompareIpAdapterIndexMap);
9965
9966 for (i = 0;i < info->NumAdapters;i++)
9967 {
9968 IP_ADAPTER_INDEX_MAP *a = &info->Adapter[i];
9969
9970 Add(o, a);
9971 }
9972
9973 Sort(o);
9974
9975 for (i = 0;i < (int)(LIST_NUM(o));i++)
9976 {
9977 IP_ADAPTER_INDEX_MAP *a = LIST_DATA(o, i);
9978
9979 DoNothing();
9980 }
9981
9982 ReleaseList(o);
9983
9984 Free(info);
9985 }
9986
9987 // Clear the DNS cache on Win32
Win32FlushDnsCache()9988 void Win32FlushDnsCache()
9989 {
9990 Run("ipconfig.exe", "/flushdns", true, false);
9991 }
9992
9993 // Update the DHCP address of the specified LAN card
Win32RenewDhcp9x(UINT if_id)9994 void Win32RenewDhcp9x(UINT if_id)
9995 {
9996 IP_INTERFACE_INFO *info;
9997 UINT size;
9998 int i;
9999 LIST *o;
10000 // Validate arguments
10001 if (if_id == 0)
10002 {
10003 return;
10004 }
10005
10006 size = sizeof(IP_INTERFACE_INFO);
10007 info = ZeroMallocFast(size);
10008
10009 if (w32net->GetInterfaceInfo(info, &size) == ERROR_INSUFFICIENT_BUFFER)
10010 {
10011 Free(info);
10012 info = ZeroMallocFast(size);
10013 }
10014
10015 if (w32net->GetInterfaceInfo(info, &size) != NO_ERROR)
10016 {
10017 Free(info);
10018 return;
10019 }
10020
10021 o = NewListFast(CompareIpAdapterIndexMap);
10022
10023 for (i = 0;i < info->NumAdapters;i++)
10024 {
10025 IP_ADAPTER_INDEX_MAP *a = &info->Adapter[i];
10026
10027 Add(o, a);
10028 }
10029
10030 Sort(o);
10031
10032 for (i = 0;i < (int)(LIST_NUM(o));i++)
10033 {
10034 IP_ADAPTER_INDEX_MAP *a = LIST_DATA(o, i);
10035
10036 if (a->Index == if_id)
10037 {
10038 char arg[MAX_PATH];
10039 Format(arg, sizeof(arg), "/renew %u", i);
10040 Run("ipconfig.exe", arg, true, false);
10041 }
10042 }
10043
10044 ReleaseList(o);
10045
10046 Free(info);
10047 }
10048
10049 // Release the DHCP address of the specified LAN card
Win32ReleaseDhcp9x(UINT if_id,bool wait)10050 void Win32ReleaseDhcp9x(UINT if_id, bool wait)
10051 {
10052 IP_INTERFACE_INFO *info;
10053 UINT size;
10054 int i;
10055 LIST *o;
10056 // Validate arguments
10057 if (if_id == 0)
10058 {
10059 return;
10060 }
10061
10062 size = sizeof(IP_INTERFACE_INFO);
10063 info = ZeroMallocFast(size);
10064
10065 if (w32net->GetInterfaceInfo(info, &size) == ERROR_INSUFFICIENT_BUFFER)
10066 {
10067 Free(info);
10068 info = ZeroMallocFast(size);
10069 }
10070
10071 if (w32net->GetInterfaceInfo(info, &size) != NO_ERROR)
10072 {
10073 Free(info);
10074 return;
10075 }
10076
10077 o = NewListFast(CompareIpAdapterIndexMap);
10078
10079 for (i = 0;i < info->NumAdapters;i++)
10080 {
10081 IP_ADAPTER_INDEX_MAP *a = &info->Adapter[i];
10082
10083 Add(o, a);
10084 }
10085
10086 Sort(o);
10087
10088 for (i = 0;i < (int)(LIST_NUM(o));i++)
10089 {
10090 IP_ADAPTER_INDEX_MAP *a = LIST_DATA(o, i);
10091
10092 if (a->Index == if_id)
10093 {
10094 char arg[MAX_PATH];
10095 Format(arg, sizeof(arg), "/release %u", i);
10096 Run("ipconfig.exe", arg, true, wait);
10097 }
10098 }
10099
10100 ReleaseList(o);
10101
10102 Free(info);
10103 }
10104
10105 // Re-obtain an IP address from a DHCP server
Win32RenewDhcp()10106 void Win32RenewDhcp()
10107 {
10108 if (OS_IS_WINDOWS_NT(GetOsInfo()->OsType))
10109 {
10110 Run("ipconfig.exe", "/renew", true, false);
10111 if (MsIsVista())
10112 {
10113 Run("ipconfig.exe", "/renew6", true, false);
10114 }
10115 else
10116 {
10117 Run("netsh.exe", "int ipv6 renew", true, false);
10118 }
10119 }
10120 else
10121 {
10122 Run("ipconfig.exe", "/renew_all", true, false);
10123 }
10124 }
10125
10126 // Enumerate a list of virtual LAN cards that contains the specified string
Win32EnumVLan(char * tag_name)10127 char **Win32EnumVLan(char *tag_name)
10128 {
10129 MIB_IFTABLE *p;
10130 UINT ret;
10131 UINT size_needed;
10132 UINT num_retry = 0;
10133 UINT i;
10134 LIST *o;
10135 char **ss;
10136 // Validate arguments
10137 if (tag_name == 0)
10138 {
10139 return NULL;
10140 }
10141
10142 RETRY:
10143 p = ZeroMallocFast(sizeof(MIB_IFTABLE));
10144 size_needed = 0;
10145
10146 // Examine the needed size
10147 ret = w32net->GetIfTable(p, &size_needed, 0);
10148 if (ret == ERROR_INSUFFICIENT_BUFFER)
10149 {
10150 // Re-allocate the memory block of the needed size
10151 Free(p);
10152 p = ZeroMallocFast(size_needed);
10153 }
10154 else if (ret != NO_ERROR)
10155 {
10156 // Acquisition failure
10157 FAILED:
10158 Free(p);
10159 return NULL;
10160 }
10161
10162 // Actually get
10163 ret = w32net->GetIfTable(p, &size_needed, FALSE);
10164 if (ret != NO_ERROR)
10165 {
10166 // Acquisition failure
10167 if ((++num_retry) >= 5)
10168 {
10169 goto FAILED;
10170 }
10171 Free(p);
10172 goto RETRY;
10173 }
10174
10175 // Search
10176 ret = 0;
10177 o = NewListFast(CompareStr);
10178 for (i = 0;i < p->dwNumEntries;i++)
10179 {
10180 MIB_IFROW *r = &p->table[i];
10181 if (SearchStrEx(r->bDescr, tag_name, 0, false) != INFINITE)
10182 {
10183 char *s = CopyStr(r->bDescr);
10184 Add(o, s);
10185 }
10186 }
10187
10188 Free(p);
10189
10190 // Sort
10191 Sort(o);
10192
10193 // Convert to string
10194 ss = ZeroMallocFast(sizeof(char *) * (LIST_NUM(o) + 1));
10195 for (i = 0;i < LIST_NUM(o);i++)
10196 {
10197 ss[i] = LIST_DATA(o, i);
10198 }
10199 ss[LIST_NUM(o)] = NULL;
10200
10201 ReleaseList(o);
10202
10203 return ss;
10204 }
10205
10206 // Get the ID of the virtual LAN card from the instance name of the virtual LAN card
Win32GetVLanInterfaceID(char * instance_name)10207 UINT Win32GetVLanInterfaceID(char *instance_name)
10208 {
10209 MIB_IFTABLE *p;
10210 UINT ret;
10211 UINT size_needed;
10212 UINT num_retry = 0;
10213 UINT i;
10214 char ps_miniport_str[MAX_SIZE];
10215 char ps_miniport_str2[MAX_SIZE];
10216 UINT min_len = 0x7FFFFFFF;
10217 // Validate arguments
10218 if (instance_name == 0)
10219 {
10220 return 0;
10221 }
10222
10223 RETRY:
10224 p = ZeroMallocFast(sizeof(MIB_IFTABLE));
10225 size_needed = 0;
10226
10227 // Examine the needed size
10228 ret = w32net->GetIfTable(p, &size_needed, 0);
10229 if (ret == ERROR_INSUFFICIENT_BUFFER)
10230 {
10231 // Re-allocate the memory block of the needed size
10232 Free(p);
10233 p = ZeroMallocFast(size_needed);
10234 }
10235 else if (ret != NO_ERROR)
10236 {
10237 // Acquisition failure
10238 FAILED:
10239 Free(p);
10240 Debug("******** GetIfTable Failed 1. Err = %u\n", ret);
10241 return 0;
10242 }
10243
10244 // Actually get
10245 ret = w32net->GetIfTable(p, &size_needed, FALSE);
10246 if (ret != NO_ERROR)
10247 {
10248 // Acquisition failure
10249 if ((++num_retry) >= 5)
10250 {
10251 goto FAILED;
10252 }
10253 Free(p);
10254 Debug("******** GetIfTable Failed 2. Err = %u\n", ret);
10255 goto RETRY;
10256 }
10257
10258 // "%s - Packet scheduler miniport"
10259 Format(ps_miniport_str, sizeof(ps_miniport_str), "%s - ", instance_name);
10260 Format(ps_miniport_str2, sizeof(ps_miniport_str2), "%s (Microsoft", instance_name);
10261
10262 // Search
10263 ret = 0;
10264 for (i = 0;i < p->dwNumEntries;i++)
10265 {
10266 MIB_IFROW *r = &p->table[i];
10267 if (instance_name[0] != '@')
10268 {
10269 if (StrCmpi(r->bDescr, instance_name) == 0 || StartWith(r->bDescr, ps_miniport_str) || StartWith(r->bDescr, ps_miniport_str2))
10270 {
10271 UINT len = StrLen(r->bDescr);
10272
10273 if (len < min_len)
10274 {
10275 ret = r->dwIndex;
10276
10277 min_len = len;
10278 }
10279 }
10280 }
10281 else
10282 {
10283 if (SearchStrEx(r->bDescr, &instance_name[1], 0, false) != INFINITE)
10284 {
10285 ret = r->dwIndex;
10286 }
10287 }
10288
10289 //Debug("if[%u] (dwIndex=%u): %u, %s\n", i, r->dwIndex, r->dwType, r->bDescr);
10290 }
10291
10292 Free(p);
10293
10294 return ret;
10295 }
10296
10297 // Get the DNS suffix in another way
Win32GetDnsSuffix(char * domain,UINT size)10298 bool Win32GetDnsSuffix(char *domain, UINT size)
10299 {
10300 IP_ADAPTER_ADDRESSES_XP *info;
10301 IP_ADAPTER_ADDRESSES_XP *cur;
10302 UINT info_size;
10303 bool ret = false;
10304 // Validate arguments
10305 ClearStr(domain, size);
10306 if (domain == NULL)
10307 {
10308 return false;
10309 }
10310 if (w32net->GetAdaptersAddresses == NULL)
10311 {
10312 return false;
10313 }
10314
10315 info_size = 0;
10316 info = ZeroMalloc(sizeof(IP_ADAPTER_ADDRESSES_XP));
10317 if (w32net->GetAdaptersAddresses(AF_INET, 0, NULL, info, &info_size) == ERROR_BUFFER_OVERFLOW)
10318 {
10319 Free(info);
10320 info = ZeroMalloc(info_size);
10321 }
10322 if (w32net->GetAdaptersAddresses(AF_INET, 0, NULL, info, &info_size) != NO_ERROR)
10323 {
10324 Free(info);
10325 return false;
10326 }
10327
10328 cur = info;
10329
10330 while (cur != NULL)
10331 {
10332 if (UniIsEmptyStr(cur->DnsSuffix) == false)
10333 {
10334 UniToStr(domain, size, cur->DnsSuffix);
10335 ret = true;
10336 break;
10337 }
10338
10339 cur = cur->Next;
10340 }
10341
10342 Free(info);
10343
10344 return ret;
10345 }
10346
10347 // Get the DNS server address of the default
Win32GetDefaultDns(IP * ip,char * domain,UINT size)10348 bool Win32GetDefaultDns(IP *ip, char *domain, UINT size)
10349 {
10350 FIXED_INFO *info;
10351 UINT info_size;
10352 char *dns_name;
10353 // Validate arguments
10354 ClearStr(domain, size);
10355 if (ip == NULL)
10356 {
10357 return false;
10358 }
10359 Zero(ip, sizeof(IP));
10360 if (w32net->GetNetworkParams == NULL)
10361 {
10362 return false;
10363 }
10364 info_size = 0;
10365 info = ZeroMallocFast(sizeof(FIXED_INFO));
10366 if (w32net->GetNetworkParams(info, &info_size) == ERROR_BUFFER_OVERFLOW)
10367 {
10368 Free(info);
10369 info = ZeroMallocFast(info_size);
10370 }
10371 if (w32net->GetNetworkParams(info, &info_size) != NO_ERROR)
10372 {
10373 Free(info);
10374 return false;
10375 }
10376
10377 if (info->DnsServerList.IpAddress.String == NULL)
10378 {
10379 Free(info);
10380 return false;
10381 }
10382
10383 dns_name = info->DnsServerList.IpAddress.String;
10384 StrToIP(ip, dns_name);
10385
10386 if (domain != NULL)
10387 {
10388 StrCpy(domain, size, info->DomainName);
10389 Trim(domain);
10390 }
10391
10392 Free(info);
10393
10394 return true;
10395 }
10396
10397 // IP conversion function for Win32
Win32UINTToIP(IP * ip,UINT i)10398 void Win32UINTToIP(IP *ip, UINT i)
10399 {
10400 UINTToIP(ip, i);
10401 }
10402
10403 // IP conversion function for Win32
Win32IPToUINT(IP * ip)10404 UINT Win32IPToUINT(IP *ip)
10405 {
10406 return IPToUINT(ip);
10407 }
10408
10409 // Remove a routing entry from the routing table
Win32DeleteRouteEntry(ROUTE_ENTRY * e)10410 void Win32DeleteRouteEntry(ROUTE_ENTRY *e)
10411 {
10412 MIB_IPFORWARDROW *p;
10413 // Validate arguments
10414 if (e == NULL)
10415 {
10416 return;
10417 }
10418
10419 p = ZeroMallocFast(sizeof(MIB_IPFORWARDROW));
10420 Win32RouteEntryToIpForwardRow(p, e);
10421
10422 // Delete
10423 w32net->DeleteIpForwardEntry(p);
10424
10425 Free(p);
10426 }
10427
10428 // Add a routing entry to the routing table
Win32AddRouteEntry(ROUTE_ENTRY * e,bool * already_exists)10429 bool Win32AddRouteEntry(ROUTE_ENTRY *e, bool *already_exists)
10430 {
10431 bool ret = false;
10432 bool dummy = false;
10433 MIB_IPFORWARDROW *p;
10434 UINT err = 0;
10435 // Validate arguments
10436 if (e == NULL)
10437 {
10438 return false;
10439 }
10440 if (already_exists == NULL)
10441 {
10442 already_exists = &dummy;
10443 }
10444
10445 *already_exists = false;
10446
10447 p = ZeroMallocFast(sizeof(MIB_IPFORWARDROW));
10448 Win32RouteEntryToIpForwardRow(p, e);
10449
10450 // Adding
10451 err = w32net->CreateIpForwardEntry(p);
10452 if (err != 0)
10453 {
10454 if (err == ERROR_OBJECT_ALREADY_EXISTS)
10455 {
10456 Debug("CreateIpForwardEntry: Already Exists\n");
10457 *already_exists = true;
10458 ret = true;
10459 }
10460 else
10461 {
10462 Debug("CreateIpForwardEntry Error: %u\n", err);
10463 ret = false;
10464 }
10465 }
10466 else
10467 {
10468 ret = true;
10469 }
10470
10471 Free(p);
10472
10473 return ret;
10474 }
10475
10476 // Get the routing table
Win32GetRouteTable()10477 ROUTE_TABLE *Win32GetRouteTable()
10478 {
10479 ROUTE_TABLE *t = ZeroMallocFast(sizeof(ROUTE_TABLE));
10480 MIB_IPFORWARDTABLE *p;
10481 UINT ret;
10482 UINT size_needed;
10483 UINT num_retry = 0;
10484 LIST *o;
10485 UINT i;
10486 ROUTE_ENTRY *e;
10487
10488 RETRY:
10489 p = ZeroMallocFast(sizeof(MIB_IFTABLE));
10490 size_needed = 0;
10491
10492 // Examine the needed size
10493 ret = w32net->GetIpForwardTable(p, &size_needed, 0);
10494 if (ret == ERROR_INSUFFICIENT_BUFFER)
10495 {
10496 // Re-allocate the memory block of the needed size
10497 Free(p);
10498 p = ZeroMallocFast(size_needed);
10499 }
10500 else if (ret != NO_ERROR)
10501 {
10502 // Acquisition failure
10503 FAILED:
10504 Free(p);
10505 t->Entry = MallocFast(0);
10506 return t;
10507 }
10508
10509 // Actually get
10510 ret = w32net->GetIpForwardTable(p, &size_needed, FALSE);
10511 if (ret != NO_ERROR)
10512 {
10513 // Acquisition failure
10514 if ((++num_retry) >= 5)
10515 {
10516 goto FAILED;
10517 }
10518 Free(p);
10519 goto RETRY;
10520 }
10521
10522 // Add to the list along
10523 o = NewListFast(Win32CompareRouteEntryByMetric);
10524 for (i = 0;i < p->dwNumEntries;i++)
10525 {
10526 e = ZeroMallocFast(sizeof(ROUTE_ENTRY));
10527 Win32IpForwardRowToRouteEntry(e, &p->table[i]);
10528 Add(o, e);
10529 }
10530 Free(p);
10531
10532 // Sort by metric
10533 Sort(o);
10534
10535 // Combine the results
10536 t->NumEntry = LIST_NUM(o);
10537 t->Entry = ToArrayEx(o, true);
10538 ReleaseList(o);
10539
10540 return t;
10541 }
10542
10543 // Sort the routing entries by metric
Win32CompareRouteEntryByMetric(void * p1,void * p2)10544 int Win32CompareRouteEntryByMetric(void *p1, void *p2)
10545 {
10546 ROUTE_ENTRY *e1, *e2;
10547 // Validate arguments
10548 if (p1 == NULL || p2 == NULL)
10549 {
10550 return 0;
10551 }
10552
10553 e1 = *(ROUTE_ENTRY **)p1;
10554 e2 = *(ROUTE_ENTRY **)p2;
10555 if (e1 == NULL || e2 == NULL)
10556 {
10557 return 0;
10558 }
10559
10560 if (e1->Metric > e2->Metric)
10561 {
10562 return 1;
10563 }
10564 else if (e1->Metric == e2->Metric)
10565 {
10566 return 0;
10567 }
10568 else
10569 {
10570 return -1;
10571 }
10572 }
10573
10574 // Convert the ROUTE_ENTRY to a MIB_IPFORWARDROW
Win32RouteEntryToIpForwardRow(void * ip_forward_row,ROUTE_ENTRY * entry)10575 void Win32RouteEntryToIpForwardRow(void *ip_forward_row, ROUTE_ENTRY *entry)
10576 {
10577 MIB_IPFORWARDROW *r;
10578 // Validate arguments
10579 if (entry == NULL || ip_forward_row == NULL)
10580 {
10581 return;
10582 }
10583
10584 r = (MIB_IPFORWARDROW *)ip_forward_row;
10585 Zero(r, sizeof(MIB_IPFORWARDROW));
10586
10587 // IP address
10588 r->dwForwardDest = Win32IPToUINT(&entry->DestIP);
10589 // Subnet mask
10590 r->dwForwardMask = Win32IPToUINT(&entry->DestMask);
10591 // Gateway IP address
10592 r->dwForwardNextHop = Win32IPToUINT(&entry->GatewayIP);
10593 // Local routing flag
10594 if (entry->LocalRouting)
10595 {
10596 // Local
10597 r->dwForwardType = 3;
10598 }
10599 else
10600 {
10601 // Remote router
10602 r->dwForwardType = 4;
10603 }
10604 // Protocol
10605 r->dwForwardProto = r->dwForwardType - 1; // Subtract by 1 in most cases
10606 if (entry->PPPConnection)
10607 {
10608 // Isn't this a PPP? Danger!
10609 r->dwForwardProto++;
10610 }
10611 // Metric
10612 r->dwForwardMetric1 = entry->Metric;
10613
10614 if (MsIsVista() == false)
10615 {
10616 r->dwForwardMetric2 = r->dwForwardMetric3 = r->dwForwardMetric4 = r->dwForwardMetric5 = INFINITE;
10617 }
10618 else
10619 {
10620 r->dwForwardMetric2 = r->dwForwardMetric3 = r->dwForwardMetric4 = r->dwForwardMetric5 = 0;
10621 r->dwForwardAge = 163240;
10622 }
10623
10624 // Interface ID
10625 r->dwForwardIfIndex = entry->InterfaceID;
10626
10627 Debug("Win32RouteEntryToIpForwardRow()\n");
10628 Debug(" r->dwForwardDest=%X\n", r->dwForwardDest);
10629 Debug(" r->dwForwardMask=%X\n", r->dwForwardMask);
10630 Debug(" r->dwForwardNextHop=%X\n", r->dwForwardNextHop);
10631 Debug(" r->dwForwardType=%u\n", r->dwForwardType);
10632 Debug(" r->dwForwardProto=%u\n", r->dwForwardProto);
10633 Debug(" r->dwForwardMetric1=%u\n", r->dwForwardMetric1);
10634 Debug(" r->dwForwardMetric2=%u\n", r->dwForwardMetric2);
10635 Debug(" r->dwForwardIfIndex=%u\n", r->dwForwardIfIndex);
10636 }
10637
10638 // Convert the MIB_IPFORWARDROW to a ROUTE_ENTRY
Win32IpForwardRowToRouteEntry(ROUTE_ENTRY * entry,void * ip_forward_row)10639 void Win32IpForwardRowToRouteEntry(ROUTE_ENTRY *entry, void *ip_forward_row)
10640 {
10641 MIB_IPFORWARDROW *r;
10642 // Validate arguments
10643 if (entry == NULL || ip_forward_row == NULL)
10644 {
10645 return;
10646 }
10647
10648 r = (MIB_IPFORWARDROW *)ip_forward_row;
10649
10650 Zero(entry, sizeof(ROUTE_ENTRY));
10651 // IP address
10652 Win32UINTToIP(&entry->DestIP, r->dwForwardDest);
10653 // Subnet mask
10654 Win32UINTToIP(&entry->DestMask, r->dwForwardMask);
10655 // Gateway IP address
10656 Win32UINTToIP(&entry->GatewayIP, r->dwForwardNextHop);
10657 // Local routing flag
10658 if (r->dwForwardType == 3)
10659 {
10660 entry->LocalRouting = true;
10661 }
10662 else
10663 {
10664 entry->LocalRouting = false;
10665 }
10666 if (entry->LocalRouting && r->dwForwardProto == 3)
10667 {
10668 // PPP. Danger!
10669 entry->PPPConnection = true;
10670 }
10671 // Metric
10672 entry->Metric = r->dwForwardMetric1;
10673 // Interface ID
10674 entry->InterfaceID = r->dwForwardIfIndex;
10675 }
10676
10677 // Initializing the socket library
Win32InitSocketLibrary()10678 void Win32InitSocketLibrary()
10679 {
10680 WSADATA data;
10681 Zero(&data, sizeof(data));
10682 WSAStartup(MAKEWORD(2, 2), &data);
10683
10684 // Load the DLL functions
10685 w32net = ZeroMalloc(sizeof(NETWORK_WIN32_FUNCTIONS));
10686 w32net->hIpHlpApi32 = LoadLibrary("iphlpapi.dll");
10687 w32net->hIcmp = LoadLibrary("icmp.dll");
10688
10689 if (w32net->hIpHlpApi32 != NULL)
10690 {
10691 w32net->CreateIpForwardEntry =
10692 (DWORD (__stdcall *)(PMIB_IPFORWARDROW))
10693 GetProcAddress(w32net->hIpHlpApi32, "CreateIpForwardEntry");
10694
10695 w32net->DeleteIpForwardEntry =
10696 (DWORD (__stdcall *)(PMIB_IPFORWARDROW))
10697 GetProcAddress(w32net->hIpHlpApi32, "DeleteIpForwardEntry");
10698
10699 w32net->GetIfTable =
10700 (DWORD (__stdcall *)(PMIB_IFTABLE, PULONG, BOOL))
10701 GetProcAddress(w32net->hIpHlpApi32, "GetIfTable");
10702
10703 w32net->GetIfTable2 =
10704 (DWORD (__stdcall *)(void **))
10705 GetProcAddress(w32net->hIpHlpApi32, "GetIfTable2");
10706
10707 w32net->FreeMibTable =
10708 (void (__stdcall *)(PVOID))
10709 GetProcAddress(w32net->hIpHlpApi32, "FreeMibTable");
10710
10711 w32net->GetIpForwardTable =
10712 (DWORD (__stdcall *)(PMIB_IPFORWARDTABLE, PULONG, BOOL))
10713 GetProcAddress(w32net->hIpHlpApi32, "GetIpForwardTable");
10714
10715 w32net->GetNetworkParams =
10716 (DWORD (__stdcall *)(PFIXED_INFO,PULONG))
10717 GetProcAddress(w32net->hIpHlpApi32, "GetNetworkParams");
10718
10719 w32net->GetAdaptersAddresses =
10720 (ULONG (__stdcall *)(ULONG,ULONG,PVOID,PIP_ADAPTER_ADDRESSES,PULONG))
10721 GetProcAddress(w32net->hIpHlpApi32, "GetAdaptersAddresses");
10722
10723 w32net->IpRenewAddress =
10724 (DWORD (__stdcall *)(PIP_ADAPTER_INDEX_MAP))
10725 GetProcAddress(w32net->hIpHlpApi32, "IpRenewAddress");
10726
10727 w32net->IpReleaseAddress =
10728 (DWORD (__stdcall *)(PIP_ADAPTER_INDEX_MAP))
10729 GetProcAddress(w32net->hIpHlpApi32, "IpReleaseAddress");
10730
10731 w32net->GetInterfaceInfo =
10732 (DWORD (__stdcall *)(PIP_INTERFACE_INFO, PULONG))
10733 GetProcAddress(w32net->hIpHlpApi32, "GetInterfaceInfo");
10734
10735 w32net->GetAdaptersInfo =
10736 (DWORD (__stdcall *)(PIP_ADAPTER_INFO, PULONG))
10737 GetProcAddress(w32net->hIpHlpApi32, "GetAdaptersInfo");
10738
10739 w32net->GetExtendedTcpTable =
10740 (DWORD (__stdcall *)(PVOID,PDWORD,BOOL,ULONG,_TCP_TABLE_CLASS,ULONG))
10741 GetProcAddress(w32net->hIpHlpApi32, "GetExtendedTcpTable");
10742
10743 w32net->AllocateAndGetTcpExTableFromStack =
10744 (DWORD (__stdcall *)(PVOID *,BOOL,HANDLE,DWORD,DWORD))
10745 GetProcAddress(w32net->hIpHlpApi32, "AllocateAndGetTcpExTableFromStack");
10746
10747 w32net->GetTcpTable =
10748 (DWORD (__stdcall *)(PMIB_TCPTABLE,PDWORD,BOOL))
10749 GetProcAddress(w32net->hIpHlpApi32, "GetTcpTable");
10750
10751 w32net->NotifyRouteChange =
10752 (DWORD (__stdcall *)(PHANDLE,LPOVERLAPPED))
10753 GetProcAddress(w32net->hIpHlpApi32, "NotifyRouteChange");
10754
10755 w32net->CancelIPChangeNotify =
10756 (BOOL (__stdcall *)(LPOVERLAPPED))
10757 GetProcAddress(w32net->hIpHlpApi32, "CancelIPChangeNotify");
10758
10759 w32net->NhpAllocateAndGetInterfaceInfoFromStack =
10760 (DWORD (__stdcall *)(IP_INTERFACE_NAME_INFO **,PDWORD,BOOL,HANDLE,DWORD))
10761 GetProcAddress(w32net->hIpHlpApi32, "NhpAllocateAndGetInterfaceInfoFromStack");
10762
10763 w32net->IcmpCreateFile =
10764 (HANDLE (__stdcall *)())
10765 GetProcAddress(w32net->hIpHlpApi32, "IcmpCreateFile");
10766
10767 w32net->IcmpCloseHandle =
10768 (BOOL (__stdcall *)(HANDLE))
10769 GetProcAddress(w32net->hIpHlpApi32, "IcmpCloseHandle");
10770
10771 w32net->IcmpSendEcho =
10772 (DWORD (__stdcall *)(HANDLE,IPAddr,LPVOID,WORD,PIP_OPTION_INFORMATION,LPVOID,DWORD,DWORD))
10773 GetProcAddress(w32net->hIpHlpApi32, "IcmpSendEcho");
10774 }
10775
10776 if (w32net->hIcmp != NULL)
10777 {
10778 if (w32net->IcmpCreateFile == NULL || w32net->IcmpCloseHandle == NULL || w32net->IcmpSendEcho == NULL)
10779 {
10780 w32net->IcmpCreateFile =
10781 (HANDLE (__stdcall *)())
10782 GetProcAddress(w32net->hIcmp, "IcmpCreateFile");
10783
10784 w32net->IcmpCloseHandle =
10785 (BOOL (__stdcall *)(HANDLE))
10786 GetProcAddress(w32net->hIcmp, "IcmpCloseHandle");
10787
10788 w32net->IcmpSendEcho =
10789 (DWORD (__stdcall *)(HANDLE,IPAddr,LPVOID,WORD,PIP_OPTION_INFORMATION,LPVOID,DWORD,DWORD))
10790 GetProcAddress(w32net->hIcmp, "IcmpSendEcho");
10791 }
10792 }
10793
10794 if (w32net->IcmpCreateFile == NULL || w32net->IcmpCloseHandle == NULL || w32net->IcmpSendEcho == NULL)
10795 {
10796 w32net->IcmpCreateFile = NULL;
10797 w32net->IcmpCloseHandle = NULL;
10798 w32net->IcmpSendEcho = NULL;
10799 }
10800 }
10801
10802 // Release of the socket library
Win32FreeSocketLibrary()10803 void Win32FreeSocketLibrary()
10804 {
10805 if (w32net != NULL)
10806 {
10807 if (w32net->hIpHlpApi32 != NULL)
10808 {
10809 FreeLibrary(w32net->hIpHlpApi32);
10810 }
10811
10812 if (w32net->hIcmp != NULL)
10813 {
10814 FreeLibrary(w32net->hIcmp);
10815 }
10816
10817 Free(w32net);
10818 w32net = NULL;
10819 }
10820
10821 WSACleanup();
10822 }
10823
10824 // Cancel
Win32Cancel(CANCEL * c)10825 void Win32Cancel(CANCEL *c)
10826 {
10827 // Validate arguments
10828 if (c == NULL)
10829 {
10830 return;
10831 }
10832
10833 SetEvent((HANDLE)c->hEvent);
10834 }
10835
10836 // Cleanup of the cancel object
Win32CleanupCancel(CANCEL * c)10837 void Win32CleanupCancel(CANCEL *c)
10838 {
10839 // Validate arguments
10840 if (c == NULL)
10841 {
10842 return;
10843 }
10844
10845 if (c->SpecialFlag == false)
10846 {
10847 CloseHandle(c->hEvent);
10848 }
10849
10850 Free(c);
10851 }
10852
10853 // New cancel object
Win32NewCancel()10854 CANCEL *Win32NewCancel()
10855 {
10856 CANCEL *c = ZeroMallocFast(sizeof(CANCEL));
10857 c->ref = NewRef();
10858 c->SpecialFlag = false;
10859 c->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
10860
10861 return c;
10862 }
10863
10864 // Waiting for a socket event
Win32WaitSockEvent(SOCK_EVENT * event,UINT timeout)10865 bool Win32WaitSockEvent(SOCK_EVENT *event, UINT timeout)
10866 {
10867 // Validate arguments
10868 if (event == NULL || timeout == 0)
10869 {
10870 return false;
10871 }
10872
10873 if (WaitForSingleObject((HANDLE)event->hEvent, timeout) == WAIT_OBJECT_0)
10874 {
10875 return true;
10876 }
10877 else
10878 {
10879 return false;
10880 }
10881 }
10882
10883 // Clean-up of the socket event
Win32CleanupSockEvent(SOCK_EVENT * event)10884 void Win32CleanupSockEvent(SOCK_EVENT *event)
10885 {
10886 // Validate arguments
10887 if (event == NULL)
10888 {
10889 return;
10890 }
10891
10892 CloseHandle((HANDLE)event->hEvent);
10893
10894 Free(event);
10895 }
10896
10897 // Set of the socket event
Win32SetSockEvent(SOCK_EVENT * event)10898 void Win32SetSockEvent(SOCK_EVENT *event)
10899 {
10900 // Validate arguments
10901 if (event == NULL)
10902 {
10903 return;
10904 }
10905
10906 SetEvent((HANDLE)event->hEvent);
10907 }
10908
10909 // Creating a socket event
Win32NewSockEvent()10910 SOCK_EVENT *Win32NewSockEvent()
10911 {
10912 SOCK_EVENT *e = ZeroMallocFast(sizeof(SOCK_EVENT));
10913
10914 e->ref = NewRef();
10915 e->hEvent = (void *)CreateEvent(NULL, FALSE, FALSE, NULL);
10916
10917 return e;
10918 }
10919
10920 // Associate the socket with socket event and set it to asynchronous mode
Win32JoinSockToSockEvent(SOCK * sock,SOCK_EVENT * event)10921 void Win32JoinSockToSockEvent(SOCK *sock, SOCK_EVENT *event)
10922 {
10923 HANDLE hEvent;
10924 // Validate arguments
10925 if (sock == NULL || event == NULL || sock->AsyncMode)
10926 {
10927 return;
10928 }
10929 if (sock->ListenMode != false || (sock->Type != SOCK_UDP && sock->Connected == false))
10930 {
10931 return;
10932 }
10933
10934 sock->AsyncMode = true;
10935
10936 hEvent = event->hEvent;
10937
10938 // Association
10939 WSAEventSelect(sock->socket, hEvent, FD_READ | FD_WRITE | FD_CLOSE);
10940
10941 // Increase the reference count of the SOCK_EVENT
10942 AddRef(event->ref);
10943 sock->SockEvent = event;
10944 }
10945
10946 // Set the socket to asynchronous mode
Win32InitAsyncSocket(SOCK * sock)10947 void Win32InitAsyncSocket(SOCK *sock)
10948 {
10949 // Validate arguments
10950 if (sock == NULL)
10951 {
10952 return;
10953 }
10954 if (sock->AsyncMode)
10955 {
10956 // This socket is already in asynchronous mode
10957 return;
10958 }
10959 if (sock->ListenMode || ((sock->Type == SOCK_TCP || sock->Type == SOCK_INPROC) && sock->Connected == false))
10960 {
10961 return;
10962 }
10963
10964 sock->AsyncMode = true;
10965
10966 if (sock->Type == SOCK_INPROC)
10967 {
10968 // Fetch the event of the TUBE
10969 TUBE *t = sock->RecvTube;
10970
10971 if (t != NULL)
10972 {
10973 if (t->SockEvent != NULL)
10974 {
10975 sock->hEvent = t->SockEvent->hEvent;
10976 }
10977 }
10978 }
10979 else
10980 {
10981 // Creating an Event
10982 sock->hEvent = (void *)CreateEvent(NULL, FALSE, FALSE, NULL);
10983
10984 // Association
10985 WSAEventSelect(sock->socket, sock->hEvent, FD_READ | FD_WRITE | FD_CLOSE);
10986 }
10987 }
10988
10989 // Release the asynchronous socket
Win32FreeAsyncSocket(SOCK * sock)10990 void Win32FreeAsyncSocket(SOCK *sock)
10991 {
10992 // Validate arguments
10993 if (sock == NULL)
10994 {
10995 return;
10996 }
10997
10998 // Asynchronous socket
10999 if (sock->hEvent != NULL)
11000 {
11001 if (sock->Type != SOCK_INPROC)
11002 {
11003 CloseHandle((HANDLE)sock->hEvent);
11004 }
11005 }
11006 sock->hEvent = NULL;
11007 sock->AsyncMode = false;
11008
11009 // Socket event
11010 if (sock->SockEvent != NULL)
11011 {
11012 ReleaseSockEvent(sock->SockEvent);
11013 sock->SockEvent = NULL;
11014 }
11015 }
11016
11017 // Select function for Win32
Win32Select(SOCKSET * set,UINT timeout,CANCEL * c1,CANCEL * c2)11018 void Win32Select(SOCKSET *set, UINT timeout, CANCEL *c1, CANCEL *c2)
11019 {
11020 HANDLE array[MAXIMUM_WAIT_OBJECTS];
11021 UINT n, i;
11022 SOCK *s;
11023 // Initialization of array
11024 Zero(array, sizeof(array));
11025 n = 0;
11026
11027 // Setting the event array
11028 if (set != NULL)
11029 {
11030 for (i = 0;i < set->NumSocket;i++)
11031 {
11032 s = set->Sock[i];
11033 if (s != NULL)
11034 {
11035 Win32InitAsyncSocket(s);
11036 if (s->hEvent != NULL)
11037 {
11038 array[n++] = (HANDLE)s->hEvent;
11039 }
11040
11041 if (s->BulkRecvTube != NULL)
11042 {
11043 array[n++] = (HANDLE)s->BulkRecvTube->SockEvent->hEvent;
11044 }
11045 }
11046 }
11047 }
11048 if (c1 != NULL && c1->hEvent != NULL)
11049 {
11050 array[n++] = c1->hEvent;
11051 }
11052 if (c2 != NULL && c2->hEvent != NULL)
11053 {
11054 array[n++] = c2->hEvent;
11055 }
11056
11057 if (timeout == 0)
11058 {
11059 return;
11060 }
11061
11062 if (n == 0)
11063 {
11064 // Call normal waiting function if no events to wait are registered
11065 SleepThread(timeout);
11066 }
11067 else
11068 {
11069 // Wait for the event if events are registered at least one
11070 if (n == 1)
11071 {
11072 // Calling a lightweight version If the event is only one
11073 WaitForSingleObject(array[0], timeout);
11074 }
11075 else
11076 {
11077 // In case of multiple events
11078 WaitForMultipleObjects(n, array, false, timeout);
11079 }
11080 }
11081 }
11082
11083 #endif // OS_WIN32
11084
11085 // Check whether the IPv6 is supported
IsIPv6Supported()11086 bool IsIPv6Supported()
11087 {
11088 #ifdef NO_IPV6
11089 return false;
11090 #else // NO_IPV6
11091 SOCKET s;
11092
11093 s = socket(AF_INET6, SOCK_STREAM, 0);
11094 if (s == INVALID_SOCKET)
11095 {
11096 return false;
11097 }
11098
11099 closesocket(s);
11100
11101 return true;
11102 #endif // NO_IPV6
11103 }
11104
11105 // Get the host name from the host cache
GetHostCache(char * hostname,UINT size,IP * ip)11106 bool GetHostCache(char *hostname, UINT size, IP *ip)
11107 {
11108 bool ret;
11109 // Validate arguments
11110 if (hostname == NULL || ip == NULL)
11111 {
11112 return false;
11113 }
11114
11115 ret = false;
11116
11117 LockList(HostCacheList);
11118 {
11119 HOSTCACHE t, *c;
11120 Zero(&t, sizeof(t));
11121 Copy(&t.IpAddress, ip, sizeof(IP));
11122
11123 c = Search(HostCacheList, &t);
11124 if (c != NULL)
11125 {
11126 if (IsEmptyStr(c->HostName) == false)
11127 {
11128 ret = true;
11129 StrCpy(hostname, size, c->HostName);
11130 }
11131 else
11132 {
11133 ret = true;
11134 StrCpy(hostname, size, "");
11135 }
11136 }
11137 }
11138 UnlockList(HostCacheList);
11139
11140 return ret;
11141 }
11142
11143 // Add to the host name cache
AddHostCache(IP * ip,char * hostname)11144 void AddHostCache(IP *ip, char *hostname)
11145 {
11146 // Validate arguments
11147 if (ip == NULL || hostname == NULL)
11148 {
11149 return;
11150 }
11151 if (IsNetworkNameCacheEnabled() == false)
11152 {
11153 return;
11154 }
11155
11156 LockList(HostCacheList);
11157 {
11158 HOSTCACHE t, *c;
11159 UINT i;
11160 LIST *o;
11161
11162 Zero(&t, sizeof(t));
11163 Copy(&t.IpAddress, ip, sizeof(IP));
11164
11165 c = Search(HostCacheList, &t);
11166 if (c == NULL)
11167 {
11168 c = ZeroMalloc(sizeof(HOSTCACHE));
11169 Copy(&c->IpAddress, ip, sizeof(IP));
11170 Add(HostCacheList, c);
11171 }
11172
11173 StrCpy(c->HostName, sizeof(c->HostName), hostname);
11174 c->Expires = Tick64() + (UINT64)EXPIRES_HOSTNAME;
11175
11176 o = NewListFast(NULL);
11177
11178 for (i = 0;i < LIST_NUM(HostCacheList);i++)
11179 {
11180 HOSTCACHE *c = LIST_DATA(HostCacheList, i);
11181
11182 if (c->Expires <= Tick64())
11183 {
11184 Add(o, c);
11185 }
11186 }
11187
11188 for (i = 0;i < LIST_NUM(o);i++)
11189 {
11190 HOSTCACHE *c = LIST_DATA(o, i);
11191
11192 if (Delete(HostCacheList, c))
11193 {
11194 Free(c);
11195 }
11196 }
11197
11198 ReleaseList(o);
11199 }
11200 UnlockList(HostCacheList);
11201 }
11202
11203 // Comparison of host name cache entries
CompareHostCache(void * p1,void * p2)11204 int CompareHostCache(void *p1, void *p2)
11205 {
11206 HOSTCACHE *c1, *c2;
11207 if (p1 == NULL || p2 == NULL)
11208 {
11209 return 0;
11210 }
11211 c1 = *(HOSTCACHE **)p1;
11212 c2 = *(HOSTCACHE **)p2;
11213 if (c1 == NULL || c2 == NULL)
11214 {
11215 return 0;
11216 }
11217
11218 return CmpIpAddr(&c1->IpAddress, &c2->IpAddress);
11219 }
11220
11221 // Release of the host name cache
FreeHostCache()11222 void FreeHostCache()
11223 {
11224 UINT i;
11225
11226 for (i = 0;i < LIST_NUM(HostCacheList);i++)
11227 {
11228 HOSTCACHE *c = LIST_DATA(HostCacheList, i);
11229
11230 Free(c);
11231 }
11232
11233 ReleaseList(HostCacheList);
11234 HostCacheList = NULL;
11235 }
11236
11237 // Initialization of the host name cache
InitHostCache()11238 void InitHostCache()
11239 {
11240 HostCacheList = NewList(CompareHostCache);
11241 }
11242
11243 // Get the number of wait threads
GetNumWaitThread()11244 UINT GetNumWaitThread()
11245 {
11246 UINT ret = 0;
11247
11248 LockList(WaitThreadList);
11249 {
11250 ret = LIST_NUM(WaitThreadList);
11251 }
11252 UnlockList(WaitThreadList);
11253
11254 return ret;
11255 }
11256
11257 // Add the thread to the thread waiting list
AddWaitThread(THREAD * t)11258 void AddWaitThread(THREAD *t)
11259 {
11260 // Validate arguments
11261 if (t == NULL)
11262 {
11263 return;
11264 }
11265
11266 AddRef(t->ref);
11267
11268 LockList(WaitThreadList);
11269 {
11270 Add(WaitThreadList, t);
11271 }
11272 UnlockList(WaitThreadList);
11273 }
11274
11275 // Remove the thread from the waiting list
DelWaitThread(THREAD * t)11276 void DelWaitThread(THREAD *t)
11277 {
11278 // Validate arguments
11279 if (t == NULL)
11280 {
11281 return;
11282 }
11283
11284 LockList(WaitThreadList);
11285 {
11286 if (Delete(WaitThreadList, t))
11287 {
11288 ReleaseThread(t);
11289 }
11290 }
11291 UnlockList(WaitThreadList);
11292 }
11293
11294 // Creating a thread waiting list
InitWaitThread()11295 void InitWaitThread()
11296 {
11297 WaitThreadList = NewList(NULL);
11298 }
11299
11300 // Release of the thread waiting list
FreeWaitThread()11301 void FreeWaitThread()
11302 {
11303 UINT i, num;
11304 THREAD **threads;
11305
11306 LockList(WaitThreadList);
11307 {
11308 num = LIST_NUM(WaitThreadList);
11309 threads = ToArray(WaitThreadList);
11310 DeleteAll(WaitThreadList);
11311 }
11312 UnlockList(WaitThreadList);
11313
11314 for (i = 0;i < num;i++)
11315 {
11316 THREAD *t = threads[i];
11317 WaitThread(t, INFINITE);
11318 ReleaseThread(t);
11319 }
11320
11321 Free(threads);
11322
11323 ReleaseList(WaitThreadList);
11324 WaitThreadList = NULL;
11325 }
11326
11327 // Check the cipher list name
CheckCipherListName(char * name)11328 bool CheckCipherListName(char *name)
11329 {
11330 UINT i;
11331 // Validate arguments
11332 if (name == NULL)
11333 {
11334 return false;
11335 }
11336
11337 for (i = 0;i < cipher_list_token->NumTokens;i++)
11338 {
11339 if (StrCmpi(cipher_list_token->Token[i], name) == 0)
11340 {
11341 return true;
11342 }
11343 }
11344
11345 return false;
11346 }
11347
11348 // Renewing the IP address of the DHCP server
RenewDhcp()11349 void RenewDhcp()
11350 {
11351 #ifdef OS_WIN32
11352 Win32RenewDhcp();
11353 #else
11354 UnixRenewDhcp();
11355 #endif
11356 }
11357
11358 // Get a domain name for UNIX
UnixGetDomainName(char * name,UINT size)11359 bool UnixGetDomainName(char *name, UINT size)
11360 {
11361 bool ret = false;
11362 BUF *b = ReadDump("/etc/resolv.conf");
11363
11364 if (b == NULL)
11365 {
11366 return false;
11367 }
11368
11369 while (true)
11370 {
11371 char *s = CfgReadNextLine(b);
11372 TOKEN_LIST *t;
11373
11374 if (s == NULL)
11375 {
11376 break;
11377 }
11378
11379 Trim(s);
11380
11381 t = ParseToken(s, " \t");
11382 if (t != NULL)
11383 {
11384 if (t->NumTokens == 2)
11385 {
11386 if (StrCmpi(t->Token[0], "domain") == 0)
11387 {
11388 StrCpy(name, size, t->Token[1]);
11389 ret = true;
11390 }
11391 }
11392 FreeToken(t);
11393 }
11394
11395 Free(s);
11396 }
11397
11398 FreeBuf(b);
11399
11400 return ret;
11401 }
11402
11403 // Get the domain name
GetDomainName(char * name,UINT size)11404 bool GetDomainName(char *name, UINT size)
11405 {
11406 bool ret = false;
11407 IP ip;
11408 // Validate arguments
11409 ClearStr(name, size);
11410 if (name == NULL)
11411 {
11412 return false;
11413 }
11414
11415 #ifdef OS_WIN32
11416 ClearStr(name, size);
11417 ret = Win32GetDefaultDns(&ip, name, size);
11418
11419 if (ret == false || IsEmptyStr(name))
11420 {
11421 ret = Win32GetDnsSuffix(name, size);
11422 }
11423 #else // OS_WIN32
11424 ret = UnixGetDomainName(name, size);
11425 #endif // OS_WIN32
11426
11427 if (ret == false)
11428 {
11429 return false;
11430 }
11431
11432 return (IsEmptyStr(name) ? false : true);
11433 }
11434
11435 // Get the default DNS server
GetDefaultDns(IP * ip)11436 bool GetDefaultDns(IP *ip)
11437 {
11438 bool ret = false;
11439 #ifdef OS_WIN32
11440 ret = Win32GetDefaultDns(ip, NULL, 0);
11441 #else
11442 ret = UnixGetDefaultDns(ip);
11443 #endif // OS_WIN32
11444 return ret;
11445 }
11446
11447 // Creating a socket event
NewSockEvent()11448 SOCK_EVENT *NewSockEvent()
11449 {
11450 SOCK_EVENT *e = NULL;
11451 #ifdef OS_WIN32
11452 e = Win32NewSockEvent();
11453 #else
11454 e = UnixNewSockEvent();
11455 #endif // OS_WIN32
11456 return e;
11457 }
11458
11459 // Set of the socket event
SetSockEvent(SOCK_EVENT * event)11460 void SetSockEvent(SOCK_EVENT *event)
11461 {
11462 #ifdef OS_WIN32
11463 Win32SetSockEvent(event);
11464 #else
11465 UnixSetSockEvent(event);
11466 #endif // OS_WIN32
11467 }
11468
11469 // Clean-up of the socket event
CleanupSockEvent(SOCK_EVENT * event)11470 void CleanupSockEvent(SOCK_EVENT *event)
11471 {
11472 #ifdef OS_WIN32
11473 Win32CleanupSockEvent(event);
11474 #else
11475 UnixCleanupSockEvent(event);
11476 #endif // OS_WIN32
11477 }
11478
11479 // Waiting for the socket event
WaitSockEvent(SOCK_EVENT * event,UINT timeout)11480 bool WaitSockEvent(SOCK_EVENT *event, UINT timeout)
11481 {
11482 bool ret = false;
11483 #ifdef OS_WIN32
11484 ret = Win32WaitSockEvent(event, timeout);
11485 #else
11486 ret = UnixWaitSockEvent(event, timeout);
11487 #endif // OS_WIN32
11488 return ret;
11489 }
11490
11491 // Release of the socket event
ReleaseSockEvent(SOCK_EVENT * event)11492 void ReleaseSockEvent(SOCK_EVENT *event)
11493 {
11494 // Validate arguments
11495 if (event == NULL)
11496 {
11497 return;
11498 }
11499
11500 if (Release(event->ref) == 0)
11501 {
11502 CleanupSockEvent(event);
11503 }
11504 }
11505
11506 // Let belonging the socket to the socket event
JoinSockToSockEvent(SOCK * sock,SOCK_EVENT * event)11507 void JoinSockToSockEvent(SOCK *sock, SOCK_EVENT *event)
11508 {
11509 // Validate arguments
11510 if (sock == NULL || event == NULL)
11511 {
11512 return;
11513 }
11514
11515 if (sock->Type == SOCK_INPROC)
11516 {
11517 // Set the SockEvent on the receiver TUBE for in-process type socket
11518 SetTubeSockEvent(sock->RecvTube, event);
11519 return;
11520 }
11521
11522 if (sock->BulkRecvTube != NULL)
11523 {
11524 // Set the SockEvent on the receiver TUBE in case of R-UDP socket
11525 SetTubeSockEvent(sock->BulkRecvTube, event);
11526 }
11527
11528 #ifdef OS_WIN32
11529 Win32JoinSockToSockEvent(sock, event);
11530 #else
11531 UnixJoinSockToSockEvent(sock, event);
11532 #endif // OS_WIN32
11533 }
11534
11535 // New special cancel object
NewCancelSpecial(void * hEvent)11536 CANCEL *NewCancelSpecial(void *hEvent)
11537 {
11538 CANCEL *c;
11539 // Validate arguments
11540 if (hEvent == NULL)
11541 {
11542 return NULL;
11543 }
11544
11545 c = ZeroMalloc(sizeof(CANCEL));
11546 c->ref = NewRef();
11547 c->SpecialFlag = true;
11548
11549 #ifdef OS_WIN32
11550 c->hEvent = (HANDLE)hEvent;
11551 #else // OS_WIN32
11552 c->pipe_read = (int)hEvent;
11553 c->pipe_write = -1;
11554 #endif // OS_WIN32
11555
11556 return c;
11557 }
11558
11559 // Creating a cancel object
NewCancel()11560 CANCEL *NewCancel()
11561 {
11562 CANCEL *c = NULL;
11563 #ifdef OS_WIN32
11564 c = Win32NewCancel();
11565 #else
11566 c = UnixNewCancel();
11567 #endif // OS_WIN32
11568 return c;
11569 }
11570
11571 // Release of the cancel object
ReleaseCancel(CANCEL * c)11572 void ReleaseCancel(CANCEL *c)
11573 {
11574 // Validate arguments
11575 if (c == NULL)
11576 {
11577 return;
11578 }
11579
11580 if (Release(c->ref) == 0)
11581 {
11582 CleanupCancel(c);
11583 }
11584 }
11585
11586 // Clean up of the cancel object
CleanupCancel(CANCEL * c)11587 void CleanupCancel(CANCEL *c)
11588 {
11589 #ifdef OS_WIN32
11590 Win32CleanupCancel(c);
11591 #else
11592 UnixCleanupCancel(c);
11593 #endif
11594 }
11595
11596 // Cancellation triggered
Cancel(CANCEL * c)11597 void Cancel(CANCEL *c)
11598 {
11599 #ifdef OS_WIN32
11600 Win32Cancel(c);
11601 #else
11602 UnixCancel(c);
11603 #endif
11604 }
11605
11606 // Calculate the optimal route from the specified routing table
GetBestRouteEntryFromRouteTable(ROUTE_TABLE * table,IP * ip)11607 ROUTE_ENTRY *GetBestRouteEntryFromRouteTable(ROUTE_TABLE *table, IP *ip)
11608 {
11609 return GetBestRouteEntryFromRouteTableEx(table, ip, 0);
11610 }
GetBestRouteEntryFromRouteTableEx(ROUTE_TABLE * table,IP * ip,UINT exclude_if_id)11611 ROUTE_ENTRY *GetBestRouteEntryFromRouteTableEx(ROUTE_TABLE *table, IP *ip, UINT exclude_if_id)
11612 {
11613 UINT i;
11614 ROUTE_ENTRY *ret = NULL;
11615 ROUTE_ENTRY *tmp = NULL;
11616 UINT64 min_score = 0;
11617 // Validate arguments
11618 if (ip == NULL || table == NULL)
11619 {
11620 return NULL;
11621 }
11622
11623 if (IsIP6(ip))
11624 {
11625 // IPv6 is not supported
11626 return NULL;
11627 }
11628
11629 // Select routing table entry by following rule
11630 // 1. Largest subnet mask
11631 // 2. Smallest metric value
11632 for (i = 0;i < table->NumEntry;i++)
11633 {
11634 ROUTE_ENTRY *e = table->Entry[i];
11635 UINT dest, net, mask;
11636
11637 dest = IPToUINT(ip);
11638 net = IPToUINT(&e->DestIP);
11639 mask = IPToUINT(&e->DestMask);
11640
11641 if (exclude_if_id != 0)
11642 {
11643 if (e->InterfaceID == exclude_if_id)
11644 {
11645 continue;
11646 }
11647 }
11648
11649 // Mask test
11650 if ((dest & mask) == (net & mask))
11651 {
11652 // Calculate the score
11653 UINT score_high32 = mask;
11654 UINT score_low32 = 0xFFFFFFFF - e->Metric;
11655 UINT64 score64 = (UINT64)score_high32 * (UINT64)0x80000000 * (UINT64)2 + (UINT64)score_low32;
11656 if (score64 == 0)
11657 {
11658 score64 = 1;
11659 }
11660
11661 e->InnerScore = score64;
11662 }
11663 }
11664
11665 tmp = NULL;
11666
11667 // Search for the item with maximum score
11668 for (i = 0;i < table->NumEntry;i++)
11669 {
11670 ROUTE_ENTRY *e = table->Entry[i];
11671
11672 if (e->InnerScore != 0)
11673 {
11674 if (e->InnerScore >= min_score)
11675 {
11676 tmp = e;
11677 min_score = e->InnerScore;
11678 }
11679 }
11680 }
11681
11682 if (tmp != NULL)
11683 {
11684 UINT dest, gateway, mask;
11685
11686 // Generate an entry
11687 ret = ZeroMallocFast(sizeof(ROUTE_ENTRY));
11688
11689 Copy(&ret->DestIP, ip, sizeof(IP));
11690 ret->DestMask.addr[0] = 255;
11691 ret->DestMask.addr[1] = 255;
11692 ret->DestMask.addr[2] = 255;
11693 ret->DestMask.addr[3] = 255;
11694 Copy(&ret->GatewayIP, &tmp->GatewayIP, sizeof(IP));
11695 ret->InterfaceID = tmp->InterfaceID;
11696 ret->LocalRouting = tmp->LocalRouting;
11697 ret->OldIfMetric = tmp->Metric;
11698 ret->Metric = 1;
11699 ret->PPPConnection = tmp->PPPConnection;
11700
11701 // Calculation related to routing control
11702 dest = IPToUINT(&tmp->DestIP);
11703 gateway = IPToUINT(&tmp->GatewayIP);
11704 mask = IPToUINT(&tmp->DestMask);
11705 if ((dest & mask) == (gateway & mask))
11706 {
11707 #ifdef OS_WIN32
11708 if (MsIsVista() == false)
11709 {
11710 // Adjust for Windows
11711 ret->PPPConnection = true;
11712 }
11713 #endif // OS_WIN32
11714 }
11715 }
11716
11717 return ret;
11718 }
11719
11720 // Release the routing entry
FreeRouteEntry(ROUTE_ENTRY * e)11721 void FreeRouteEntry(ROUTE_ENTRY *e)
11722 {
11723 // Validate arguments
11724 if (e == NULL)
11725 {
11726 return;
11727 }
11728
11729 Free(e);
11730 }
11731
11732 // Get the best route entry by analyzing the current routing table
GetBestRouteEntry(IP * ip)11733 ROUTE_ENTRY *GetBestRouteEntry(IP *ip)
11734 {
11735 return GetBestRouteEntryEx(ip, 0);
11736 }
GetBestRouteEntryEx(IP * ip,UINT exclude_if_id)11737 ROUTE_ENTRY *GetBestRouteEntryEx(IP *ip, UINT exclude_if_id)
11738 {
11739 ROUTE_TABLE *table;
11740 ROUTE_ENTRY *e = NULL;
11741 // Validate arguments
11742 if (ip == NULL)
11743 {
11744 return NULL;
11745 }
11746
11747 table = GetRouteTable();
11748 if (table == NULL)
11749 {
11750 return NULL;
11751 }
11752
11753 e = GetBestRouteEntryFromRouteTableEx(table, ip, exclude_if_id);
11754 FreeRouteTable(table);
11755
11756 return e;
11757 }
11758
11759 // Get the interface ID of the virtual LAN card
GetVLanInterfaceID(char * tag_name)11760 UINT GetVLanInterfaceID(char *tag_name)
11761 {
11762 UINT ret = 0;
11763 #ifdef OS_WIN32
11764 ret = Win32GetVLanInterfaceID(tag_name);
11765 #else // OS_WIN32
11766 ret = UnixGetVLanInterfaceID(tag_name);
11767 #endif // OS_WIN32
11768 return ret;
11769 }
11770
11771 // Release of enumeration variable of virtual LAN card
FreeEnumVLan(char ** s)11772 void FreeEnumVLan(char **s)
11773 {
11774 char *a;
11775 UINT i;
11776 // Validate arguments
11777 if (s == NULL)
11778 {
11779 return;
11780 }
11781
11782 i = 0;
11783 while (true)
11784 {
11785 a = s[i++];
11786 if (a == NULL)
11787 {
11788 break;
11789 }
11790 Free(a);
11791 }
11792
11793 Free(s);
11794 }
11795
11796 // Enumeration of virtual LAN cards
EnumVLan(char * tag_name)11797 char **EnumVLan(char *tag_name)
11798 {
11799 char **ret = NULL;
11800 #ifdef OS_WIN32
11801 ret = Win32EnumVLan(tag_name);
11802 #else // OS_WIN32
11803 ret = UnixEnumVLan(tag_name);
11804 #endif // OS_WIN32
11805 return ret;
11806 }
11807
11808 // Display the routing table
DebugPrintRouteTable(ROUTE_TABLE * r)11809 void DebugPrintRouteTable(ROUTE_TABLE *r)
11810 {
11811 UINT i;
11812 // Validate arguments
11813 if (r == NULL)
11814 {
11815 return;
11816 }
11817
11818 if (IsDebug() == false)
11819 {
11820 return;
11821 }
11822
11823 Debug("---- Routing Table (%u Entries) ----\n", r->NumEntry);
11824
11825 for (i = 0;i < r->NumEntry;i++)
11826 {
11827 Debug(" ");
11828
11829 DebugPrintRoute(r->Entry[i]);
11830 }
11831
11832 Debug("------------------------------------\n");
11833 }
11834
11835 // Display the routing table entry
DebugPrintRoute(ROUTE_ENTRY * e)11836 void DebugPrintRoute(ROUTE_ENTRY *e)
11837 {
11838 char tmp[MAX_SIZE];
11839 // Validate arguments
11840 if (e == NULL)
11841 {
11842 return;
11843 }
11844
11845 if (IsDebug() == false)
11846 {
11847 return;
11848 }
11849
11850 RouteToStr(tmp, sizeof(tmp), e);
11851
11852 Debug("%s\n", tmp);
11853 }
11854
11855 // Convert the routing table entry to string
RouteToStr(char * str,UINT str_size,ROUTE_ENTRY * e)11856 void RouteToStr(char *str, UINT str_size, ROUTE_ENTRY *e)
11857 {
11858 char dest_ip[MAX_PATH];
11859 char dest_mask[MAX_PATH];
11860 char gateway_ip[MAX_PATH];
11861 // Validate arguments
11862 if (str == NULL || e == NULL)
11863 {
11864 return;
11865 }
11866
11867 IPToStr(dest_ip, sizeof(dest_ip), &e->DestIP);
11868 IPToStr(dest_mask, sizeof(dest_mask), &e->DestMask);
11869 IPToStr(gateway_ip, sizeof(gateway_ip), &e->GatewayIP);
11870
11871 Format(str, str_size, "%s/%s %s m=%u oif=%u if=%u lo=%u p=%u",
11872 dest_ip, dest_mask, gateway_ip,
11873 e->Metric, e->OldIfMetric, e->InterfaceID,
11874 e->LocalRouting, e->PPPConnection);
11875 }
11876
11877 // Delete the routing table
DeleteRouteEntry(ROUTE_ENTRY * e)11878 void DeleteRouteEntry(ROUTE_ENTRY *e)
11879 {
11880 Debug("DeleteRouteEntry();\n");
11881 #ifdef OS_WIN32
11882 Win32DeleteRouteEntry(e);
11883 #else // OS_WIN32
11884 UnixDeleteRouteEntry(e);
11885 #endif
11886 }
11887
11888 // Add to the routing table
AddRouteEntry(ROUTE_ENTRY * e)11889 bool AddRouteEntry(ROUTE_ENTRY *e)
11890 {
11891 bool dummy = false;
11892 return AddRouteEntryEx(e, &dummy);
11893 }
AddRouteEntryEx(ROUTE_ENTRY * e,bool * already_exists)11894 bool AddRouteEntryEx(ROUTE_ENTRY *e, bool *already_exists)
11895 {
11896 bool ret = false;
11897 Debug("AddRouteEntryEx();\n");
11898 #ifdef OS_WIN32
11899 ret = Win32AddRouteEntry(e, already_exists);
11900 #else // OS_WIN32
11901 ret = UnixAddRouteEntry(e, already_exists);
11902 #endif
11903 return ret;
11904 }
11905
11906 // Get the routing table
GetRouteTable()11907 ROUTE_TABLE *GetRouteTable()
11908 {
11909 ROUTE_TABLE *t = NULL;
11910 UINT i;
11911 BUF *buf = NewBuf();
11912 UCHAR hash[MD5_SIZE];
11913
11914 #ifdef OS_WIN32
11915 t = Win32GetRouteTable();
11916 #else //OS_WIN32
11917 t = UnixGetRouteTable();
11918 #endif // OS_WIN32
11919
11920 WriteBuf(buf, &t->NumEntry, sizeof(t->NumEntry));
11921
11922 for (i = 0;i < t->NumEntry;i++)
11923 {
11924 ROUTE_ENTRY *e = t->Entry[i];
11925
11926 WriteBuf(buf, e, sizeof(ROUTE_ENTRY));
11927 }
11928
11929 Hash(hash, buf->Buf, buf->Size, false);
11930
11931 FreeBuf(buf);
11932
11933 Copy(&t->HashedValue, hash, sizeof(t->HashedValue));
11934
11935 return t;
11936 }
11937
11938 // Release of the routing table
FreeRouteTable(ROUTE_TABLE * t)11939 void FreeRouteTable(ROUTE_TABLE *t)
11940 {
11941 UINT i;
11942 // Validate arguments
11943 if (t == NULL)
11944 {
11945 return;
11946 }
11947
11948 for (i = 0;i < t->NumEntry;i++)
11949 {
11950 Free(t->Entry[i]);
11951 }
11952 Free(t->Entry);
11953 Free(t);
11954 }
11955
11956 // UDP receiving
RecvFrom(SOCK * sock,IP * src_addr,UINT * src_port,void * data,UINT size)11957 UINT RecvFrom(SOCK *sock, IP *src_addr, UINT *src_port, void *data, UINT size)
11958 {
11959 SOCKET s;
11960 int ret, sz;
11961 struct sockaddr_in addr;
11962 // Validate arguments
11963 if (sock != NULL)
11964 {
11965 sock->IgnoreRecvErr = false;
11966 }
11967 if (sock == NULL || src_addr == NULL || src_port == NULL || data == NULL)
11968 {
11969 return false;
11970 }
11971 if (sock->Type != SOCK_UDP || sock->socket == INVALID_SOCKET)
11972 {
11973 return false;
11974 }
11975 if (size == 0)
11976 {
11977 return false;
11978 }
11979
11980 if (sock->IPv6)
11981 {
11982 return RecvFrom6(sock, src_addr, src_port, data, size);
11983 }
11984
11985 s = sock->socket;
11986
11987 sz = sizeof(addr);
11988 ret = recvfrom(s, data, size, 0, (struct sockaddr *)&addr, (int *)&sz);
11989 if (ret > 0)
11990 {
11991 InAddrToIP(src_addr, &addr.sin_addr);
11992 *src_port = (UINT)ntohs(addr.sin_port);
11993 if (sock->IsRawSocket)
11994 {
11995 *src_port = sock->LocalPort;
11996 /*
11997 {
11998 char tmp[MAX_SIZE];
11999
12000 IPToStr(tmp, sizeof(tmp), &sock->LocalIP);
12001 Debug("Raw: %u from %s\n", sock->LocalPort, tmp);
12002 }*/
12003 }
12004
12005 Lock(sock->lock);
12006 {
12007 sock->RecvNum++;
12008 sock->RecvSize += (UINT64)ret;
12009 }
12010 Unlock(sock->lock);
12011
12012 // Debug("UDP RecvFrom: %u\n", ret);
12013
12014 return (UINT)ret;
12015 }
12016 else
12017 {
12018 sock->IgnoreRecvErr = false;
12019
12020 #ifdef OS_WIN32
12021 if (WSAGetLastError() == WSAECONNRESET || WSAGetLastError() == WSAENETRESET || WSAGetLastError() == WSAEMSGSIZE || WSAGetLastError() == WSAENETUNREACH ||
12022 WSAGetLastError() == WSAENOBUFS || WSAGetLastError() == WSAEHOSTUNREACH || WSAGetLastError() == WSAEUSERS || WSAGetLastError() == WSAEADDRNOTAVAIL || WSAGetLastError() == WSAEADDRNOTAVAIL)
12023 {
12024 sock->IgnoreRecvErr = true;
12025 }
12026 else if (WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINPROGRESS)
12027 {
12028 return SOCK_LATER;
12029 }
12030 else
12031 {
12032 UINT e = WSAGetLastError();
12033 // Debug("RecvFrom Error: %u\n", e);
12034 }
12035 #else // OS_WIN32
12036 if (errno == ECONNREFUSED || errno == ECONNRESET || errno == EMSGSIZE || errno == ENOBUFS || errno == ENOMEM || errno == EINTR)
12037 {
12038 sock->IgnoreRecvErr = true;
12039 }
12040 else if (errno == EAGAIN)
12041 {
12042 return SOCK_LATER;
12043 }
12044 #endif // OS_WIN32
12045 return 0;
12046 }
12047 }
RecvFrom6(SOCK * sock,IP * src_addr,UINT * src_port,void * data,UINT size)12048 UINT RecvFrom6(SOCK *sock, IP *src_addr, UINT *src_port, void *data, UINT size)
12049 {
12050 SOCKET s;
12051 int ret, sz;
12052 struct sockaddr_in6 addr;
12053 // Validate arguments
12054 if (sock != NULL)
12055 {
12056 sock->IgnoreRecvErr = false;
12057 }
12058 if (sock == NULL || src_addr == NULL || src_port == NULL || data == NULL)
12059 {
12060 return false;
12061 }
12062 if (sock->Type != SOCK_UDP || sock->socket == INVALID_SOCKET)
12063 {
12064 return false;
12065 }
12066 if (size == 0)
12067 {
12068 return false;
12069 }
12070
12071 s = sock->socket;
12072
12073 sz = sizeof(addr);
12074 ret = recvfrom(s, data, size, 0, (struct sockaddr *)&addr, (int *)&sz);
12075 if (ret > 0)
12076 {
12077 InAddrToIP6(src_addr, &addr.sin6_addr);
12078 src_addr->ipv6_scope_id = addr.sin6_scope_id;
12079 *src_port = (UINT)ntohs(addr.sin6_port);
12080 if (sock->IsRawSocket)
12081 {
12082 *src_port = sock->LocalPort;
12083 }
12084
12085 Lock(sock->lock);
12086 {
12087 sock->RecvNum++;
12088 sock->RecvSize += (UINT64)ret;
12089 }
12090 Unlock(sock->lock);
12091
12092 // Debug("UDP RecvFrom: %u\n", ret);
12093
12094 return (UINT)ret;
12095 }
12096 else
12097 {
12098 sock->IgnoreRecvErr = false;
12099
12100 #ifdef OS_WIN32
12101 if (WSAGetLastError() == WSAECONNRESET || WSAGetLastError() == WSAENETRESET || WSAGetLastError() == WSAEMSGSIZE || WSAGetLastError() == WSAENETUNREACH ||
12102 WSAGetLastError() == WSAENOBUFS || WSAGetLastError() == WSAEHOSTUNREACH || WSAGetLastError() == WSAEUSERS || WSAGetLastError() == WSAEADDRNOTAVAIL || WSAGetLastError() == WSAEADDRNOTAVAIL)
12103 {
12104 sock->IgnoreRecvErr = true;
12105 }
12106 else if (WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINPROGRESS)
12107 {
12108 return SOCK_LATER;
12109 }
12110 else
12111 {
12112 UINT e = WSAGetLastError();
12113 // Debug("RecvFrom Error: %u\n", e);
12114 }
12115 #else // OS_WIN32
12116 if (errno == ECONNREFUSED || errno == ECONNRESET || errno == EMSGSIZE || errno == ENOBUFS || errno == ENOMEM || errno == EINTR)
12117 {
12118 sock->IgnoreRecvErr = true;
12119 }
12120 else if (errno == EAGAIN)
12121 {
12122 return SOCK_LATER;
12123 }
12124 #endif // OS_WIN32
12125 return 0;
12126 }
12127 }
12128
12129 // Lock the OpenSSL
LockOpenSSL()12130 void LockOpenSSL()
12131 {
12132 Lock(openssl_lock);
12133 }
12134
12135 // Unlock the OpenSSL
UnlockOpenSSL()12136 void UnlockOpenSSL()
12137 {
12138 Unlock(openssl_lock);
12139 }
12140
12141 // UDP transmission
SendTo(SOCK * sock,IP * dest_addr,UINT dest_port,void * data,UINT size)12142 UINT SendTo(SOCK *sock, IP *dest_addr, UINT dest_port, void *data, UINT size)
12143 {
12144 return SendToEx(sock, dest_addr, dest_port, data, size, false);
12145 }
SendToEx(SOCK * sock,IP * dest_addr,UINT dest_port,void * data,UINT size,bool broadcast)12146 UINT SendToEx(SOCK *sock, IP *dest_addr, UINT dest_port, void *data, UINT size, bool broadcast)
12147 {
12148 SOCKET s;
12149 int ret;
12150 struct sockaddr_in addr;
12151 // Validate arguments
12152 if (sock != NULL)
12153 {
12154 sock->IgnoreSendErr = false;
12155 }
12156 if (sock == NULL || dest_addr == NULL || (sock->IsRawSocket == false && dest_port == 0) || data == NULL)
12157 {
12158 return 0;
12159 }
12160 if (dest_port >= 65536 && sock->IsRawSocket == false)
12161 {
12162 return 0;
12163 }
12164 if (sock->Type != SOCK_UDP || sock->socket == INVALID_SOCKET)
12165 {
12166 return 0;
12167 }
12168 if (size == 0)
12169 {
12170 return 0;
12171 }
12172
12173 if (sock->IPv6)
12174 {
12175 return SendTo6Ex(sock, dest_addr, dest_port, data, size, broadcast);
12176 }
12177
12178 if (IsIP4(dest_addr) == false)
12179 {
12180 return 0;
12181 }
12182
12183 s = sock->socket;
12184 Zero(&addr, sizeof(addr));
12185 addr.sin_family = AF_INET;
12186 if (sock->IsRawSocket == false)
12187 {
12188 addr.sin_port = htons((USHORT)dest_port);
12189 }
12190 IPToInAddr(&addr.sin_addr, dest_addr);
12191
12192 if ((dest_addr->addr[0] == 255 && dest_addr->addr[1] == 255 &&
12193 dest_addr->addr[2] == 255 && dest_addr->addr[3] == 255) ||
12194 (dest_addr->addr[0] >= 224 && dest_addr->addr[0] <= 239)
12195 || broadcast)
12196 {
12197 if (sock->UdpBroadcast == false)
12198 {
12199 bool yes = true;
12200
12201 sock->UdpBroadcast = true;
12202
12203 setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char *)&yes, sizeof(yes));
12204 }
12205 }
12206
12207 ret = sendto(s, data, size, 0, (struct sockaddr *)&addr, sizeof(addr));
12208 if (ret != (int)size)
12209 {
12210 sock->IgnoreSendErr = false;
12211
12212 #ifdef OS_WIN32
12213 if (WSAGetLastError() == WSAECONNRESET || WSAGetLastError() == WSAENETRESET || WSAGetLastError() == WSAEMSGSIZE || WSAGetLastError() == WSAENETUNREACH ||
12214 WSAGetLastError() == WSAENOBUFS || WSAGetLastError() == WSAEHOSTUNREACH || WSAGetLastError() == WSAEUSERS || WSAGetLastError() == WSAEINVAL || WSAGetLastError() == WSAEADDRNOTAVAIL)
12215 {
12216 sock->IgnoreSendErr = true;
12217 }
12218 else if (WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINPROGRESS)
12219 {
12220 return SOCK_LATER;
12221 }
12222 else
12223 {
12224 UINT e = WSAGetLastError();
12225 Debug("SendTo Error; %u\n", e);
12226 }
12227 #else // OS_WIN32
12228 if (errno == ECONNREFUSED || errno == ECONNRESET || errno == EMSGSIZE || errno == ENOBUFS || errno == ENOMEM || errno == EINTR)
12229 {
12230 sock->IgnoreSendErr = true;
12231 }
12232 else if (errno == EAGAIN)
12233 {
12234 return SOCK_LATER;
12235 }
12236 #endif // OS_WIN32
12237 return 0;
12238 }
12239
12240 Lock(sock->lock);
12241 {
12242 sock->SendSize += (UINT64)size;
12243 sock->SendNum++;
12244 }
12245 Unlock(sock->lock);
12246
12247 return ret;
12248 }
SendTo6(SOCK * sock,IP * dest_addr,UINT dest_port,void * data,UINT size)12249 UINT SendTo6(SOCK *sock, IP *dest_addr, UINT dest_port, void *data, UINT size)
12250 {
12251 return SendTo6Ex(sock, dest_addr, dest_port, data, size, false);
12252 }
SendTo6Ex(SOCK * sock,IP * dest_addr,UINT dest_port,void * data,UINT size,bool broadcast)12253 UINT SendTo6Ex(SOCK *sock, IP *dest_addr, UINT dest_port, void *data, UINT size, bool broadcast)
12254 {
12255 SOCKET s;
12256 int ret;
12257 struct sockaddr_in6 addr;
12258 UINT type;
12259 // Validate arguments
12260 if (sock != NULL)
12261 {
12262 sock->IgnoreSendErr = false;
12263 }
12264 if (sock == NULL || dest_addr == NULL || (sock->IsRawSocket == false && dest_port == 0) || data == NULL)
12265 {
12266 return 0;
12267 }
12268 if (dest_port >= 65536 && sock->IsRawSocket == false)
12269 {
12270 return 0;
12271 }
12272 if (sock->Type != SOCK_UDP || sock->socket == INVALID_SOCKET)
12273 {
12274 return 0;
12275 }
12276 if (size == 0)
12277 {
12278 return 0;
12279 }
12280
12281 if (IsIP6(dest_addr) == false)
12282 {
12283 return 0;
12284 }
12285
12286 s = sock->socket;
12287 Zero(&addr, sizeof(addr));
12288 addr.sin6_family = AF_INET6;
12289 if (sock->IsRawSocket == false)
12290 {
12291 addr.sin6_port = htons((USHORT)dest_port);
12292 }
12293 IPToInAddr6(&addr.sin6_addr, dest_addr);
12294 addr.sin6_scope_id = dest_addr->ipv6_scope_id;
12295
12296 type = GetIPAddrType6(dest_addr);
12297
12298 if ((type & IPV6_ADDR_MULTICAST) || broadcast)
12299 {
12300 if (sock->UdpBroadcast == false)
12301 {
12302 bool yes = true;
12303
12304 sock->UdpBroadcast = true;
12305
12306 setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char *)&yes, sizeof(yes));
12307 }
12308 }
12309
12310 ret = sendto(s, data, size, 0, (struct sockaddr *)&addr, sizeof(addr));
12311 if (ret != (int)size)
12312 {
12313 sock->IgnoreSendErr = false;
12314
12315 #ifdef OS_WIN32
12316 if (WSAGetLastError() == WSAECONNRESET || WSAGetLastError() == WSAENETRESET || WSAGetLastError() == WSAEMSGSIZE || WSAGetLastError() == WSAENETUNREACH ||
12317 WSAGetLastError() == WSAENOBUFS || WSAGetLastError() == WSAEHOSTUNREACH || WSAGetLastError() == WSAEUSERS || WSAGetLastError() == WSAEINVAL || WSAGetLastError() == WSAEADDRNOTAVAIL)
12318 {
12319 sock->IgnoreSendErr = true;
12320 }
12321 else if (WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINPROGRESS)
12322 {
12323 return SOCK_LATER;
12324 }
12325 else
12326 {
12327 UINT e = WSAGetLastError();
12328 }
12329 #else // OS_WIN32
12330 if (errno == ECONNREFUSED || errno == ECONNRESET || errno == EMSGSIZE || errno == ENOBUFS || errno == ENOMEM || errno == EINTR)
12331 {
12332 sock->IgnoreSendErr = true;
12333 }
12334 else if (errno == EAGAIN)
12335 {
12336 return SOCK_LATER;
12337 }
12338 #endif // OS_WIN32
12339 return 0;
12340 }
12341
12342 Lock(sock->lock);
12343 {
12344 sock->SendSize += (UINT64)size;
12345 sock->SendNum++;
12346 }
12347 Unlock(sock->lock);
12348
12349 return ret;
12350 }
12351
12352 // Disable the UDP checksum
DisableUDPChecksum(SOCK * s)12353 void DisableUDPChecksum(SOCK *s)
12354 {
12355 bool true_flag = true;
12356 // Validate arguments
12357 if (s == NULL || s->Type != SOCK_UDP)
12358 {
12359 return;
12360 }
12361
12362 if (s->socket != INVALID_SOCKET)
12363 {
12364 if (s->IPv6 == false)
12365 {
12366 #ifdef UDP_NOCHECKSUM
12367 setsockopt(s->socket, IPPROTO_UDP, UDP_NOCHECKSUM, (char *)&true_flag, sizeof(bool));
12368 #endif // UDP_NOCHECKSUM
12369 }
12370 }
12371 }
12372
12373 // Set the socket to asynchronous mode
InitAsyncSocket(SOCK * sock)12374 void InitAsyncSocket(SOCK *sock)
12375 {
12376 #ifdef OS_WIN32
12377 Win32InitAsyncSocket(sock);
12378 #else // OS_WIN32
12379 UnixInitAsyncSocket(sock);
12380 #endif // OS_WIN32
12381 }
12382
12383 // Get a new available UDP port number
GetNewAvailableUdpPortRand()12384 UINT GetNewAvailableUdpPortRand()
12385 {
12386 UINT num_retry = 8;
12387 UINT i;
12388 UINT ret = 0;
12389 UCHAR seed[SHA1_SIZE];
12390
12391 Rand(seed, sizeof(seed));
12392
12393 for (i = 0;i < num_retry;i++)
12394 {
12395 SOCK *s = NewUDPEx2Rand(false, NULL, seed, sizeof(seed), RAND_UDP_PORT_DEFAULT_NUM_RETRY);
12396
12397 if (s != NULL)
12398 {
12399 ret = s->LocalPort;
12400
12401 Disconnect(s);
12402 ReleaseSock(s);
12403 }
12404
12405 if (ret != 0)
12406 {
12407 break;
12408 }
12409 }
12410
12411 return ret;
12412 }
12413
12414 // Open a UDP port (port number is random, but determine the randomness in the seed)
NewUDPEx2Rand(bool ipv6,IP * ip,void * rand_seed,UINT rand_seed_size,UINT num_retry)12415 SOCK *NewUDPEx2Rand(bool ipv6, IP *ip, void *rand_seed, UINT rand_seed_size, UINT num_retry)
12416 {
12417 UINT i;
12418 // Validate arguments
12419 if (rand_seed == NULL || rand_seed_size == 0)
12420 {
12421 return NULL;
12422 }
12423 if (num_retry == 0)
12424 {
12425 num_retry = RAND_UDP_PORT_DEFAULT_NUM_RETRY;
12426 }
12427
12428 for (i = 0; i < (num_retry + 1);i++)
12429 {
12430 BUF *buf = NewBuf();
12431 UCHAR hash[SHA1_SIZE];
12432 UINT port = 0;
12433 SOCK *s;
12434
12435 WriteBuf(buf, rand_seed, rand_seed_size);
12436 WriteBufInt(buf, i);
12437
12438 HashSha1(hash, buf->Buf, buf->Size);
12439
12440 FreeBuf(buf);
12441
12442 port = READ_UINT(hash);
12443
12444 port = RAND_UDP_PORT_START + (port % (RAND_UDP_PORT_END - RAND_UDP_PORT_START));
12445
12446 s = NewUDPEx2(port, ipv6, ip);
12447
12448 if (s != NULL)
12449 {
12450 return s;
12451 }
12452 }
12453
12454 return NewUDPEx2(0, ipv6, ip);
12455 }
12456
12457 // Generate a random port number (based on the EXE path and machine key)
NewRandPortByMachineAndExePath(UINT start_port,UINT end_port,UINT additional_int)12458 UINT NewRandPortByMachineAndExePath(UINT start_port, UINT end_port, UINT additional_int)
12459 {
12460 BUF *b;
12461 char machine_name[MAX_SIZE];
12462 wchar_t exe_path[MAX_PATH];
12463 char *product_id = NULL;
12464 UCHAR hash[SHA1_SIZE];
12465
12466 #ifdef OS_WIN32
12467 product_id = MsRegReadStr(REG_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "ProductId");
12468 if (product_id == NULL)
12469 {
12470 product_id = MsRegReadStr(REG_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion", "ProductId");
12471 }
12472 #endif // OS_WIN32
12473
12474 b = NewBuf();
12475
12476 GetMachineHostName(machine_name, sizeof(machine_name));
12477 Trim(machine_name);
12478 StrUpper(machine_name);
12479
12480 GetExeNameW(exe_path, sizeof(exe_path));
12481 UniTrim(exe_path);
12482 UniStrUpper(exe_path);
12483
12484 WriteBuf(b, machine_name, StrSize(machine_name));
12485 WriteBuf(b, exe_path, UniStrSize(exe_path));
12486 WriteBuf(b, product_id, StrSize(product_id));
12487 WriteBufInt(b, additional_int);
12488
12489 HashSha1(hash, b->Buf, b->Size);
12490
12491 FreeBuf(b);
12492
12493 Free(product_id);
12494
12495 return (READ_UINT(hash) % (end_port - start_port)) + start_port;
12496 }
12497
12498 // Open the UDP port (based on the EXE path and machine key)
NewUDPEx2RandMachineAndExePath(bool ipv6,IP * ip,UINT num_retry,UCHAR rand_port_id)12499 SOCK *NewUDPEx2RandMachineAndExePath(bool ipv6, IP *ip, UINT num_retry, UCHAR rand_port_id)
12500 {
12501 BUF *b;
12502 char machine_name[MAX_SIZE];
12503 wchar_t exe_path[MAX_PATH];
12504 char *product_id = NULL;
12505 UCHAR hash[SHA1_SIZE];
12506
12507 #ifdef OS_WIN32
12508 product_id = MsRegReadStr(REG_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "ProductId");
12509 if (product_id == NULL)
12510 {
12511 product_id = MsRegReadStr(REG_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion", "ProductId");
12512 }
12513 #endif // OS_WIN32
12514
12515 b = NewBuf();
12516
12517 GetMachineHostName(machine_name, sizeof(machine_name));
12518 Trim(machine_name);
12519 StrUpper(machine_name);
12520
12521 GetExeNameW(exe_path, sizeof(exe_path));
12522 UniTrim(exe_path);
12523 UniStrUpper(exe_path);
12524
12525 WriteBuf(b, machine_name, StrSize(machine_name));
12526 WriteBuf(b, exe_path, UniStrSize(exe_path));
12527 WriteBuf(b, product_id, StrSize(product_id));
12528 WriteBufChar(b, rand_port_id);
12529 //WriteBufInt(b, GetHostIPAddressHash32());
12530
12531 HashSha1(hash, b->Buf, b->Size);
12532
12533 FreeBuf(b);
12534
12535 Free(product_id);
12536
12537 return NewUDPEx2Rand(ipv6, ip, hash, sizeof(hash), num_retry);
12538 }
12539
12540 // Set the DF bit of the socket
ClearSockDfBit(SOCK * s)12541 void ClearSockDfBit(SOCK *s)
12542 {
12543 #ifdef IP_PMTUDISC_DONT
12544 #ifdef IP_MTU_DISCOVER
12545 UINT value = IP_PMTUDISC_DONT;
12546 if (s == NULL)
12547 {
12548 return;
12549 }
12550
12551 setsockopt(s->socket, IPPROTO_IP, IP_MTU_DISCOVER, (char *)&value, sizeof(value));
12552 #endif // IP_MTU_DISCOVER
12553 #endif // IP_PMTUDISC_DONT
12554 }
12555
12556 // Set the header-include option
SetRawSockHeaderIncludeOption(SOCK * s,bool enable)12557 void SetRawSockHeaderIncludeOption(SOCK *s, bool enable)
12558 {
12559 UINT value = BOOL_TO_INT(enable);
12560 if (s == NULL || s->IsRawSocket == false)
12561 {
12562 return;
12563 }
12564
12565 setsockopt(s->socket, IPPROTO_IP, IP_HDRINCL, (char *)&value, sizeof(value));
12566
12567 s->RawIP_HeaderIncludeFlag = enable;
12568 }
12569
12570 // Create and initialize the UDP socket
12571 // If port is specified as 0, system assigns a certain port.
NewUDP(UINT port)12572 SOCK *NewUDP(UINT port)
12573 {
12574 return NewUDPEx(port, false);
12575 }
NewUDPEx(UINT port,bool ipv6)12576 SOCK *NewUDPEx(UINT port, bool ipv6)
12577 {
12578 return NewUDPEx2(port, ipv6, NULL);
12579 }
NewUDPEx2(UINT port,bool ipv6,IP * ip)12580 SOCK *NewUDPEx2(UINT port, bool ipv6, IP *ip)
12581 {
12582 if (ipv6 == false)
12583 {
12584 return NewUDP4(port, ip);
12585 }
12586 else
12587 {
12588 return NewUDP6(port, ip);
12589 }
12590 }
NewUDPEx3(UINT port,IP * ip)12591 SOCK *NewUDPEx3(UINT port, IP *ip)
12592 {
12593 // Validate arguments
12594 if (ip == NULL)
12595 {
12596 return NewUDPEx2(port, false, NULL);
12597 }
12598
12599 if (IsIP4(ip))
12600 {
12601 return NewUDPEx2(port, false, ip);
12602 }
12603 else
12604 {
12605 return NewUDPEx2(port, true, ip);
12606 }
12607 }
NewUDP4(UINT port,IP * ip)12608 SOCK *NewUDP4(UINT port, IP *ip)
12609 {
12610 SOCK *sock;
12611 SOCKET s;
12612 struct sockaddr_in addr;
12613 // Validate arguments
12614 if (ip != NULL && IsIP4(ip) == false)
12615 {
12616 return NULL;
12617 }
12618
12619 if (IS_SPECIAL_PORT(port) == false)
12620 {
12621 s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
12622 }
12623 else
12624 {
12625 s = socket(AF_INET, SOCK_RAW, GET_SPECIAL_PORT(port));
12626 }
12627 if (s == INVALID_SOCKET)
12628 {
12629 return NULL;
12630 }
12631
12632 Zero(&addr, sizeof(addr));
12633 addr.sin_family = AF_INET;
12634
12635 if (ip == NULL || IsZeroIP(ip))
12636 {
12637 addr.sin_addr.s_addr = htonl(INADDR_ANY);
12638 }
12639 else
12640 {
12641 IPToInAddr(&addr.sin_addr, ip);
12642 }
12643
12644 if (port == 0 || IS_SPECIAL_PORT(port))
12645 {
12646 addr.sin_port = 0;
12647 }
12648 else
12649 {
12650 addr.sin_port = htons((USHORT)port);
12651 }
12652
12653 if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) != 0)
12654 {
12655 // Failure
12656 if (port != 0)
12657 {
12658 bool true_flag = true;
12659 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&true_flag, sizeof(bool));
12660 if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) != 0)
12661 {
12662 bool false_flag = false;
12663 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&false_flag, sizeof(bool));
12664 #ifdef SO_EXCLUSIVEADDRUSE
12665 setsockopt(s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char *)&true_flag, sizeof(bool));
12666 #endif // SO_EXCLUSIVEADDRUSE
12667 if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) != 0)
12668 {
12669 closesocket(s);
12670 return NULL;
12671 }
12672 }
12673 }
12674 else
12675 {
12676 closesocket(s);
12677 return NULL;
12678 }
12679 }
12680
12681 sock = NewSock();
12682
12683 sock->Type = SOCK_UDP;
12684 sock->Connected = false;
12685 sock->AsyncMode = false;
12686 sock->ServerMode = false;
12687 if (port != 0)
12688 {
12689 sock->ServerMode = true;
12690 }
12691
12692 sock->socket = s;
12693
12694 InitUdpSocketBufferSize((int)s);
12695
12696 if (IS_SPECIAL_PORT(port))
12697 {
12698 bool no = false;
12699 setsockopt(sock->socket, IPPROTO_IP, IP_HDRINCL, (char *)&no, sizeof(no));
12700
12701 sock->IsRawSocket = true;
12702 sock->RawSocketIPProtocol = GET_SPECIAL_PORT(port);
12703 }
12704
12705 QuerySocketInformation(sock);
12706
12707 return sock;
12708 }
NewUDP6(UINT port,IP * ip)12709 SOCK *NewUDP6(UINT port, IP *ip)
12710 {
12711 SOCK *sock;
12712 SOCKET s;
12713 struct sockaddr_in6 addr;
12714 // Validate arguments
12715 if (ip != NULL && IsIP6(ip) == false)
12716 {
12717 return NULL;
12718 }
12719
12720 if (IS_SPECIAL_PORT(port) == false)
12721 {
12722 s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
12723 }
12724 else
12725 {
12726 s = socket(AF_INET6, SOCK_RAW, GET_SPECIAL_PORT(port));
12727 }
12728 if (s == INVALID_SOCKET)
12729 {
12730 return NULL;
12731 }
12732
12733 Zero(&addr, sizeof(addr));
12734 addr.sin6_family = AF_INET6;
12735 if (port == 0)
12736 {
12737 addr.sin6_port = 0;
12738 }
12739 else
12740 {
12741 addr.sin6_port = htons((USHORT)port);
12742 }
12743
12744 if (ip != NULL && IsZeroIP(ip) == false)
12745 {
12746 IPToInAddr6(&addr.sin6_addr, ip);
12747 addr.sin6_scope_id = ip->ipv6_scope_id;
12748 }
12749
12750 if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) != 0)
12751 {
12752 // Failure
12753 if (port != 0)
12754 {
12755 bool true_flag = true;
12756 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&true_flag, sizeof(bool));
12757 if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) != 0)
12758 {
12759 bool false_flag = false;
12760 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&false_flag, sizeof(bool));
12761 #ifdef SO_EXCLUSIVEADDRUSE
12762 setsockopt(s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char *)&true_flag, sizeof(bool));
12763 #endif // SO_EXCLUSIVEADDRUSE
12764 if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) != 0)
12765 {
12766 closesocket(s);
12767 return NULL;
12768 }
12769 }
12770 }
12771 else
12772 {
12773 closesocket(s);
12774 return NULL;
12775 }
12776 }
12777
12778 sock = NewSock();
12779
12780 sock->Type = SOCK_UDP;
12781 sock->Connected = false;
12782 sock->AsyncMode = false;
12783 sock->ServerMode = false;
12784 sock->IPv6 = true;
12785 if (port != 0)
12786 {
12787 sock->ServerMode = true;
12788 }
12789
12790 sock->socket = s;
12791
12792 InitUdpSocketBufferSize(s);
12793
12794 if (IS_SPECIAL_PORT(port))
12795 {
12796 bool no = false;
12797 #ifdef IPV6_HDRINCL
12798 setsockopt(sock->socket, IPPROTO_IP, IPV6_HDRINCL, (char *)&no, sizeof(no));
12799 #endif // IPV6_HDRINCL
12800 setsockopt(sock->socket, IPPROTO_IP, IP_HDRINCL, (char *)&no, sizeof(no));
12801
12802 sock->IsRawSocket = true;
12803 sock->RawSocketIPProtocol = GET_SPECIAL_PORT(port);
12804 }
12805
12806 QuerySocketInformation(sock);
12807
12808 return sock;
12809 }
12810
12811 // Select function
Select(SOCKSET * set,UINT timeout,CANCEL * c1,CANCEL * c2)12812 void Select(SOCKSET *set, UINT timeout, CANCEL *c1, CANCEL *c2)
12813 {
12814 #ifdef OS_WIN32
12815 Win32Select(set, timeout, c1, c2);
12816 #else
12817 UnixSelect(set, timeout, c1, c2);
12818 #endif // OS_WIN32
12819 }
12820
12821 // Add a socket to the socket set
AddSockSet(SOCKSET * set,SOCK * sock)12822 void AddSockSet(SOCKSET *set, SOCK *sock)
12823 {
12824 // Validate arguments
12825 if (set == NULL || sock == NULL)
12826 {
12827 return;
12828 }
12829 if (sock->Type == SOCK_TCP && sock->Connected == false)
12830 {
12831 return;
12832 }
12833
12834 if (set->NumSocket >= MAX_SOCKSET_NUM)
12835 {
12836 // Upper limit
12837 return;
12838 }
12839 set->Sock[set->NumSocket++] = sock;
12840 }
12841
12842 // Initializing the socket set
InitSockSet(SOCKSET * set)12843 void InitSockSet(SOCKSET *set)
12844 {
12845 // Validate arguments
12846 if (set == NULL)
12847 {
12848 return;
12849 }
12850
12851 Zero(set, sizeof(SOCKSET));
12852 }
12853
12854 // Receive data and discard all of them
RecvAllWithDiscard(SOCK * sock,UINT size,bool secure)12855 bool RecvAllWithDiscard(SOCK *sock, UINT size, bool secure)
12856 {
12857 static UCHAR buffer[4096];
12858 UINT recv_size, sz, ret;
12859 if (sock == NULL)
12860 {
12861 return false;
12862 }
12863 if (size == 0)
12864 {
12865 return true;
12866 }
12867 if (sock->AsyncMode)
12868 {
12869 return false;
12870 }
12871
12872 recv_size = 0;
12873
12874 while (true)
12875 {
12876 sz = MIN(size - recv_size, sizeof(buffer));
12877 ret = Recv(sock, buffer, sz, secure);
12878 if (ret == 0)
12879 {
12880 return false;
12881 }
12882 if (ret == SOCK_LATER)
12883 {
12884 // I suppose that this is safe because the RecvAll() function is used only
12885 // if the sock->AsyncMode == true. And the Recv() function may return
12886 // SOCK_LATER only if the sock->AsyncMode == false. Therefore the call of
12887 // Recv() function in the RecvAll() function never returns SOCK_LATER.
12888 return false;
12889 }
12890 recv_size += ret;
12891 if (recv_size >= size)
12892 {
12893 return true;
12894 }
12895 }
12896 }
12897
12898 // Receive all by TCP
RecvAll(SOCK * sock,void * data,UINT size,bool secure)12899 bool RecvAll(SOCK *sock, void *data, UINT size, bool secure)
12900 {
12901 UINT recv_size, sz, ret;
12902 // Validate arguments
12903 if (sock == NULL || data == NULL)
12904 {
12905 return false;
12906 }
12907 if (size == 0)
12908 {
12909 return true;
12910 }
12911 if (sock->AsyncMode)
12912 {
12913 return false;
12914 }
12915
12916 recv_size = 0;
12917
12918 while (true)
12919 {
12920 sz = size - recv_size;
12921 ret = Recv(sock, (UCHAR *)data + recv_size, sz, secure);
12922 if (ret == 0)
12923 {
12924 return false;
12925 }
12926 if (ret == SOCK_LATER)
12927 {
12928 // I suppose that this is safe because the RecvAll() function is used only
12929 // if the sock->AsyncMode == true. And the Recv() function may return
12930 // SOCK_LATER only if the sock->AsyncMode == false. Therefore the call of
12931 // Recv() function in the RecvAll() function never returns SOCK_LATER.
12932 return false;
12933 }
12934 recv_size += ret;
12935 if (recv_size >= size)
12936 {
12937 return true;
12938 }
12939 }
12940 }
12941
12942 // Send the TCP send buffer
SendNow(SOCK * sock,int secure)12943 bool SendNow(SOCK *sock, int secure)
12944 {
12945 bool ret;
12946 // Validate arguments
12947 if (sock == NULL || sock->AsyncMode != false)
12948 {
12949 return false;
12950 }
12951 if (sock->SendBuf->Size == 0)
12952 {
12953 return true;
12954 }
12955
12956 ret = SendAll(sock, sock->SendBuf->Buf, sock->SendBuf->Size, secure);
12957 ClearBuf(sock->SendBuf);
12958
12959 return ret;
12960 }
12961
12962 // Append to the TCP send buffer
SendAdd(SOCK * sock,void * data,UINT size)12963 void SendAdd(SOCK *sock, void *data, UINT size)
12964 {
12965 // Validate arguments
12966 if (sock == NULL || data == NULL || size == 0 || sock->AsyncMode != false)
12967 {
12968 return;
12969 }
12970
12971 WriteBuf(sock->SendBuf, data, size);
12972 }
12973
12974 // Send all by TCP
SendAll(SOCK * sock,void * data,UINT size,bool secure)12975 bool SendAll(SOCK *sock, void *data, UINT size, bool secure)
12976 {
12977 UCHAR *buf;
12978 UINT sent_size;
12979 UINT ret;
12980 // Validate arguments
12981 if (sock == NULL || data == NULL)
12982 {
12983 return false;
12984 }
12985 if (sock->AsyncMode)
12986 {
12987 return false;
12988 }
12989 if (size == 0)
12990 {
12991 return true;
12992 }
12993
12994 buf = (UCHAR *)data;
12995 sent_size = 0;
12996
12997 while (true)
12998 {
12999 ret = Send(sock, buf, size - sent_size, secure);
13000 if (ret == 0)
13001 {
13002 return false;
13003 }
13004 sent_size += ret;
13005 buf += ret;
13006 if (sent_size >= size)
13007 {
13008 return true;
13009 }
13010 }
13011 }
13012
13013 // Set the cipher algorithm name to want to use
SetWantToUseCipher(SOCK * sock,char * name)13014 void SetWantToUseCipher(SOCK *sock, char *name)
13015 {
13016 char tmp[2048];
13017 // Validate arguments
13018 if (sock == NULL || name == NULL)
13019 {
13020 return;
13021 }
13022
13023 if (sock->WaitToUseCipher)
13024 {
13025 Free(sock->WaitToUseCipher);
13026 }
13027
13028 Zero(tmp, sizeof(tmp));
13029 StrCpy(tmp, sizeof(tmp), name);
13030 StrCat(tmp, sizeof(tmp), " ");
13031 StrCat(tmp, sizeof(tmp), cipher_list);
13032
13033 sock->WaitToUseCipher = CopyStr(tmp);
13034 }
13035
13036 // Add all the chain certificates in the chain_certs directory
AddChainSslCertOnDirectory(struct ssl_ctx_st * ctx)13037 void AddChainSslCertOnDirectory(struct ssl_ctx_st *ctx)
13038 {
13039 wchar_t dirname[MAX_SIZE];
13040 wchar_t exedir[MAX_SIZE];
13041 wchar_t txtname[MAX_SIZE];
13042 DIRLIST *dir;
13043 LIST *o;
13044 UINT i;
13045
13046 // Validate arguments
13047 if (ctx == NULL)
13048 {
13049 return;
13050 }
13051
13052 o = NewListFast(NULL);
13053
13054 GetDbDirW(exedir, sizeof(exedir));
13055
13056 CombinePathW(dirname, sizeof(dirname), exedir, L"chain_certs");
13057
13058 MakeDirExW(dirname);
13059
13060 CombinePathW(txtname, sizeof(txtname), dirname, L"Readme_Chain_Certs.txt");
13061
13062 if (IsFileExistsW(txtname) == false)
13063 {
13064 FileCopyW(L"|chain_certs.txt", txtname);
13065 }
13066
13067 dir = EnumDirW(dirname);
13068
13069 if (dir != NULL)
13070 {
13071 for (i = 0;i < dir->NumFiles;i++)
13072 {
13073 DIRENT *e = dir->File[i];
13074
13075 if (e->Folder == false)
13076 {
13077 wchar_t tmp[MAX_SIZE];
13078 X *x;
13079
13080 CombinePathW(tmp, sizeof(tmp), dirname, e->FileNameW);
13081
13082 x = FileToXW(tmp);
13083
13084 if (x != NULL)
13085 {
13086 UINT j;
13087 bool exists = false;
13088 UCHAR hash[SHA1_SIZE];
13089
13090 GetXDigest(x, hash, true);
13091
13092 for (j = 0;j < LIST_NUM(o);j++)
13093 {
13094 UCHAR *hash2 = LIST_DATA(o, j);
13095
13096 if (Cmp(hash, hash2, SHA1_SIZE) == 0)
13097 {
13098 exists = true;
13099 }
13100 }
13101
13102 if (exists == false)
13103 {
13104 AddChainSslCert(ctx, x);
13105
13106 Add(o, Clone(hash, SHA1_SIZE));
13107 }
13108
13109 FreeX(x);
13110 }
13111 }
13112 }
13113
13114 FreeDir(dir);
13115 }
13116
13117 for (i = 0;i < LIST_NUM(o);i++)
13118 {
13119 UCHAR *hash = LIST_DATA(o, i);
13120
13121 Free(hash);
13122 }
13123
13124 ReleaseList(o);
13125 }
13126
13127 // Add the chain certificate
AddChainSslCert(struct ssl_ctx_st * ctx,X * x)13128 bool AddChainSslCert(struct ssl_ctx_st *ctx, X *x)
13129 {
13130 bool ret = false;
13131 X *x_copy;
13132 // Validate arguments
13133 if (ctx == NULL || x == NULL)
13134 {
13135 return ret;
13136 }
13137
13138 x_copy = CloneX(x);
13139
13140 if (x_copy != NULL)
13141 {
13142 SSL_CTX_add_extra_chain_cert(ctx, x_copy->x509);
13143 x_copy->do_not_free = true;
13144
13145 ret = true;
13146
13147 FreeX(x_copy);
13148 }
13149
13150 return ret;
13151 }
13152
13153 // Start a TCP-SSL communication
StartSSL(SOCK * sock,X * x,K * priv)13154 bool StartSSL(SOCK *sock, X *x, K *priv)
13155 {
13156 return StartSSLEx(sock, x, priv, true, 0, NULL);
13157 }
StartSSLEx(SOCK * sock,X * x,K * priv,bool client_tls,UINT ssl_timeout,char * sni_hostname)13158 bool StartSSLEx(SOCK *sock, X *x, K *priv, bool client_tls, UINT ssl_timeout, char *sni_hostname)
13159 {
13160 X509 *x509;
13161 EVP_PKEY *key;
13162 UINT prev_timeout = 1024;
13163 SSL_CTX *ssl_ctx;
13164
13165 #ifdef UNIX_SOLARIS
13166 SOCKET_TIMEOUT_PARAM *ttparam;
13167 #endif //UNIX_SOLARIS
13168
13169 // Validate arguments
13170 if (sock == NULL)
13171 {
13172 Debug("StartSSL Error: #0\n");
13173 return false;
13174 }
13175 if (sock->Connected && sock->Type == SOCK_INPROC && sock->ListenMode == false)
13176 {
13177 sock->SecureMode = true;
13178 return true;
13179 }
13180 if (sock->Connected == false || sock->socket == INVALID_SOCKET ||
13181 sock->ListenMode != false)
13182 {
13183 Debug("StartSSL Error: #1\n");
13184 return false;
13185 }
13186 if (x != NULL && priv == NULL)
13187 {
13188 Debug("StartSSL Error: #2\n");
13189 return false;
13190 }
13191 if (ssl_timeout == 0)
13192 {
13193 ssl_timeout = TIMEOUT_SSL_CONNECT;
13194 }
13195
13196 if (sock->SecureMode)
13197 {
13198 //Debug("StartSSL Error: #3\n");
13199 // SSL communication has already started
13200 return true;
13201 }
13202
13203 Lock(sock->ssl_lock);
13204 if (sock->SecureMode)
13205 {
13206 //Debug("StartSSL Error: #4\n");
13207 // SSL communication has already started
13208 Unlock(sock->ssl_lock);
13209 return true;
13210 }
13211
13212 ssl_ctx = NewSSLCtx(sock->ServerMode);
13213
13214 Lock(openssl_lock);
13215 {
13216 if (sock->ServerMode)
13217 {
13218 SSL_CTX_set_ssl_version(ssl_ctx, SSLv23_method());
13219
13220 #ifdef SSL_OP_NO_SSLv2
13221 SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSLv2);
13222 #endif // SSL_OP_NO_SSLv2
13223
13224 if (sock->SslAcceptSettings.AcceptOnlyTls)
13225 {
13226 #ifdef SSL_OP_NO_SSLv3
13227 SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSLv3);
13228 #endif // SSL_OP_NO_SSLv3
13229 }
13230
13231 if (sock->SslAcceptSettings.Tls_Disable1_0)
13232 {
13233 #ifdef SSL_OP_NO_TLSv1
13234 SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TLSv1);
13235 #endif // SSL_OP_NO_TLSv1
13236 }
13237
13238 if (sock->SslAcceptSettings.Tls_Disable1_1)
13239 {
13240 #ifdef SSL_OP_NO_TLSv1_1
13241 SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TLSv1_1);
13242 #endif // SSL_OP_NO_TLSv1_1
13243 }
13244
13245 if (sock->SslAcceptSettings.Tls_Disable1_2)
13246 {
13247 #ifdef SSL_OP_NO_TLSv1_2
13248 SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TLSv1_2);
13249 #endif // SSL_OP_NO_TLSv1_2
13250 }
13251
13252 if (sock->SslAcceptSettings.Tls_Disable1_3)
13253 {
13254 #ifdef SSL_OP_NO_TLSv1_3
13255 SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TLSv1_3);
13256 #endif // SSL_OP_NO_TLSv1_3
13257 }
13258
13259 Unlock(openssl_lock);
13260 AddChainSslCertOnDirectory(ssl_ctx);
13261 Lock(openssl_lock);
13262 }
13263 else
13264 {
13265 if (client_tls == false)
13266 {
13267 // Use SSL v3
13268 #ifndef SSL_OP_NO_SSL_MASK
13269 #if OPENSSL_VERSION_NUMBER < 0x10100000L
13270 SSL_CTX_set_ssl_version(ssl_ctx, SSLv3_method());
13271 #else
13272 SSL_CTX_set_ssl_version(ssl_ctx, SSLv23_method());
13273 #endif
13274 #else // SSL_OP_NO_SSL_MASK
13275 SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSL_MASK & ~SSL_OP_NO_SSLv3);
13276 #endif // SSL_OP_NO_SSL_MASK
13277 }
13278 else
13279 {
13280 // Use TLS 1.0 or later
13281 SSL_CTX_set_ssl_version(ssl_ctx, SSLv23_client_method());
13282 }
13283 }
13284 sock->ssl = SSL_new(ssl_ctx);
13285 SSL_set_fd(sock->ssl, (int)sock->socket);
13286
13287 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
13288 if (sock->ServerMode == false && client_tls)
13289 {
13290 if (IsEmptyStr(sni_hostname) == false)
13291 {
13292 // Set the SNI host name
13293 SSL_set_tlsext_host_name(sock->ssl, sni_hostname);
13294 }
13295 }
13296 #endif // SSL_CTRL_SET_TLSEXT_HOSTNAME
13297
13298 }
13299 Unlock(openssl_lock);
13300
13301 if (x != NULL)
13302 {
13303 // Check the certificate and the private key
13304 if (CheckXandK(x, priv))
13305 {
13306 // Use the certificate
13307 x509 = x->x509;
13308 key = priv->pkey;
13309
13310 Lock(openssl_lock);
13311 {
13312 SSL_use_certificate(sock->ssl, x509);
13313 SSL_use_PrivateKey(sock->ssl, key);
13314 }
13315 Unlock(openssl_lock);
13316 }
13317 }
13318
13319 if (sock->WaitToUseCipher != NULL)
13320 {
13321 // Set the cipher algorithm name to want to use
13322 Lock(openssl_lock);
13323 {
13324 SSL_set_cipher_list(sock->ssl, sock->WaitToUseCipher);
13325 }
13326 Unlock(openssl_lock);
13327 }
13328 else
13329 {
13330 // Set the OpenSSL default cipher algorithms
13331 Lock(openssl_lock);
13332 {
13333 SSL_set_cipher_list(sock->ssl, OPENSSL_DEFAULT_CIPHER_LIST);
13334 }
13335 Unlock(openssl_lock);
13336 }
13337
13338 if (sock->ServerMode)
13339 {
13340 // Lock(ssl_connect_lock);
13341
13342 // Run the time-out thread for SOLARIS
13343 #ifdef UNIX_SOLARIS
13344 ttparam = NewSocketTimeout(sock);
13345 #endif // UNIX_SOLARIS
13346
13347 // Server mode
13348 if (SSL_accept(sock->ssl) <= 0)
13349 {
13350
13351 // Stop the timeout thread
13352 #ifdef UNIX_SOLARIS
13353 FreeSocketTimeout(ttparam);
13354 #endif // UNIX_SOLARIS
13355
13356 // Unlock(ssl_connect_lock);
13357 // SSL-Accept failure
13358 Lock(openssl_lock);
13359 {
13360 SSL_free(sock->ssl);
13361 sock->ssl = NULL;
13362 }
13363 Unlock(openssl_lock);
13364
13365 Unlock(sock->ssl_lock);
13366 Debug("StartSSL Error: #5\n");
13367 FreeSSLCtx(ssl_ctx);
13368 return false;
13369 }
13370
13371 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
13372 #ifdef TLSEXT_NAMETYPE_host_name
13373 if (true)
13374 {
13375 // Get the SNI host name
13376 const char *sni_recv_hostname = SSL_get_servername(sock->ssl, TLSEXT_NAMETYPE_host_name);
13377
13378 if (IsEmptyStr((char *)sni_recv_hostname) == false)
13379 {
13380 StrCpy(sock->SniHostname, sizeof(sock->SniHostname), (char *)sni_recv_hostname);
13381 }
13382 }
13383 #endif // TLSEXT_NAMETYPE_host_name
13384 #endif // SSL_CTRL_SET_TLSEXT_HOSTNAME
13385
13386 // Stop the timeout thread
13387 #ifdef UNIX_SOLARIS
13388 FreeSocketTimeout(ttparam);
13389 #endif // UNIX_SOLARIS
13390
13391 // Unlock(ssl_connect_lock);
13392 }
13393 else
13394 {
13395 prev_timeout = GetTimeout(sock);
13396 SetTimeout(sock, ssl_timeout);
13397 Lock(ssl_connect_lock);
13398 // Client mode
13399 if (SSL_connect(sock->ssl) <= 0)
13400 {
13401 Unlock(ssl_connect_lock);
13402 // SSL-connect failure
13403 Lock(openssl_lock);
13404 {
13405 SSL_free(sock->ssl);
13406 sock->ssl = NULL;
13407 }
13408 Unlock(openssl_lock);
13409
13410 Unlock(sock->ssl_lock);
13411 Debug("StartSSL Error: #5\n");
13412 SetTimeout(sock, prev_timeout);
13413 FreeSSLCtx(ssl_ctx);
13414 return false;
13415 }
13416 Unlock(ssl_connect_lock);
13417 SetTimeout(sock, prev_timeout);
13418 }
13419
13420 // SSL communication is initiated
13421 sock->SecureMode = true;
13422
13423 // Get the certificate of the remote host
13424 Lock(openssl_lock);
13425 {
13426 x509 = SSL_get_peer_certificate(sock->ssl);
13427
13428 sock->SslVersion = SSL_get_version(sock->ssl);
13429 }
13430 Unlock(openssl_lock);
13431
13432 if (x509 == NULL)
13433 {
13434 // The certificate does not exist on the remote host
13435 sock->RemoteX = NULL;
13436 }
13437 else
13438 {
13439 // Got a certificate
13440 sock->RemoteX = X509ToX(x509);
13441 }
13442
13443 // Get the certificate of local host
13444 Lock(openssl_lock);
13445 {
13446 x509 = SSL_get_certificate(sock->ssl);
13447 }
13448 Unlock(openssl_lock);
13449
13450 if (x509 == NULL)
13451 {
13452 // The certificate does not exist on the remote host
13453 sock->LocalX = NULL;
13454 }
13455 else
13456 {
13457 X *local_x;
13458 // Got a certificate
13459 local_x = X509ToX(x509);
13460 local_x->do_not_free = true;
13461 sock->LocalX = CloneX(local_x);
13462 FreeX(local_x);
13463 }
13464
13465 // Automatic retry mode
13466 SSL_set_mode(sock->ssl, SSL_MODE_AUTO_RETRY);
13467
13468 // Strange flag
13469 SSL_set_mode(sock->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
13470
13471 sock->ssl_ctx = ssl_ctx;
13472
13473 // Get the algorithm name used to encrypt
13474 Lock(openssl_lock);
13475 {
13476 sock->CipherName = CopyStr((char *)SSL_get_cipher(sock->ssl));
13477 }
13478 Unlock(openssl_lock);
13479 Debug("SSL connected with %s\n", SSL_get_version(sock->ssl));
13480
13481 Unlock(sock->ssl_lock);
13482
13483 #ifdef ENABLE_SSL_LOGGING
13484 if (sock->ServerMode)
13485 {
13486 SockEnableSslLogging(sock);
13487 }
13488 #endif // ENABLE_SSL_LOGGING
13489
13490 return true;
13491 }
13492
13493
13494
13495 #ifdef ENABLE_SSL_LOGGING
13496
13497 // Enable SSL logging
SockEnableSslLogging(SOCK * s)13498 void SockEnableSslLogging(SOCK *s)
13499 {
13500 char dirname[MAX_PATH];
13501 char tmp[MAX_PATH];
13502 char dtstr[MAX_PATH];
13503 char fn1[MAX_PATH], fn2[MAX_PATH];
13504 // Validate arguments
13505 if (s == NULL)
13506 {
13507 return;
13508 }
13509
13510 if (s->IsSslLoggingEnabled)
13511 {
13512 return;
13513 }
13514
13515 s->IsSslLoggingEnabled = true;
13516
13517 GetDateTimeStrMilli64ForFileName(dtstr, sizeof(dtstr), LocalTime64());
13518 Format(tmp, sizeof(tmp), "%s__%r_%u__%r_%u", dtstr,
13519 &s->LocalIP, s->LocalPort, &s->RemoteIP, s->RemotePort);
13520
13521 CombinePath(dirname, sizeof(dirname), SSL_LOGGING_DIRNAME, tmp);
13522
13523 MakeDirEx(dirname);
13524
13525 CombinePath(fn1, sizeof(fn1), dirname, "send.c");
13526 CombinePath(fn2, sizeof(fn2), dirname, "recv.c");
13527
13528 s->SslLogging_Send = FileCreate(fn1);
13529 s->SslLogging_Recv = FileCreate(fn2);
13530
13531 s->SslLogging_Lock = NewLock();
13532 }
13533
13534 // Close SSL logging
SockCloseSslLogging(SOCK * s)13535 void SockCloseSslLogging(SOCK *s)
13536 {
13537 // Validate arguments
13538 if (s == NULL)
13539 {
13540 return;
13541 }
13542
13543 if (s->IsSslLoggingEnabled == false)
13544 {
13545 return;
13546 }
13547
13548 s->IsSslLoggingEnabled = false;
13549
13550 FileClose(s->SslLogging_Recv);
13551 s->SslLogging_Recv = NULL;
13552
13553 FileClose(s->SslLogging_Send);
13554 s->SslLogging_Send = NULL;
13555
13556 DeleteLock(s->SslLogging_Lock);
13557 s->SslLogging_Lock = NULL;
13558 }
13559
13560 // Write SSL log
SockWriteSslLog(SOCK * s,void * send_data,UINT send_size,void * recv_data,UINT recv_size)13561 void SockWriteSslLog(SOCK *s, void *send_data, UINT send_size, void *recv_data, UINT recv_size)
13562 {
13563 // Validate arguments
13564 if (s == NULL)
13565 {
13566 return;
13567 }
13568
13569 if (s->IsSslLoggingEnabled == false)
13570 {
13571 return;
13572 }
13573
13574 Lock(s->SslLogging_Lock);
13575 {
13576 if (s->SslLogging_Send != NULL)
13577 {
13578 if (send_size >= 1 && send_data != NULL)
13579 {
13580 FileWrite(s->SslLogging_Send, send_data, send_size);
13581 }
13582 }
13583
13584 if (s->SslLogging_Recv != NULL)
13585 {
13586 if (recv_size >= 1 && recv_data != NULL)
13587 {
13588 FileWrite(s->SslLogging_Recv, recv_data, recv_size);
13589 }
13590 }
13591 }
13592 Unlock(s->SslLogging_Lock);
13593 }
13594
13595 #endif // ENABLE_SSL_LOGGING
13596
13597 // Set the flag to indicate that the socket doesn't require reading
SetNoNeedToRead(SOCK * sock)13598 void SetNoNeedToRead(SOCK *sock)
13599 {
13600 // Validate arguments
13601 if (sock == NULL)
13602 {
13603 return;
13604 }
13605
13606 sock->NoNeedToRead = true;
13607 }
13608
13609 // TCP-SSL receive
SecureRecv(SOCK * sock,void * data,UINT size)13610 UINT SecureRecv(SOCK *sock, void *data, UINT size)
13611 {
13612 SOCKET s;
13613 int ret, e = 0;
13614 SSL *ssl;
13615
13616 #ifdef UNIX_SOLARIS
13617 SOCKET_TIMEOUT_PARAM *ttparam;
13618 #endif //UNIX_SOLARIS
13619
13620 s = sock->socket;
13621 ssl = sock->ssl;
13622
13623 if (sock->AsyncMode)
13624 {
13625 // Confirm whether the data is readable even 1 byte in the case of asynchronous mode.
13626 // To read data results blocking, if there is no readable data.
13627 // We must avoid blocking.
13628 char c;
13629 Lock(sock->ssl_lock);
13630 {
13631 if (sock->Connected == false)
13632 {
13633 Unlock(sock->ssl_lock);
13634 Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__);
13635 return 0;
13636 }
13637 ret = SSL_peek(ssl, &c, sizeof(c));
13638 }
13639 Unlock(sock->ssl_lock);
13640 if (ret == 0)
13641 {
13642 // The communication have been disconnected
13643 Disconnect(sock);
13644 Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__);
13645 return 0;
13646 }
13647 if (ret < 0)
13648 {
13649 // An error has occurred
13650 e = SSL_get_error(ssl, ret);
13651 if (e == SSL_ERROR_WANT_READ || e == SSL_ERROR_WANT_WRITE || e == SSL_ERROR_SSL)
13652 {
13653 if (e == SSL_ERROR_SSL
13654 #if OPENSSL_VERSION_NUMBER < 0x10100000L
13655 &&
13656 sock->ssl->s3->send_alert[0] == SSL3_AL_FATAL &&
13657 sock->ssl->s3->send_alert[0] != sock->Ssl_Init_Async_SendAlert[0] &&
13658 sock->ssl->s3->send_alert[1] != sock->Ssl_Init_Async_SendAlert[1]
13659 #endif
13660 )
13661 {
13662 Debug("%s %u SSL Fatal Error on ASYNC socket !!!\n", __FILE__, __LINE__);
13663 Disconnect(sock);
13664 return 0;
13665 }
13666 // Packet has not arrived yet, that is not to be read
13667 return SOCK_LATER;
13668 }
13669 }
13670 }
13671
13672 // Receive
13673 Lock(sock->ssl_lock);
13674 {
13675 if (sock->Connected == false)
13676 {
13677 Unlock(sock->ssl_lock);
13678 Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__);
13679 return 0;
13680 }
13681
13682 #ifdef OS_UNIX
13683 if (sock->AsyncMode == false)
13684 {
13685 sock->CallingThread = pthread_self();
13686 }
13687 #endif // OS_UNIX
13688
13689 // Run the time-out thread for SOLARIS
13690 #ifdef UNIX_SOLARIS
13691 ttparam = NewSocketTimeout(sock);
13692 #endif // UNIX_SOLARIS
13693
13694 ret = SSL_read(ssl, data, size);
13695
13696 // Stop the timeout thread
13697 #ifdef UNIX_SOLARIS
13698 FreeSocketTimeout(ttparam);
13699 #endif // UNIX_SOLARIS
13700
13701
13702 #ifdef OS_UNIX
13703 if (sock->AsyncMode == false)
13704 {
13705 sock->CallingThread = 0;
13706 }
13707 #endif // OS_UNIX
13708
13709 if (ret < 0)
13710 {
13711 e = SSL_get_error(ssl, ret);
13712 }
13713
13714 }
13715 Unlock(sock->ssl_lock);
13716
13717 #ifdef ENABLE_SSL_LOGGING
13718 if (ret > 0)
13719 {
13720 SockWriteSslLog(sock, NULL, 0, data, ret);
13721 }
13722 #endif // ENABLE_SSL_LOGGING
13723
13724 if (ret > 0)
13725 {
13726 // Successful reception
13727 sock->RecvSize += (UINT64)ret;
13728 sock->RecvNum++;
13729
13730 return (UINT)ret;
13731 }
13732 if (ret == 0)
13733 {
13734 // Disconnect the communication
13735 Disconnect(sock);
13736 //Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__);
13737 return 0;
13738 }
13739 if (sock->AsyncMode)
13740 {
13741 if (e == SSL_ERROR_WANT_READ || e == SSL_ERROR_WANT_WRITE || e == SSL_ERROR_SSL)
13742 {
13743 if (e == SSL_ERROR_SSL
13744 #if OPENSSL_VERSION_NUMBER < 0x10100000L
13745 &&
13746 sock->ssl->s3->send_alert[0] == SSL3_AL_FATAL &&
13747 sock->ssl->s3->send_alert[0] != sock->Ssl_Init_Async_SendAlert[0] &&
13748 sock->ssl->s3->send_alert[1] != sock->Ssl_Init_Async_SendAlert[1]
13749 #endif
13750 )
13751 {
13752 Debug("%s %u SSL Fatal Error on ASYNC socket !!!\n", __FILE__, __LINE__);
13753 Disconnect(sock);
13754 return 0;
13755 }
13756
13757 // Packet has not yet arrived
13758 return SOCK_LATER;
13759 }
13760 }
13761 Disconnect(sock);
13762 Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__);
13763 return 0;
13764 }
13765
13766 // TCP-SSL transmission
SecureSend(SOCK * sock,void * data,UINT size)13767 UINT SecureSend(SOCK *sock, void *data, UINT size)
13768 {
13769 SOCKET s;
13770 int ret, e;
13771 SSL *ssl;
13772 s = sock->socket;
13773 ssl = sock->ssl;
13774
13775 if (sock->AsyncMode)
13776 {
13777 // Asynchronous mode
13778 SSL_set_mode(ssl, SSL_MODE_ENABLE_PARTIAL_WRITE);
13779 }
13780
13781 // Transmission
13782 Lock(sock->ssl_lock);
13783 {
13784 if (sock->Connected == false)
13785 {
13786 Unlock(sock->ssl_lock);
13787 Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__);
13788 return 0;
13789 }
13790
13791 ret = SSL_write(ssl, data, size);
13792 if (ret < 0)
13793 {
13794 e = SSL_get_error(ssl, ret);
13795 }
13796 }
13797 Unlock(sock->ssl_lock);
13798
13799 #ifdef ENABLE_SSL_LOGGING
13800 if (ret > 0)
13801 {
13802 SockWriteSslLog(sock, data, ret, NULL, 0);
13803 }
13804 #endif // ENABLE_SSL_LOGGING
13805
13806 if (ret > 0)
13807 {
13808 // Successful transmission
13809 sock->SendSize += (UINT64)ret;
13810 sock->SendNum++;
13811 sock->WriteBlocked = false;
13812 return (UINT)ret;
13813 }
13814 if (ret == 0)
13815 {
13816 // Disconnect
13817 Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__);
13818 Disconnect(sock);
13819 return 0;
13820 }
13821
13822 if (sock->AsyncMode)
13823 {
13824 // Confirmation of the error value
13825 if (e == SSL_ERROR_WANT_READ || e == SSL_ERROR_WANT_WRITE || e == SSL_ERROR_SSL)
13826 {
13827 sock->WriteBlocked = true;
13828 return SOCK_LATER;
13829 }
13830 Debug("%s %u e=%u\n", __FILE__, __LINE__, e);
13831 }
13832 //Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__);
13833 Disconnect(sock);
13834 return 0;
13835 }
13836
13837 // Peep the TCP
Peek(SOCK * sock,void * data,UINT size)13838 UINT Peek(SOCK *sock, void *data, UINT size)
13839 {
13840 SOCKET s;
13841 int ret;
13842
13843 // Validate arguments
13844 if (sock == NULL || data == NULL || size == 0)
13845 {
13846 return 0;
13847 }
13848 if (sock->Type == SOCK_INPROC)
13849 {
13850 return 0;
13851 }
13852 if (sock->Type != SOCK_TCP || sock->Connected == false || sock->ListenMode != false ||
13853 sock->socket == INVALID_SOCKET)
13854 {
13855 return 0;
13856 }
13857 if (sock->AsyncMode)
13858 {
13859 return 0;
13860 }
13861
13862 // Receive
13863 s = sock->socket;
13864
13865 ret = recv(s, data, size, MSG_PEEK);
13866
13867 //Debug("Peek: %u\n", ret);
13868
13869 if (ret > 0)
13870 {
13871 return ret;
13872 }
13873
13874 return 0;
13875 }
13876
13877 // TCP receive
Recv(SOCK * sock,void * data,UINT size,bool secure)13878 UINT Recv(SOCK *sock, void *data, UINT size, bool secure)
13879 {
13880 SOCKET s;
13881 int ret;
13882
13883 #ifdef UNIX_SOLARIS
13884 SOCKET_TIMEOUT_PARAM *ttparam;
13885 #endif //UNIX_SOLARIS
13886
13887 // Validate arguments
13888 if (sock == NULL || data == NULL || size == 0)
13889 {
13890 return 0;
13891 }
13892
13893 sock->NoNeedToRead = false;
13894
13895 if (sock->Type == SOCK_INPROC)
13896 {
13897 return RecvInProc(sock, data, size);
13898 }
13899 if (sock->Type != SOCK_TCP || sock->Connected == false || sock->ListenMode != false ||
13900 sock->socket == INVALID_SOCKET)
13901 {
13902 return 0;
13903 }
13904 if (secure != false && sock->SecureMode == false)
13905 {
13906 return 0;
13907 }
13908
13909 if (secure)
13910 {
13911 return SecureRecv(sock, data, size);
13912 }
13913
13914 // Receive
13915 s = sock->socket;
13916
13917
13918 #ifdef OS_UNIX
13919 if (sock->AsyncMode == false)
13920 {
13921 sock->CallingThread = pthread_self();
13922 }
13923 #endif // OS_UNIX
13924
13925 // Start of the timeout thread for SOLARIS
13926 #ifdef UNIX_SOLARIS
13927 ttparam = NewSocketTimeout(sock);
13928 #endif // UNIX_SOLARIS
13929
13930 ret = recv(s, data, size, 0);
13931
13932 // Stop the timeout thread
13933 #ifdef UNIX_SOLARIS
13934 FreeSocketTimeout(ttparam);
13935 #endif // UNIX_SOLARIS
13936
13937 #ifdef OS_UNIX
13938 if (sock->AsyncMode == false)
13939 {
13940 sock->CallingThread = 0;
13941 }
13942 #endif // OS_UNIX
13943
13944 if (ret > 0)
13945 {
13946 // Successful reception
13947 Lock(sock->lock);
13948 {
13949 sock->RecvSize += (UINT64)ret;
13950 sock->SendNum++;
13951 }
13952 Unlock(sock->lock);
13953 return (UINT)ret;
13954 }
13955
13956 // Transmission failure
13957 if (sock->AsyncMode)
13958 {
13959 // In asynchronous mode, examine the error
13960 if (ret == SOCKET_ERROR)
13961 {
13962 #ifdef OS_WIN32
13963 if (WSAGetLastError() == WSAEWOULDBLOCK)
13964 {
13965 // In blocking
13966 return SOCK_LATER;
13967 }
13968 else
13969 {
13970 //Debug("Socket Error: %u\n", WSAGetLastError());
13971 }
13972 #else // OS_WIN32
13973 if (errno == EAGAIN)
13974 {
13975 // In blocking
13976 return SOCK_LATER;
13977 }
13978 #endif // OS_WIN32
13979 }
13980 }
13981
13982 // Disconnected
13983 Disconnect(sock);
13984 return 0;
13985 }
13986
13987 // TCP transmission
Send(SOCK * sock,void * data,UINT size,bool secure)13988 UINT Send(SOCK *sock, void *data, UINT size, bool secure)
13989 {
13990 SOCKET s;
13991 int ret;
13992 // Validate arguments
13993 if (sock == NULL || data == NULL || size == 0)
13994 {
13995 return 0;
13996 }
13997 if (sock->Type == SOCK_INPROC)
13998 {
13999 return SendInProc(sock, data, size);
14000 }
14001 size = MIN(size, MAX_SEND_BUF_MEM_SIZE);
14002 if (sock->Type != SOCK_TCP || sock->Connected == false || sock->ListenMode != false ||
14003 sock->socket == INVALID_SOCKET)
14004 {
14005 return 0;
14006 }
14007 if (secure != false && sock->SecureMode == false)
14008 {
14009 return 0;
14010 }
14011
14012 if (secure)
14013 {
14014 return SecureSend(sock, data, size);
14015 }
14016
14017 // Transmission
14018 s = sock->socket;
14019 ret = send(s, data, size, 0);
14020 if (ret > 0)
14021 {
14022 // Successful transmission
14023 Lock(sock->lock);
14024 {
14025 sock->SendSize += (UINT64)ret;
14026 sock->SendNum++;
14027 }
14028 Unlock(sock->lock);
14029 sock->WriteBlocked = false;
14030 return (UINT)ret;
14031 }
14032
14033 // Transmission failure
14034 if (sock->AsyncMode)
14035 {
14036 // In asynchronous mode, examine the error
14037 if (ret == SOCKET_ERROR)
14038 {
14039 #ifdef OS_WIN32
14040 if (WSAGetLastError() == WSAEWOULDBLOCK)
14041 {
14042 // In blocking
14043 sock->WriteBlocked = true;
14044 return SOCK_LATER;
14045 }
14046 else
14047 {
14048 //Debug("Socket Error: %u\n", WSAGetLastError());
14049 }
14050 #else // OS_WIN32
14051 if (errno == EAGAIN)
14052 {
14053 // In blocking
14054 sock->WriteBlocked = true;
14055 return SOCK_LATER;
14056 }
14057 #endif // OS_WIN32
14058 }
14059 }
14060
14061 // Disconnected
14062 Disconnect(sock);
14063 return 0;
14064 }
14065
14066 // Get the time-out value (in milliseconds)
GetTimeout(SOCK * sock)14067 UINT GetTimeout(SOCK *sock)
14068 {
14069 // Validate arguments
14070 if (sock == NULL)
14071 {
14072 return INFINITE;
14073 }
14074 if (sock->Type != SOCK_TCP && sock->Type != SOCK_INPROC)
14075 {
14076 return INFINITE;
14077 }
14078
14079 return sock->TimeOut;
14080 }
14081
14082 // Setting the time-out value (in milliseconds)
SetTimeout(SOCK * sock,UINT timeout)14083 void SetTimeout(SOCK *sock, UINT timeout)
14084 {
14085 // Validate arguments
14086 if (sock == NULL)
14087 {
14088 return;
14089 }
14090 if (sock->Type == SOCK_UDP)
14091 {
14092 return;
14093 }
14094
14095 if (timeout == INFINITE)
14096 {
14097 timeout = TIMEOUT_INFINITE;
14098 }
14099
14100 sock->TimeOut = timeout;
14101
14102 // Debug("SetTimeout(%u)\n",timeout);
14103
14104 if (sock->Type != SOCK_INPROC)
14105 {
14106 #ifdef OS_WIN32
14107 setsockopt(sock->socket, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(UINT));
14108 setsockopt(sock->socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(UINT));
14109 #endif
14110
14111 #ifdef OS_UNIX
14112 #ifndef UNIX_SOLARIS
14113 {
14114 struct timeval tv_timeout;
14115
14116 tv_timeout.tv_sec = timeout / 1000; // miliseconds to seconds
14117 tv_timeout.tv_usec = (timeout % 1000) * 1000; // miliseconds to microseconds
14118
14119 setsockopt(sock->socket, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv_timeout, sizeof(tv_timeout));
14120 setsockopt(sock->socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv_timeout, sizeof(tv_timeout));
14121 }
14122 #endif // UNIX_SOLARIS
14123 #endif // OS_UNIX
14124 }
14125 }
14126
14127 // Disable GetHostName call by accepting new TCP connection
DisableGetHostNameWhenAcceptInit()14128 void DisableGetHostNameWhenAcceptInit()
14129 {
14130 disable_gethostname_by_accept = true;
14131 }
14132
14133 // Initialize the connection acceptance
AcceptInit(SOCK * s)14134 void AcceptInit(SOCK *s)
14135 {
14136 AcceptInitEx(s, false);
14137 }
AcceptInitEx(SOCK * s,bool no_lookup_hostname)14138 void AcceptInitEx(SOCK *s, bool no_lookup_hostname)
14139 {
14140 char tmp[MAX_SIZE];
14141 // Validate arguments
14142 if (s == NULL)
14143 {
14144 return;
14145 }
14146
14147 Zero(tmp, sizeof(tmp));
14148
14149 if (disable_gethostname_by_accept == false && no_lookup_hostname == false)
14150 {
14151 if (GetHostName(tmp, sizeof(tmp), &s->RemoteIP) == false ||
14152 IsEmptyStr(tmp))
14153 {
14154 IPToStr(tmp, sizeof(tmp), &s->RemoteIP);
14155 }
14156 }
14157 else
14158 {
14159 IPToStr(tmp, sizeof(tmp), &s->RemoteIP);
14160 }
14161
14162 if (s->RemoteHostname != NULL)
14163 {
14164 Free(s->RemoteHostname);
14165 }
14166
14167 s->RemoteHostname = CopyStr(tmp);
14168 }
14169
14170 // TCP connection acceptance (IPv4)
Accept(SOCK * sock)14171 SOCK *Accept(SOCK *sock)
14172 {
14173 SOCK *ret;
14174 SOCKET s, new_socket;
14175 int size;
14176 struct sockaddr_in addr;
14177 bool true_flag = true;
14178 // Validate arguments
14179 if (sock == NULL)
14180 {
14181 return NULL;
14182 }
14183 if (sock->Type == SOCK_INPROC)
14184 {
14185 return AcceptInProc(sock);
14186 }
14187 if (sock->Type == SOCK_REVERSE_LISTEN)
14188 {
14189 return AcceptReverse(sock);
14190 }
14191 if (sock->Type == SOCK_RUDP_LISTEN)
14192 {
14193 return AcceptRUDP(sock);
14194 }
14195 if (sock->ListenMode == false || sock->Type != SOCK_TCP || sock->ServerMode == false)
14196 {
14197 return NULL;
14198 }
14199 if (sock->CancelAccept)
14200 {
14201 return NULL;
14202 }
14203 if (sock->IPv6)
14204 {
14205 return Accept6(sock);
14206 }
14207
14208 s = sock->socket;
14209 if (s == INVALID_SOCKET)
14210 {
14211 return NULL;
14212 }
14213 Zero(&addr, sizeof(addr));
14214 size = sizeof(addr);
14215
14216 #ifdef OS_UNIX
14217 #if defined(UNIX_LINUX) || defined(UNIX_MACOS)
14218 UnixIgnoreSignalForThread(SIGUSR1);
14219 #endif // defined(UNIX_LINUX) || defined(UNIX_MACOS)
14220 sock->CallingThread = pthread_self();
14221 #endif // OS_UNIX
14222
14223 #ifdef OS_WIN32
14224 if (sock->EnableConditionalAccept)
14225 {
14226 new_socket = Win32Accept(sock, s, (struct sockaddr *)&addr,(int *)&size, false);
14227 }
14228 else
14229 {
14230 new_socket = accept(s, (struct sockaddr *)&addr,(int *)&size);
14231 }
14232 #else // OS_WIN32
14233 new_socket = accept(s, (struct sockaddr *)&addr,(int *)&size);
14234 #endif // OS_WIN32
14235
14236 #ifdef OS_UNIX
14237 sock->CallingThread = 0;
14238 #endif // OS_UNIX
14239
14240 if (new_socket == INVALID_SOCKET)
14241 {
14242 if (sock->CancelAccept)
14243 {
14244 sock->AcceptCanceled = true;
14245 }
14246 return NULL;
14247 }
14248 if (sock->CancelAccept)
14249 {
14250 sock->AcceptCanceled = true;
14251 closesocket(new_socket);
14252 return NULL;
14253 }
14254
14255 ret = NewSock();
14256 ret->socket = new_socket;
14257 ret->Connected = true;
14258 ret->AsyncMode = false;
14259 ret->Type = SOCK_TCP;
14260 ret->ServerMode = true;
14261 ret->SecureMode = false;
14262
14263 // Configuring the TCP options
14264 setsockopt(ret->socket, IPPROTO_TCP, TCP_NODELAY, (char *)&true_flag, sizeof(bool));
14265
14266 // Initialization of the time-out value
14267 SetTimeout(ret, TIMEOUT_INFINITE);
14268
14269 // Socket information
14270 QuerySocketInformation(ret);
14271
14272 if (IsLocalHostIP(&ret->RemoteIP) == false)
14273 {
14274 ret->IpClientAdded = true;
14275 AddIpClient(&ret->RemoteIP);
14276 }
14277
14278 if (IsZeroIp(&sock->LocalIP) == false && IsLocalHostIP(&sock->LocalIP) == false)
14279 {
14280 IP current_ip;
14281
14282 if (GetCurrentGlobalIP(¤t_ip, false) == false)
14283 {
14284 SetCurrentGlobalIP(&sock->LocalIP, false);
14285 }
14286 }
14287
14288 StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_NATIVE_V4);
14289
14290 AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails), "IPv4");
14291
14292 return ret;
14293 }
14294
14295 // TCP connection acceptance (IPv6)
Accept6(SOCK * sock)14296 SOCK *Accept6(SOCK *sock)
14297 {
14298 SOCK *ret;
14299 SOCKET s, new_socket;
14300 int size;
14301 struct sockaddr_in6 addr;
14302 bool true_flag = true;
14303 // Validate arguments
14304 if (sock == NULL)
14305 {
14306 return NULL;
14307 }
14308 if (sock->ListenMode == false || sock->Type != SOCK_TCP || sock->ServerMode == false)
14309 {
14310 return NULL;
14311 }
14312 if (sock->CancelAccept)
14313 {
14314 return NULL;
14315 }
14316 if (sock->IPv6 == false)
14317 {
14318 return NULL;
14319 }
14320
14321 s = sock->socket;
14322 if (s == INVALID_SOCKET)
14323 {
14324 return NULL;
14325 }
14326 Zero(&addr, sizeof(addr));
14327 size = sizeof(addr);
14328
14329 #ifdef OS_UNIX
14330 #if defined(UNIX_LINUX) || defined(UNIX_MACOS)
14331 UnixIgnoreSignalForThread(SIGUSR1);
14332 #endif // defined(UNIX_LINUX) || defined(UNIX_MACOS)
14333 sock->CallingThread = pthread_self();
14334 #endif // OS_UNIX
14335
14336 #ifdef OS_WIN32
14337 if (sock->EnableConditionalAccept)
14338 {
14339 new_socket = Win32Accept(sock, s, (struct sockaddr *)&addr,(int *)&size, true);
14340 }
14341 else
14342 {
14343 new_socket = accept(s, (struct sockaddr *)&addr,(int *)&size);
14344 }
14345 #else // OS_WIN32
14346 new_socket = accept(s, (struct sockaddr *)&addr,(int *)&size);
14347 #endif // OS_WIN32
14348
14349 #ifdef OS_UNIX
14350 sock->CallingThread = 0;
14351 #endif // OS_UNIX
14352
14353 if (new_socket == INVALID_SOCKET)
14354 {
14355 if (sock->CancelAccept)
14356 {
14357 sock->AcceptCanceled = true;
14358 }
14359 return NULL;
14360 }
14361 if (sock->CancelAccept)
14362 {
14363 sock->AcceptCanceled = true;
14364 closesocket(new_socket);
14365 return NULL;
14366 }
14367
14368 ret = NewSock();
14369 ret->socket = new_socket;
14370 ret->Connected = true;
14371 ret->AsyncMode = false;
14372 ret->Type = SOCK_TCP;
14373 ret->ServerMode = true;
14374 ret->SecureMode = false;
14375
14376 // Configuring the TCP options
14377 setsockopt(ret->socket, IPPROTO_TCP, TCP_NODELAY, (char *)&true_flag, sizeof(bool));
14378
14379 // Initialize the time-out value
14380 SetTimeout(ret, TIMEOUT_INFINITE);
14381
14382 // Socket information
14383 QuerySocketInformation(ret);
14384
14385 if (IsLocalHostIP(&ret->RemoteIP) == false)
14386 {
14387 ret->IpClientAdded = true;
14388 AddIpClient(&ret->RemoteIP);
14389 }
14390 if (IsZeroIp(&sock->LocalIP) == false && IsLocalHostIP(&sock->LocalIP) == false)
14391 {
14392 IP current_ip;
14393
14394 if (GetCurrentGlobalIP(¤t_ip, true) == false)
14395 {
14396 SetCurrentGlobalIP(&sock->LocalIP, true);
14397 }
14398 }
14399
14400 StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_NATIVE_V6);
14401
14402 AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails), "IPv6");
14403
14404 return ret;
14405 }
14406
14407 // Standby for TCP (IPv6)
Listen6(UINT port)14408 SOCK *Listen6(UINT port)
14409 {
14410 return ListenEx6(port, false);
14411 }
ListenEx6(UINT port,bool local_only)14412 SOCK *ListenEx6(UINT port, bool local_only)
14413 {
14414 return ListenEx62(port, local_only, false);
14415 }
ListenEx62(UINT port,bool local_only,bool enable_ca)14416 SOCK *ListenEx62(UINT port, bool local_only, bool enable_ca)
14417 {
14418 SOCKET s;
14419 SOCK *sock;
14420 struct sockaddr_in6 addr;
14421 struct in6_addr in;
14422 bool true_flag = true;
14423 bool disable_conditional_accept = false;
14424 IP localhost;
14425 UINT backlog = SOMAXCONN;
14426 // Validate arguments
14427 if (port == 0 || port >= 65536)
14428 {
14429 return NULL;
14430 }
14431
14432 #ifdef OS_WIN32
14433 if (MsIsVista() == false)
14434 {
14435 // Disable the Conditional Accept due to a bug in Windows
14436 enable_ca = false;
14437 }
14438 #endif // OS_WIN32
14439
14440 // Initialization
14441 Zero(&addr, sizeof(addr));
14442 Zero(&in, sizeof(in));
14443 GetLocalHostIP6(&localhost);
14444
14445 addr.sin6_port = htons((UINT)port);
14446 addr.sin6_family = AF_INET6;
14447
14448 if (local_only)
14449 {
14450 IPToInAddr6(&addr.sin6_addr, &localhost);
14451
14452 enable_ca = false;
14453 }
14454
14455 // Creating a socket
14456 s = socket(AF_INET6, SOCK_STREAM, 0);
14457 if (s == INVALID_SOCKET)
14458 {
14459 return NULL;
14460 }
14461
14462 #ifdef OS_UNIX
14463 // It is necessary to set the IPv6 Only flag on a UNIX system
14464 setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &true_flag, sizeof(true_flag));
14465 #endif // OS_UNIX
14466
14467 //SetSocketSendRecvBufferSize(s, SOCKET_BUFFER_SIZE);
14468
14469 #ifdef OS_UNIX
14470 // This only have enabled for UNIX system since there is a bug
14471 // in the implementation of REUSEADDR in Windows OS
14472 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&true_flag, sizeof(bool));
14473 #endif // OS_UNIX
14474
14475 if (bind(s, (struct sockaddr *)&addr, sizeof(struct sockaddr_in6)) != 0)
14476 {
14477 // Bind failure
14478 closesocket(s);
14479 return NULL;
14480 }
14481
14482 #ifdef OS_WIN32
14483 if (enable_ca)
14484 {
14485 if (MsIsWinXPOrGreater())
14486 {
14487 setsockopt(s, SOL_SOCKET, SO_CONDITIONAL_ACCEPT, (char *)&true_flag, sizeof(bool));
14488
14489 backlog = 1;
14490 }
14491 }
14492 #endif // OS_WIN32
14493
14494 if (listen(s, backlog))
14495 {
14496 // Listen failure
14497 closesocket(s);
14498 return NULL;
14499 }
14500
14501 // Success
14502 sock = NewSock();
14503 sock->Connected = false;
14504 sock->AsyncMode = false;
14505 sock->ServerMode = true;
14506 sock->Type = SOCK_TCP;
14507 sock->socket = s;
14508 sock->ListenMode = true;
14509 sock->SecureMode = false;
14510 sock->LocalPort = port;
14511 sock->IPv6 = true;
14512 sock->LocalOnly = local_only;
14513 sock->EnableConditionalAccept = enable_ca;
14514
14515 return sock;
14516 }
14517
14518 // Standby for the TCP
Listen(UINT port)14519 SOCK *Listen(UINT port)
14520 {
14521 return ListenEx(port, false);
14522 }
ListenEx(UINT port,bool local_only)14523 SOCK *ListenEx(UINT port, bool local_only)
14524 {
14525 return ListenEx2(port, local_only, false);
14526 }
ListenEx2(UINT port,bool local_only,bool enable_ca)14527 SOCK *ListenEx2(UINT port, bool local_only, bool enable_ca)
14528 {
14529 SOCKET s;
14530 SOCK *sock;
14531 struct sockaddr_in addr;
14532 struct in_addr in;
14533 bool true_flag = true;
14534 IP localhost;
14535 UINT backlog = SOMAXCONN;
14536 // Validate arguments
14537 if (port == 0 || port >= 65536)
14538 {
14539 return NULL;
14540 }
14541
14542 #ifdef OS_WIN32
14543 if (MsIsVista() == false)
14544 {
14545 // Disable the Conditional Accept due to a bug in Windows
14546 enable_ca = false;
14547 }
14548 #endif // OS_WIN32
14549
14550 // Initialization
14551 Zero(&addr, sizeof(addr));
14552 Zero(&in, sizeof(in));
14553 SetIP(&localhost, 127, 0, 0, 1);
14554
14555 addr.sin_port = htons((UINT)port);
14556 *((UINT *)&addr.sin_addr) = htonl(INADDR_ANY);
14557 addr.sin_family = AF_INET;
14558
14559 if (local_only)
14560 {
14561 IPToInAddr(&addr.sin_addr, &localhost);
14562
14563 enable_ca = false;
14564 }
14565
14566 // Creating a socket
14567 s = socket(AF_INET, SOCK_STREAM, 0);
14568 if (s == INVALID_SOCKET)
14569 {
14570 return NULL;
14571 }
14572
14573 //SetSocketSendRecvBufferSize(s, SOCKET_BUFFER_SIZE);
14574
14575 #ifdef OS_UNIX
14576 // This only have enabled for UNIX system since there is a bug
14577 // in the implementation of REUSEADDR in Windows OS
14578 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&true_flag, sizeof(bool));
14579 #endif // OS_UNIX
14580
14581 if (bind(s, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) != 0)
14582 {
14583 // Bind failure
14584 closesocket(s);
14585 return NULL;
14586 }
14587
14588 #ifdef OS_WIN32
14589 if (enable_ca)
14590 {
14591 if (MsIsWinXPOrGreater())
14592 {
14593 setsockopt(s, SOL_SOCKET, SO_CONDITIONAL_ACCEPT, (char *)&true_flag, sizeof(bool));
14594
14595 backlog = 1;
14596 }
14597 }
14598 #endif // OS_WIN32
14599
14600 if (listen(s, backlog))
14601 {
14602 // Listen failure
14603 closesocket(s);
14604 return NULL;
14605 }
14606
14607 // Success
14608 sock = NewSock();
14609 sock->Connected = false;
14610 sock->AsyncMode = false;
14611 sock->ServerMode = true;
14612 sock->Type = SOCK_TCP;
14613 sock->socket = s;
14614 sock->ListenMode = true;
14615 sock->SecureMode = false;
14616 sock->LocalPort = port;
14617 sock->LocalOnly = local_only;
14618 sock->EnableConditionalAccept = enable_ca;
14619
14620 return sock;
14621 }
14622
14623 // TCP disconnect
Disconnect(SOCK * sock)14624 void Disconnect(SOCK *sock)
14625 {
14626 SOCKET s;
14627 bool true_flag = true;
14628 bool false_flag = false;
14629 // Validate arguments
14630 if (sock == NULL)
14631 {
14632 return;
14633 }
14634
14635 sock->Disconnecting = true;
14636
14637 #ifdef ENABLE_SSL_LOGGING
14638 SockCloseSslLogging(sock);
14639 #endif // ENABLE_SSL_LOGGING
14640
14641 #ifdef OS_UNIX
14642 UnixFreeAsyncSocket(sock);
14643 #endif // UnixFreeAsyncSocket
14644
14645 if (sock->Type == SOCK_TCP && sock->ListenMode)
14646 {
14647 bool no_tcp_check_port = false;
14648
14649 // Connect to localhost if the socket is in listening
14650 sock->CancelAccept = true;
14651
14652 #if defined(UNIX_LINUX) || defined(UNIX_MACOS)
14653 {
14654 pthread_t t = sock->CallingThread;
14655
14656 // Send a signal to the socket to abort accept() forcibly on Linux
14657 if (t != 0)
14658 {
14659 pthread_kill(t, SIGUSR1);
14660
14661 SleepThread(200);
14662 }
14663 }
14664 #endif // defined(UNIX_LINUX) || defined(UNIX_MACOS)
14665
14666 #ifdef OS_WIN32
14667 if (sock->hAcceptEvent != NULL)
14668 {
14669 SetEvent(sock->hAcceptEvent);
14670
14671 no_tcp_check_port = true;
14672 }
14673 #endif // OS_WIN32
14674
14675 if (sock->AcceptCanceled == false)
14676 {
14677 if (no_tcp_check_port == false)
14678 {
14679 if (sock->IPv6 == false)
14680 {
14681 CheckTCPPort("127.0.0.1", sock->LocalPort);
14682 }
14683 else
14684 {
14685 CheckTCPPort("::1", sock->LocalPort);
14686 }
14687 }
14688 }
14689 }
14690
14691 Lock(disconnect_function_lock);
14692
14693 Lock(sock->disconnect_lock);
14694
14695 if (sock->Type == SOCK_TCP)
14696 {
14697 if (sock->socket != INVALID_SOCKET)
14698 {
14699 // Forced disconnection flag
14700 #ifdef SO_DONTLINGER
14701 setsockopt(sock->socket, SOL_SOCKET, SO_DONTLINGER, (char *)&true_flag, sizeof(bool));
14702 #else // SO_DONTLINGER
14703 setsockopt(sock->socket, SOL_SOCKET, SO_LINGER, (char *)&false_flag, sizeof(bool));
14704 #endif // SO_DONTLINGER
14705 // setsockopt(sock->socket, SOL_SOCKET, SO_REUSEADDR, (char *)&true_flag, sizeof(bool));
14706 }
14707
14708 // TCP socket
14709 Lock(sock->lock);
14710 {
14711 if (sock->socket == INVALID_SOCKET)
14712 {
14713 Unlock(sock->lock);
14714 Unlock(sock->disconnect_lock);
14715 Unlock(disconnect_function_lock);
14716 return;
14717 }
14718 s = sock->socket;
14719
14720 if (sock->Connected)
14721 {
14722 struct linger ling;
14723 Zero(&ling, sizeof(ling));
14724
14725
14726 #if 0
14727 // SSL disconnect
14728 Lock(sock->ssl_lock);
14729 {
14730 if (sock->SecureMode)
14731 {
14732 SSL_shutdown(sock->ssl);
14733 }
14734 }
14735 Unlock(sock->ssl_lock);
14736 #endif
14737 // Disconnect
14738 shutdown(s, 2);
14739 }
14740
14741 // Close the socket
14742 closesocket(s);
14743
14744 #ifdef OS_UNIX
14745 #ifdef FIX_SSL_BLOCKING
14746 if (sock->CallingThread != NULL)
14747 {
14748 pthread_kill(sock->CallingThread, 64);
14749 }
14750 #endif // FIX_SSL_BLOCKING
14751 #endif // OS_UNIX
14752
14753 // Release the SSL
14754 Lock(sock->ssl_lock);
14755 {
14756 if (sock->SecureMode)
14757 {
14758 if (sock->ssl != NULL)
14759 {
14760 Lock(openssl_lock);
14761 {
14762 SSL_free(sock->ssl);
14763 FreeSSLCtx(sock->ssl_ctx);
14764 }
14765 Unlock(openssl_lock);
14766 sock->ssl = NULL;
14767 sock->ssl_ctx = NULL;
14768 }
14769 sock->Connected = false;
14770 sock->SecureMode = false;
14771 }
14772 }
14773 Unlock(sock->ssl_lock);
14774
14775 // Initialization
14776 sock->socket = INVALID_SOCKET;
14777 sock->Type = 0;
14778 sock->AsyncMode = false;
14779 sock->Connected = false;
14780 sock->ListenMode = false;
14781 sock->SecureMode = false;
14782
14783 if (sock->IpClientAdded)
14784 {
14785 DelIpClient(&sock->RemoteIP);
14786 sock->IpClientAdded = false;
14787 }
14788 }
14789 Unlock(sock->lock);
14790
14791 if (sock->BulkSendTube != NULL)
14792 {
14793 TubeDisconnect(sock->BulkSendTube);
14794 }
14795
14796 if (sock->BulkRecvTube != NULL)
14797 {
14798 TubeDisconnect(sock->BulkRecvTube);
14799 }
14800 }
14801 else if (sock->Type == SOCK_UDP)
14802 {
14803 // UDP socket
14804 Lock(sock->lock);
14805 {
14806 if (sock->socket == INVALID_SOCKET)
14807 {
14808 Unlock(sock->lock);
14809 Unlock(sock->disconnect_lock);
14810 Unlock(disconnect_function_lock);
14811 return;
14812 }
14813
14814 s = sock->socket;
14815
14816 // Close the socket
14817 closesocket(s);
14818
14819 // Initialization
14820 sock->socket = INVALID_SOCKET;
14821 sock->Type = 0;
14822 sock->AsyncMode = false;
14823 sock->Connected = false;
14824 sock->ListenMode = false;
14825 sock->SecureMode = false;
14826 }
14827 Unlock(sock->lock);
14828 }
14829 else if (sock->Type == SOCK_INPROC)
14830 {
14831 // In-process socket
14832 if (sock->ListenMode)
14833 {
14834 // Stop the Accept process
14835 sock->CancelAccept = true;
14836
14837 Set(sock->InProcAcceptEvent);
14838
14839 LockQueue(sock->InProcAcceptQueue);
14840 {
14841 while (true)
14842 {
14843 SOCK *ss = GetNext(sock->InProcAcceptQueue);
14844 if (ss == NULL)
14845 {
14846 break;
14847 }
14848
14849 Disconnect(ss);
14850 ReleaseSock(ss);
14851 }
14852 }
14853 UnlockQueue(sock->InProcAcceptQueue);
14854 }
14855 else
14856 {
14857 // Disconnect the Tube
14858 TubeDisconnect(sock->SendTube);
14859 TubeDisconnect(sock->RecvTube);
14860
14861 sock->socket = INVALID_SOCKET;
14862 sock->AsyncMode = false;
14863 sock->Connected = false;
14864 sock->ListenMode = false;
14865 sock->SecureMode = false;
14866 }
14867 }
14868 else if (sock->Type == SOCK_RUDP_LISTEN)
14869 {
14870 // RUDP Listen socket
14871 if (sock->ListenMode)
14872 {
14873 // Stop the Accept process
14874 sock->CancelAccept = true;
14875
14876 Set(sock->R_UDP_Stack->NewSockConnectEvent);
14877
14878 sock->R_UDP_Stack->Halt = true;
14879 Set(sock->R_UDP_Stack->HaltEvent);
14880 SetSockEvent(sock->R_UDP_Stack->SockEvent);
14881 }
14882 }
14883 else if (sock->Type == SOCK_REVERSE_LISTEN)
14884 {
14885 // Reverse Listen socket
14886 if (sock->ListenMode)
14887 {
14888 // Stop the Accept process
14889 sock->CancelAccept = true;
14890
14891 Set(sock->ReverseAcceptEvent);
14892
14893 LockQueue(sock->ReverseAcceptQueue);
14894 {
14895 while (true)
14896 {
14897 SOCK *ss = GetNext(sock->ReverseAcceptQueue);
14898 if (ss == NULL)
14899 {
14900 break;
14901 }
14902
14903 Disconnect(ss);
14904 ReleaseSock(ss);
14905 }
14906 }
14907 UnlockQueue(sock->ReverseAcceptQueue);
14908 }
14909 }
14910 Unlock(sock->disconnect_lock);
14911
14912 Unlock(disconnect_function_lock);
14913 }
14914
14915 typedef struct TCP_PORT_CHECK
14916 {
14917 REF *ref;
14918 char hostname[MAX_SIZE];
14919 UINT port;
14920 bool ok;
14921 } TCP_PORT_CHECK;
14922
14923 // The thread to check the TCP port
CheckTCPPortThread(THREAD * thread,void * param)14924 void CheckTCPPortThread(THREAD *thread, void *param)
14925 {
14926 TCP_PORT_CHECK *c;
14927 SOCK *s;
14928 // Validate arguments
14929 if (thread == NULL || param == NULL)
14930 {
14931 return;
14932 }
14933
14934 c = (TCP_PORT_CHECK *)param;
14935 AddRef(c->ref);
14936 NoticeThreadInit(thread);
14937
14938 AddWaitThread(thread);
14939
14940 s = Connect(c->hostname, c->port);
14941 if (s != NULL)
14942 {
14943 c->ok = true;
14944 Disconnect(s);
14945 ReleaseSock(s);
14946 }
14947
14948 if (Release(c->ref) == 0)
14949 {
14950 Free(c);
14951 }
14952
14953 DelWaitThread(thread);
14954 }
14955
14956 // Check whether the TCP port can be connected
CheckTCPPortEx(char * hostname,UINT port,UINT timeout)14957 bool CheckTCPPortEx(char *hostname, UINT port, UINT timeout)
14958 {
14959 SOCK *s;
14960 // Validate arguments
14961 if (hostname == NULL || port == 0 || port >= 65536)
14962 {
14963 return false;
14964 }
14965
14966 if (timeout == 0)
14967 {
14968 timeout = TIMEOUT_TCP_PORT_CHECK;
14969 }
14970
14971 s = ConnectEx(hostname, port, timeout);
14972 if (s == NULL)
14973 {
14974 return false;
14975 }
14976 else
14977 {
14978 Disconnect(s);
14979 ReleaseSock(s);
14980 return true;
14981 }
14982 }
CheckTCPPort(char * hostname,UINT port)14983 bool CheckTCPPort(char *hostname, UINT port)
14984 {
14985 return CheckTCPPortEx(hostname, port, TIMEOUT_TCP_PORT_CHECK);
14986 }
14987
14988 #ifdef OS_UNIX
14989 // Connection with timeout (UNIX version)
connect_timeout(SOCKET s,struct sockaddr * addr,int size,int timeout,bool * cancel_flag)14990 int connect_timeout(SOCKET s, struct sockaddr *addr, int size, int timeout, bool *cancel_flag)
14991 {
14992 SOCKSET set;
14993 bool ok = false;
14994 UINT64 start_time;
14995 // Validate arguments
14996 if (s == INVALID_SOCKET || addr == NULL)
14997 {
14998 return -1;
14999 }
15000 if (timeout == 0)
15001 {
15002 timeout = TIMEOUT_TCP_PORT_CHECK;
15003 }
15004
15005 UnixSetSocketNonBlockingMode(s, true);
15006
15007 start_time = Tick64();
15008
15009 while (true)
15010 {
15011 int ret;
15012 ret = connect(s, addr, size);
15013 if (ret == 0 || errno == EISCONN)
15014 {
15015 ok = true;
15016 break;
15017 }
15018 else
15019 {
15020 if (((start_time + (UINT64)timeout) <= Tick64()) || (errno != EAGAIN && errno != EINPROGRESS && errno != EALREADY))
15021 {
15022 // Failure
15023 break;
15024 }
15025 else if (*cancel_flag)
15026 {
15027 // Cancel
15028 break;
15029 }
15030 else
15031 {
15032 // Connecting
15033 SleepThread(50);
15034 UnixSelectInner(1, (UINT *)&s, 1, (UINT *)&s, 100);
15035 }
15036 }
15037 }
15038
15039 UnixSetSocketNonBlockingMode(s, false);
15040
15041 if (ok)
15042 {
15043 return 0;
15044 }
15045 else
15046 {
15047 return -1;
15048 }
15049 }
15050 #else
15051 // Connection with timeout (Win32 version)
connect_timeout(SOCKET s,struct sockaddr * addr,int size,int timeout,bool * cancel_flag)15052 int connect_timeout(SOCKET s, struct sockaddr *addr, int size, int timeout, bool *cancel_flag)
15053 {
15054 UINT64 start_time;
15055 bool ok = false;
15056 bool timeouted = false;
15057 WSAEVENT hEvent;
15058 UINT zero = 0;
15059 UINT tmp = 0;
15060 UINT ret_size = 0;
15061 bool is_nt = false;
15062 // Validate arguments
15063 if (s == INVALID_SOCKET || addr == NULL)
15064 {
15065 return -1;
15066 }
15067 if (timeout == 0)
15068 {
15069 timeout = TIMEOUT_TCP_PORT_CHECK;
15070 }
15071
15072 is_nt = OS_IS_WINDOWS_NT(GetOsInfo()->OsType);
15073
15074 // Create an event
15075 hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
15076
15077 // Associate the socket with the event
15078 WSAEventSelect(s, hEvent, FD_CONNECT);
15079
15080 start_time = Tick64();
15081
15082 while (true)
15083 {
15084 int ret;
15085
15086 ret = connect(s, addr, size);
15087
15088 if (ret == 0)
15089 {
15090 ok = true;
15091 break;
15092 }
15093 else
15094 {
15095 int err = WSAGetLastError();
15096 //Debug("err=%u\n", err);
15097 //Debug("cancel_flag=%u\n", *cancel_flag);
15098 if (timeouted && ((err == WSAEALREADY) || (err == WSAEWOULDBLOCK && !is_nt)))
15099 {
15100 // Time-out
15101 ok = false;
15102 break;
15103 }
15104 if (*cancel_flag)
15105 {
15106 // Cancel
15107 ok = false;
15108 break;
15109 }
15110 if (err == WSAEISCONN || (err == WSAEINVAL && is_nt))
15111 {
15112 ok = true;
15113 break;
15114 }
15115 if (((start_time + (UINT64)timeout) <= Tick64()) || (err != WSAEWOULDBLOCK && err != WSAEALREADY && (is_nt || err != WSAEINVAL)))
15116 {
15117 // Failure (timeout)
15118 break;
15119 }
15120 else
15121 {
15122 SleepThread(10);
15123 // Connecting
15124 if (WaitForSingleObject(hEvent, 100) == WAIT_OBJECT_0)
15125 {
15126 timeouted = true;
15127 }
15128 }
15129 }
15130 }
15131
15132 // Remove the socket from the event
15133 WSAEventSelect(s, hEvent, 0);
15134
15135 // Restore to synchronized socket
15136 WSAIoctl(s, FIONBIO, &zero, sizeof(zero), &tmp, sizeof(tmp), &ret_size, NULL, NULL);
15137
15138 // Close the event
15139 CloseHandle(hEvent);
15140
15141 if (ok)
15142 {
15143 return 0;
15144 }
15145 else
15146 {
15147 return -1;
15148 }
15149 }
15150 #endif // OS_UNIX
15151
15152 // Set the TOS value of the socket
SetSockTos(SOCK * s,int tos)15153 void SetSockTos(SOCK *s, int tos)
15154 {
15155 // Validate arguments
15156 if (s == NULL)
15157 {
15158 return;
15159 }
15160
15161 if (s->CurrentTos == tos)
15162 {
15163 return;
15164 }
15165
15166 #ifdef IP_TOS
15167 setsockopt(s->socket, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int));
15168 #endif // IP_TOS
15169
15170 s->CurrentTos = tos;
15171 }
15172
15173 // Set the priority of the socket
SetSockHighPriority(SOCK * s,bool flag)15174 void SetSockHighPriority(SOCK *s, bool flag)
15175 {
15176 // Validate arguments
15177 if (s == NULL)
15178 {
15179 return;
15180 }
15181
15182 SetSockTos(s, (flag ? 16 : 0));
15183 }
15184
15185 // Connect to the IPv4 host using a socket
ConnectTimeoutIPv4(IP * ip,UINT port,UINT timeout,bool * cancel_flag)15186 SOCKET ConnectTimeoutIPv4(IP *ip, UINT port, UINT timeout, bool *cancel_flag)
15187 {
15188 SOCKET s;
15189 struct sockaddr_in sockaddr4;
15190 struct in_addr addr4;
15191
15192 Zero(&sockaddr4, sizeof(sockaddr4));
15193 Zero(&addr4, sizeof(addr4));
15194
15195 // Generate a sockaddr_in
15196 IPToInAddr(&addr4, ip);
15197 sockaddr4.sin_port = htons((USHORT)port);
15198 sockaddr4.sin_family = AF_INET;
15199 sockaddr4.sin_addr.s_addr = addr4.s_addr;
15200
15201 // Socket creation
15202 s = socket(AF_INET, SOCK_STREAM, 0);
15203 if (s != INVALID_SOCKET)
15204 {
15205 // Connection
15206 if (connect_timeout(s, (struct sockaddr *)&sockaddr4, sizeof(struct sockaddr_in), timeout, cancel_flag) != 0)
15207 {
15208 // Connection failure
15209 closesocket(s);
15210 s = INVALID_SOCKET;
15211 }
15212 }
15213
15214 return s;
15215 }
15216
15217 // Identify whether the HTTPS server to be connected is a SoftEther VPN
DetectIsServerSoftEtherVPN(SOCK * s)15218 bool DetectIsServerSoftEtherVPN(SOCK *s)
15219 {
15220 HTTP_HEADER *h;
15221 char ip_str[MAX_SIZE];
15222 char *send_str;
15223 UINT content_len;
15224 BUF *recv_buf;
15225 void *socket_buffer;
15226 UINT socket_buffer_size = 32768;
15227 bool ok = false;
15228 // Validate arguments
15229 if (s == NULL)
15230 {
15231 return false;
15232 }
15233
15234 IPToStr(ip_str, sizeof(ip_str), &s->RemoteIP);
15235
15236 // Request generation
15237 h = NewHttpHeaderEx("GET", "/", "HTTP/1.1", true);
15238 AddHttpValue(h, NewHttpValue("X-VPN", "1"));
15239 AddHttpValue(h, NewHttpValue("Host", ip_str));
15240 AddHttpValue(h, NewHttpValue("Keep-Alive", HTTP_KEEP_ALIVE));
15241 AddHttpValue(h, NewHttpValue("Connection", "Keep-Alive"));
15242 AddHttpValue(h, NewHttpValue("Accept-Language", "ja"));
15243 AddHttpValue(h, NewHttpValue("User-Agent", DEFAULT_USER_AGENT));
15244 AddHttpValue(h, NewHttpValue("Pragma", "no-cache"));
15245 AddHttpValue(h, NewHttpValue("Cache-Control", "no-cache"));
15246
15247
15248
15249 send_str = HttpHeaderToStr(h);
15250 FreeHttpHeader(h);
15251
15252 // Transmission
15253 if (SendAll(s, send_str, StrLen(send_str), true) == false)
15254 {
15255 Free(send_str);
15256 return false;
15257 }
15258
15259 Free(send_str);
15260
15261 // Receive
15262 h = RecvHttpHeader(s);
15263 if (h == NULL)
15264 {
15265 return false;
15266 }
15267
15268 // Get the length of the content
15269 content_len = GetContentLength(h);
15270 FreeHttpHeader(h);
15271
15272 if (content_len == 0 || content_len >= (1024 * 1024))
15273 {
15274 return false;
15275 }
15276
15277 // Receive contents
15278 recv_buf = NewBuf();
15279 socket_buffer = Malloc(socket_buffer_size);
15280
15281 while (true)
15282 {
15283 UINT recvsize = MIN(socket_buffer_size, content_len - recv_buf->Size);
15284 UINT size;
15285
15286 if (recvsize == 0)
15287 {
15288 ok = true;
15289 break;
15290 }
15291
15292 size = Recv(s, socket_buffer, recvsize, true);
15293 if (size == 0)
15294 {
15295 // Disconnected
15296 break;
15297 }
15298
15299 WriteBuf(recv_buf, socket_buffer, size);
15300 }
15301
15302 SeekBuf(recv_buf, 0, 0);
15303 Free(socket_buffer);
15304
15305 if (ok)
15306 {
15307 // Examine to confirm whether the incoming data is a SoftEther VPN protocol
15308 char tmp[1024];
15309
15310 Zero(tmp, sizeof(tmp));
15311
15312 Copy(tmp, recv_buf->Buf, MIN(recv_buf->Size, (sizeof(tmp) - 1)));
15313
15314 ok = false;
15315
15316 if (StartWith(tmp, http_detect_server_startwith))
15317 {
15318 ok = true;
15319 }
15320 else if (InStr(tmp, http_detect_server_tag_future))
15321 {
15322 ok = true;
15323 }
15324 }
15325
15326 FreeBuf(recv_buf);
15327
15328 return ok;
15329 }
15330
15331 // TCP connection thread
ConnectThreadForTcp(THREAD * thread,void * param)15332 void ConnectThreadForTcp(THREAD *thread, void *param)
15333 {
15334 SOCK *sock;
15335 char hostname[MAX_SIZE];
15336 CONNECT_TCP_RUDP_PARAM *p = (CONNECT_TCP_RUDP_PARAM *)param;
15337 if (thread == NULL || p == NULL)
15338 {
15339 return;
15340 }
15341
15342 // Delay
15343 if (p->Delay >= 1)
15344 {
15345 WaitEx(NULL, p->Delay, p->CancelFlag);
15346 }
15347
15348 // Connecting process
15349 IPToStr(hostname, sizeof(hostname), &p->Ip);
15350 sock = ConnectEx3(hostname, p->Port, p->Timeout, p->CancelFlag, NULL, NULL, false, false, true);
15351
15352 if (sock != NULL && p->Tcp_TryStartSsl)
15353 {
15354 bool ssl_ret = false;
15355
15356 p->Tcp_InNegotiation = true;
15357
15358 // Attempt the SSL negotiation to take this opportunity
15359 Lock(p->CancelLock);
15360 {
15361 if ((*p->CancelFlag) == false)
15362 {
15363 p->CancelDisconnectSock = sock;
15364 AddRef(sock->ref);
15365 }
15366 else
15367 {
15368 Debug("User Cancel to StartSSL.\n");
15369 goto LABEL_CANCEL;
15370 }
15371 }
15372 Unlock(p->CancelLock);
15373
15374 // Start the SSL communication
15375 ssl_ret = StartSSLEx(sock, NULL, NULL, p->Tcp_SslNoTls, 0, p->Hostname);
15376
15377 if (ssl_ret)
15378 {
15379 // Identify whether the HTTPS server to be connected is a SoftEther VPN
15380 SetTimeout(sock, (10 * 1000));
15381 ssl_ret = DetectIsServerSoftEtherVPN(sock);
15382 SetTimeout(sock, INFINITE);
15383
15384 if (ssl_ret == false)
15385 {
15386 Debug("DetectIsServerSoftEtherVPN Error.\n");
15387 }
15388 }
15389
15390 Lock(p->CancelLock);
15391 {
15392 ReleaseSock(p->CancelDisconnectSock);
15393 p->CancelDisconnectSock = NULL;
15394 LABEL_CANCEL:
15395 DoNothing();
15396 }
15397 Unlock(p->CancelLock);
15398
15399 if (ssl_ret == false)
15400 {
15401 // SSL negotiation failure
15402 Disconnect(sock);
15403 ReleaseSock(sock);
15404
15405 Debug("Fail to StartSSL.\n");
15406
15407 sock = NULL;
15408 }
15409 }
15410
15411 p->Result_Tcp_Sock = sock;
15412 p->Ok = (p->Result_Tcp_Sock == NULL ? false : true);
15413 p->FinishedTick = Tick64();
15414 p->Finished = true;
15415 p->Tcp_InNegotiation = false;
15416
15417 Set(p->FinishEvent);
15418 }
15419
15420 // R-UDP over ICMP / over DNS connection thread
ConnectThreadForOverDnsOrIcmp(THREAD * thread,void * param)15421 void ConnectThreadForOverDnsOrIcmp(THREAD *thread, void *param)
15422 {
15423 SOCK *sock;
15424 CONNECT_TCP_RUDP_PARAM *p = (CONNECT_TCP_RUDP_PARAM *)param;
15425 if (thread == NULL || p == NULL)
15426 {
15427 return;
15428 }
15429
15430 // Delay
15431 if (p->Delay >= 1)
15432 {
15433 WaitEx(NULL, p->Delay, p->CancelFlag);
15434 }
15435
15436 // Connecting process
15437 sock = NewRUDPClientDirect(p->SvcName, &p->Ip,
15438 (p->RUdpProtocol == RUDP_PROTOCOL_DNS ? 53 : MAKE_SPECIAL_PORT(IP_PROTO_ICMPV4)),
15439 &p->NatT_ErrorCode, p->Timeout, p->CancelFlag, NULL, NULL,
15440 (p->RUdpProtocol == RUDP_PROTOCOL_DNS ? 0 : MAKE_SPECIAL_PORT(IP_PROTO_ICMPV4)),
15441 (p->RUdpProtocol == RUDP_PROTOCOL_DNS ? true : false));
15442
15443 p->Result_Nat_T_Sock = sock;
15444 p->Ok = (p->Result_Nat_T_Sock == NULL ? false : true);
15445 p->FinishedTick = Tick64();
15446 p->Finished = true;
15447
15448 Set(p->FinishEvent);
15449 }
15450
15451 // R-UDP (via NAT-T) connection thread
ConnectThreadForRUDP(THREAD * thread,void * param)15452 void ConnectThreadForRUDP(THREAD *thread, void *param)
15453 {
15454 SOCK *sock;
15455 CONNECT_TCP_RUDP_PARAM *p = (CONNECT_TCP_RUDP_PARAM *)param;
15456 if (thread == NULL || p == NULL)
15457 {
15458 return;
15459 }
15460
15461 // Delay
15462 if (p->Delay >= 1)
15463 {
15464 WaitEx(NULL, p->Delay, p->CancelFlag);
15465 }
15466
15467 // Connecting process
15468 sock = NewRUDPClientNatT(p->SvcName, &p->Ip, &p->NatT_ErrorCode, p->Timeout, p->CancelFlag, p->HintStr, p->TargetHostname);
15469
15470 p->Result_Nat_T_Sock = sock;
15471 p->Ok = (p->Result_Nat_T_Sock == NULL ? false : true);
15472 p->FinishedTick = Tick64();
15473 p->Finished = true;
15474
15475 Set(p->FinishEvent);
15476 }
15477
15478 // TCP connection
Connect(char * hostname,UINT port)15479 SOCK *Connect(char *hostname, UINT port)
15480 {
15481 return ConnectEx(hostname, port, 0);
15482 }
ConnectEx(char * hostname,UINT port,UINT timeout)15483 SOCK *ConnectEx(char *hostname, UINT port, UINT timeout)
15484 {
15485 return ConnectEx2(hostname, port, timeout, NULL);
15486 }
ConnectEx2(char * hostname,UINT port,UINT timeout,bool * cancel_flag)15487 SOCK *ConnectEx2(char *hostname, UINT port, UINT timeout, bool *cancel_flag)
15488 {
15489 return ConnectEx3(hostname, port, timeout, cancel_flag, NULL, NULL, false, false, true);
15490 }
ConnectEx3(char * hostname,UINT port,UINT timeout,bool * cancel_flag,char * nat_t_svc_name,UINT * nat_t_error_code,bool try_start_ssl,bool ssl_no_tls,bool no_get_hostname)15491 SOCK *ConnectEx3(char *hostname, UINT port, UINT timeout, bool *cancel_flag, char *nat_t_svc_name, UINT *nat_t_error_code, bool try_start_ssl, bool ssl_no_tls, bool no_get_hostname)
15492 {
15493 return ConnectEx4(hostname, port, timeout, cancel_flag, nat_t_svc_name, nat_t_error_code, try_start_ssl, ssl_no_tls,
15494 no_get_hostname, NULL);
15495 }
ConnectEx4(char * hostname,UINT port,UINT timeout,bool * cancel_flag,char * nat_t_svc_name,UINT * nat_t_error_code,bool try_start_ssl,bool ssl_no_tls,bool no_get_hostname,IP * ret_ip)15496 SOCK *ConnectEx4(char *hostname, UINT port, UINT timeout, bool *cancel_flag, char *nat_t_svc_name, UINT *nat_t_error_code, bool try_start_ssl, bool ssl_no_tls, bool no_get_hostname, IP *ret_ip)
15497 {
15498 SOCK *sock;
15499 SOCKET s;
15500 struct linger ling;
15501 IP ip4;
15502 IP ip6;
15503 bool true_flag = true;
15504 bool false_flag = false;
15505 char tmp[MAX_SIZE];
15506 IP current_ip;
15507 bool is_ipv6 = false;
15508 bool dummy = false;
15509 bool use_natt = false;
15510 char hostname_original[MAX_SIZE];
15511 char hint_str[MAX_SIZE];
15512 bool force_use_natt = false;
15513 UINT dummy_int = 0;
15514 IP dummy_ret_ip;
15515 // Validate arguments
15516 if (hostname == NULL || port == 0 || port >= 65536 || IsEmptyStr(hostname))
15517 {
15518 return NULL;
15519 }
15520 if (timeout == 0)
15521 {
15522 timeout = TIMEOUT_TCP_PORT_CHECK;
15523 }
15524 if (cancel_flag == NULL)
15525 {
15526 cancel_flag = &dummy;
15527 }
15528 if (nat_t_error_code == NULL)
15529 {
15530 nat_t_error_code = &dummy_int;
15531 }
15532
15533 Zero(&dummy_ret_ip, sizeof(IP));
15534 if (ret_ip == NULL)
15535 {
15536 ret_ip = &dummy_ret_ip;
15537 }
15538
15539 Zero(hint_str, sizeof(hint_str));
15540 StrCpy(hostname_original, sizeof(hostname_original), hostname);
15541
15542 use_natt = (IsEmptyStr(nat_t_svc_name) ? false : true);
15543
15544 if (use_natt)
15545 {
15546 // In case of using NAT-T, split host name if the '/' is included in the host name
15547 UINT i = SearchStrEx(hostname, "/", 0, false);
15548
15549 if (i == INFINITE)
15550 {
15551 // Not included
15552 StrCpy(hostname_original, sizeof(hostname_original), hostname);
15553 }
15554 else
15555 {
15556 // Included
15557 StrCpy(hostname_original, sizeof(hostname_original), hostname);
15558 hostname_original[i] = 0;
15559
15560 // Force to use the NAT-T
15561 force_use_natt = true;
15562
15563 // Copy the hint string
15564 StrCpy(hint_str, sizeof(hint_str), hostname + i + 1);
15565
15566 if (StrCmpi(hint_str, "tcp") == 0 || StrCmpi(hint_str, "disable") == 0
15567 || StrCmpi(hint_str, "disabled") == 0
15568 || StrCmpi(hint_str, "no") == 0 || StrCmpi(hint_str, "none") == 0)
15569 {
15570 // Force not to use the NAT-T
15571 force_use_natt = false;
15572 use_natt = false;
15573 }
15574 }
15575 }
15576 else
15577 {
15578 StrCpy(hostname_original, sizeof(hostname_original), hostname);
15579 }
15580
15581 Zero(¤t_ip, sizeof(current_ip));
15582
15583 Zero(&ip4, sizeof(ip4));
15584 Zero(&ip6, sizeof(ip6));
15585
15586 if (IsZeroIp(ret_ip) == false)
15587 {
15588 // Skip name resolution
15589 if (IsIP6(ret_ip))
15590 {
15591 Copy(&ip6, ret_ip, sizeof(IP));
15592 }
15593 else
15594 {
15595 Copy(&ip4, ret_ip, sizeof(IP));
15596 }
15597
15598 //Debug("Using cached IP address: %s = %r\n", hostname_original, ret_ip);
15599 }
15600 else
15601 {
15602 // Forward resolution
15603 if (GetIP46Ex(&ip4, &ip6, hostname_original, 0, cancel_flag) == false)
15604 {
15605 return NULL;
15606 }
15607 }
15608
15609 if (IsZeroIp(&ip4) == false && IsIPLocalHostOrMySelf(&ip4))
15610 {
15611 // NAT-T isn't used in the case of connection to localhost
15612 force_use_natt = false;
15613 use_natt = false;
15614 }
15615
15616 s = INVALID_SOCKET;
15617
15618 // Attempt to connect with IPv4
15619 if (IsZeroIp(&ip4) == false)
15620 {
15621 if (use_natt == false)
15622 {
15623 // Normal connection without using NAT-T
15624 s = ConnectTimeoutIPv4(&ip4, port, timeout, cancel_flag);
15625
15626 if (s != INVALID_SOCKET)
15627 {
15628 Copy(¤t_ip, &ip4, sizeof(IP));
15629
15630 Copy(ret_ip, &ip4, sizeof(IP));
15631 }
15632 }
15633 else if (force_use_natt)
15634 {
15635 // The connection by forcing the use of NAT-T (not to connection with normal TCP)
15636 SOCK *nat_t_sock = NewRUDPClientNatT(nat_t_svc_name, &ip4, nat_t_error_code, timeout, cancel_flag,
15637 hint_str, hostname);
15638
15639 if (nat_t_sock != NULL)
15640 {
15641 StrCpy(nat_t_sock->UnderlayProtocol, sizeof(nat_t_sock->UnderlayProtocol), SOCK_UNDERLAY_NAT_T);
15642 AddProtocolDetailsStr(nat_t_sock->ProtocolDetails, sizeof(nat_t_sock->ProtocolDetails),
15643 "RUDP");
15644 }
15645
15646 Copy(ret_ip, &ip4, sizeof(IP));
15647
15648 return nat_t_sock;
15649 }
15650 else
15651 {
15652 // Use the connections using NAT-T with normal TCP connection together
15653 // (Use multiple threads to try to connect in four connection methods concurrently)
15654 CONNECT_TCP_RUDP_PARAM p1, p2, p3, p4;
15655 EVENT *finish_event;
15656 THREAD *t1, *t2, *t3, *t4;
15657 UINT64 start_tick = Tick64();
15658 UINT64 giveup_for_all_tick = start_tick + (UINT64)SOCK_CONNECT_WAIT_FOR_ICMP_AND_DNS_AT_LEAST;
15659 bool cancel_flag2 = false;
15660 SOCK *cancel_sock = NULL;
15661
15662 finish_event = NewEvent();
15663
15664 Zero(&p1, sizeof(p1));
15665 Zero(&p2, sizeof(p2));
15666 Zero(&p3, sizeof(p3));
15667 Zero(&p4, sizeof(p4));
15668
15669 // p1: TCP
15670 StrCpy(p1.Hostname, sizeof(p1.Hostname), hostname_original);
15671 Copy(&p1.Ip, &ip4, sizeof(IP));
15672 p1.Port = port;
15673 p1.Timeout = timeout;
15674 p1.CancelFlag = &cancel_flag2;
15675 p1.FinishEvent = finish_event;
15676 p1.Tcp_TryStartSsl = try_start_ssl;
15677 p1.Tcp_SslNoTls = ssl_no_tls;
15678 p1.CancelLock = NewLock();
15679
15680 // p2: NAT-T
15681 StrCpy(p2.Hostname, sizeof(p2.Hostname), hostname_original);
15682 Copy(&p2.Ip, &ip4, sizeof(IP));
15683 p2.Port = port;
15684 p2.Timeout = timeout;
15685 p2.CancelFlag = &cancel_flag2;
15686 p2.FinishEvent = finish_event;
15687
15688 StrCpy(p2.HintStr, sizeof(p2.HintStr), hint_str);
15689 StrCpy(p2.TargetHostname, sizeof(p2.TargetHostname), hostname);
15690 StrCpy(p2.SvcName, sizeof(p2.SvcName), nat_t_svc_name);
15691 p2.Delay = 30; // Delay by 30ms
15692
15693 // p3: over ICMP
15694 StrCpy(p3.Hostname, sizeof(p3.Hostname), hostname_original);
15695 Copy(&p3.Ip, &ip4, sizeof(IP));
15696 p3.Port = port;
15697 p3.Timeout = timeout;
15698 p3.CancelFlag = &cancel_flag2;
15699 p3.FinishEvent = finish_event;
15700 StrCpy(p3.SvcName, sizeof(p3.SvcName), nat_t_svc_name);
15701 p3.RUdpProtocol = RUDP_PROTOCOL_ICMP;
15702 p3.Delay = 200; // Delay by 200ms
15703
15704 // p4: over DNS
15705 StrCpy(p4.Hostname, sizeof(p4.Hostname), hostname_original);
15706 Copy(&p4.Ip, &ip4, sizeof(IP));
15707 p4.Port = port;
15708 p4.Timeout = timeout;
15709 p4.CancelFlag = &cancel_flag2;
15710 p4.FinishEvent = finish_event;
15711 StrCpy(p4.SvcName, sizeof(p4.SvcName), nat_t_svc_name);
15712 p4.RUdpProtocol = RUDP_PROTOCOL_DNS;
15713 p4.Delay = 100; // Delay by 100ms
15714
15715 t1 = NewThread(ConnectThreadForTcp, &p1);
15716 t2 = NewThread(ConnectThreadForRUDP, &p2);
15717 t4 = NewThread(ConnectThreadForOverDnsOrIcmp, &p4);
15718 t3 = NewThread(ConnectThreadForOverDnsOrIcmp, &p3);
15719
15720 while (true)
15721 {
15722 UINT64 now = Tick64();
15723
15724 if (*cancel_flag)
15725 {
15726 // Cancel by the user
15727 break;
15728 }
15729
15730 if (p1.Finished && p2.Finished)
15731 {
15732 // Results for both the TCP and the NAT-T were confirmed
15733 if (now >= giveup_for_all_tick)
15734 {
15735 // Wait at least minimum time until successful of the ICMP or the DNS
15736 break;
15737 }
15738
15739 if (p3.Ok || p4.Ok)
15740 {
15741 // Exit the loop immediately if any of the ICMP or the DNS is successful
15742 break;
15743 }
15744 }
15745
15746 if (p1.Finished && p1.Ok)
15747 {
15748 // Have successfully connected by TCP
15749 break;
15750 }
15751
15752 if (p2.Finished && p2.Ok)
15753 {
15754 UINT p1_wait_time;
15755 UINT64 tcp_giveup_tick;
15756 UINT p2_spent_time;
15757 // Have successfully connected by R-UDP
15758 if (p1.Finished)
15759 {
15760 // Result of TCP is confirmed
15761 break;
15762 }
15763
15764 // Calculate the time takes to complete connection of R-UDP
15765 p2_spent_time = (UINT)(p2.FinishedTick - start_tick);
15766
15767 // Decide the grace time for results of TCP until settled.
15768 // The grace time is four times the duration of the R-UDP, and at least 400 milliseconds from the start,
15769 // and up to 2500 milliseconds after the R-UDP results settled
15770 p1_wait_time = p2_spent_time * 4;
15771 p1_wait_time = MAX(p1_wait_time, 400);
15772 //Debug("p2_spent_time = %u, p1_wait_time = %u\n", p2_spent_time, p1_wait_time);
15773
15774 tcp_giveup_tick = start_tick + (UINT64)p1_wait_time;
15775 tcp_giveup_tick = MIN(tcp_giveup_tick, (p2.FinishedTick + 2500ULL));
15776
15777 if (now >= tcp_giveup_tick)
15778 {
15779 // Result of the TCP is uncertain, but give up
15780 if (p1.Finished || p1.Tcp_InNegotiation == false)
15781 {
15782 // Break only when TCP SSL negotiation is not being processed
15783 break;
15784 }
15785 }
15786 }
15787
15788 Wait(finish_event, 25);
15789 }
15790
15791 cancel_flag2 = true;
15792
15793 Lock(p1.CancelLock);
15794 {
15795 if (p1.CancelDisconnectSock != NULL)
15796 {
15797 cancel_sock = p1.CancelDisconnectSock;
15798
15799 AddRef(cancel_sock->ref);
15800 }
15801 }
15802 Unlock(p1.CancelLock);
15803
15804 if (cancel_sock != NULL)
15805 {
15806 Disconnect(cancel_sock);
15807 ReleaseSock(cancel_sock);
15808 }
15809
15810 WaitThread(t1, INFINITE);
15811 WaitThread(t2, INFINITE);
15812 WaitThread(t3, INFINITE);
15813 WaitThread(t4, INFINITE);
15814 ReleaseThread(t1);
15815 ReleaseThread(t2);
15816 ReleaseThread(t3);
15817 ReleaseThread(t4);
15818 ReleaseEvent(finish_event);
15819
15820 DeleteLock(p1.CancelLock);
15821
15822 if (*cancel_flag)
15823 {
15824 // Abandon all the results because the user canceled
15825 Disconnect(p1.Result_Nat_T_Sock);
15826 ReleaseSock(p1.Result_Nat_T_Sock);
15827 Disconnect(p2.Result_Nat_T_Sock);
15828 ReleaseSock(p2.Result_Nat_T_Sock);
15829 Disconnect(p3.Result_Nat_T_Sock);
15830 ReleaseSock(p3.Result_Nat_T_Sock);
15831 Disconnect(p4.Result_Nat_T_Sock);
15832 ReleaseSock(p4.Result_Nat_T_Sock);
15833
15834 return NULL;
15835 }
15836
15837 if (p1.Ok)
15838 {
15839 char hostname[MAX_SIZE];
15840
15841 // Use the results of the TCP
15842 // Dispose other results
15843 Disconnect(p2.Result_Nat_T_Sock);
15844 ReleaseSock(p2.Result_Nat_T_Sock);
15845 Disconnect(p3.Result_Nat_T_Sock);
15846 ReleaseSock(p3.Result_Nat_T_Sock);
15847 Disconnect(p4.Result_Nat_T_Sock);
15848 ReleaseSock(p4.Result_Nat_T_Sock);
15849
15850 if (GetHostName(hostname, sizeof(hostname), &ip4))
15851 {
15852 Free(p1.Result_Tcp_Sock->RemoteHostname);
15853 p1.Result_Tcp_Sock->RemoteHostname = CopyStr(hostname);
15854 }
15855
15856 Copy(ret_ip, &ip4, sizeof(IP));
15857
15858 return p1.Result_Tcp_Sock;
15859 }
15860 else if (p2.Ok)
15861 {
15862 // Use the results of the R-UDP
15863 // Dispose other results
15864 Disconnect(p3.Result_Nat_T_Sock);
15865 ReleaseSock(p3.Result_Nat_T_Sock);
15866 Disconnect(p4.Result_Nat_T_Sock);
15867 ReleaseSock(p4.Result_Nat_T_Sock);
15868
15869 StrCpy(p2.Result_Nat_T_Sock->UnderlayProtocol, sizeof(p2.Result_Nat_T_Sock->UnderlayProtocol),
15870 SOCK_UNDERLAY_NAT_T);
15871 AddProtocolDetailsStr(p2.Result_Nat_T_Sock->UnderlayProtocol, sizeof(p2.Result_Nat_T_Sock->UnderlayProtocol),
15872 "RUDP/UDP");
15873
15874 Copy(ret_ip, &ip4, sizeof(IP));
15875
15876 return p2.Result_Nat_T_Sock;
15877 }
15878 else if (p4.Ok)
15879 {
15880 // Use this if over-DNS success
15881 // Dispose other results
15882 Disconnect(p3.Result_Nat_T_Sock);
15883 ReleaseSock(p3.Result_Nat_T_Sock);
15884
15885 StrCpy(p4.Result_Nat_T_Sock->UnderlayProtocol, sizeof(p4.Result_Nat_T_Sock->UnderlayProtocol),
15886 SOCK_UNDERLAY_DNS);
15887 AddProtocolDetailsStr(p4.Result_Nat_T_Sock->UnderlayProtocol, sizeof(p4.Result_Nat_T_Sock->UnderlayProtocol),
15888 "RUDP/DNS");
15889
15890 Copy(ret_ip, &ip4, sizeof(IP));
15891
15892 return p4.Result_Nat_T_Sock;
15893 }
15894 else if (p3.Ok)
15895 {
15896 // Use this if over ICMP success
15897 StrCpy(p3.Result_Nat_T_Sock->UnderlayProtocol, sizeof(p3.Result_Nat_T_Sock->UnderlayProtocol),
15898 SOCK_UNDERLAY_ICMP);
15899 AddProtocolDetailsStr(p3.Result_Nat_T_Sock->UnderlayProtocol, sizeof(p3.Result_Nat_T_Sock->UnderlayProtocol),
15900 "RUDP/ICMP");
15901
15902 Copy(ret_ip, &ip4, sizeof(IP));
15903
15904 return p3.Result_Nat_T_Sock;
15905 }
15906 else
15907 {
15908 // Continue the process if all trials failed
15909 *nat_t_error_code = p2.NatT_ErrorCode;
15910 }
15911 }
15912 }
15913
15914 // Attempt to connect with IPv6
15915 if (s == INVALID_SOCKET && IsZeroIp(&ip6) == false)
15916 {
15917 struct sockaddr_in6 sockaddr6;
15918 struct in6_addr addr6;
15919
15920 Zero(&sockaddr6, sizeof(sockaddr6));
15921 Zero(&addr6, sizeof(addr6));
15922
15923 // Generation of the sockaddr_in6
15924 IPToInAddr6(&addr6, &ip6);
15925 sockaddr6.sin6_port = htons((USHORT)port);
15926 sockaddr6.sin6_family = AF_INET6;
15927 sockaddr6.sin6_scope_id = ip6.ipv6_scope_id;
15928 Copy(&sockaddr6.sin6_addr, &addr6, sizeof(addr6));
15929
15930 // Socket creation
15931 s = socket(AF_INET6, SOCK_STREAM, 0);
15932 if (s != INVALID_SOCKET)
15933 {
15934 // Connection
15935 if (connect_timeout(s, (struct sockaddr *)&sockaddr6, sizeof(struct sockaddr_in6), timeout, cancel_flag) != 0)
15936 {
15937 // Connection failure
15938 closesocket(s);
15939 s = INVALID_SOCKET;
15940 }
15941 else
15942 {
15943 Copy(¤t_ip, &ip6, sizeof(IP));
15944
15945 is_ipv6 = true;
15946
15947 Copy(ret_ip, &ip6, sizeof(IP));
15948 }
15949 }
15950 }
15951
15952 if (s == INVALID_SOCKET)
15953 {
15954 // Connection fails on both of IPv4, IPv6
15955 return NULL;
15956 }
15957
15958 // Creating a SOCK
15959 sock = NewSock();
15960 sock->socket = s;
15961 sock->Type = SOCK_TCP;
15962 sock->ServerMode = false;
15963
15964 StrCpy(sock->UnderlayProtocol, sizeof(sock->UnderlayProtocol),
15965 (is_ipv6 ? SOCK_UNDERLAY_NATIVE_V6 : SOCK_UNDERLAY_NATIVE_V4));
15966
15967 AddProtocolDetailsStr(sock->ProtocolDetails, sizeof(sock->ProtocolDetails),
15968 is_ipv6 ? "IPv6" : "IPv4");
15969
15970 // Host name resolution
15971 if (no_get_hostname || (GetHostName(tmp, sizeof(tmp), ¤t_ip) == false))
15972 {
15973 StrCpy(tmp, sizeof(tmp), hostname_original);
15974 }
15975
15976 //Debug("PTR: %s\n", tmp);
15977
15978 sock->RemoteHostname = CopyStr(tmp);
15979
15980 // Debug("new socket: %u\n", s);
15981
15982 Zero(&ling, sizeof(ling));
15983 // Forced disconnection flag
15984 #ifdef SO_DONTLINGER
15985 setsockopt(sock->socket, SOL_SOCKET, SO_DONTLINGER, (char *)&true_flag, sizeof(bool));
15986 #else // SO_DONTLINGER
15987 setsockopt(sock->socket, SOL_SOCKET, SO_LINGER, (char *)&false_flag, sizeof(bool));
15988 #endif // SO_DONTLINGER
15989 // setsockopt(sock->socket, SOL_SOCKET, SO_REUSEADDR, (char *)&true_flag, sizeof(bool));
15990
15991 // Configuring TCP options
15992 setsockopt(sock->socket, IPPROTO_TCP, TCP_NODELAY, (char *)&true_flag, sizeof(bool));
15993
15994 // Initialization of the time-out value
15995 SetTimeout(sock, TIMEOUT_INFINITE);
15996
15997 // Get the socket information
15998 QuerySocketInformation(sock);
15999
16000 if (IsZeroIp(&sock->LocalIP) == false && IsLocalHostIP(&sock->LocalIP) == false)
16001 {
16002 IP current_ip;
16003
16004 if (GetCurrentGlobalIP(¤t_ip, is_ipv6) == false)
16005 {
16006 SetCurrentGlobalIP(&sock->LocalIP, is_ipv6);
16007 }
16008 }
16009
16010 sock->Connected = true;
16011 sock->AsyncMode = false;
16012 sock->SecureMode = false;
16013 sock->IPv6 = is_ipv6;
16014
16015 return sock;
16016 }
16017
16018 // Get the current accepting IPv4 address
TryGetCurrentAcceptingIPv4Address(IP * ip)16019 void TryGetCurrentAcceptingIPv4Address(IP *ip)
16020 {
16021 SOCK *s = ConnectEx(UDP_NAT_T_GET_PRIVATE_IP_TCP_SERVER, 80, 2000);
16022
16023 if (s != NULL)
16024 {
16025 Disconnect(s);
16026 ReleaseSock(s);
16027 }
16028
16029 if (GetCurrentGlobalIP(ip, false))
16030 {
16031 return;
16032 }
16033
16034 GetCurrentGlobalIPGuess(ip, false);
16035 }
16036
16037 // Add a protocol details strings
AddProtocolDetailsStr(char * dst,UINT dst_size,char * str)16038 void AddProtocolDetailsStr(char *dst, UINT dst_size, char *str)
16039 {
16040 TOKEN_LIST *t1, *t2;
16041 UINT i, j;
16042 if (dst == NULL || str == NULL)
16043 {
16044 return;
16045 }
16046
16047 t1 = ParseTokenWithoutNullStr(dst, " ");
16048 t2 = ParseTokenWithoutNullStr(str, " ");
16049
16050 for (i = 0;i < t2->NumTokens;i++)
16051 {
16052 bool exists = false;
16053 for (j = 0;j < t1->NumTokens;j++)
16054 {
16055 if (StrCmpi(t1->Token[j], t2->Token[i]) == 0)
16056 {
16057 exists = true;
16058 break;
16059 }
16060 }
16061
16062 if (exists == false)
16063 {
16064 StrCat(dst, dst_size, t2->Token[i]);
16065 StrCat(dst, dst_size, " ");
16066 }
16067 }
16068
16069 FreeToken(t1);
16070 FreeToken(t2);
16071 }
AddProtocolDetailsKeyValueStr(char * dst,UINT dst_size,char * key,char * value)16072 void AddProtocolDetailsKeyValueStr(char *dst, UINT dst_size, char *key, char *value)
16073 {
16074 char tmp[128];
16075 StrCpy(tmp, sizeof(tmp), key);
16076 StrCat(tmp, sizeof(tmp), "=");
16077 StrCat(tmp, sizeof(tmp), value);
16078 AddProtocolDetailsStr(dst, dst_size, tmp);
16079 }
AddProtocolDetailsKeyValueInt(char * dst,UINT dst_size,char * key,UINT value)16080 void AddProtocolDetailsKeyValueInt(char *dst, UINT dst_size, char *key, UINT value)
16081 {
16082 char tmp[128];
16083 ToStr(tmp, value);
16084 AddProtocolDetailsKeyValueStr(dst, dst_size, key, tmp);
16085 }
16086
16087 // Maximize the I/O buffer size of the socket
SetSocketSendRecvBufferSize(SOCKET s,UINT size)16088 void SetSocketSendRecvBufferSize(SOCKET s, UINT size)
16089 {
16090 int value = (int)size;
16091 // Validate arguments
16092 if (s == INVALID_SOCKET)
16093 {
16094 return;
16095 }
16096
16097 setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&value, sizeof(int));
16098 setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *)&value, sizeof(int));
16099 }
16100
16101 // Get the buffer size of the socket
GetSocketBufferSize(SOCKET s,bool send)16102 UINT GetSocketBufferSize(SOCKET s, bool send)
16103 {
16104 int value = 0;
16105 int len = sizeof(int);
16106 // Validate arguments
16107 if (s == INVALID_SOCKET)
16108 {
16109 return 0;
16110 }
16111
16112 if (getsockopt(s, SOL_SOCKET, (send ? SO_SNDBUF : SO_RCVBUF), (char *)&value, &len) != 0)
16113 {
16114 return 0;
16115 }
16116
16117 return value;
16118 }
16119
16120 // Setting the buffer size of the socket
SetSocketBufferSize(SOCKET s,bool send,UINT size)16121 bool SetSocketBufferSize(SOCKET s, bool send, UINT size)
16122 {
16123 int value = (int)size;
16124 // Validate arguments
16125 if (s == INVALID_SOCKET)
16126 {
16127 return false;
16128 }
16129
16130 if (setsockopt(s, SOL_SOCKET, (send ? SO_SNDBUF : SO_RCVBUF), (char *)&value, sizeof(int)) != 0)
16131 {
16132 return false;
16133 }
16134
16135 return true;
16136 }
SetSocketBufferSizeWithBestEffort(SOCKET s,bool send,UINT size)16137 UINT SetSocketBufferSizeWithBestEffort(SOCKET s, bool send, UINT size)
16138 {
16139 // Validate arguments
16140 if (s == INVALID_SOCKET)
16141 {
16142 return 0;
16143 }
16144
16145 while (true)
16146 {
16147 if (SetSocketBufferSize(s, send, size))
16148 {
16149 return size;
16150 }
16151
16152 size = (UINT)((double)size / 1.5);
16153
16154 if (size <= 32767)
16155 {
16156 return 0;
16157 }
16158 }
16159 }
16160
16161 // Initialize the buffer size of the UDP socket
InitUdpSocketBufferSize(SOCKET s)16162 void InitUdpSocketBufferSize(SOCKET s)
16163 {
16164 SetSocketBufferSizeWithBestEffort(s, true, UDP_MAX_BUFFER_SIZE);
16165 SetSocketBufferSizeWithBestEffort(s, false, UDP_MAX_BUFFER_SIZE);
16166 }
16167
16168 // Get the socket information
QuerySocketInformation(SOCK * sock)16169 void QuerySocketInformation(SOCK *sock)
16170 {
16171 // Validate arguments
16172 if (sock == NULL)
16173 {
16174 return;
16175 }
16176
16177 Lock(sock->lock);
16178 {
16179 struct sockaddr_in6 sockaddr6;
16180 struct in6_addr *addr6;
16181 int size;
16182 DWORD dw;
16183 UINT opt_value = 0;
16184
16185 if (sock->Type == SOCK_TCP)
16186 {
16187 // Get the information of the remote host
16188 size = sizeof(sockaddr6);
16189 if (getpeername(sock->socket, (struct sockaddr *)&sockaddr6, (int *)&size) == 0)
16190 {
16191 if (size >= sizeof(struct sockaddr_in6))
16192 {
16193 sock->RemotePort = (UINT)ntohs(sockaddr6.sin6_port);
16194 addr6 = &sockaddr6.sin6_addr;
16195 InAddrToIP6(&sock->RemoteIP, addr6);
16196 sock->RemoteIP.ipv6_scope_id = sockaddr6.sin6_scope_id;
16197 }
16198 else
16199 {
16200 struct sockaddr_in *sockaddr;
16201 struct in_addr *addr;
16202
16203 sockaddr = (struct sockaddr_in *)&sockaddr6;
16204 sock->RemotePort = (UINT)ntohs(sockaddr->sin_port);
16205 addr = &sockaddr->sin_addr;
16206 InAddrToIP(&sock->RemoteIP, addr);
16207 }
16208 }
16209 }
16210
16211 // Get the local host information
16212 size = sizeof(sockaddr6);
16213 if (getsockname(sock->socket, (struct sockaddr *)&sockaddr6, (int *)&size) == 0)
16214 {
16215 if (size >= sizeof(struct sockaddr_in6))
16216 {
16217 sock->LocalPort = (UINT)ntohs(sockaddr6.sin6_port);
16218 addr6 = &sockaddr6.sin6_addr;
16219 InAddrToIP6(&sock->LocalIP, addr6);
16220 sock->LocalIP.ipv6_scope_id = sockaddr6.sin6_scope_id;
16221 }
16222 else
16223 {
16224 struct sockaddr_in *sockaddr;
16225 struct in_addr *addr;
16226
16227 sockaddr = (struct sockaddr_in *)&sockaddr6;
16228 sock->LocalPort = (UINT)ntohs(sockaddr->sin_port);
16229 addr = &sockaddr->sin_addr;
16230 InAddrToIP(&sock->LocalIP, addr);
16231 }
16232 }
16233
16234 if (sock->IsRawSocket)
16235 {
16236 sock->LocalPort = sock->RemotePort = MAKE_SPECIAL_PORT(sock->RawSocketIPProtocol);
16237 }
16238
16239 if (sock->Type == SOCK_UDP)
16240 {
16241 sock->UdpMaxMsgSize = UDP_MAX_MSG_SIZE_DEFAULT;
16242
16243 #ifdef OS_WIN32
16244 if (true)
16245 {
16246 // Get the buffer size that can be transmitted and received at once
16247 UINT max_value = 0;
16248 int len = sizeof(UINT);
16249
16250 if (getsockopt(sock->socket, SOL_SOCKET, SO_MAX_MSG_SIZE, (char *)&max_value, &len) == 0)
16251 {
16252 sock->UdpMaxMsgSize = max_value;
16253 }
16254 }
16255 #endif // OS_WIN32
16256 }
16257
16258 if (sock->IPv6)
16259 {
16260 #ifdef IPV6_UNICAST_HOPS
16261 opt_value = IPV6_UNICAST_HOPS;
16262 #endif // IPV6_UNICAST_HOPS
16263 }
16264 else
16265 {
16266 #ifdef IP_TTL
16267 opt_value = IP_TTL;
16268 #endif // IP_TTL
16269 }
16270
16271 // Support of the TTL value
16272 size = sizeof(DWORD);
16273 if (opt_value == 0 ||
16274 getsockopt(sock->socket, (sock->IPv6 ? IPPROTO_IPV6 : IPPROTO_IP), opt_value, (char *)&dw, &size) != 0)
16275 {
16276 sock->IsTtlSupported = false;
16277 }
16278 else
16279 {
16280 sock->IsTtlSupported = true;
16281 sock->CurrentTtl = dw;
16282 }
16283 }
16284 Unlock(sock->lock);
16285 }
16286
16287 // Setting the TTL value
SetTtl(SOCK * sock,UINT ttl)16288 bool SetTtl(SOCK *sock, UINT ttl)
16289 {
16290 DWORD dw;
16291 int size;
16292 UINT opt_value = 0;
16293 // Validate arguments
16294 if (sock == NULL)
16295 {
16296 return false;
16297 }
16298
16299 if (sock->IsTtlSupported == false)
16300 {
16301 return false;
16302 }
16303
16304 if (sock->CurrentTtl == ttl)
16305 {
16306 return true;
16307 }
16308
16309 dw = ttl;
16310 size = sizeof(DWORD);
16311
16312 if (sock->IPv6)
16313 {
16314 #ifdef IPV6_UNICAST_HOPS
16315 opt_value = IPV6_UNICAST_HOPS;
16316 #endif // IPV6_UNICAST_HOPS
16317 }
16318 else
16319 {
16320 #ifdef IP_TTL
16321 opt_value = IP_TTL;
16322 #endif // IP_TTL
16323 }
16324
16325 if (opt_value == 0 ||
16326 setsockopt(sock->socket, (sock->IPv6 ? IPPROTO_IPV6 : IPPROTO_IP), opt_value, (char *)&dw, size) == false)
16327 {
16328 return false;
16329 }
16330
16331 sock->CurrentTtl = ttl;
16332
16333 return true;
16334 }
16335
16336 // Release of the socket
ReleaseSock(SOCK * s)16337 void ReleaseSock(SOCK *s)
16338 {
16339 // Validate arguments
16340 if (s == NULL)
16341 {
16342 return;
16343 }
16344
16345 if (Release(s->ref) == 0)
16346 {
16347 if (s->ListenMode == false && s->ServerMode)
16348 {
16349 Print("");
16350 }
16351 CleanupSock(s);
16352 }
16353 }
16354
16355 // Clean-up of the socket
CleanupSock(SOCK * s)16356 void CleanupSock(SOCK *s)
16357 {
16358 // Validate arguments
16359 if (s == NULL)
16360 {
16361 return;
16362 }
16363
16364 // {Debug("CleanupSock: Disconnect() Called: %s %u\n", __FILE__, __LINE__);Disconnect(s);}
16365 Disconnect(s);
16366
16367 if (s->InProcAcceptQueue != NULL)
16368 {
16369 while (true)
16370 {
16371 SOCK *ss = GetNext(s->InProcAcceptQueue);
16372 if (ss == NULL)
16373 {
16374 break;
16375 }
16376
16377 Disconnect(ss);
16378 ReleaseSock(ss);
16379 }
16380
16381 ReleaseQueue(s->InProcAcceptQueue);
16382 }
16383
16384 if (s->InProcAcceptEvent != NULL)
16385 {
16386 ReleaseEvent(s->InProcAcceptEvent);
16387 }
16388
16389 if (s->ReverseAcceptQueue != NULL)
16390 {
16391 while (true)
16392 {
16393 SOCK *ss = GetNext(s->ReverseAcceptQueue);
16394 if (ss == NULL)
16395 {
16396 break;
16397 }
16398
16399 Disconnect(ss);
16400 ReleaseSock(ss);
16401 }
16402
16403 ReleaseQueue(s->ReverseAcceptQueue);
16404 }
16405
16406 if (s->ReverseAcceptEvent != NULL)
16407 {
16408 ReleaseEvent(s->ReverseAcceptEvent);
16409 }
16410
16411 if (s->SendTube != NULL)
16412 {
16413 TubeDisconnect(s->SendTube);
16414 ReleaseTube(s->SendTube);
16415 }
16416
16417 if (s->RecvTube != NULL)
16418 {
16419 TubeDisconnect(s->RecvTube);
16420 ReleaseTube(s->RecvTube);
16421 }
16422
16423 if (s->BulkRecvTube != NULL)
16424 {
16425 TubeDisconnect(s->BulkRecvTube);
16426 ReleaseTube(s->BulkRecvTube);
16427 }
16428
16429 if (s->BulkSendTube != NULL)
16430 {
16431 TubeDisconnect(s->BulkSendTube);
16432 ReleaseTube(s->BulkSendTube);
16433 }
16434
16435 if (s->BulkSendKey != NULL)
16436 {
16437 ReleaseSharedBuffer(s->BulkSendKey);
16438 }
16439
16440 if (s->BulkRecvKey != NULL)
16441 {
16442 ReleaseSharedBuffer(s->BulkRecvKey);
16443 }
16444
16445 if (s->InProcRecvFifo != NULL)
16446 {
16447 ReleaseFifo(s->InProcRecvFifo);
16448 }
16449
16450 if (s->R_UDP_Stack != NULL)
16451 {
16452 FreeRUDP(s->R_UDP_Stack);
16453 }
16454
16455 #ifdef OS_WIN32
16456 Win32FreeAsyncSocket(s);
16457 #else // OS_WIN32
16458 UnixFreeAsyncSocket(s);
16459 #endif // OS_WIN32
16460
16461 FreeBuf(s->SendBuf);
16462 if (s->socket != INVALID_SOCKET)
16463 {
16464 #ifdef OS_WIN32
16465 closesocket(s->socket);
16466 #else // OS_WIN32
16467 close(s->socket);
16468 #endif // OS_WIN32
16469 }
16470 Free(s->RemoteHostname);
16471
16472 #ifdef OS_WIN32
16473 if (s->hAcceptEvent != NULL)
16474 {
16475 CloseHandle(s->hAcceptEvent);
16476 }
16477 #endif // OS_WIN32
16478
16479 // Release the certificate
16480 if (s->RemoteX != NULL)
16481 {
16482 FreeX(s->RemoteX);
16483 s->RemoteX = NULL;
16484 }
16485 if (s->LocalX != NULL)
16486 {
16487 FreeX(s->LocalX);
16488 s->LocalX = NULL;
16489 }
16490
16491 // Cipher algorithm name
16492 if (s->CipherName != NULL)
16493 {
16494 Free(s->CipherName);
16495 s->CipherName = NULL;
16496 }
16497
16498 Free(s->WaitToUseCipher);
16499 DeleteLock(s->lock);
16500 DeleteLock(s->ssl_lock);
16501 DeleteLock(s->disconnect_lock);
16502
16503 Dec(num_tcp_connections);
16504
16505 Free(s);
16506 }
16507
16508 // Creating a new socket
NewSock()16509 SOCK *NewSock()
16510 {
16511 SOCK *s = ZeroMallocFast(sizeof(SOCK));
16512
16513 s->ref = NewRef();
16514 s->lock = NewLock();
16515 s->SendBuf = NewBuf();
16516 s->socket = INVALID_SOCKET;
16517 s->ssl_lock = NewLock();
16518 s->disconnect_lock = NewLock();
16519
16520 Inc(num_tcp_connections);
16521
16522 return s;
16523 }
16524
16525 // Convert the IP to UINT
IPToUINT(IP * ip)16526 UINT IPToUINT(IP *ip)
16527 {
16528 UCHAR *b;
16529 UINT i, value = 0;
16530 // Validate arguments
16531 if (ip == NULL)
16532 {
16533 return 0;
16534 }
16535
16536 b = (UCHAR *)&value;
16537 for (i = 0;i < 4;i++)
16538 {
16539 b[i] = ip->addr[i];
16540 }
16541
16542 return value;
16543 }
16544
16545 // Convert UINT to IP
UINTToIP(IP * ip,UINT value)16546 void UINTToIP(IP *ip, UINT value)
16547 {
16548 UCHAR *b;
16549 UINT i;
16550 // Validate arguments
16551 if (ip == NULL)
16552 {
16553 return;
16554 }
16555
16556 ZeroIP4(ip);
16557
16558 b = (UCHAR *)&value;
16559 for (i = 0;i < 4;i++)
16560 {
16561 ip->addr[i] = b[i];
16562 }
16563 }
16564
16565 // Get the host name of the computer
GetMachineHostName(char * name,UINT size)16566 void GetMachineHostName(char *name, UINT size)
16567 {
16568 char tmp[MAX_SIZE];
16569 UINT i, len;
16570 // Validate arguments
16571 if (name == NULL)
16572 {
16573 return;
16574 }
16575
16576 GetMachineName(tmp, sizeof(tmp));
16577
16578 len = StrLen(tmp);
16579 for (i = 0;i < len;i++)
16580 {
16581 if (tmp[i] == '.')
16582 {
16583 tmp[i] = 0;
16584 }
16585 }
16586
16587 ConvertSafeFileName(name, size, tmp);
16588 }
16589
16590 // Get the IP address of this computer
GetMachineIp(IP * ip)16591 void GetMachineIp(IP *ip)
16592 {
16593 char tmp[MAX_SIZE];
16594 // Validate arguments
16595 if (ip == NULL)
16596 {
16597 return;
16598 }
16599
16600 Zero(ip, sizeof(IP));
16601 SetIP(ip, 127, 0, 0, 1);
16602
16603 GetMachineName(tmp, sizeof(tmp));
16604 GetIP(ip, tmp);
16605 }
16606
16607 // Get the computer name from 'hosts'
GetMachineNameFromHosts(char * name,UINT size)16608 bool GetMachineNameFromHosts(char *name, UINT size)
16609 {
16610 bool ret = false;
16611 char *s;
16612 BUF *b;
16613 // Validate arguments
16614 if (name == NULL)
16615 {
16616 return false;
16617 }
16618
16619 b = ReadDump("/etc/hosts");
16620 if (b == NULL)
16621 {
16622 return false;
16623 }
16624
16625 while (true)
16626 {
16627 s = CfgReadNextLine(b);
16628 if (s == NULL)
16629 {
16630 break;
16631 }
16632 else
16633 {
16634 TOKEN_LIST *t = ParseToken(s, " \t");
16635
16636 if (t != NULL)
16637 {
16638 if (t->NumTokens >= 2)
16639 {
16640 if (StrCmpi(t->Token[0], "127.0.0.1") == 0)
16641 {
16642 UINT i;
16643
16644 for (i = 1;i < t->NumTokens;i++)
16645 {
16646 if (StartWith(t->Token[i], "localhost") == false)
16647 {
16648 StrCpy(name, size, t->Token[i]);
16649 ret = true;
16650 }
16651 }
16652 }
16653 }
16654 }
16655 FreeToken(t);
16656 }
16657
16658 Free(s);
16659 }
16660
16661 FreeBuf(b);
16662
16663 return ret;
16664 }
16665
16666 // Get the computer name of this computer
GetMachineName(char * name,UINT size)16667 void GetMachineName(char *name, UINT size)
16668 {
16669 GetMachineNameEx(name, size, false);
16670 }
GetMachineNameEx(char * name,UINT size,bool no_load_hosts)16671 void GetMachineNameEx(char *name, UINT size, bool no_load_hosts)
16672 {
16673 static char name_cache[MAX_SIZE];
16674 static bool name_cached = false;
16675 char tmp[MAX_SIZE];
16676 char tmp2[MAX_SIZE];
16677 // Validate arguments
16678 if (name == NULL)
16679 {
16680 return;
16681 }
16682
16683 Lock(machine_name_lock);
16684 {
16685 if (name_cached != false)
16686 {
16687 StrCpy(name, size, name_cache);
16688 Unlock(machine_name_lock);
16689 return;
16690 }
16691 ClearStr(tmp, sizeof(tmp));
16692 if (gethostname(tmp, MAX_SIZE) != 0)
16693 {
16694 StrCpy(name, size, "Unknown");
16695 Unlock(machine_name_lock);
16696 return;
16697 }
16698 ClearStr(name, size);
16699 StrCpy(name, size, tmp);
16700 if (IsEmptyStr(name) || StartWith(name, "localhost"))
16701 {
16702 #ifdef OS_WIN32
16703 ClearStr(name, size);
16704 MsGetComputerName(name, size);
16705 #endif // OS_WIN32
16706 }
16707 if (IsEmptyStr(name) || StartWith(name, "localhost"))
16708 {
16709 if (no_load_hosts == false && OS_IS_UNIX(GetOsInfo()->OsType))
16710 {
16711 if (GetMachineNameFromHosts(tmp2, sizeof(tmp2)))
16712 {
16713 StrCpy(name, sizeof(name), tmp2); // 2019/02/09 by Dayiuu Nobori: DO NOT fix it! It affects DDNS configs.
16714 }
16715 }
16716 }
16717
16718 StrCpy(name_cache, sizeof(name_cache), name);
16719 name_cached = true;
16720 }
16721 Unlock(machine_name_lock);
16722 }
16723
16724 // Host name acquisition thread
GetHostNameThread(THREAD * t,void * p)16725 void GetHostNameThread(THREAD *t, void *p)
16726 {
16727 IP *ip;
16728 char hostname[256];
16729 // Validate arguments
16730 if (t == NULL || p == NULL)
16731 {
16732 return;
16733 }
16734
16735 ip = (IP *)p;
16736
16737 AddWaitThread(t);
16738
16739 NoticeThreadInit(t);
16740
16741 if (GetHostNameInner(hostname, sizeof(hostname), ip))
16742 {
16743 AddHostCache(ip, hostname);
16744 }
16745
16746 Free(ip);
16747
16748 DelWaitThread(t);
16749 }
16750
16751 // Get the host name
GetHostName(char * hostname,UINT size,IP * ip)16752 bool GetHostName(char *hostname, UINT size, IP *ip)
16753 {
16754 THREAD *t;
16755 IP *p_ip;
16756 bool ret;
16757 // Validate arguments
16758 if (hostname == NULL || ip == NULL)
16759 {
16760 return false;
16761 }
16762
16763 if (GetHostCache(hostname, size, ip))
16764 {
16765 if (IsEmptyStr(hostname) == false)
16766 {
16767 return true;
16768 }
16769 else
16770 {
16771 return false;
16772 }
16773 }
16774
16775 p_ip = ZeroMalloc(sizeof(IP));
16776 Copy(p_ip, ip, sizeof(IP));
16777
16778 t = NewThread(GetHostNameThread, p_ip);
16779
16780 WaitThreadInit(t);
16781
16782 WaitThread(t, TIMEOUT_HOSTNAME);
16783
16784 ReleaseThread(t);
16785
16786 ret = GetHostCache(hostname, size, ip);
16787 if (ret == false)
16788 {
16789 if (IsIP4(ip))
16790 {
16791 ret = GetNetBiosName(hostname, size, ip);
16792 if (ret)
16793 {
16794 AddHostCache(ip, hostname);
16795 }
16796 }
16797 }
16798 else
16799 {
16800 if (IsEmptyStr(hostname))
16801 {
16802 ret = false;
16803 }
16804 }
16805 if (ret == false)
16806 {
16807 AddHostCache(ip, "");
16808 StrCpy(hostname, size, "");
16809 }
16810
16811 return ret;
16812 }
16813
16814 // Perform a DNS reverse query
GetHostNameInner(char * hostname,UINT size,IP * ip)16815 bool GetHostNameInner(char *hostname, UINT size, IP *ip)
16816 {
16817 struct in_addr addr;
16818 struct sockaddr_in sa;
16819 char tmp[MAX_SIZE];
16820 char ip_str[64];
16821 // Validate arguments
16822 if (hostname == NULL || ip == NULL)
16823 {
16824 return false;
16825 }
16826
16827 if (IsIP6(ip))
16828 {
16829 return GetHostNameInner6(hostname, size, ip);
16830 }
16831
16832 // Reverse resolution
16833 IPToInAddr(&addr, ip);
16834 Zero(&sa, sizeof(sa));
16835 sa.sin_family = AF_INET;
16836
16837 #if defined(UNIX_BSD) || defined(UNIX_MACOS)
16838 sa.sin_len = INET_ADDRSTRLEN;
16839 #endif // UNIX_BSD || UNIX_MACOS
16840
16841 Copy(&sa.sin_addr, &addr, sizeof(struct in_addr));
16842 sa.sin_port = 0;
16843
16844 if (getnameinfo((struct sockaddr *)&sa, sizeof(sa), tmp, sizeof(tmp), NULL, 0, 0) != 0)
16845 {
16846 return false;
16847 }
16848
16849 IPToStr(ip_str, sizeof(ip_str), ip);
16850
16851 if (StrCmpi(tmp, ip_str) == 0)
16852 {
16853 return false;
16854 }
16855
16856 if (IsEmptyStr(tmp))
16857 {
16858 return false;
16859 }
16860
16861 StrCpy(hostname, size, tmp);
16862
16863 return true;
16864 }
GetHostNameInner6(char * hostname,UINT size,IP * ip)16865 bool GetHostNameInner6(char *hostname, UINT size, IP *ip)
16866 {
16867 struct in6_addr addr;
16868 struct sockaddr_in6 sa;
16869 char tmp[MAX_SIZE];
16870 char ip_str[256];
16871 // Validate arguments
16872 if (hostname == NULL || ip == NULL)
16873 {
16874 return false;
16875 }
16876
16877 // Reverse resolution
16878 IPToInAddr6(&addr, ip);
16879 Zero(&sa, sizeof(sa));
16880 sa.sin6_family = AF_INET6;
16881
16882 #if defined(UNIX_BSD) || defined(UNIX_MACOS)
16883 sa.sin6_len = INET6_ADDRSTRLEN;
16884 #endif // UNIX_BSD || UNIX_MACOS
16885
16886 Copy(&sa.sin6_addr, &addr, sizeof(struct in6_addr));
16887 sa.sin6_port = 0;
16888
16889 if (getnameinfo((struct sockaddr *)&sa, sizeof(sa), tmp, sizeof(tmp), NULL, 0, 0) != 0)
16890 {
16891 return false;
16892 }
16893
16894 IPToStr(ip_str, sizeof(ip_str), ip);
16895
16896 if (StrCmpi(tmp, ip_str) == 0)
16897 {
16898 return false;
16899 }
16900
16901 if (IsEmptyStr(tmp))
16902 {
16903 return false;
16904 }
16905
16906 StrCpy(hostname, size, tmp);
16907
16908 return true;
16909 }
16910
16911 #define NUM_NBT_QUERYS_SEND 3
16912
16913 // Get the NetBIOS name of the machine from the IP address
GetNetBiosName(char * name,UINT size,IP * ip)16914 bool GetNetBiosName(char *name, UINT size, IP *ip)
16915 {
16916 SOCK *s;
16917 UINT i, j;
16918 bool flag = false;
16919 bool ok = false;
16920 NBTREQUEST req;
16921 UCHAR buf[1024];
16922 USHORT tran_id[NUM_NBT_QUERYS_SEND];
16923 UINT64 timeout_tick;
16924 // Validate arguments
16925 if (name == NULL || ip == NULL)
16926 {
16927 return false;
16928 }
16929
16930 IPToStr(name, size, ip);
16931
16932 for (i = 0;i < NUM_NBT_QUERYS_SEND;i++)
16933 {
16934 tran_id[i] = Rand16();
16935 }
16936
16937 s = NewUDP(0);
16938 if (s == NULL)
16939 {
16940 return false;
16941 }
16942
16943 for (j = 0;j < NUM_NBT_QUERYS_SEND;j++)
16944 {
16945 Zero(&req, sizeof(req));
16946 req.TransactionId = Endian16(tran_id[j]);
16947 req.NumQuestions = Endian16(1);
16948 req.Query[0] = 0x20;
16949 req.Query[1] = 0x43;
16950 req.Query[2] = 0x4b;
16951 for (i = 3;i <= 32;i++)
16952 {
16953 req.Query[i] = 0x41;
16954 }
16955 req.Query[35] = 0x21;
16956 req.Query[37] = 0x01;
16957
16958 if (SendTo(s, ip, 137, &req, sizeof(req)) == 0)
16959 {
16960 ReleaseSock(s);
16961 return false;
16962 }
16963 }
16964
16965 timeout_tick = Tick64() + (UINT64)TIMEOUT_NETBIOS_HOSTNAME;
16966
16967 while (1)
16968 {
16969 UINT ret;
16970 IP src_ip;
16971 UINT src_port;
16972 SOCKSET set;
16973 if (Tick64() >= timeout_tick)
16974 {
16975 break;
16976 }
16977 InitSockSet(&set);
16978 AddSockSet(&set, s);
16979 Select(&set, 100, NULL, NULL);
16980
16981 if (flag == false)
16982 {
16983 flag = true;
16984 }
16985 else
16986 {
16987 SleepThread(10);
16988 }
16989
16990 ret = RecvFrom(s, &src_ip, &src_port, buf, sizeof(buf));
16991
16992 if (ret == SOCK_LATER)
16993 {
16994 continue;
16995 }
16996 else if (ret == 0)
16997 {
16998 break;
16999 }
17000 else
17001 {
17002 if (ret >= sizeof(NBTRESPONSE))
17003 {
17004 NBTRESPONSE *r = (NBTRESPONSE *)buf;
17005 bool b = false;
17006 UINT i;
17007 USHORT id = Endian16(r->TransactionId);
17008 for (i = 0;i < NUM_NBT_QUERYS_SEND;i++)
17009 {
17010 if (id == tran_id[i])
17011 {
17012 b = true;
17013 break;
17014 }
17015 }
17016 if (b)
17017 {
17018 if (r->Flags != 0 && r->NumQuestions == 0 && r->AnswerRRs >= 1)
17019 {
17020 if (r->Response[0] == 0x20 && r->Response[1] == 0x43 &&
17021 r->Response[2] == 0x4b)
17022 {
17023 if (r->Response[34] == 0x00 && r->Response[35] == 0x21 &&
17024 r->Response[36] == 0x00 && r->Response[37] == 0x01)
17025 {
17026 char *a = (char *)(&r->Response[45]);
17027 if (StrCheckLen(a, 15))
17028 {
17029 if (IsEmptyStr(a) == false)
17030 {
17031 StrCpy(name, size, a);
17032 Trim(name);
17033 ok = true;
17034 }
17035 else
17036 {
17037 ok = false;
17038 break;
17039 }
17040 }
17041 }
17042 }
17043 }
17044 }
17045 }
17046 }
17047 }
17048
17049 ReleaseSock(s);
17050 return ok;
17051 }
17052
17053 // Set the IP address
SetIP(IP * ip,UCHAR a1,UCHAR a2,UCHAR a3,UCHAR a4)17054 void SetIP(IP *ip, UCHAR a1, UCHAR a2, UCHAR a3, UCHAR a4)
17055 {
17056 // Validate arguments
17057 if (ip == NULL)
17058 {
17059 return;
17060 }
17061
17062 Zero(ip, sizeof(IP));
17063 ip->addr[0] = a1;
17064 ip->addr[1] = a2;
17065 ip->addr[2] = a3;
17066 ip->addr[3] = a4;
17067 }
SetIP32(UCHAR a1,UCHAR a2,UCHAR a3,UCHAR a4)17068 UINT SetIP32(UCHAR a1, UCHAR a2, UCHAR a3, UCHAR a4)
17069 {
17070 IP ip;
17071
17072 Zero(&ip, sizeof(ip));
17073 SetIP(&ip, a1, a2, a3, a4);
17074
17075 return IPToUINT(&ip);
17076 }
17077
17078 // Get either of v4 and v6 results with a DNS forward lookup (The IPv4 precedes in the case of both results)
GetIP46Any4(IP * ip,char * hostname)17079 bool GetIP46Any4(IP *ip, char *hostname)
17080 {
17081 IP ip4, ip6;
17082 bool b = false;
17083 // Validate arguments
17084 if (ip == NULL || hostname == NULL)
17085 {
17086 return false;
17087 }
17088
17089 if (GetIP46(&ip4, &ip6, hostname) == false)
17090 {
17091 return false;
17092 }
17093
17094 if (IsZeroIp(&ip6) == false)
17095 {
17096 Copy(ip, &ip6, sizeof(IP));
17097
17098 b = true;
17099 }
17100
17101 if (IsZeroIp(&ip4) == false)
17102 {
17103 Copy(ip, &ip4, sizeof(IP));
17104
17105 b = true;
17106 }
17107
17108 return b;
17109 }
17110
17111 // Get either of v4 and v6 results with a DNS forward lookup (The IPv6 precedes in the case of both)
GetIP46Any6(IP * ip,char * hostname)17112 bool GetIP46Any6(IP *ip, char *hostname)
17113 {
17114 IP ip4, ip6;
17115 bool b = false;
17116 // Validate arguments
17117 if (ip == NULL || hostname == NULL)
17118 {
17119 return false;
17120 }
17121
17122 if (GetIP46(&ip4, &ip6, hostname) == false)
17123 {
17124 return false;
17125 }
17126
17127 if (IsZeroIp(&ip4) == false)
17128 {
17129 Copy(ip, &ip4, sizeof(IP));
17130
17131 b = true;
17132 }
17133
17134 if (IsZeroIp(&ip6) == false)
17135 {
17136 Copy(ip, &ip6, sizeof(IP));
17137
17138 b = true;
17139 }
17140
17141 return b;
17142 }
17143
17144 // Obtain in both v4 and v6 results with a DNS forward lookup
GetIP46(IP * ip4,IP * ip6,char * hostname)17145 bool GetIP46(IP *ip4, IP *ip6, char *hostname)
17146 {
17147 return GetIP46Ex(ip4, ip6, hostname, 0, NULL);
17148 }
GetIP46Ex(IP * ip4,IP * ip6,char * hostname,UINT timeout,bool * cancel)17149 bool GetIP46Ex(IP *ip4, IP *ip6, char *hostname, UINT timeout, bool *cancel)
17150 {
17151 IP a, b;
17152 bool ok_a, ok_b;
17153 // Validate arguments
17154 if (ip4 == NULL || ip6 == NULL || hostname == NULL)
17155 {
17156 return false;
17157 }
17158
17159 ZeroIP4(ip4);
17160 ZeroIP6(ip6);
17161
17162 ok_a = ok_b = false;
17163
17164 if (GetIP6Ex(&a, hostname, timeout, cancel))
17165 {
17166 ok_a = true;
17167 }
17168
17169 if (GetIP4Ex(&b, hostname, timeout, cancel))
17170 {
17171 ok_b = true;
17172 }
17173
17174 if (ok_a)
17175 {
17176 if (IsIP4(&a))
17177 {
17178 Copy(ip4, &a, sizeof(IP));
17179 }
17180 }
17181 if (ok_b)
17182 {
17183 if (IsIP4(&b))
17184 {
17185 Copy(ip4, &b, sizeof(IP));
17186 }
17187
17188 if (IsIP6(&b))
17189 {
17190 Copy(ip6, &b, sizeof(IP));
17191 }
17192 }
17193 if (ok_a)
17194 {
17195 if (IsIP6(&a))
17196 {
17197 Copy(ip6, &a, sizeof(IP));
17198 }
17199 }
17200
17201 if (IsZeroIp(ip4) && IsZeroIp(ip6))
17202 {
17203 return false;
17204 }
17205
17206 return true;
17207 }
17208
17209 // Clean-up of the parameters for GetIP thread
CleanupGetIPThreadParam(GETIP_THREAD_PARAM * p)17210 void CleanupGetIPThreadParam(GETIP_THREAD_PARAM *p)
17211 {
17212 // Validate arguments
17213 if (p == NULL)
17214 {
17215 return;
17216 }
17217
17218 Free(p);
17219 }
17220
17221 // Release of the parameters of the GetIP for thread
ReleaseGetIPThreadParam(GETIP_THREAD_PARAM * p)17222 void ReleaseGetIPThreadParam(GETIP_THREAD_PARAM *p)
17223 {
17224 // Validate arguments
17225 if (p == NULL)
17226 {
17227 return;
17228 }
17229
17230 if (Release(p->Ref) == 0)
17231 {
17232 CleanupGetIPThreadParam(p);
17233 }
17234 }
17235
17236 // Thread to perform to query the DNS forward lookup (with timeout)
GetIP4Ex6ExThread(THREAD * t,void * param)17237 void GetIP4Ex6ExThread(THREAD *t, void *param)
17238 {
17239 GETIP_THREAD_PARAM *p;
17240 // Validate arguments
17241 if (t == NULL || param == NULL)
17242 {
17243 return;
17244 }
17245
17246 p = (GETIP_THREAD_PARAM *)param;
17247
17248 AddRef(p->Ref);
17249
17250 NoticeThreadInit(t);
17251
17252 AddWaitThread(t);
17253
17254 // Execution of resolution
17255 if (p->IPv6 == false)
17256 {
17257 // IPv4
17258 p->Ok = GetIP4Inner(&p->Ip, p->HostName);
17259 }
17260 else
17261 {
17262 // IPv6
17263 p->Ok = GetIP6Inner(&p->Ip, p->HostName);
17264 }
17265
17266 ReleaseGetIPThreadParam(p);
17267
17268 DelWaitThread(t);
17269
17270 Dec(getip_thread_counter);
17271 }
17272
17273 // Perform a forward DNS query (with timeout)
GetIP4Ex6Ex(IP * ip,char * hostname_arg,UINT timeout,bool ipv6,bool * cancel)17274 bool GetIP4Ex6Ex(IP *ip, char *hostname_arg, UINT timeout, bool ipv6, bool *cancel)
17275 {
17276 return GetIP4Ex6Ex2(ip, hostname_arg, timeout, ipv6, cancel, false);
17277 }
GetIP4Ex6Ex2(IP * ip,char * hostname_arg,UINT timeout,bool ipv6,bool * cancel,bool only_direct_dns)17278 bool GetIP4Ex6Ex2(IP *ip, char *hostname_arg, UINT timeout, bool ipv6, bool *cancel, bool only_direct_dns)
17279 {
17280 GETIP_THREAD_PARAM *p;
17281 THREAD *t;
17282 bool ret = false;
17283 UINT64 start_tick = 0;
17284 UINT64 end_tick = 0;
17285 UINT64 spent_time = 0;
17286 UINT64 now;
17287 UINT n;
17288 bool use_dns_proxy = false;
17289 char hostname[260];
17290 UINT i;
17291 bool timed_out;
17292 // Validate arguments
17293 if (ip == NULL || hostname_arg == NULL)
17294 {
17295 return false;
17296 }
17297 if (timeout == 0)
17298 {
17299 timeout = TIMEOUT_GETIP;
17300 }
17301
17302 Zero(hostname, sizeof(hostname));
17303 StrCpy(hostname, sizeof(hostname), hostname_arg);
17304
17305 i = SearchStrEx(hostname, "/", 0, true);
17306 if (i != INFINITE)
17307 {
17308 hostname[i] = 0;
17309 }
17310
17311 if (ipv6 == false)
17312 {
17313 IP ip2;
17314
17315 if (StrToIP(&ip2, hostname) && IsZeroIp(&ip2) == false)
17316 {
17317 if (IsIP4(&ip2))
17318 {
17319 // IPv4 address direct specification
17320 Copy(ip, &ip2, sizeof(IP));
17321 return true;
17322 }
17323 else
17324 {
17325 // IPv6 address direct specification
17326 return false;
17327 }
17328 }
17329 }
17330 else
17331 {
17332 IP ip2;
17333
17334 if (StrToIP(&ip2, hostname) && IsZeroIp(&ip2) == false)
17335 {
17336 if (IsIP6(&ip2))
17337 {
17338 // IPv6 address direct specification
17339 Copy(ip, &ip2, sizeof(IP));
17340 return true;
17341 }
17342 else
17343 {
17344 // IPv4 address direct specification
17345 return false;
17346 }
17347 }
17348 }
17349
17350 if (only_direct_dns == false)
17351 {
17352 if (ipv6 == false)
17353 {
17354 if (IsUseDnsProxy())
17355 {
17356 use_dns_proxy = true;
17357 }
17358 }
17359 }
17360
17361
17362 // check the quota
17363 start_tick = Tick64();
17364 end_tick = start_tick + (UINT64)timeout;
17365
17366 n = 0;
17367
17368 timed_out = false;
17369
17370 while (true)
17371 {
17372 UINT64 now = Tick64();
17373 UINT64 remain;
17374 UINT remain32;
17375
17376 if (GetGetIpThreadMaxNum() > GetCurrentGetIpThreadNum())
17377 {
17378 // below the quota
17379 break;
17380 }
17381
17382 if (now >= end_tick)
17383 {
17384 // timeouted
17385 timed_out = true;
17386 break;
17387 }
17388
17389 if (cancel != NULL && (*cancel))
17390 {
17391 // cancelled
17392 timed_out = true;
17393 break;
17394 }
17395
17396 remain = end_tick - now;
17397 remain32 = MIN((UINT)remain, 100);
17398
17399 SleepThread(remain32);
17400 n++;
17401 }
17402
17403 now = Tick64();
17404 spent_time = now - start_tick;
17405
17406 if (n == 0)
17407 {
17408 spent_time = 0;
17409 }
17410
17411 if ((UINT)spent_time >= timeout)
17412 {
17413 timed_out = true;
17414 }
17415
17416 if (timed_out)
17417 {
17418 IP ip2;
17419
17420 // timed out, cancelled
17421 if (QueryDnsCache(&ip2, hostname))
17422 {
17423 ret = true;
17424
17425 Copy(ip, &ip2, sizeof(IP));
17426 }
17427
17428 Debug("GetIP4Ex6Ex2: Worker thread quota exceeded: max=%u current=%u\n",
17429 GetGetIpThreadMaxNum(), GetCurrentGetIpThreadNum());
17430
17431 return ret;
17432 }
17433
17434 // Increment the counter
17435 Inc(getip_thread_counter);
17436
17437 if (spent_time != 0)
17438 {
17439 Debug("GetIP4Ex6Ex2: Waited for %u msecs to create a worker thread.\n",
17440 spent_time);
17441 }
17442
17443 timeout -= (UINT)spent_time;
17444
17445 p = ZeroMalloc(sizeof(GETIP_THREAD_PARAM));
17446 p->Ref = NewRef();
17447 StrCpy(p->HostName, sizeof(p->HostName), hostname);
17448 p->IPv6 = ipv6;
17449 p->Timeout = timeout;
17450 p->Ok = false;
17451
17452 t = NewThread(GetIP4Ex6ExThread, p);
17453 WaitThreadInit(t);
17454
17455 if (cancel == NULL)
17456 {
17457 WaitThread(t, timeout);
17458 }
17459 else
17460 {
17461 start_tick = Tick64();
17462 end_tick = start_tick + (UINT64)timeout;
17463
17464 while (true)
17465 {
17466 UINT64 now = Tick64();
17467 UINT64 remain;
17468 UINT remain32;
17469
17470 if (*cancel)
17471 {
17472 break;
17473 }
17474
17475 if (now >= end_tick)
17476 {
17477 break;
17478 }
17479
17480 remain = end_tick - now;
17481 remain32 = MIN((UINT)remain, 100);
17482
17483 if (WaitThread(t, remain32))
17484 {
17485 break;
17486 }
17487 }
17488 }
17489
17490 ReleaseThread(t);
17491
17492 if (p->Ok)
17493 {
17494 ret = true;
17495 Copy(ip, &p->Ip, sizeof(IP));
17496 }
17497 else
17498 {
17499 IP ip2;
17500
17501 #if 0
17502 if (only_direct_dns == false)
17503 {
17504 if (ipv6)
17505 {
17506 UINT flets_type = DetectFletsType();
17507
17508 // if I'm in the FLETs of NTT East,
17509 // try to get an IP address using the DNS proxy server
17510 if ((flets_type & FLETS_DETECT_TYPE_EAST_BFLETS_PRIVATE) &&
17511 GetIPViaDnsProxyForJapanFlets(ip, hostname, true, 0, cancel, NULL))
17512 {
17513 // B FLETs
17514 ret = true;
17515 }
17516 else if ((flets_type & FLETS_DETECT_TYPE_EAST_NGN_PRIVATE) &&
17517 GetIPViaDnsProxyForJapanFlets(ip, hostname, true, 0, cancel, FLETS_NGN_EAST_DNS_PROXY_HOSTNAME))
17518 {
17519 // FLET'S Hikar-Next (NTT East)
17520 ret = true;
17521 }
17522 else if ((flets_type & FLETS_DETECT_TYPE_WEST_NGN_PRIVATE) &&
17523 GetIPViaDnsProxyForJapanFlets(ip, hostname, true, 0, cancel, FLETS_NGN_WEST_DNS_PROXY_HOSTNAME))
17524 {
17525 // FLET'S Hikar-Next (NTT West)
17526 ret = true;
17527 }
17528 }
17529 }
17530 #endif
17531
17532 if (QueryDnsCache(&ip2, hostname))
17533 {
17534 ret = true;
17535
17536 Copy(ip, &ip2, sizeof(IP));
17537 }
17538 }
17539
17540
17541 ReleaseGetIPThreadParam(p);
17542
17543 return ret;
17544 }
GetIP4Ex(IP * ip,char * hostname,UINT timeout,bool * cancel)17545 bool GetIP4Ex(IP *ip, char *hostname, UINT timeout, bool *cancel)
17546 {
17547 return GetIP4Ex6Ex(ip, hostname, timeout, false, cancel);
17548 }
GetIP6Ex(IP * ip,char * hostname,UINT timeout,bool * cancel)17549 bool GetIP6Ex(IP *ip, char *hostname, UINT timeout, bool *cancel)
17550 {
17551 return GetIP4Ex6Ex(ip, hostname, timeout, true, cancel);
17552 }
GetIP4(IP * ip,char * hostname)17553 bool GetIP4(IP *ip, char *hostname)
17554 {
17555 return GetIP4Ex(ip, hostname, 0, NULL);
17556 }
GetIP6(IP * ip,char * hostname)17557 bool GetIP6(IP *ip, char *hostname)
17558 {
17559 return GetIP6Ex(ip, hostname, 0, NULL);
17560 }
17561
17562 // Perform a DNS forward lookup query
GetIP(IP * ip,char * hostname)17563 bool GetIP(IP *ip, char *hostname)
17564 {
17565 return GetIPEx(ip, hostname, false);
17566 }
GetIPEx(IP * ip,char * hostname,bool ipv6)17567 bool GetIPEx(IP *ip, char *hostname, bool ipv6)
17568 {
17569 if (ipv6 == false)
17570 {
17571 return GetIP4(ip, hostname);
17572 }
17573 else
17574 {
17575 return GetIP6(ip, hostname);
17576 }
17577 }
GetIP6Inner(IP * ip,char * hostname)17578 bool GetIP6Inner(IP *ip, char *hostname)
17579 {
17580 struct sockaddr_in6 in;
17581 struct in6_addr addr;
17582 struct addrinfo hint;
17583 struct addrinfo *info;
17584 // Validate arguments
17585 if (ip == NULL || hostname == NULL)
17586 {
17587 return false;
17588 }
17589
17590 if (IsEmptyStr(hostname))
17591 {
17592 return false;
17593 }
17594
17595 if (StrCmpi(hostname, "localhost") == 0)
17596 {
17597 GetLocalHostIP6(ip);
17598 return true;
17599 }
17600
17601 if (StrToIP6(ip, hostname) == false && StrToIP(ip, hostname) == false)
17602 {
17603 // Forward resolution
17604 Zero(&hint, sizeof(hint));
17605 hint.ai_family = AF_INET6;
17606 hint.ai_socktype = SOCK_STREAM;
17607 hint.ai_protocol = IPPROTO_TCP;
17608 info = NULL;
17609
17610 if (getaddrinfo(hostname, NULL, &hint, &info) != 0 ||
17611 info->ai_family != AF_INET6)
17612 {
17613 if (info)
17614 {
17615 freeaddrinfo(info);
17616 }
17617 return QueryDnsCacheEx(ip, hostname, true);
17618 }
17619 // Forward resolution success
17620 Copy(&in, info->ai_addr, sizeof(struct sockaddr_in6));
17621 freeaddrinfo(info);
17622
17623 Copy(&addr, &in.sin6_addr, sizeof(addr));
17624 InAddrToIP6(ip, &addr);
17625 }
17626
17627 // Save Cache
17628 NewDnsCache(hostname, ip);
17629
17630 return true;
17631 }
GetIP4Inner(IP * ip,char * hostname)17632 bool GetIP4Inner(IP *ip, char *hostname)
17633 {
17634 struct sockaddr_in in;
17635 struct in_addr addr;
17636 struct addrinfo hint;
17637 struct addrinfo *info;
17638 // Validate arguments
17639 if (ip == NULL || hostname == NULL)
17640 {
17641 return false;
17642 }
17643
17644 if (IsEmptyStr(hostname))
17645 {
17646 return false;
17647 }
17648
17649 if (StrCmpi(hostname, "localhost") == 0)
17650 {
17651 SetIP(ip, 127, 0, 0, 1);
17652 return true;
17653 }
17654
17655 if (StrToIP6(ip, hostname) == false && StrToIP(ip, hostname) == false)
17656 {
17657 // Forward resolution
17658 Zero(&hint, sizeof(hint));
17659 hint.ai_family = AF_INET;
17660 hint.ai_socktype = SOCK_STREAM;
17661 hint.ai_protocol = IPPROTO_TCP;
17662 info = NULL;
17663
17664 if (getaddrinfo(hostname, NULL, &hint, &info) != 0 ||
17665 info->ai_family != AF_INET)
17666 {
17667 if (info)
17668 {
17669 freeaddrinfo(info);
17670 }
17671 return QueryDnsCache(ip, hostname);
17672 }
17673 // Forward resolution success
17674 Copy(&in, info->ai_addr, sizeof(struct sockaddr_in));
17675 freeaddrinfo(info);
17676 Copy(&addr, &in.sin_addr, sizeof(addr));
17677 InAddrToIP(ip, &addr);
17678 }
17679
17680 // Save Cache
17681 NewDnsCache(hostname, ip);
17682
17683 return true;
17684 }
17685
17686 // Search in the DNS cache
QueryDnsCache(IP * ip,char * hostname)17687 bool QueryDnsCache(IP *ip, char *hostname)
17688 {
17689 return QueryDnsCacheEx(ip, hostname, false);
17690 }
QueryDnsCacheEx(IP * ip,char * hostname,bool ipv6)17691 bool QueryDnsCacheEx(IP *ip, char *hostname, bool ipv6)
17692 {
17693 DNSCACHE *c;
17694 char tmp[MAX_SIZE];
17695 // Validate arguments
17696 if (ip == NULL || hostname == NULL)
17697 {
17698 return false;
17699 }
17700
17701 GenDnsCacheKeyName(tmp, sizeof(tmp), hostname, ipv6);
17702
17703 c = FindDnsCache(tmp);
17704 if (c == NULL)
17705 {
17706 return false;
17707 }
17708
17709 Copy(ip, &c->IpAddress, sizeof(IP));
17710
17711 return true;
17712 }
17713
17714 // Convert the IP to a string
IPToUniStr(wchar_t * str,UINT size,IP * ip)17715 void IPToUniStr(wchar_t *str, UINT size, IP *ip)
17716 {
17717 char tmp[128];
17718
17719 IPToStr(tmp, sizeof(tmp), ip);
17720 StrToUni(str, size, tmp);
17721 }
17722
17723 // Convert the IP to a string (32bit UINT)
IPToUniStr32(wchar_t * str,UINT size,UINT ip)17724 void IPToUniStr32(wchar_t *str, UINT size, UINT ip)
17725 {
17726 char tmp[128];
17727
17728 IPToStr32(tmp, sizeof(tmp), ip);
17729 StrToUni(str, size, tmp);
17730 }
17731
17732 // Convert the IP to a string (128bit byte array)
IPToStr128(char * str,UINT size,UCHAR * ip_bytes)17733 void IPToStr128(char *str, UINT size, UCHAR *ip_bytes)
17734 {
17735 IP ip_st;
17736 // Validate arguments
17737 if (str == NULL)
17738 {
17739 return;
17740 }
17741
17742 SetIP6(&ip_st, ip_bytes);
17743 IPToStr(str, size, &ip_st);
17744 }
17745
17746 // Convert the IP to a string (32bit UINT)
IPToStr32(char * str,UINT size,UINT ip)17747 void IPToStr32(char *str, UINT size, UINT ip)
17748 {
17749 IP ip_st;
17750 // Validate arguments
17751 if (str == NULL)
17752 {
17753 return;
17754 }
17755
17756 UINTToIP(&ip_st, ip);
17757 IPToStr(str, size, &ip_st);
17758 }
17759
17760 // Convert IPv4 or IPv6 to a string
IPToStr4or6(char * str,UINT size,UINT ip_4_uint,UCHAR * ip_6_bytes)17761 void IPToStr4or6(char *str, UINT size, UINT ip_4_uint, UCHAR *ip_6_bytes)
17762 {
17763 IP ip4;
17764 IP ip6;
17765 IP ip;
17766 // Validate arguments
17767 if (str == NULL)
17768 {
17769 return;
17770 }
17771
17772 Zero(&ip, sizeof(ip));
17773
17774 UINTToIP(&ip4, ip_4_uint);
17775 SetIP6(&ip6, ip_6_bytes);
17776
17777 if (IsIP6(&ip4) || (IsZeroIp(&ip4) && (IsZeroIp(&ip6) == false)))
17778 {
17779 Copy(&ip, &ip6, sizeof(IP));
17780 }
17781 else
17782 {
17783 Copy(&ip, &ip4, sizeof(IP));
17784 }
17785
17786 IPToStr(str, size, &ip);
17787 }
17788
17789 // Convert the IP to a string
IPToStr(char * str,UINT size,IP * ip)17790 void IPToStr(char *str, UINT size, IP *ip)
17791 {
17792 // Validate arguments
17793 if (str == NULL || ip == NULL)
17794 {
17795 return;
17796 }
17797
17798 if (IsIP6(ip))
17799 {
17800 IPToStr6(str, size, ip);
17801 }
17802 else
17803 {
17804 IPToStr4(str, size, ip);
17805 }
17806 }
17807
17808 // Convert the IPv4 to a string
IPToStr4(char * str,UINT size,IP * ip)17809 void IPToStr4(char *str, UINT size, IP *ip)
17810 {
17811 // Validate arguments
17812 if (str == NULL || ip == NULL)
17813 {
17814 return;
17815 }
17816
17817 // Conversion
17818 snprintf(str, size != 0 ? size : 64, "%u.%u.%u.%u", ip->addr[0], ip->addr[1], ip->addr[2], ip->addr[3]);
17819 }
17820
17821 // Convert the string to an IP
StrToIP(IP * ip,char * str)17822 bool StrToIP(IP *ip, char *str)
17823 {
17824 TOKEN_LIST *token;
17825 char *tmp;
17826 UINT i;
17827 // Validate arguments
17828 if (ip == NULL || str == NULL)
17829 {
17830 return false;
17831 }
17832
17833 if (StrToIP6(ip, str))
17834 {
17835 return true;
17836 }
17837
17838 Zero(ip, sizeof(IP));
17839
17840 tmp = CopyStr(str);
17841 Trim(tmp);
17842 token = ParseToken(tmp, ".");
17843 Free(tmp);
17844
17845 if (token->NumTokens != 4)
17846 {
17847 FreeToken(token);
17848 return false;
17849 }
17850 for (i = 0;i < 4;i++)
17851 {
17852 char *s = token->Token[i];
17853 if (s[0] < '0' || s[0] > '9' ||
17854 (ToInt(s) >= 256))
17855 {
17856 FreeToken(token);
17857 return false;
17858 }
17859 }
17860 Zero(ip, sizeof(IP));
17861 for (i = 0;i < 4;i++)
17862 {
17863 ip->addr[i] = (UCHAR)ToInt(token->Token[i]);
17864 }
17865
17866 FreeToken(token);
17867
17868 return true;
17869 }
StrToIP32(char * str)17870 UINT StrToIP32(char *str)
17871 {
17872 IP ip;
17873 // Validate arguments
17874 if (str == NULL)
17875 {
17876 return 0;
17877 }
17878
17879 if (StrToIP(&ip, str) == false)
17880 {
17881 return 0;
17882 }
17883
17884 return IPToUINT(&ip);
17885 }
UniStrToIP(IP * ip,wchar_t * str)17886 bool UniStrToIP(IP *ip, wchar_t *str)
17887 {
17888 char *tmp;
17889 bool ret;
17890
17891 tmp = CopyUniToStr(str);
17892 ret = StrToIP(ip, tmp);
17893 Free(tmp);
17894
17895 return ret;
17896 }
UniStrToIP32(wchar_t * str)17897 UINT UniStrToIP32(wchar_t *str)
17898 {
17899 UINT ret;
17900 char *tmp;
17901
17902 tmp = CopyUniToStr(str);
17903 ret = StrToIP32(tmp);
17904 Free(tmp);
17905
17906 return ret;
17907 }
17908
17909 // Convert the IP to the in_addr
IPToInAddr(struct in_addr * addr,IP * ip)17910 void IPToInAddr(struct in_addr *addr, IP *ip)
17911 {
17912 UINT i;
17913 // Validate arguments
17914 if (addr == NULL || ip == NULL)
17915 {
17916 return;
17917 }
17918
17919 Zero(addr, sizeof(struct in_addr));
17920
17921 if (IsIP6(ip) == false)
17922 {
17923 for (i = 0;i < 4;i++)
17924 {
17925 ((UCHAR *)addr)[i] = ip->addr[i];
17926 }
17927 }
17928 }
17929
17930 // Convert the IP to the in6_addr
IPToInAddr6(struct in6_addr * addr,IP * ip)17931 void IPToInAddr6(struct in6_addr *addr, IP *ip)
17932 {
17933 UINT i;
17934 // Validate arguments
17935 if (addr == NULL || ip == NULL)
17936 {
17937 return;
17938 }
17939
17940 Zero(addr, sizeof(struct in6_addr));
17941
17942 if (IsIP6(ip))
17943 {
17944 for (i = 0;i < 16;i++)
17945 {
17946 ((UCHAR *)addr)[i] = ip->ipv6_addr[i];
17947 }
17948 }
17949 }
17950
17951 // Convert the in_addr to the IP
InAddrToIP(IP * ip,struct in_addr * addr)17952 void InAddrToIP(IP *ip, struct in_addr *addr)
17953 {
17954 UINT i;
17955 // Validate arguments
17956 if (ip == NULL || addr == NULL)
17957 {
17958 return;
17959 }
17960
17961 Zero(ip, sizeof(IP));
17962
17963 for (i = 0;i < 4;i++)
17964 {
17965 ip->addr[i] = ((UCHAR *)addr)[i];
17966 }
17967 }
17968
17969 // Convert the in6_addr to the IP
InAddrToIP6(IP * ip,struct in6_addr * addr)17970 void InAddrToIP6(IP *ip, struct in6_addr *addr)
17971 {
17972 UINT i;
17973 // Validate arguments
17974 if (ip == NULL || addr == NULL)
17975 {
17976 return;
17977 }
17978
17979 ZeroIP6(ip);
17980 for (i = 0;i < 16;i++)
17981 {
17982 ip->ipv6_addr[i] = ((UCHAR *)addr)[i];
17983 }
17984 }
17985
17986 // Search in the DNS cache
FindDnsCache(char * hostname)17987 DNSCACHE *FindDnsCache(char *hostname)
17988 {
17989 return FindDnsCacheEx(hostname, false);
17990 }
FindDnsCacheEx(char * hostname,bool ipv6)17991 DNSCACHE *FindDnsCacheEx(char *hostname, bool ipv6)
17992 {
17993 DNSCACHE *c;
17994 char tmp[MAX_SIZE];
17995 if (hostname == NULL)
17996 {
17997 return NULL;
17998 }
17999
18000 GenDnsCacheKeyName(tmp, sizeof(tmp), hostname, ipv6);
18001
18002 LockDnsCache();
18003 {
18004 DNSCACHE t;
18005 t.HostName = tmp;
18006 c = Search(DnsCache, &t);
18007 }
18008 UnlockDnsCache();
18009
18010 return c;
18011 }
18012
18013 // Generate the IPv4 / IPv6 key name for the DNS cache
GenDnsCacheKeyName(char * dst,UINT size,char * src,bool ipv6)18014 void GenDnsCacheKeyName(char *dst, UINT size, char *src, bool ipv6)
18015 {
18016 // Validate arguments
18017 if (dst == NULL || src == NULL)
18018 {
18019 return;
18020 }
18021
18022 if (ipv6 == false)
18023 {
18024 StrCpy(dst, size, src);
18025 }
18026 else
18027 {
18028 Format(dst, size, "%s@ipv6", src);
18029 }
18030 }
18031
18032 // Registration of the new DNS cache
NewDnsCache(char * hostname,IP * ip)18033 void NewDnsCache(char *hostname, IP *ip)
18034 {
18035 NewDnsCacheEx(hostname, ip, IsIP6(ip));
18036 }
NewDnsCacheEx(char * hostname,IP * ip,bool ipv6)18037 void NewDnsCacheEx(char *hostname, IP *ip, bool ipv6)
18038 {
18039 DNSCACHE *c;
18040 char tmp[MAX_PATH];
18041 // Validate arguments
18042 if (hostname == NULL || ip == NULL)
18043 {
18044 return;
18045 }
18046
18047 if (IsNetworkNameCacheEnabled() == false)
18048 {
18049 return;
18050 }
18051
18052 GenDnsCacheKeyName(tmp, sizeof(tmp), hostname, ipv6);
18053
18054 LockDnsCache();
18055 {
18056 DNSCACHE t;
18057
18058 // Search for anything matches to the hostname first
18059 t.HostName = tmp;
18060 c = Search(DnsCache, &t);
18061
18062 if (c == NULL)
18063 {
18064 // Newly register
18065 c = ZeroMalloc(sizeof(DNSCACHE));
18066 c->HostName = CopyStr(tmp);
18067
18068 Copy(&c->IpAddress, ip, sizeof(IP));
18069
18070 Add(DnsCache, c);
18071 }
18072 else
18073 {
18074 // Update
18075 Copy(&c->IpAddress, ip, sizeof(IP));
18076 }
18077 }
18078 UnlockDnsCache();
18079 }
18080
18081 // Name comparison of the DNS cache entries
CompareDnsCache(void * p1,void * p2)18082 int CompareDnsCache(void *p1, void *p2)
18083 {
18084 DNSCACHE *c1, *c2;
18085 if (p1 == NULL || p2 == NULL)
18086 {
18087 return 0;
18088 }
18089 c1 = *(DNSCACHE **)p1;
18090 c2 = *(DNSCACHE **)p2;
18091 if (c1 == NULL || c2 == NULL)
18092 {
18093 return 0;
18094 }
18095
18096 return StrCmpi(c1->HostName, c2->HostName);
18097 }
18098
18099 // Initialization of the DNS cache
InitDnsCache()18100 void InitDnsCache()
18101 {
18102 // Creating a List
18103 DnsCache = NewList(CompareDnsCache);
18104 }
18105
18106 // Release of the DNS cache
FreeDnsCache()18107 void FreeDnsCache()
18108 {
18109 LockDnsCache();
18110 {
18111 DNSCACHE *c;
18112 UINT i;
18113 for (i = 0;i < LIST_NUM(DnsCache);i++)
18114 {
18115 // Release the memory for the entry
18116 c = LIST_DATA(DnsCache, i);
18117 Free(c->HostName);
18118 Free(c);
18119 }
18120 }
18121 UnlockDnsCache();
18122
18123 // Release the list
18124 ReleaseList(DnsCache);
18125 DnsCache = NULL;
18126 }
18127
18128 // Lock the DNS cache
LockDnsCache()18129 void LockDnsCache()
18130 {
18131 LockList(DnsCache);
18132 }
18133
18134 // Unlock the DNS cache
UnlockDnsCache()18135 void UnlockDnsCache()
18136 {
18137 UnlockList(DnsCache);
18138 }
18139
18140 // DH temp key callback
TmpDhCallback(SSL * ssl,int is_export,int keylength)18141 DH *TmpDhCallback(SSL *ssl, int is_export, int keylength)
18142 {
18143 DH *ret = NULL;
18144
18145 if (dh_2048 != NULL)
18146 {
18147 ret = dh_2048->dh;
18148 }
18149
18150 return ret;
18151 }
18152
18153 // Create the SSL_CTX
NewSSLCtx(bool server_mode)18154 struct ssl_ctx_st *NewSSLCtx(bool server_mode)
18155 {
18156 struct ssl_ctx_st *ctx = SSL_CTX_new(SSLv23_method());
18157
18158 #ifdef SSL_OP_NO_TICKET
18159 SSL_CTX_set_options(ctx, SSL_OP_NO_TICKET);
18160 #endif // SSL_OP_NO_TICKET
18161
18162 #ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
18163 if (server_mode)
18164 {
18165 SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
18166 }
18167 #endif // SSL_OP_CIPHER_SERVER_PREFERENCE
18168
18169 SSL_CTX_set_tmp_dh_callback(ctx, TmpDhCallback);
18170
18171 #ifdef SSL_CTX_set_ecdh_auto
18172 SSL_CTX_set_ecdh_auto(ctx, 1);
18173 #endif // SSL_CTX_set_ecdh_auto
18174
18175 #if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(LIBRESSL_VERSION_NUMBER)
18176 // For compatibility with VPN 3.0 or older
18177 SSL_CTX_set_security_level(ctx, 0);
18178 #endif
18179
18180 return ctx;
18181 }
18182
18183 // Release of the SSL_CTX
FreeSSLCtx(struct ssl_ctx_st * ctx)18184 void FreeSSLCtx(struct ssl_ctx_st *ctx)
18185 {
18186 // Validate arguments
18187 if (ctx == NULL)
18188 {
18189 return;
18190 }
18191
18192 SSL_CTX_free(ctx);
18193 }
18194
18195 // The number of get ip threads
SetGetIpThreadMaxNum(UINT num)18196 void SetGetIpThreadMaxNum(UINT num)
18197 {
18198 max_getip_thread = num;
18199 }
GetGetIpThreadMaxNum()18200 UINT GetGetIpThreadMaxNum()
18201 {
18202 UINT ret = max_getip_thread;
18203
18204 if (ret == 0)
18205 {
18206 ret = 0x7FFFFFFF;
18207 }
18208
18209 return ret;
18210 }
GetCurrentGetIpThreadNum()18211 UINT GetCurrentGetIpThreadNum()
18212 {
18213 return Count(getip_thread_counter);
18214 }
18215
18216 // Initialize the network communication module
InitNetwork()18217 void InitNetwork()
18218 {
18219 disable_gethostname_by_accept = false;
18220
18221
18222 InitDynList();
18223
18224
18225 host_ip_address_list_cache_lock = NewLock();
18226 host_ip_address_list_cache_last = 0;
18227
18228 num_tcp_connections = NewCounter();
18229
18230 getip_thread_counter = NewCounter();
18231
18232 // Initialization of client list
18233 InitIpClientList();
18234
18235 // Thread related initialization
18236 InitWaitThread();
18237
18238 // Initialization of the host name cache
18239 InitHostCache();
18240
18241 #ifdef OS_WIN32
18242 // Initializing the socket library
18243 Win32InitSocketLibrary();
18244 #else
18245 UnixInitSocketLibrary();
18246 #endif // OS_WIN32
18247
18248 // Initialization of the DNS cache
18249 InitDnsCache();
18250
18251 // Locking initialization
18252 machine_name_lock = NewLock();
18253 disconnect_function_lock = NewLock();
18254 aho = NewLock();
18255 machine_ip_process_hash_lock = NewLock();
18256 socket_library_lock = NewLock();
18257 //ssl_connect_lock = NewLock(); //2012.9.28 Not required for recent OpenSSL
18258 // ssl_accept_lock = NewLock();
18259 dns_lock = NewLock();
18260 unix_dns_server_addr_lock = NewLock();
18261 Zero(&unix_dns_server, sizeof(unix_dns_server));
18262 local_mac_list_lock = NewLock();
18263
18264 cipher_list_token = ParseToken(cipher_list, " ");
18265
18266 current_global_ip_lock = NewLock();
18267 current_fqdn_lock = NewLock();
18268 current_global_ip_set = false;
18269
18270 disable_cache = false;
18271
18272
18273 dh_2048 = DhNew2048();
18274
18275 Zero(rand_port_numbers, sizeof(rand_port_numbers));
18276
18277 SetGetIpThreadMaxNum(DEFAULT_GETIP_THREAD_MAX_NUM);
18278 }
18279
18280 // Enable the network name cache
EnableNetworkNameCache()18281 void EnableNetworkNameCache()
18282 {
18283 disable_cache = false;
18284 }
18285
18286 // Disable the network name cache
DisableNetworkNameCache()18287 void DisableNetworkNameCache()
18288 {
18289 disable_cache = true;
18290 }
18291
18292 // Get whether the network name cache is enabled
IsNetworkNameCacheEnabled()18293 bool IsNetworkNameCacheEnabled()
18294 {
18295 return !disable_cache;
18296 }
18297
18298 // Get the cipher algorithm list
GetCipherList()18299 TOKEN_LIST *GetCipherList()
18300 {
18301 return cipher_list_token;
18302 }
18303
18304 // Get the TCP connections counter
GetNumTcpConnectionsCounter()18305 COUNTER *GetNumTcpConnectionsCounter()
18306 {
18307 return num_tcp_connections;
18308 }
18309
18310 // Get the current global IP address
GetCurrentGlobalIP(IP * ip,bool ipv6)18311 bool GetCurrentGlobalIP(IP *ip, bool ipv6)
18312 {
18313 bool ret = false;
18314 // Validate arguments
18315 if (ip == NULL)
18316 {
18317 return false;
18318 }
18319
18320 Zero(ip, sizeof(IP));
18321
18322 Lock(current_global_ip_lock);
18323 {
18324 if (ipv6 == false)
18325 {
18326 Copy(ip, ¤t_glocal_ipv4, sizeof(IP));
18327 }
18328 else
18329 {
18330 Copy(ip, ¤t_glocal_ipv6, sizeof(IP));
18331 }
18332
18333 ret = current_global_ip_set;
18334 }
18335 Unlock(current_global_ip_lock);
18336
18337 return ret;
18338 }
18339
18340 // Check whether the specified IP address is assigned to the local host
IsIPMyHost(IP * ip)18341 bool IsIPMyHost(IP *ip)
18342 {
18343 LIST *o;
18344 UINT i;
18345 bool ret = false;
18346 // Validate arguments
18347 if (ip == NULL)
18348 {
18349 return false;
18350 }
18351
18352 if (IsZeroIp(ip))
18353 {
18354 return false;
18355 }
18356
18357 // Search to check whether it matches to any of the IP of the local host
18358 o = GetHostIPAddressList();
18359
18360 for (i = 0;i < LIST_NUM(o);i++)
18361 {
18362 IP *p = LIST_DATA(o, i);
18363
18364 if (CmpIpAddr(p, ip) == 0)
18365 {
18366 // Matched
18367 ret = true;
18368 break;
18369 }
18370 }
18371
18372 FreeHostIPAddressList(o);
18373
18374 if (ret == false)
18375 {
18376 if (IsLocalHostIP(ip))
18377 {
18378 // localhost IP addresses
18379 ret = true;
18380 }
18381 }
18382
18383 return ret;
18384 }
18385
18386 // Check whether the specified IP address is a private IP address
IsIPPrivate(IP * ip)18387 bool IsIPPrivate(IP *ip)
18388 {
18389 // Validate arguments
18390 if (ip == NULL)
18391 {
18392 return false;
18393 }
18394
18395 if (ip->addr[0] == 10)
18396 {
18397 return true;
18398 }
18399
18400 if (ip->addr[0] == 172)
18401 {
18402 if (ip->addr[1] >= 16 && ip->addr[1] <= 31)
18403 {
18404 return true;
18405 }
18406 }
18407
18408 if (ip->addr[0] == 192 && ip->addr[1] == 168)
18409 {
18410 return true;
18411 }
18412
18413 if (ip->addr[0] == 169 && ip->addr[1] == 254)
18414 {
18415 return true;
18416 }
18417
18418 if (ip->addr[0] == 100)
18419 {
18420 if (ip->addr[1] >= 64 && ip->addr[1] <= 127)
18421 {
18422 return true;
18423 }
18424 }
18425
18426 if (g_private_ip_list != NULL)
18427 {
18428 if (IsIP4(ip))
18429 {
18430 UINT ip4 = IPToUINT(ip);
18431
18432 return IsOnPrivateIPFile(ip4);
18433 }
18434 }
18435
18436 return false;
18437 }
18438
18439 // Is the IP address either local or private?
IsIPLocalOrPrivate(IP * ip)18440 bool IsIPLocalOrPrivate(IP *ip)
18441 {
18442 // Validate arguments
18443 if (ip == NULL)
18444 {
18445 return false;
18446 }
18447
18448 if (IsIPPrivate(ip))
18449 {
18450 return true;
18451 }
18452
18453 if (IsLocalHostIP(ip))
18454 {
18455 return true;
18456 }
18457
18458 if (IsIPMyHost(ip))
18459 {
18460 return true;
18461 }
18462
18463 return false;
18464 }
18465
18466 // Read a private IP list file
LoadPrivateIPFile()18467 void LoadPrivateIPFile()
18468 {
18469 BUF *b = ReadDump(PRIVATE_IP_TXT_FILENAME);
18470 LIST *o;
18471 if (b == NULL)
18472 {
18473 return;
18474 }
18475
18476 o = NewList(NULL);
18477
18478 while (true)
18479 {
18480 char *line = CfgReadNextLine(b);
18481 if (line == NULL)
18482 {
18483 break;
18484 }
18485
18486 Trim(line);
18487
18488 if (IsEmptyStr(line) == false)
18489 {
18490 UINT ip = 0, mask = 0;
18491
18492 if (ParseIpAndSubnetMask4(line, &ip, &mask))
18493 {
18494 PRIVATE_IP_SUBNET *p = ZeroMalloc(sizeof(PRIVATE_IP_SUBNET));
18495
18496 p->Ip = ip;
18497 p->Mask = mask;
18498 p->Ip2 = ip & mask;
18499
18500 Add(o, p);
18501 }
18502 }
18503
18504 Free(line);
18505 }
18506
18507 g_private_ip_list = o;
18508 g_use_privateip_file = true;
18509
18510 FreeBuf(b);
18511 }
18512
18513 // Examine whether the specified IP address is in the private IP file
IsOnPrivateIPFile(UINT ip)18514 bool IsOnPrivateIPFile(UINT ip)
18515 {
18516 bool ret = false;
18517
18518 if (g_private_ip_list != NULL)
18519 {
18520 LIST *o = g_private_ip_list;
18521 UINT i;
18522
18523 for (i = 0;i < LIST_NUM(o);i++)
18524 {
18525 PRIVATE_IP_SUBNET *p = LIST_DATA(o, i);
18526
18527 if ((ip & p->Mask) == p->Ip2)
18528 {
18529 ret = true;
18530 }
18531 }
18532 }
18533
18534 return ret;
18535 }
18536
18537 // Free the private IP file
FreePrivateIPFile()18538 void FreePrivateIPFile()
18539 {
18540 if (g_private_ip_list != NULL)
18541 {
18542 LIST *o = g_private_ip_list;
18543 UINT i;
18544
18545 g_private_ip_list = NULL;
18546
18547 for (i = 0;i < LIST_NUM(o);i++)
18548 {
18549 PRIVATE_IP_SUBNET *p = LIST_DATA(o, i);
18550
18551 Free(p);
18552 }
18553
18554 ReleaseList(o);
18555 }
18556
18557 g_use_privateip_file = false;
18558 }
18559
18560 // Check whether the specified IP address is in the same network to this computer
IsIPAddressInSameLocalNetwork(IP * a)18561 bool IsIPAddressInSameLocalNetwork(IP *a)
18562 {
18563 bool ret = false;
18564 LIST *o;
18565 UINT i;
18566 // Validate arguments
18567 if (a == NULL)
18568 {
18569 return false;
18570 }
18571
18572 o = GetHostIPAddressList();
18573
18574 if (o != NULL)
18575 {
18576 for (i = 0;i < LIST_NUM(o);i++)
18577 {
18578 IP *p = LIST_DATA(o, i);
18579
18580 if (IsIP4(p))
18581 {
18582 if (IsZeroIp(p) == false && p->addr[0] != 127)
18583 {
18584 if (IsInSameNetwork4Standard(p, a))
18585 {
18586 ret = true;
18587 break;
18588 }
18589 }
18590 }
18591 }
18592
18593 FreeHostIPAddressList(o);
18594 }
18595
18596 return ret;
18597 }
18598
18599 // Guess the IPv4, IPv6 global address from the IP address list of the current interface
GetCurrentGlobalIPGuess(IP * ip,bool ipv6)18600 void GetCurrentGlobalIPGuess(IP *ip, bool ipv6)
18601 {
18602 LIST *o;
18603 UINT i;
18604 // Validate arguments
18605 if (ip == NULL)
18606 {
18607 return;
18608 }
18609
18610 Zero(ip, sizeof(IP));
18611
18612 o = GetHostIPAddressList();
18613
18614 if (ipv6 == false)
18615 {
18616 // IPv4
18617 for (i = 0;i < LIST_NUM(o);i++)
18618 {
18619 IP *p = LIST_DATA(o, i);
18620
18621 if (IsIP4(p))
18622 {
18623 if (IsZeroIp(p) == false && IsIPPrivate(p) == false && p->addr[0] != 127)
18624 {
18625 Copy(ip, p, sizeof(IP));
18626 }
18627 }
18628 }
18629
18630 if (IsZeroIp(ip))
18631 {
18632 for (i = 0;i < LIST_NUM(o);i++)
18633 {
18634 IP *p = LIST_DATA(o, i);
18635
18636 if (IsIP4(p))
18637 {
18638 if (IsZeroIp(p) == false && IsIPPrivate(p) && p->addr[0] != 127)
18639 {
18640 Copy(ip, p, sizeof(IP));
18641 }
18642 }
18643 }
18644 }
18645
18646 if (IsZeroIp(ip))
18647 {
18648 SetIP(ip, 127, 0, 0, 1);
18649 }
18650 }
18651 else
18652 {
18653 // IPv6
18654 for (i = 0;i < LIST_NUM(o);i++)
18655 {
18656 IP *p = LIST_DATA(o, i);
18657
18658 if (IsIP6(p))
18659 {
18660 UINT type = GetIPAddrType6(p);
18661
18662 if ((type & IPV6_ADDR_GLOBAL_UNICAST) && ((type & IPV6_ADDR_ZERO) == 0) && ((type & IPV6_ADDR_LOOPBACK) == 0))
18663 {
18664 Copy(ip, p, sizeof(IP));
18665 }
18666 }
18667 }
18668 }
18669
18670 FreeHostIPAddressList(o);
18671 }
18672
18673 // Record the current global IP address
SetCurrentGlobalIP(IP * ip,bool ipv6)18674 void SetCurrentGlobalIP(IP *ip, bool ipv6)
18675 {
18676 // Validate arguments
18677 if (ip == NULL)
18678 {
18679 return;
18680 }
18681
18682 if (IsZeroIp(ip))
18683 {
18684 return;
18685 }
18686
18687 Lock(current_global_ip_lock);
18688 {
18689 if (ipv6 == false)
18690 {
18691 Copy(¤t_glocal_ipv4, ip, sizeof(IP));
18692 }
18693 else
18694 {
18695 Copy(¤t_glocal_ipv6, ip, sizeof(IP));
18696 }
18697
18698 current_global_ip_set = true;
18699 }
18700 Unlock(current_global_ip_lock);
18701 }
18702
18703 // Release of the network communication module
FreeNetwork()18704 void FreeNetwork()
18705 {
18706
18707 if (dh_2048 != NULL)
18708 {
18709 DhFree(dh_2048);
18710 dh_2048 = NULL;
18711 }
18712
18713 // Release of thread-related
18714 FreeWaitThread();
18715
18716 FreeToken(cipher_list_token);
18717 cipher_list_token = NULL;
18718
18719 Zero(&unix_dns_server, sizeof(unix_dns_server));
18720
18721 // Release the locks
18722 DeleteLock(unix_dns_server_addr_lock);
18723 DeleteLock(dns_lock);
18724 DeleteLock(ssl_accept_lock);
18725 DeleteLock(machine_name_lock);
18726 DeleteLock(disconnect_function_lock);
18727 DeleteLock(aho);
18728 DeleteLock(socket_library_lock);
18729 DeleteLock(ssl_connect_lock);
18730 DeleteLock(machine_ip_process_hash_lock);
18731 machine_name_lock = NULL;
18732 ssl_accept_lock = machine_name_lock = disconnect_function_lock =
18733 aho = socket_library_lock = ssl_connect_lock = machine_ip_process_hash_lock = NULL;
18734
18735 // Release of the DNS cache
18736 FreeDnsCache();
18737
18738 // Release of the host name cache
18739 FreeHostCache();
18740
18741 #ifdef OS_WIN32
18742 // Release of the socket library
18743 Win32FreeSocketLibrary();
18744 #else
18745 UnixFreeSocketLibrary();
18746 #endif // OS_WIN32
18747
18748 DeleteCounter(num_tcp_connections);
18749 num_tcp_connections = NULL;
18750
18751 // Release of client list
18752 FreeIpClientList();
18753
18754 DeleteLock(current_global_ip_lock);
18755 current_global_ip_lock = NULL;
18756
18757 DeleteLock(current_fqdn_lock);
18758 current_fqdn_lock = NULL;
18759
18760 // Release of the local MAC list
18761 if (local_mac_list != NULL)
18762 {
18763 FreeNicList(local_mac_list);
18764 local_mac_list = NULL;
18765 }
18766
18767 DeleteLock(local_mac_list_lock);
18768 local_mac_list_lock = NULL;
18769
18770 DeleteLock(host_ip_address_list_cache_lock);
18771 host_ip_address_list_cache_lock = NULL;
18772
18773 FreeHostIPAddressList(host_ip_address_cache);
18774 host_ip_address_cache = NULL;
18775
18776
18777 FreeDynList();
18778
18779 DeleteCounter(getip_thread_counter);
18780 getip_thread_counter = NULL;
18781
18782 }
18783
18784 // Add a socket to socket list
AddSockList(SOCKLIST * sl,SOCK * s)18785 void AddSockList(SOCKLIST *sl, SOCK *s)
18786 {
18787 // Validate arguments
18788 if (sl == NULL || s == NULL)
18789 {
18790 return;
18791 }
18792
18793 LockList(sl->SockList);
18794 {
18795 if (IsInList(sl->SockList, s) == false)
18796 {
18797 AddRef(s->ref);
18798
18799 Insert(sl->SockList, s);
18800 }
18801 }
18802 UnlockList(sl->SockList);
18803 }
18804
18805 // Remove the socket from socket list
DelSockList(SOCKLIST * sl,SOCK * s)18806 void DelSockList(SOCKLIST *sl, SOCK *s)
18807 {
18808 // Validate arguments
18809 if (sl == NULL || s == NULL)
18810 {
18811 return;
18812 }
18813
18814 LockList(sl->SockList);
18815 {
18816 if (Delete(sl->SockList, s))
18817 {
18818 ReleaseSock(s);
18819 }
18820 }
18821 UnlockList(sl->SockList);
18822 }
18823
18824 // Stop all the sockets in the list and delete it
StopSockList(SOCKLIST * sl)18825 void StopSockList(SOCKLIST *sl)
18826 {
18827 SOCK **ss;
18828 UINT num, i;
18829 // Validate arguments
18830 if (sl == NULL)
18831 {
18832 return;
18833 }
18834
18835 LockList(sl->SockList);
18836 {
18837 num = LIST_NUM(sl->SockList);
18838 ss = ToArray(sl->SockList);
18839
18840 DeleteAll(sl->SockList);
18841 }
18842 UnlockList(sl->SockList);
18843
18844 for (i = 0;i < num;i++)
18845 {
18846 SOCK *s = ss[i];
18847
18848 Disconnect(s);
18849 ReleaseSock(s);
18850 }
18851
18852 Free(ss);
18853 }
18854
18855 // Delete the socket list
FreeSockList(SOCKLIST * sl)18856 void FreeSockList(SOCKLIST *sl)
18857 {
18858 // Validate arguments
18859 if (sl == NULL)
18860 {
18861 return;
18862 }
18863
18864 StopSockList(sl);
18865
18866 ReleaseList(sl->SockList);
18867
18868 Free(sl);
18869 }
18870
18871 // Creating a socket list
NewSockList()18872 SOCKLIST *NewSockList()
18873 {
18874 SOCKLIST *sl = ZeroMallocFast(sizeof(SOCKLIST));
18875
18876 sl->SockList = NewList(NULL);
18877
18878 return sl;
18879 }
18880
18881 // Time-out thread of the socket on Solaris
SocketTimeoutThread(THREAD * t,void * param)18882 void SocketTimeoutThread(THREAD *t, void *param)
18883 {
18884 SOCKET_TIMEOUT_PARAM *ttparam;
18885 ttparam = (SOCKET_TIMEOUT_PARAM *)param;
18886
18887 // Wait for time-out period
18888 Select(NULL, ttparam->sock->TimeOut, ttparam->cancel, NULL);
18889
18890 // Disconnect if it is blocked
18891 if(! ttparam->unblocked)
18892 {
18893 // Debug("Socket timeouted\n");
18894 closesocket(ttparam->sock->socket);
18895 }
18896 else
18897 {
18898 // Debug("Socket timeout cancelled\n");
18899 }
18900 }
18901
18902 // Initialize and start the thread for time-out
NewSocketTimeout(SOCK * sock)18903 SOCKET_TIMEOUT_PARAM *NewSocketTimeout(SOCK *sock)
18904 {
18905 SOCKET_TIMEOUT_PARAM *ttp;
18906 if(! sock->AsyncMode && sock->TimeOut != TIMEOUT_INFINITE)
18907 {
18908 // Debug("NewSockTimeout(%u)\n",sock->TimeOut);
18909
18910 ttp = (SOCKET_TIMEOUT_PARAM*)Malloc(sizeof(SOCKET_TIMEOUT_PARAM));
18911
18912 // Set the parameters of the time-out thread
18913 ttp->cancel = NewCancel();
18914 ttp->sock = sock;
18915 ttp->unblocked = false;
18916 ttp->thread = NewThread(SocketTimeoutThread, ttp);
18917 return ttp;
18918 }
18919 return NULL;
18920 }
18921
18922 // Stop and free the thread for timeout
FreeSocketTimeout(SOCKET_TIMEOUT_PARAM * ttp)18923 void FreeSocketTimeout(SOCKET_TIMEOUT_PARAM *ttp)
18924 {
18925 if(ttp == NULL)
18926 {
18927 return;
18928 }
18929
18930 ttp->unblocked = true;
18931 Cancel(ttp->cancel);
18932 WaitThread(ttp->thread, INFINITE);
18933 ReleaseCancel(ttp->cancel);
18934 ReleaseThread(ttp->thread);
18935 Free(ttp);
18936 // Debug("FreeSocketTimeout succeed\n");
18937 return;
18938 }
18939
18940 // Parse the IP address and subnet mask
ParseIpAndSubnetMask46(char * src,IP * ip,IP * mask)18941 bool ParseIpAndSubnetMask46(char *src, IP *ip, IP *mask)
18942 {
18943 // Validate arguments
18944 if (src == NULL || ip == NULL || mask == NULL)
18945 {
18946 return false;
18947 }
18948
18949 if (ParseIpAndMask46(src, ip, mask) == false)
18950 {
18951 return false;
18952 }
18953
18954 if (IsIP4(ip))
18955 {
18956 return IsSubnetMask4(mask);
18957 }
18958 else
18959 {
18960 return IsSubnetMask6(mask);
18961 }
18962 }
ParseIpAndSubnetMask6(char * src,IP * ip,IP * mask)18963 bool ParseIpAndSubnetMask6(char *src, IP *ip, IP *mask)
18964 {
18965 if (ParseIpAndSubnetMask46(src, ip, mask) == false)
18966 {
18967 return false;
18968 }
18969
18970 if (IsIP6(ip) == false)
18971 {
18972 return false;
18973 }
18974
18975 return true;
18976 }
ParseIpAndSubnetMask4(char * src,UINT * ip,UINT * mask)18977 bool ParseIpAndSubnetMask4(char *src, UINT *ip, UINT *mask)
18978 {
18979 IP ip2, mask2;
18980 // Validate arguments
18981 if (src == NULL)
18982 {
18983 return false;
18984 }
18985
18986 if (ParseIpAndSubnetMask46(src, &ip2, &mask2) == false)
18987 {
18988 return false;
18989 }
18990
18991 if (IsIP4(&ip2) == false)
18992 {
18993 return false;
18994 }
18995
18996 if (ip != NULL)
18997 {
18998 *ip = IPToUINT(&ip2);
18999 }
19000
19001 if (mask != NULL)
19002 {
19003 *mask = IPToUINT(&mask2);
19004 }
19005
19006 return true;
19007 }
19008
19009
19010 // Parse the IP address and the mask
ParseIpAndMask46(char * src,IP * ip,IP * mask)19011 bool ParseIpAndMask46(char *src, IP *ip, IP *mask)
19012 {
19013 TOKEN_LIST *t;
19014 char *ipstr;
19015 char *subnetstr;
19016 bool ret = false;
19017 IP ip2;
19018 IP mask2;
19019 // Validate arguments
19020 if (src == NULL || ip == NULL || mask == NULL)
19021 {
19022 return false;
19023 }
19024
19025 Zero(&ip2, sizeof(IP));
19026 Zero(&mask2, sizeof(IP));
19027
19028 t = ParseToken(src, "/");
19029 if (t->NumTokens != 2)
19030 {
19031 FreeToken(t);
19032 return false;
19033 }
19034
19035 ipstr = t->Token[0];
19036 subnetstr = t->Token[1];
19037 Trim(ipstr);
19038 Trim(subnetstr);
19039
19040 if (StrToIP(&ip2, ipstr))
19041 {
19042 if (StrToIP(&mask2, subnetstr))
19043 {
19044 // Compare the kind of the mask part and the IP address part to confirm same
19045 if (IsIP6(&ip2) && IsIP6(&mask2))
19046 {
19047 // Both are IPv6
19048 ret = true;
19049 Copy(ip, &ip2, sizeof(IP));
19050 Copy(mask, &mask2, sizeof(IP));
19051 }
19052 else if (IsIP4(&ip2) && IsIP4(&mask2))
19053 {
19054 // Both are IPv4
19055 ret = true;
19056 Copy(ip, &ip2, sizeof(IP));
19057 Copy(mask, &mask2, sizeof(IP));
19058 }
19059 }
19060 else
19061 {
19062 if (IsNum(subnetstr))
19063 {
19064 UINT i = ToInt(subnetstr);
19065 // Mask part is a number
19066 if (IsIP6(&ip2) && i <= 128)
19067 {
19068 ret = true;
19069 Copy(ip, &ip2, sizeof(IP));
19070 IntToSubnetMask6(mask, i);
19071 }
19072 else if (i <= 32)
19073 {
19074 ret = true;
19075 Copy(ip, &ip2, sizeof(IP));
19076 IntToSubnetMask4(mask, i);
19077 }
19078 }
19079 }
19080 }
19081
19082 FreeToken(t);
19083
19084 return ret;
19085 }
ParseIpAndMask4(char * src,UINT * ip,UINT * mask)19086 bool ParseIpAndMask4(char *src, UINT *ip, UINT *mask)
19087 {
19088 IP ip_ip, ip_mask;
19089 if (ParseIpAndMask46(src, &ip_ip, &ip_mask) == false)
19090 {
19091 return false;
19092 }
19093
19094 if (IsIP4(&ip_ip) == false)
19095 {
19096 return false;
19097 }
19098
19099 if (ip != NULL)
19100 {
19101 *ip = IPToUINT(&ip_ip);
19102 }
19103
19104 if (mask != NULL)
19105 {
19106 *mask = IPToUINT(&ip_mask);
19107 }
19108
19109 return true;
19110 }
ParseIpAndMask6(char * src,IP * ip,IP * mask)19111 bool ParseIpAndMask6(char *src, IP *ip, IP *mask)
19112 {
19113 if (ParseIpAndMask46(src, ip, mask) == false)
19114 {
19115 return false;
19116 }
19117
19118 if (IsIP6(ip) == false)
19119 {
19120 return false;
19121 }
19122
19123 return true;
19124 }
19125
19126
19127 // Check whether the specification of the IPv4 address is correct
IsIpStr4(char * str)19128 bool IsIpStr4(char *str)
19129 {
19130 // Validate arguments
19131 if (str == NULL)
19132 {
19133 return false;
19134 }
19135
19136 if (StrToIP32(str) == 0 && StrCmpi(str, "0.0.0.0") != 0)
19137 {
19138 return false;
19139 }
19140
19141 return true;
19142 }
19143
19144 // Check whether the specification of the IPv6 address is correct
IsIpStr6(char * str)19145 bool IsIpStr6(char *str)
19146 {
19147 IP ip;
19148 // Validate arguments
19149 if (str == NULL)
19150 {
19151 return false;
19152 }
19153
19154 if (StrToIP6(&ip, str) == false)
19155 {
19156 return false;
19157 }
19158
19159 return true;
19160 }
19161
19162 // Check whether the IP address specification is correct
IsIpStr46(char * str)19163 bool IsIpStr46(char *str)
19164 {
19165 if (IsIpStr4(str) || IsIpStr6(str))
19166 {
19167 return true;
19168 }
19169
19170 return false;
19171 }
19172
19173
19174 // Convert the string to an IPv4 mask
StrToMask4(IP * mask,char * str)19175 bool StrToMask4(IP *mask, char *str)
19176 {
19177 // Validate arguments
19178 if (mask == NULL || str == NULL)
19179 {
19180 return false;
19181 }
19182
19183 if (str[0] == '/')
19184 {
19185 str++;
19186 }
19187
19188 if (IsNum(str))
19189 {
19190 UINT n = ToInt(str);
19191
19192 if (n <= 32)
19193 {
19194 IntToSubnetMask4(mask, n);
19195 return true;
19196 }
19197 else
19198 {
19199 return false;
19200 }
19201 }
19202 else
19203 {
19204 if (StrToIP(mask, str) == false)
19205 {
19206 return false;
19207 }
19208 else
19209 {
19210 return IsIP4(mask);
19211 }
19212 }
19213 }
19214
19215 // Convert the string to an IPv6 mask
StrToMask6(IP * mask,char * str)19216 bool StrToMask6(IP *mask, char *str)
19217 {
19218 // Validate arguments
19219 if (mask == NULL || str == NULL)
19220 {
19221 return false;
19222 }
19223
19224 if (str[0] == '/')
19225 {
19226 str++;
19227 }
19228
19229 if (IsNum(str))
19230 {
19231 UINT n = ToInt(str);
19232
19233 if (n <= 128)
19234 {
19235 IntToSubnetMask6(mask, n);
19236 return true;
19237 }
19238 else
19239 {
19240 return false;
19241 }
19242 }
19243 else
19244 {
19245 if (StrToIP(mask, str) == false)
19246 {
19247 return false;
19248 }
19249 else
19250 {
19251 return IsIP6(mask);
19252 }
19253 }
19254 }
StrToMask6Addr(IPV6_ADDR * mask,char * str)19255 bool StrToMask6Addr(IPV6_ADDR *mask, char *str)
19256 {
19257 IP ip;
19258
19259 if (StrToMask6(&ip, str) == false)
19260 {
19261 return false;
19262 }
19263
19264 if (IPToIPv6Addr(mask, &ip) == false)
19265 {
19266 return false;
19267 }
19268
19269 return true;
19270 }
19271
19272 // Convert the string to an IPv4 / IPv6 mask
StrToMask46(IP * mask,char * str,bool ipv6)19273 bool StrToMask46(IP *mask, char *str, bool ipv6)
19274 {
19275 if (ipv6)
19276 {
19277 return StrToMask6(mask, str);
19278 }
19279 else
19280 {
19281 return StrToMask4(mask, str);
19282 }
19283 }
19284
19285
19286 // Convert the IPv4 / IPv6 mask to a string
MaskToStr(char * str,UINT size,IP * mask)19287 void MaskToStr(char *str, UINT size, IP *mask)
19288 {
19289 MaskToStrEx(str, size, mask, false);
19290 }
MaskToStrEx(char * str,UINT size,IP * mask,bool always_full_address)19291 void MaskToStrEx(char *str, UINT size, IP *mask, bool always_full_address)
19292 {
19293 // Validate arguments
19294 if (str == NULL || mask == NULL)
19295 {
19296 return;
19297 }
19298
19299 if (always_full_address == false && IsSubnetMask(mask))
19300 {
19301 ToStr(str, SubnetMaskToInt(mask));
19302 }
19303 else
19304 {
19305 IPToStr(str, size, mask);
19306 }
19307 }
MaskToStr32(char * str,UINT size,UINT mask)19308 void MaskToStr32(char *str, UINT size, UINT mask)
19309 {
19310 MaskToStr32Ex(str, size, mask, false);
19311 }
MaskToStr32Ex(char * str,UINT size,UINT mask,bool always_full_address)19312 void MaskToStr32Ex(char *str, UINT size, UINT mask, bool always_full_address)
19313 {
19314 IP ip;
19315
19316 UINTToIP(&ip, mask);
19317
19318 MaskToStrEx(str, size, &ip, always_full_address);
19319 }
Mask6AddrToStrEx(char * str,UINT size,IPV6_ADDR * mask,bool always_full_address)19320 void Mask6AddrToStrEx(char *str, UINT size, IPV6_ADDR *mask, bool always_full_address)
19321 {
19322 IP ip;
19323
19324 // Validate arguments
19325 if (str == NULL || mask == NULL)
19326 {
19327 StrCpy(str, size, "");
19328 return;
19329 }
19330
19331 IPv6AddrToIP(&ip, mask);
19332
19333 MaskToStrEx(str, size, &ip, always_full_address);
19334 }
Mask6AddrToStr(char * str,UINT size,IPV6_ADDR * mask)19335 void Mask6AddrToStr(char *str, UINT size, IPV6_ADDR *mask)
19336 {
19337 Mask6AddrToStrEx(str, size, mask, false);
19338 }
19339
19340 // Disconnecting of the tube
TubeDisconnect(TUBE * t)19341 void TubeDisconnect(TUBE *t)
19342 {
19343 // Validate arguments
19344 if (t == NULL)
19345 {
19346 return;
19347 }
19348
19349 if (t->TubePairData == NULL)
19350 {
19351 return;
19352 }
19353
19354 Lock(t->TubePairData->Lock);
19355 {
19356 t->TubePairData->IsDisconnected = true;
19357
19358 Set(t->TubePairData->Event1);
19359 Set(t->TubePairData->Event2);
19360 SetSockEvent(t->TubePairData->SockEvent1);
19361 SetSockEvent(t->TubePairData->SockEvent2);
19362 }
19363 Unlock(t->TubePairData->Lock);
19364 }
19365
19366 // Creating a tube pair
NewTubePair(TUBE ** t1,TUBE ** t2,UINT size_of_header)19367 void NewTubePair(TUBE **t1, TUBE **t2, UINT size_of_header)
19368 {
19369 TUBEPAIR_DATA *d;
19370 // Validate arguments
19371 if (t1 == NULL || t2 == NULL)
19372 {
19373 return;
19374 }
19375
19376 *t1 = NewTube(size_of_header);
19377 *t2 = NewTube(size_of_header);
19378
19379 (*t1)->IndexInTubePair = 0;
19380 (*t2)->IndexInTubePair = 1;
19381
19382 d = NewTubePairData();
19383 AddRef(d->Ref);
19384
19385 (*t1)->TubePairData = d;
19386 (*t2)->TubePairData = d;
19387
19388 d->Event1 = (*t1)->Event;
19389 d->Event2 = (*t2)->Event;
19390
19391 AddRef(d->Event1->ref);
19392 AddRef(d->Event2->ref);
19393 }
19394
19395 // Creating a tube pair data
NewTubePairData()19396 TUBEPAIR_DATA *NewTubePairData()
19397 {
19398 TUBEPAIR_DATA *d = ZeroMalloc(sizeof(TUBEPAIR_DATA));
19399
19400 d->Ref = NewRef();
19401
19402 d->Lock = NewLock();
19403
19404 return d;
19405 }
19406
19407 // Set the SockEvent to the tube
SetTubeSockEvent(TUBE * t,SOCK_EVENT * e)19408 void SetTubeSockEvent(TUBE *t, SOCK_EVENT *e)
19409 {
19410 // Validate arguments
19411 if (t == NULL)
19412 {
19413 return;
19414 }
19415
19416 Lock(t->Lock);
19417 {
19418 TUBEPAIR_DATA *d;
19419
19420 if (t->SockEvent != e)
19421 {
19422 if (t->SockEvent != NULL)
19423 {
19424 ReleaseSockEvent(t->SockEvent);
19425 }
19426
19427 if (e != NULL)
19428 {
19429 AddRef(e->ref);
19430 }
19431
19432 t->SockEvent = e;
19433 }
19434
19435 d = t->TubePairData;
19436
19437 if (d != NULL)
19438 {
19439 Lock(d->Lock);
19440 {
19441 SOCK_EVENT **sep = (t->IndexInTubePair == 0 ? &d->SockEvent1 : &d->SockEvent2);
19442
19443 if (*sep != e)
19444 {
19445 if (*sep != NULL)
19446 {
19447 ReleaseSockEvent(*sep);
19448 }
19449
19450 if (e != NULL)
19451 {
19452 AddRef(e->ref);
19453 }
19454
19455 *sep = e;
19456 }
19457 }
19458 Unlock(d->Lock);
19459 }
19460 }
19461 Unlock(t->Lock);
19462 }
19463
19464 // Release of the tube pair data
ReleaseTubePairData(TUBEPAIR_DATA * d)19465 void ReleaseTubePairData(TUBEPAIR_DATA *d)
19466 {
19467 // Validate arguments
19468 if (d == NULL)
19469 {
19470 return;
19471 }
19472
19473 if (Release(d->Ref) == 0)
19474 {
19475 CleanupTubePairData(d);
19476 }
19477 }
CleanupTubePairData(TUBEPAIR_DATA * d)19478 void CleanupTubePairData(TUBEPAIR_DATA *d)
19479 {
19480 // Validate arguments
19481 if (d == NULL)
19482 {
19483 return;
19484 }
19485
19486 ReleaseEvent(d->Event1);
19487 ReleaseEvent(d->Event2);
19488
19489 ReleaseSockEvent(d->SockEvent1);
19490 ReleaseSockEvent(d->SockEvent2);
19491
19492 DeleteLock(d->Lock);
19493
19494 Free(d);
19495 }
19496
19497 // Check whether the tube is connected to the opponent still
IsTubeConnected(TUBE * t)19498 bool IsTubeConnected(TUBE *t)
19499 {
19500 // Validate arguments
19501 if (t == NULL)
19502 {
19503 return false;
19504 }
19505
19506 if (t->TubePairData == NULL)
19507 {
19508 return true;
19509 }
19510
19511 if (t->TubePairData->IsDisconnected)
19512 {
19513 return false;
19514 }
19515
19516 return true;
19517 }
19518
19519 // Send the data to the tube
TubeSend(TUBE * t,void * data,UINT size,void * header)19520 bool TubeSend(TUBE *t, void *data, UINT size, void *header)
19521 {
19522 return TubeSendEx(t, data, size, header, false);
19523 }
TubeSendEx(TUBE * t,void * data,UINT size,void * header,bool no_flush)19524 bool TubeSendEx(TUBE *t, void *data, UINT size, void *header, bool no_flush)
19525 {
19526 return TubeSendEx2(t, data, size, header, no_flush, 0);
19527 }
TubeSendEx2(TUBE * t,void * data,UINT size,void * header,bool no_flush,UINT max_num_in_queue)19528 bool TubeSendEx2(TUBE *t, void *data, UINT size, void *header, bool no_flush, UINT max_num_in_queue)
19529 {
19530 // Validate arguments
19531 if (t == NULL || data == NULL || size == 0)
19532 {
19533 return false;
19534 }
19535
19536 if (IsTubeConnected(t) == false)
19537 {
19538 return false;
19539 }
19540
19541 LockQueue(t->Queue);
19542 {
19543 if (max_num_in_queue == 0 || (t->Queue->num_item <= max_num_in_queue))
19544 {
19545 InsertQueue(t->Queue, NewTubeData(data, size, header, t->SizeOfHeader));
19546 }
19547 else
19548 {
19549 no_flush = true;
19550 }
19551 }
19552 UnlockQueue(t->Queue);
19553
19554 if (no_flush == false)
19555 {
19556 Set(t->Event);
19557 SetSockEvent(t->SockEvent);
19558 }
19559
19560 return true;
19561 }
19562
19563 // Flush the tube
TubeFlush(TUBE * t)19564 void TubeFlush(TUBE *t)
19565 {
19566 TubeFlushEx(t, false);
19567 }
TubeFlushEx(TUBE * t,bool force)19568 void TubeFlushEx(TUBE *t, bool force)
19569 {
19570 // Validate arguments
19571 if (t == NULL)
19572 {
19573 return;
19574 }
19575
19576 if (IsTubeConnected(t) == false)
19577 {
19578 return;
19579 }
19580
19581 if (force == false)
19582 {
19583 if (t->Queue->num_item == 0)
19584 {
19585 return;
19586 }
19587 }
19588
19589 Set(t->Event);
19590 SetSockEvent(t->SockEvent);
19591 }
19592
19593 // Receive the data from the tube (asynchronous)
TubeRecvAsync(TUBE * t)19594 TUBEDATA *TubeRecvAsync(TUBE *t)
19595 {
19596 TUBEDATA *d;
19597 // Validate arguments
19598 if (t == NULL)
19599 {
19600 return NULL;
19601 }
19602
19603 if (IsTubeConnected(t) == false)
19604 {
19605 return NULL;
19606 }
19607
19608 LockQueue(t->Queue);
19609 {
19610 d = GetNext(t->Queue);
19611 }
19612 UnlockQueue(t->Queue);
19613
19614 return d;
19615 }
19616
19617 // Get the SockEvent associated with the tube
GetTubeSockEvent(TUBE * t)19618 SOCK_EVENT *GetTubeSockEvent(TUBE *t)
19619 {
19620 SOCK_EVENT *e = NULL;
19621 // Validate arguments
19622 if (t == NULL)
19623 {
19624 return NULL;
19625 }
19626
19627 Lock(t->Lock);
19628 {
19629 if (t->SockEvent != NULL)
19630 {
19631 AddRef(t->SockEvent->ref);
19632
19633 e = t->SockEvent;
19634 }
19635 }
19636 Unlock(t->Lock);
19637
19638 return e;
19639 }
19640
19641 // Receive the data from the tube (synchronous)
TubeRecvSync(TUBE * t,UINT timeout)19642 TUBEDATA *TubeRecvSync(TUBE *t, UINT timeout)
19643 {
19644 UINT64 start_tick, timeout_tick;
19645 TUBEDATA *d = NULL;
19646 // Validate arguments
19647 if (t == NULL)
19648 {
19649 return NULL;
19650 }
19651
19652 if (IsTubeConnected(t) == false)
19653 {
19654 return NULL;
19655 }
19656
19657 start_tick = Tick64();
19658 timeout_tick = start_tick + (UINT64)timeout;
19659
19660 while (true)
19661 {
19662 UINT64 now = Tick64();
19663 UINT remain_time;
19664 SOCK_EVENT *e;
19665 UINT interval;
19666
19667 d = NULL;
19668
19669 if (IsTubeConnected(t) == false)
19670 {
19671 break;
19672 }
19673
19674 LockQueue(t->Queue);
19675 {
19676 d = GetNext(t->Queue);
19677 }
19678 UnlockQueue(t->Queue);
19679
19680 if (d != NULL)
19681 {
19682 break;
19683 }
19684
19685 if (timeout != INFINITE && now >= timeout_tick)
19686 {
19687 return NULL;
19688 }
19689
19690 remain_time = (UINT)(timeout_tick - now);
19691
19692 e = GetTubeSockEvent(t);
19693
19694 interval = (timeout == INFINITE ? INFINITE : remain_time);
19695
19696 if (e == NULL)
19697 {
19698 Wait(t->Event, interval);
19699 }
19700 else
19701 {
19702 WaitSockEvent(e, interval);
19703
19704 ReleaseSockEvent(e);
19705 }
19706 }
19707
19708 return d;
19709 }
19710
19711 // Creating a tube
NewTube(UINT size_of_header)19712 TUBE *NewTube(UINT size_of_header)
19713 {
19714 TUBE *t = ZeroMalloc(sizeof(TUBE));
19715
19716 t->Event = NewEvent();
19717 t->Queue = NewQueue();
19718 t->Ref = NewRef();
19719 t->Lock = NewLock();
19720 t->SockEvent = NewSockEvent();
19721
19722 t->SizeOfHeader = size_of_header;
19723
19724 return t;
19725 }
19726
19727 // Release of the tube
ReleaseTube(TUBE * t)19728 void ReleaseTube(TUBE *t)
19729 {
19730 // Validate arguments
19731 if (t == NULL)
19732 {
19733 return;
19734 }
19735
19736 if (Release(t->Ref) == 0)
19737 {
19738 CleanupTube(t);
19739 }
19740 }
CleanupTube(TUBE * t)19741 void CleanupTube(TUBE *t)
19742 {
19743 // Validate arguments
19744 if (t == NULL)
19745 {
19746 return;
19747 }
19748
19749 while (true)
19750 {
19751 TUBEDATA *d = GetNext(t->Queue);
19752 if (d == NULL)
19753 {
19754 break;
19755 }
19756
19757 FreeTubeData(d);
19758 }
19759
19760 ReleaseQueue(t->Queue);
19761 ReleaseEvent(t->Event);
19762 ReleaseSockEvent(t->SockEvent);
19763
19764 ReleaseTubePairData(t->TubePairData);
19765
19766 DeleteLock(t->Lock);
19767
19768 Free(t);
19769 }
19770
19771 // Creating a tube data
NewTubeData(void * data,UINT size,void * header,UINT header_size)19772 TUBEDATA *NewTubeData(void *data, UINT size, void *header, UINT header_size)
19773 {
19774 TUBEDATA *d;
19775 // Validate arguments
19776 if (size == 0 || data == NULL)
19777 {
19778 return NULL;
19779 }
19780
19781 d = ZeroMalloc(sizeof(TUBEDATA));
19782
19783 d->Data = Clone(data, size);
19784 d->DataSize = size;
19785 if (header != NULL)
19786 {
19787 d->Header = Clone(header, header_size);
19788 d->HeaderSize = header_size;
19789 }
19790 else
19791 {
19792 d->Header = ZeroMalloc(header_size);
19793 }
19794
19795 return d;
19796 }
19797
19798 // Release of the tube data
FreeTubeData(TUBEDATA * d)19799 void FreeTubeData(TUBEDATA *d)
19800 {
19801 // Validate arguments
19802 if (d == NULL)
19803 {
19804 return;
19805 }
19806
19807 Free(d->Data);
19808 Free(d->Header);
19809
19810 Free(d);
19811 }
19812
19813 // Release of the IP address list of the host
FreeHostIPAddressList(LIST * o)19814 void FreeHostIPAddressList(LIST *o)
19815 {
19816 UINT i;
19817 // Validate arguments
19818 if (o == NULL)
19819 {
19820 return;
19821 }
19822
19823 for (i = 0;i < LIST_NUM(o);i++)
19824 {
19825 IP *ip = LIST_DATA(o, i);
19826
19827 Free(ip);
19828 }
19829
19830 ReleaseList(o);
19831 }
19832
19833 // Get whether the specified IP address is held by this host
IsMyIPAddress(IP * ip)19834 bool IsMyIPAddress(IP *ip)
19835 {
19836 LIST *o;
19837 UINT i;
19838 bool ret = false;
19839 // Validate arguments
19840 if (ip == NULL)
19841 {
19842 return false;
19843 }
19844
19845 o = GetHostIPAddressList();
19846
19847 for (i = 0;i < LIST_NUM(o);i++)
19848 {
19849 IP *a = LIST_DATA(o, i);
19850
19851 if (CmpIpAddr(ip, a) == 0)
19852 {
19853 ret = true;
19854 break;
19855 }
19856 }
19857
19858 FreeHostIPAddressList(o);
19859
19860 return ret;
19861 }
19862
19863 // Add the IP address to the list
AddHostIPAddressToList(LIST * o,IP * ip)19864 void AddHostIPAddressToList(LIST *o, IP *ip)
19865 {
19866 IP *r;
19867 // Validate arguments
19868 if (o == NULL || ip == NULL)
19869 {
19870 return;
19871 }
19872
19873 r = Search(o, ip);
19874 if (r != NULL)
19875 {
19876 return;
19877 }
19878
19879 Insert(o, Clone(ip, sizeof(IP)));
19880 }
19881
19882 // Comparison of the IP address list items
CmpIpAddressList(void * p1,void * p2)19883 int CmpIpAddressList(void *p1, void *p2)
19884 {
19885 IP *ip1, *ip2;
19886 UINT r;
19887 // Validate arguments
19888 if (p1 == NULL || p2 == NULL)
19889 {
19890 return 0;
19891 }
19892 ip1 = *(IP **)p1;
19893 ip2 = *(IP **)p2;
19894 if (ip1 == NULL || ip2 == NULL)
19895 {
19896 return 0;
19897 }
19898
19899 // IPv4 < IPv6
19900 r = COMPARE_RET(IsIP6(ip1), IsIP6(ip2));
19901 if (r != 0)
19902 {
19903 return r;
19904 }
19905
19906 // any > specified IP
19907 if (IsZeroIP(ip1) && IsZeroIP(ip2) == false)
19908 {
19909 return 1;
19910 }
19911 if (IsZeroIP(ip1) == false && IsZeroIP(ip2))
19912 {
19913 return -1;
19914 }
19915
19916 // local > others
19917 if (IsLocalHostIP(ip1) && IsLocalHostIP(ip2) == false)
19918 {
19919 return 1;
19920 }
19921 if (IsLocalHostIP(ip1) == false && IsLocalHostIP(ip2))
19922 {
19923 return -1;
19924 }
19925
19926 // ip address
19927 r = CmpIpAddr(ip1, ip2);
19928 if (r != 0)
19929 {
19930 return r;
19931 }
19932
19933 // interface index
19934 if (IsIP6(ip1))
19935 {
19936 r = COMPARE_RET(ip1->ipv6_scope_id, ip2->ipv6_scope_id);
19937 }
19938 else
19939 {
19940 r = 0;
19941 }
19942
19943 return r;
19944 }
19945
19946 // Get the IP address list hash of the host
GetHostIPAddressListHash()19947 UINT64 GetHostIPAddressListHash()
19948 {
19949 UINT i;
19950 LIST *o;
19951 BUF *buf = NewBuf();
19952 UCHAR hash[SHA1_SIZE];
19953 UINT64 ret = 0;
19954
19955 o = GetHostIPAddressList();
19956
19957 if (o != NULL)
19958 {
19959 for (i = 0;i < LIST_NUM(o);i++)
19960 {
19961 IP *ip = LIST_DATA(o, i);
19962 char tmp[128];
19963
19964 Zero(tmp, sizeof(tmp));
19965 IPToStr(tmp, sizeof(tmp), ip);
19966
19967 WriteBufStr(buf, tmp);
19968 }
19969
19970 FreeHostIPAddressList(o);
19971 }
19972
19973 WriteBufStr(buf, "test");
19974
19975 HashSha1(hash, buf->Buf, buf->Size);
19976
19977 FreeBuf(buf);
19978
19979 Copy(&ret, hash, sizeof(UINT64));
19980
19981 ret = Endian64(ret);
19982
19983 return ret;
19984 }
19985
19986 // Get the IP address list of the host (using cache)
GetHostIPAddressList()19987 LIST *GetHostIPAddressList()
19988 {
19989 LIST *o = NULL;
19990 if (host_ip_address_list_cache_lock == NULL)
19991 {
19992 return GetHostIPAddressListInternal();
19993 }
19994
19995 Lock(host_ip_address_list_cache_lock);
19996 {
19997 UINT64 now = Tick64();
19998
19999 if (host_ip_address_list_cache_last == 0 ||
20000 ((host_ip_address_list_cache_last + (UINT64)HOST_IP_ADDRESS_LIST_CACHE) < now) ||
20001 host_ip_address_cache == NULL)
20002 {
20003 if (host_ip_address_cache != NULL)
20004 {
20005 FreeHostIPAddressList(host_ip_address_cache);
20006 }
20007
20008 host_ip_address_cache = GetHostIPAddressListInternal();
20009
20010 host_ip_address_list_cache_last = now;
20011 }
20012
20013 o = CloneIPAddressList(host_ip_address_cache);
20014 }
20015 Unlock(host_ip_address_list_cache_lock);
20016
20017 if (o == NULL)
20018 {
20019 o = GetHostIPAddressListInternal();
20020 }
20021
20022 return o;
20023 }
20024
20025 // Copy of the IP address list
CloneIPAddressList(LIST * o)20026 LIST *CloneIPAddressList(LIST *o)
20027 {
20028 LIST *ret;
20029 UINT i;
20030 // Validate arguments
20031 if (o == NULL)
20032 {
20033 return NULL;
20034 }
20035
20036 ret = NewListFast(CmpIpAddressList);
20037
20038 for (i = 0;i < LIST_NUM(o);i++)
20039 {
20040 IP *ip = LIST_DATA(o, i);
20041
20042 if (ip != NULL)
20043 {
20044 ip = Clone(ip, sizeof(IP));
20045
20046 Add(ret, ip);
20047 }
20048 }
20049
20050 return ret;
20051 }
20052
20053 // Get an IP address list of the host
GetHostIPAddressListInternal()20054 LIST *GetHostIPAddressListInternal()
20055 {
20056 char hostname[MAX_SIZE];
20057 LIST *o;
20058 IP any6, any4;
20059 IP local6, local4;
20060 bool is_v6_supported = IsIPv6Supported();
20061
20062 GetLocalHostIP4(&local4);
20063 GetLocalHostIP6(&local6);
20064
20065 ZeroIP4(&any4);
20066 ZeroIP6(&any6);
20067
20068 Zero(hostname, sizeof(hostname));
20069
20070 gethostname(hostname, sizeof(hostname));
20071
20072 o = NewListFast(CmpIpAddressList);
20073
20074 // any
20075 AddHostIPAddressToList(o, &any4);
20076 if (is_v6_supported)
20077 {
20078 AddHostIPAddressToList(o, &any6);
20079 }
20080
20081 // localhost
20082 AddHostIPAddressToList(o, &local4);
20083 if (is_v6_supported)
20084 {
20085 AddHostIPAddressToList(o, &local6);
20086 }
20087
20088 #ifndef MAYAQUA_SUPPORTS_GETIFADDRS
20089 // IPv4
20090 if (true)
20091 {
20092 struct sockaddr_in in;
20093 struct in_addr addr;
20094 struct addrinfo hint;
20095 struct addrinfo *info;
20096
20097 // Debug("***** GetHostIPAddressListInternal IPv4 Begin *****\n");
20098
20099 Zero(&hint, sizeof(hint));
20100 hint.ai_family = AF_INET;
20101 hint.ai_socktype = SOCK_DGRAM;
20102 hint.ai_protocol = IPPROTO_UDP;
20103 info = NULL;
20104
20105 if (getaddrinfo(hostname, NULL, &hint, &info) == 0)
20106 {
20107 if (info->ai_family == AF_INET)
20108 {
20109 struct addrinfo *current = info;
20110 while (current != NULL)
20111 {
20112 IP ip;
20113
20114 Copy(&in, current->ai_addr, sizeof(in));
20115 Copy(&addr, &in.sin_addr, sizeof(addr));
20116
20117 InAddrToIP(&ip, &addr);
20118 AddHostIPAddressToList(o, &ip);
20119
20120 // Debug("%r\n", &ip);
20121
20122 current = current->ai_next;
20123 }
20124 }
20125
20126 freeaddrinfo(info);
20127 }
20128 // Debug("***** GetHostIPAddressListInternal IPv4 End *****\n");
20129 }
20130
20131 #ifndef UNIX_LINUX
20132 // IPv6
20133 if (is_v6_supported)
20134 {
20135 struct sockaddr_in6 in;
20136 struct in6_addr addr;
20137 struct addrinfo hint;
20138 struct addrinfo *info;
20139
20140 Zero(&hint, sizeof(hint));
20141 hint.ai_family = AF_INET6;
20142 hint.ai_socktype = SOCK_DGRAM;
20143 hint.ai_protocol = IPPROTO_UDP;
20144 info = NULL;
20145
20146 // Debug("***** GetHostIPAddressListInternal IPv6 Begin *****\n");
20147
20148 if (getaddrinfo(hostname, NULL, &hint, &info) == 0)
20149 {
20150 if (info->ai_family == AF_INET6)
20151 {
20152 struct addrinfo *current = info;
20153 while (current != NULL)
20154 {
20155 IP ip;
20156
20157 Copy(&in, current->ai_addr, sizeof(in));
20158 Copy(&addr, &in.sin6_addr, sizeof(addr));
20159
20160 InAddrToIP6(&ip, &addr);
20161 ip.ipv6_scope_id = in.sin6_scope_id;
20162
20163 AddHostIPAddressToList(o, &ip);
20164
20165 // Debug("%r\n", &ip);
20166
20167 current = current->ai_next;
20168 }
20169 }
20170
20171 freeaddrinfo(info);
20172 }
20173 // Debug("***** GetHostIPAddressListInternal IPv6 End *****\n");
20174 }
20175 #endif // UNIX_LINUX
20176 #endif // MAYAQUA_SUPPORTS_GETIFADDRS
20177
20178 #ifdef MAYAQUA_SUPPORTS_GETIFADDRS
20179 // If the getifaddrs is available, use this
20180 if (true)
20181 {
20182 struct ifaddrs *aa = NULL;
20183
20184 if (getifaddrs(&aa) == 0)
20185 {
20186 struct ifaddrs *a = aa;
20187
20188 while (a != NULL)
20189 {
20190 if (a->ifa_addr != NULL)
20191 {
20192 struct sockaddr *addr = a->ifa_addr;
20193
20194 if (addr->sa_family == AF_INET)
20195 {
20196 IP ip;
20197 struct sockaddr_in *d = (struct sockaddr_in *)addr;
20198 struct in_addr *addr = &d->sin_addr;
20199
20200 InAddrToIP(&ip, addr);
20201
20202 AddHostIPAddressToList(o, &ip);
20203 }
20204 else if (addr->sa_family == AF_INET6)
20205 {
20206 IP ip;
20207 struct sockaddr_in6 *d = (struct sockaddr_in6 *)addr;
20208 UINT scope_id = d->sin6_scope_id;
20209 struct in6_addr *addr = &d->sin6_addr;
20210
20211 InAddrToIP6(&ip, addr);
20212 ip.ipv6_scope_id = scope_id;
20213
20214 AddHostIPAddressToList(o, &ip);
20215 }
20216 }
20217
20218 a = a->ifa_next;
20219 }
20220
20221 freeifaddrs(aa);
20222 }
20223 }
20224 #endif // MAYAQUA_SUPPORTS_GETIFADDRS
20225
20226 return o;
20227 }
20228
20229 // Get whether the UDP listener opens the specified port
IsUdpPortOpened(UDPLISTENER * u,IP * server_ip,UINT port)20230 bool IsUdpPortOpened(UDPLISTENER *u, IP *server_ip, UINT port)
20231 {
20232 UINT i;
20233 // Validate arguments
20234 if (u == NULL || port == 0)
20235 {
20236 return false;
20237 }
20238
20239 if (server_ip != NULL)
20240 {
20241 for (i = 0;i < LIST_NUM(u->SockList);i++)
20242 {
20243 UDPLISTENER_SOCK *us = LIST_DATA(u->SockList, i);
20244
20245 if (us->Sock != NULL && us->HasError == false)
20246 {
20247 if (us->Port == port)
20248 {
20249 if (CmpIpAddr(server_ip, &us->IpAddress) == 0)
20250 {
20251 return true;
20252 }
20253 }
20254 }
20255 }
20256 }
20257
20258 for (i = 0;i < LIST_NUM(u->SockList);i++)
20259 {
20260 UDPLISTENER_SOCK *us = LIST_DATA(u->SockList, i);
20261
20262 if (us->Sock != NULL && us->HasError == false)
20263 {
20264 if (us->Port == port)
20265 {
20266 if (IsZeroIP(&us->IpAddress))
20267 {
20268 return true;
20269 }
20270 }
20271 }
20272 }
20273
20274 return false;
20275 }
20276
20277 // IP address acquisition thread
QueryIpThreadMain(THREAD * thread,void * param)20278 void QueryIpThreadMain(THREAD *thread, void *param)
20279 {
20280 QUERYIPTHREAD *t = (QUERYIPTHREAD *)param;
20281 // Validate arguments
20282 if (thread == NULL || param == NULL)
20283 {
20284 return;
20285 }
20286
20287 while (t->Halt == false)
20288 {
20289 UINT next_wait_time = 0;
20290 IP ip;
20291 bool ok = false;
20292
20293 if (GetIP4Ex(&ip, t->Hostname, 5000, &t->Halt))
20294 {
20295 if (IsZeroIP(&ip) == false)
20296 {
20297 Lock(t->Lock);
20298 {
20299 Copy(&t->Ip, &ip, sizeof(IP));
20300 }
20301 Unlock(t->Lock);
20302
20303 ok = true;
20304 }
20305 }
20306
20307 if (ok == false)
20308 {
20309 next_wait_time = t->IntervalLastNg;
20310 }
20311 else
20312 {
20313 next_wait_time = t->IntervalLastOk;
20314 }
20315
20316 if (t->Halt)
20317 {
20318 break;
20319 }
20320
20321 Wait(t->HaltEvent, next_wait_time);
20322 }
20323 }
20324
20325 // Creating an IP address acquisition thread
NewQueryIpThread(char * hostname,UINT interval_last_ok,UINT interval_last_ng)20326 QUERYIPTHREAD *NewQueryIpThread(char *hostname, UINT interval_last_ok, UINT interval_last_ng)
20327 {
20328 QUERYIPTHREAD *t;
20329
20330 t = ZeroMalloc(sizeof(QUERYIPTHREAD));
20331
20332 t->HaltEvent = NewEvent();
20333 t->Lock = NewLock();
20334 StrCpy(t->Hostname, sizeof(t->Hostname), hostname);
20335 t->IntervalLastOk = interval_last_ok;
20336 t->IntervalLastNg = interval_last_ng;
20337
20338 t->Thread = NewThread(QueryIpThreadMain, t);
20339
20340 return t;
20341 }
20342
20343 // Get the results of the IP address acquisition thread
GetQueryIpThreadResult(QUERYIPTHREAD * t,IP * ip)20344 bool GetQueryIpThreadResult(QUERYIPTHREAD *t, IP *ip)
20345 {
20346 bool ret = false;
20347 Zero(ip, sizeof(IP));
20348 // Validate arguments
20349 if (t == NULL || ip == NULL)
20350 {
20351 return false;
20352 }
20353
20354 Lock(t->Lock);
20355
20356 if (IsZero(&t->Ip, sizeof(IP)))
20357 {
20358 ret = false;
20359 }
20360 else
20361 {
20362 Copy(ip, &t->Ip, sizeof(IP));
20363 }
20364
20365 Unlock(t->Lock);
20366
20367 return ret;
20368 }
20369
20370 // Release of the IP address acquisition thread
FreeQueryIpThread(QUERYIPTHREAD * t)20371 void FreeQueryIpThread(QUERYIPTHREAD *t)
20372 {
20373 // Validate arguments
20374 if (t == NULL)
20375 {
20376 return;
20377 }
20378
20379 t->Halt = true;
20380 Set(t->HaltEvent);
20381
20382 WaitThread(t->Thread, INFINITE);
20383 ReleaseThread(t->Thread);
20384
20385 ReleaseEvent(t->HaltEvent);
20386
20387 DeleteLock(t->Lock);
20388
20389 Free(t);
20390 }
20391
20392 // Get a public port list which is known by UDP listener
UdpListenerGetPublicPortList(UDPLISTENER * u,char * dst,UINT size)20393 void UdpListenerGetPublicPortList(UDPLISTENER *u, char *dst, UINT size)
20394 {
20395 UINT k;
20396 // Validate arguments
20397 ClearStr(dst, size);
20398 if (u == NULL || dst == NULL)
20399 {
20400 return;
20401 }
20402
20403 LockList(u->PortList);
20404 {
20405 for (k = 0;k < LIST_NUM(u->SockList);k++)
20406 {
20407 UDPLISTENER_SOCK *us = LIST_DATA(u->SockList, k);
20408
20409 if (us->PublicPort != 0)
20410 {
20411 char tmp[64];
20412 ToStr(tmp, us->PublicPort);
20413 StrCat(dst, size, tmp);
20414 StrCat(dst, size, " ");
20415 }
20416 }
20417 }
20418 UnlockList(u->PortList);
20419
20420 Trim(dst);
20421 }
20422
20423 // UDP listener thread
UdpListenerThread(THREAD * thread,void * param)20424 void UdpListenerThread(THREAD *thread, void *param)
20425 {
20426 UDPLISTENER *u = (UDPLISTENER *)param;
20427 UINT i, j, k;
20428 UINT buf_size = 65536;
20429 void *buf;
20430 bool cont_flag;
20431 BUF *ip_list_buf = NewBuf();
20432 // Validate arguments
20433 if (thread == NULL || param == NULL)
20434 {
20435 return;
20436 }
20437
20438 buf = Malloc(buf_size);
20439
20440 // Initializing the socket list
20441 u->SockList = NewList(NULL);
20442
20443 u->LastCheckTick = 0;
20444
20445 // u->PollMyIpAndPort = true;
20446
20447 // Main loop
20448 while (u->Halt == false)
20449 {
20450 LIST *recv_list;
20451 UINT recv_list_total_size = 0;
20452 UINT64 now = Tick64();
20453 UINT interval;
20454 bool stage_changed = false;
20455 IP nat_t_ip;
20456
20457 Zero(&nat_t_ip, sizeof(nat_t_ip));
20458
20459
20460 if (u->LastCheckTick == 0 || (now >= (u->LastCheckTick + UDPLISTENER_CHECK_INTERVAL)))
20461 {
20462 LIST *iplist;
20463 LIST *del_us_list = NewListFast(NULL);
20464 BUF *ip_list_buf_new = NewBuf();
20465
20466 u->LastCheckTick = now;
20467
20468 // Obtain an IP address list
20469 iplist = GetHostIPAddressList();
20470
20471 LockList(u->PortList);
20472 {
20473 for (k = 0;k < LIST_NUM(u->SockList);k++)
20474 {
20475 UDPLISTENER_SOCK *us = LIST_DATA(u->SockList, k);
20476
20477 us->Mark = false;
20478 }
20479
20480 // If the combination of the IP address and the port number doesn't exist in the list, add it to the list
20481 for (i = 0;i < LIST_NUM(iplist);i++)
20482 {
20483 IP *ip = LIST_DATA(iplist, i);
20484
20485 WriteBuf(ip_list_buf_new, ip, sizeof(IP));
20486
20487 for (j = 0;j < LIST_NUM(u->PortList);j++)
20488 {
20489 UINT k;
20490 UINT *port = LIST_DATA(u->PortList, j);
20491 bool existing = false;
20492
20493 if (IsZeroIP(ip) && (IS_SPECIAL_PORT(*port)))
20494 {
20495 continue;
20496 }
20497
20498
20499 for (k = 0;k < LIST_NUM(u->SockList);k++)
20500 {
20501 UDPLISTENER_SOCK *us = LIST_DATA(u->SockList, k);
20502
20503 if (CmpIpAddr(&us->IpAddress, ip) == 0 && us->Port == *port)
20504 {
20505 existing = true;
20506
20507 us->Mark = true;
20508
20509 break;
20510 }
20511 }
20512
20513 if (existing == false)
20514 {
20515 UDPLISTENER_SOCK *us = ZeroMalloc(sizeof(UDPLISTENER_SOCK));
20516
20517 Copy(&us->IpAddress, ip, sizeof(IP));
20518 us->Port = *port;
20519
20520 us->Mark = true;
20521
20522 Add(u->SockList, us);
20523 }
20524 }
20525 }
20526
20527 // If any errors suspected or the combination of IP address and port number
20528 // has been regarded to delete already, delete it
20529 for (k = 0;k < LIST_NUM(u->SockList);k++)
20530 {
20531 UDPLISTENER_SOCK *us = LIST_DATA(u->SockList, k);
20532
20533 if (us->Mark == false || us->HasError)
20534 {
20535 Debug("mark=%u error=%u\n", us->Mark, us->HasError);
20536 Add(del_us_list, us);
20537 }
20538 }
20539
20540 for (i = 0;i < LIST_NUM(del_us_list);i++)
20541 {
20542 UDPLISTENER_SOCK *us = LIST_DATA(del_us_list, i);
20543
20544 char ipstr[MAX_SIZE];
20545
20546 IPToStr(ipstr, sizeof(ipstr), &us->IpAddress);
20547 Debug("Closed UDP Port %u at %s.\n", us->Port, ipstr);
20548
20549 Delete(u->SockList, us);
20550
20551 if (us->Sock != NULL)
20552 {
20553 Disconnect(us->Sock);
20554 ReleaseSock(us->Sock);
20555 }
20556
20557 Free(us);
20558 }
20559 }
20560 UnlockList(u->PortList);
20561
20562 // Open the UDP sockets which is not opend yet
20563 for (k = 0;k < LIST_NUM(u->SockList);k++)
20564 {
20565 UDPLISTENER_SOCK *us = LIST_DATA(u->SockList, k);
20566
20567 if (us->Sock == NULL)
20568 {
20569 char ipstr[MAX_SIZE];
20570
20571 IPToStr(ipstr, sizeof(ipstr), &us->IpAddress);
20572
20573 if (us->ErrorDebugDisplayed == false)
20574 {
20575 Debug("Opening UDP Port %u at %s ...", us->Port, ipstr);
20576 }
20577
20578 us->Sock = NewUDPEx2(us->Port, IsIP6(&us->IpAddress), &us->IpAddress);
20579
20580 if (us->Sock != NULL)
20581 {
20582 if (us->ErrorDebugDisplayed == false)
20583 {
20584 Debug("Ok.\n");
20585 }
20586 else
20587 {
20588 Debug("Opening UDP Port %u at %s ...", us->Port, ipstr);
20589 Debug("Ok.\n");
20590 }
20591 JoinSockToSockEvent(us->Sock, u->Event);
20592
20593 us->ErrorDebugDisplayed = false;
20594 }
20595 else
20596 {
20597 if (us->ErrorDebugDisplayed == false)
20598 {
20599 Debug("Error.\n");
20600 }
20601
20602 us->ErrorDebugDisplayed = true;
20603 }
20604 }
20605 }
20606
20607 FreeHostIPAddressList(iplist);
20608
20609 ReleaseList(del_us_list);
20610
20611 if (CompareBuf(ip_list_buf, ip_list_buf_new) == false)
20612 {
20613 u->HostIPAddressListChanged = true;
20614 }
20615
20616 FreeBuf(ip_list_buf);
20617 ip_list_buf = ip_list_buf_new;
20618 }
20619
20620 LABEL_RESTART:
20621
20622 stage_changed = false;
20623
20624 recv_list = NewListFast(NULL);
20625 recv_list_total_size = 0;
20626
20627 if (u->PollMyIpAndPort)
20628 {
20629 {
20630 // Create a thread to get a NAT-T IP address if necessary
20631 if (u->GetNatTIpThread == NULL)
20632 {
20633 char natt_hostname[MAX_SIZE];
20634
20635 RUDPGetRegisterHostNameByIP(natt_hostname, sizeof(natt_hostname), NULL);
20636
20637 u->GetNatTIpThread = NewQueryIpThread(natt_hostname, QUERYIPTHREAD_INTERVAL_LAST_OK, QUERYIPTHREAD_INTERVAL_LAST_NG);
20638 }
20639
20640 GetQueryIpThreadResult(u->GetNatTIpThread, &nat_t_ip);
20641 }
20642 }
20643
20644 // Receive the data that is arriving at the socket
20645 for (k = 0;k < LIST_NUM(u->SockList);k++)
20646 {
20647 UDPLISTENER_SOCK *us = LIST_DATA(u->SockList, k);
20648
20649 if (us->Sock != NULL)
20650 {
20651 UINT num_ignore_errors = 0;
20652
20653 if (u->PollMyIpAndPort && IsIP4(&us->IpAddress))
20654 {
20655 if (us->NextMyIpAndPortPollTick == 0 || us->NextMyIpAndPortPollTick <= now)
20656 {
20657 // Examine the self IP address and the self port number by using NAT-T server
20658 us->NextMyIpAndPortPollTick = now + (UINT64)GenRandInterval(UDP_NAT_T_NAT_STATUS_CHECK_INTERVAL_MIN, UDP_NAT_T_NAT_STATUS_CHECK_INTERVAL_MAX);
20659
20660 if (IsZeroIP(&nat_t_ip) == false
20661 )
20662 {
20663 UCHAR c = 'A';
20664
20665 SendTo(us->Sock, &nat_t_ip, UDP_NAT_T_PORT, &c, 1);
20666 }
20667 }
20668 }
20669
20670 while (true)
20671 {
20672 IP src_addr;
20673 UINT src_port;
20674 UDPPACKET *p;
20675 UINT size;
20676
20677 if (u->RecvBufSize != 0 && recv_list_total_size >= u->RecvBufSize)
20678 {
20679 // No more receive packet since the buffer is full
20680 break;
20681 }
20682
20683 size = RecvFrom(us->Sock, &src_addr, &src_port, buf, buf_size);
20684 if (size == 0)
20685 {
20686 // Socket failure
20687 if (us->Sock->IgnoreRecvErr == false)
20688 {
20689 LABEL_FATAL_ERROR:
20690 Debug("RecvFrom has Error.\n");
20691 us->HasError = true;
20692 }
20693 else
20694 {
20695 if ((num_ignore_errors++) >= MAX_NUM_IGNORE_ERRORS)
20696 {
20697 goto LABEL_FATAL_ERROR;
20698 }
20699 }
20700 break;
20701 }
20702 else if (size == SOCK_LATER)
20703 {
20704 // No packet
20705 break;
20706 }
20707 //Debug("UDP %u\n", size);
20708
20709 if (src_port == UDP_NAT_T_PORT && CmpIpAddr(&src_addr, &nat_t_ip) == 0)
20710 {
20711 // Receive a packet in which the IP address and the port number are written from the NAT-T server
20712 if (size >= 8)
20713 {
20714 IP my_ip;
20715 UINT my_port;
20716
20717 if (RUDPParseIPAndPortStr(buf, size, &my_ip, &my_port))
20718 {
20719 Copy(&us->PublicIpAddress, &my_ip, sizeof(IP));
20720 us->PublicPort = my_port;
20721 }
20722 }
20723 }
20724 else
20725 {
20726 // Receive a regular packet
20727 p = NewUdpPacket(&src_addr, src_port, &us->Sock->LocalIP, us->Sock->LocalPort,
20728 Clone(buf, size), size);
20729
20730 if (p->SrcPort == MAKE_SPECIAL_PORT(52))
20731 {
20732 p->SrcPort = p->DestPort = MAKE_SPECIAL_PORT(50);
20733 }
20734
20735 Add(recv_list, p);
20736
20737 recv_list_total_size += size;
20738 }
20739
20740 stage_changed = true;
20741 }
20742 }
20743 }
20744
20745 // Pass the received packet to the procedure
20746 // Print("recv_list_total_size = %u\n", recv_list_total_size);
20747 u->RecvProc(u, recv_list);
20748
20749 // Release the packet
20750 for (i = 0;i < LIST_NUM(recv_list);i++)
20751 {
20752 UDPPACKET *p = LIST_DATA(recv_list, i);
20753
20754 FreeUdpPacket(p);
20755 }
20756
20757 ReleaseList(recv_list);
20758
20759 cont_flag = true;
20760
20761 do
20762 {
20763 // When there are packets to be transmitted, transmit it
20764 LockList(u->SendPacketList);
20765 {
20766 UDPLISTENER_SOCK *last_us = NULL;
20767 IP last_src_ip;
20768 UINT last_src_port;
20769
20770 Zero(&last_src_ip, sizeof(IP));
20771 last_src_port = 0;
20772
20773 // Print("LIST_NUM(u->SendPacketList) = %u\n", LIST_NUM(u->SendPacketList));
20774
20775 for (i = 0;i < LIST_NUM(u->SendPacketList);i++)
20776 {
20777 UDPPACKET *p = LIST_DATA(u->SendPacketList, i);
20778 UDPLISTENER_SOCK *us;
20779
20780 if (last_us != NULL && last_src_port == p->SrcPort && CmpIpAddr(&last_src_ip, &p->SrcIP) == 0)
20781 {
20782 us = last_us;
20783 }
20784 else
20785 {
20786 // Search for a good interface for the transmission
20787 us = DetermineUdpSocketForSending(u, p);
20788
20789 if (us != NULL)
20790 {
20791 last_us = us;
20792 last_src_port = p->SrcPort;
20793 Copy(&last_src_ip, &p->SrcIP, sizeof(IP));
20794 }
20795 }
20796
20797 if (us != NULL)
20798 {
20799 // Send
20800 UINT ret = SendTo(us->Sock, &p->DstIP, p->DestPort, p->Data, p->Size);
20801
20802 if (ret == 0)
20803 {
20804 if (us->Sock->IgnoreSendErr == false)
20805 {
20806 // Socket failure
20807 Debug("SendTo has Error.\n");
20808 us->HasError = true;
20809 last_us = NULL;
20810 }
20811 }
20812 else
20813 {
20814 if (ret != SOCK_LATER)
20815 {
20816 stage_changed = true;
20817 }
20818 }
20819 }
20820
20821 FreeUdpPacket(p);
20822 }
20823 DeleteAll(u->SendPacketList);
20824 }
20825 UnlockList(u->SendPacketList);
20826
20827 if (LIST_NUM(u->SendPacketList) == 0)
20828 {
20829 cont_flag = false;
20830 }
20831 }
20832 while (cont_flag);
20833
20834 if (stage_changed && u->Halt == false)
20835 {
20836 goto LABEL_RESTART;
20837 }
20838
20839 // Timing adjustment
20840 interval = GetNextIntervalForInterrupt(u->Interrupts);
20841
20842 if (interval == INFINITE)
20843 {
20844 interval = UDPLISTENER_WAIT_INTERVAL;
20845 }
20846 else
20847 {
20848 interval = MIN(UDPLISTENER_WAIT_INTERVAL, interval);
20849 }
20850
20851 if (interval >= 1)
20852 {
20853 WaitSockEvent(u->Event, interval);
20854 }
20855 }
20856
20857 if (u->GetNatTIpThread != NULL)
20858 {
20859 FreeQueryIpThread(u->GetNatTIpThread);
20860 }
20861
20862 // Release of the socket list
20863 for (i = 0;i < LIST_NUM(u->SockList);i++)
20864 {
20865 UDPLISTENER_SOCK *us = (UDPLISTENER_SOCK *)LIST_DATA(u->SockList, i);
20866
20867 Disconnect(us->Sock);
20868 ReleaseSock(us->Sock);
20869
20870 Free(us);
20871 }
20872 ReleaseList(u->SockList);
20873
20874 FreeBuf(ip_list_buf);
20875
20876 Free(buf);
20877 }
20878
20879 // Select the best UDP socket to be used for transmission
DetermineUdpSocketForSending(UDPLISTENER * u,UDPPACKET * p)20880 UDPLISTENER_SOCK *DetermineUdpSocketForSending(UDPLISTENER *u, UDPPACKET *p)
20881 {
20882 UINT i;
20883 // Validate arguments
20884 if (u == NULL || p == NULL)
20885 {
20886 return NULL;
20887 }
20888
20889 for (i = 0;i < LIST_NUM(u->SockList);i++)
20890 {
20891 UDPLISTENER_SOCK *us = LIST_DATA(u->SockList, i);
20892
20893 if (us->Sock != NULL && us->HasError == false)
20894 {
20895 if (us->Port == p->SrcPort)
20896 {
20897 if (CmpIpAddr(&us->IpAddress, &p->SrcIP) == 0)
20898 {
20899 return us;
20900 }
20901 }
20902 }
20903 }
20904
20905 for (i = 0;i < LIST_NUM(u->SockList);i++)
20906 {
20907 UDPLISTENER_SOCK *us = LIST_DATA(u->SockList, i);
20908
20909 if (us->Sock != NULL && us->HasError == false)
20910 {
20911 if (us->Port == p->SrcPort)
20912 {
20913 if (IsZeroIP(&us->IpAddress))
20914 {
20915 if ((IsIP4(&p->DstIP) && IsIP4(&us->IpAddress)) ||
20916 (IsIP6(&p->DstIP) && IsIP6(&us->IpAddress)))
20917 {
20918 return us;
20919 }
20920 }
20921 }
20922 }
20923 }
20924
20925 return NULL;
20926 }
20927
20928 // Release of the UDP packet
FreeUdpPacket(UDPPACKET * p)20929 void FreeUdpPacket(UDPPACKET *p)
20930 {
20931 // Validate arguments
20932 if (p == NULL)
20933 {
20934 return;
20935 }
20936
20937 Free(p->Data);
20938 Free(p);
20939 }
20940
20941 // Create a new UDP packet
NewUdpPacket(IP * src_ip,UINT src_port,IP * dst_ip,UINT dst_port,void * data,UINT size)20942 UDPPACKET *NewUdpPacket(IP *src_ip, UINT src_port, IP *dst_ip, UINT dst_port, void *data, UINT size)
20943 {
20944 UDPPACKET *p;
20945 // Validate arguments
20946 if (data == NULL || size == 0 || dst_ip == NULL || dst_port == 0)
20947 {
20948 return NULL;
20949 }
20950
20951 p = ZeroMalloc(sizeof(UDPPACKET));
20952
20953 p->Data = data;
20954 p->Size = size;
20955
20956 Copy(&p->SrcIP, src_ip, sizeof(IP));
20957 p->SrcPort = src_port;
20958
20959 Copy(&p->DstIP, dst_ip, sizeof(IP));
20960 p->DestPort = dst_port;
20961
20962 return p;
20963 }
20964
20965 // Transmit the packets via UDP Listener
UdpListenerSendPackets(UDPLISTENER * u,LIST * packet_list)20966 void UdpListenerSendPackets(UDPLISTENER *u, LIST *packet_list)
20967 {
20968 UINT num = 0;
20969 // Validate arguments
20970 if (u == NULL || packet_list == NULL)
20971 {
20972 return;
20973 }
20974
20975 LockList(u->SendPacketList);
20976 {
20977 UINT i;
20978
20979 num = LIST_NUM(packet_list);
20980
20981 for (i = 0;i < LIST_NUM(packet_list);i++)
20982 {
20983 UDPPACKET *p = LIST_DATA(packet_list, i);
20984
20985 Add(u->SendPacketList, p);
20986 }
20987 }
20988 UnlockList(u->SendPacketList);
20989
20990 if (num >= 1)
20991 {
20992 SetSockEvent(u->Event);
20993 }
20994 }
UdpListenerSendPacket(UDPLISTENER * u,UDPPACKET * packet)20995 void UdpListenerSendPacket(UDPLISTENER *u, UDPPACKET *packet)
20996 {
20997 LIST *o;
20998 // Validate arguments
20999 if (u == NULL || packet == NULL)
21000 {
21001 return;
21002 }
21003
21004 o = NewListFast(NULL);
21005 Add(o, packet);
21006
21007 UdpListenerSendPackets(u, o);
21008
21009 ReleaseList(o);
21010 }
21011
21012 // Creating a UDP listener
NewUdpListener(UDPLISTENER_RECV_PROC * recv_proc,void * param)21013 UDPLISTENER *NewUdpListener(UDPLISTENER_RECV_PROC *recv_proc, void *param)
21014 {
21015 UDPLISTENER *u;
21016 // Validate arguments
21017 if (recv_proc == NULL)
21018 {
21019 return NULL;
21020 }
21021
21022 u = ZeroMalloc(sizeof(UDPLISTENER));
21023
21024 u->RecvBufSize = UDP_MAX_BUFFER_SIZE;
21025
21026 u->Param = param;
21027
21028 u->PortList = NewList(NULL);
21029 u->Event = NewSockEvent();
21030
21031 u->RecvProc = recv_proc;
21032 u->SendPacketList = NewList(NULL);
21033
21034 u->Interrupts = NewInterruptManager();
21035
21036 u->Thread = NewThread(UdpListenerThread, u);
21037
21038 return u;
21039 }
21040
21041 // Release the UDP listener
FreeUdpListener(UDPLISTENER * u)21042 void FreeUdpListener(UDPLISTENER *u)
21043 {
21044 UINT i;
21045 // Validate arguments
21046 if (u == NULL)
21047 {
21048 return;
21049 }
21050
21051 u->Halt = true;
21052 SetSockEvent(u->Event);
21053
21054 WaitThread(u->Thread, INFINITE);
21055 ReleaseThread(u->Thread);
21056 ReleaseSockEvent(u->Event);
21057
21058 ReleaseIntList(u->PortList);
21059
21060 for (i = 0;i < LIST_NUM(u->SendPacketList);i++)
21061 {
21062 UDPPACKET *p = LIST_DATA(u->SendPacketList, i);
21063
21064 FreeUdpPacket(p);
21065 }
21066
21067 ReleaseList(u->SendPacketList);
21068
21069 FreeInterruptManager(u->Interrupts);
21070
21071 Free(u);
21072 }
21073
21074 // Add the UDP port
AddPortToUdpListener(UDPLISTENER * u,UINT port)21075 void AddPortToUdpListener(UDPLISTENER *u, UINT port)
21076 {
21077 // Validate arguments
21078 if (u == NULL || port == 0)
21079 {
21080 return;
21081 }
21082
21083 LockList(u->PortList);
21084 {
21085 AddIntDistinct(u->PortList, port);
21086 }
21087 UnlockList(u->PortList);
21088
21089 SetSockEvent(u->Event);
21090 }
21091
21092 // Get the port list
GetUdpListenerPortList(UDPLISTENER * u,UINT ** port_list)21093 UINT GetUdpListenerPortList(UDPLISTENER *u, UINT **port_list)
21094 {
21095 UINT num_ports;
21096 // Validate arguments
21097 if (u == NULL || port_list == NULL)
21098 {
21099 return 0;
21100 }
21101
21102 LockList(u->PortList);
21103 {
21104 UINT *ports;
21105 UINT i;
21106
21107 num_ports = LIST_NUM(u->PortList);
21108 ports = ZeroMalloc(sizeof(UINT) * num_ports);
21109
21110 for (i = 0;i < num_ports;i++)
21111 {
21112 ports[i] = *((UINT *)(LIST_DATA(u->PortList, i)));
21113 }
21114
21115 *port_list = ports;
21116 }
21117 UnlockList(u->PortList);
21118
21119 return num_ports;
21120 }
21121
21122 // Dekete all the UDP ports
DeleteAllPortFromUdpListener(UDPLISTENER * u)21123 void DeleteAllPortFromUdpListener(UDPLISTENER *u)
21124 {
21125 // Validate arguments
21126 if (u == NULL)
21127 {
21128 return;
21129 }
21130
21131 LockList(u->PortList);
21132 {
21133 UINT num_ports = LIST_NUM(u->PortList);
21134 UINT *ports = ZeroMalloc(sizeof(UINT) * num_ports);
21135 UINT i;
21136
21137 for (i = 0;i < num_ports;i++)
21138 {
21139 ports[i] = *((UINT *)(LIST_DATA(u->PortList, i)));
21140 }
21141
21142 for (i = 0;i < num_ports;i++)
21143 {
21144 UINT port = ports[i];
21145
21146 DelInt(u->PortList, port);
21147 }
21148
21149 Free(ports);
21150 }
21151 UnlockList(u->PortList);
21152
21153 SetSockEvent(u->Event);
21154 }
21155
21156 // Delete the UDP port
DeletePortFromUdpListener(UDPLISTENER * u,UINT port)21157 void DeletePortFromUdpListener(UDPLISTENER *u, UINT port)
21158 {
21159 // Validate arguments
21160 if (u == NULL || port == 0)
21161 {
21162 return;
21163 }
21164
21165 LockList(u->PortList);
21166 {
21167 DelInt(u->PortList, port);
21168 }
21169 UnlockList(u->PortList);
21170
21171 SetSockEvent(u->Event);
21172 }
21173
21174 // Sort function of the interrupt management list
CmpInterruptManagerTickList(void * p1,void * p2)21175 int CmpInterruptManagerTickList(void *p1, void *p2)
21176 {
21177 UINT64 *v1, *v2;
21178 if (p1 == NULL || p2 == NULL)
21179 {
21180 return 0;
21181 }
21182
21183 v1 = *(UINT64 **)p1;
21184 v2 = *(UINT64 **)p2;
21185 if (v1 == NULL || v2 == NULL)
21186 {
21187 return 0;
21188 }
21189
21190 if (*v1 > *v2)
21191 {
21192 return 1;
21193 }
21194 else if (*v1 < *v2)
21195 {
21196 return -1;
21197 }
21198 else
21199 {
21200 return 0;
21201 }
21202 }
21203
21204 // Initialization of the interrupt management
NewInterruptManager()21205 INTERRUPT_MANAGER *NewInterruptManager()
21206 {
21207 INTERRUPT_MANAGER *m = ZeroMalloc(sizeof(INTERRUPT_MANAGER));
21208
21209 m->TickList = NewList(CmpInterruptManagerTickList);
21210
21211 return m;
21212 }
21213
21214 // Release of the interrupt management
FreeInterruptManager(INTERRUPT_MANAGER * m)21215 void FreeInterruptManager(INTERRUPT_MANAGER *m)
21216 {
21217 UINT i;
21218 // Validate arguments
21219 if (m == NULL)
21220 {
21221 return;
21222 }
21223
21224 for (i = 0;i < LIST_NUM(m->TickList);i++)
21225 {
21226 UINT64 *v = LIST_DATA(m->TickList, i);
21227
21228 Free(v);
21229 }
21230
21231 ReleaseList(m->TickList);
21232
21233 Free(m);
21234 }
21235
21236 // Add a number to the interrupt management
AddInterrupt(INTERRUPT_MANAGER * m,UINT64 tick)21237 void AddInterrupt(INTERRUPT_MANAGER *m, UINT64 tick)
21238 {
21239 // Validate arguments
21240 if (tick == 0)
21241 {
21242 return;
21243 }
21244
21245 LockList(m->TickList);
21246 {
21247 if (Search(m->TickList, &tick) == NULL)
21248 {
21249 Insert(m->TickList, Clone(&tick, sizeof(UINT64)));
21250 }
21251 }
21252 UnlockList(m->TickList);
21253 }
21254
21255 // Get the interval to the next calling
GetNextIntervalForInterrupt(INTERRUPT_MANAGER * m)21256 UINT GetNextIntervalForInterrupt(INTERRUPT_MANAGER *m)
21257 {
21258 UINT ret = INFINITE;
21259 UINT i;
21260 LIST *o = NULL;
21261 UINT64 now = Tick64();
21262 // Validate arguments
21263 if (m == NULL)
21264 {
21265 return 0;
21266 }
21267
21268 LockList(m->TickList);
21269 {
21270 // Remove entries older than now already
21271 for (i = 0;i < LIST_NUM(m->TickList);i++)
21272 {
21273 UINT64 *v = LIST_DATA(m->TickList, i);
21274
21275 if (now >= *v)
21276 {
21277 ret = 0;
21278
21279 if (o == NULL)
21280 {
21281 o = NewListFast(NULL);
21282 }
21283
21284 Add(o, v);
21285 }
21286 else
21287 {
21288 break;
21289 }
21290 }
21291
21292 for (i = 0;i < LIST_NUM(o);i++)
21293 {
21294 UINT64 *v = LIST_DATA(o, i);
21295
21296 Free(v);
21297
21298 Delete(m->TickList, v);
21299 }
21300
21301 if (o != NULL)
21302 {
21303 ReleaseList(o);
21304 }
21305
21306 if (ret == INFINITE)
21307 {
21308 if (LIST_NUM(m->TickList) >= 1)
21309 {
21310 UINT64 *v = LIST_DATA(m->TickList, 0);
21311
21312 ret = (UINT)(*v - now);
21313 }
21314 }
21315 }
21316 UnlockList(m->TickList);
21317
21318 return ret;
21319 }
21320
21321 // Let that the listening socket for the reverse socket to accept the new socket
InjectNewReverseSocketToAccept(SOCK * listen_sock,SOCK * s,IP * client_ip,UINT client_port)21322 void InjectNewReverseSocketToAccept(SOCK *listen_sock, SOCK *s, IP *client_ip, UINT client_port)
21323 {
21324 bool ok = false;
21325 // Validate arguments
21326 if (listen_sock == NULL || s == NULL)
21327 {
21328 return;
21329 }
21330
21331 LockQueue(listen_sock->ReverseAcceptQueue);
21332 {
21333 if (listen_sock->CancelAccept == false && listen_sock->Disconnecting == false)
21334 {
21335 InsertQueue(listen_sock->ReverseAcceptQueue, s);
21336
21337 ok = true;
21338
21339 s->ServerMode = true;
21340 s->IsReverseAcceptedSocket = true;
21341
21342 Copy(&s->RemoteIP, client_ip, sizeof(IP));
21343 s->RemotePort = client_port;
21344 }
21345 }
21346 UnlockQueue(listen_sock->ReverseAcceptQueue);
21347
21348 if (ok == false)
21349 {
21350 Disconnect(s);
21351 ReleaseSock(s);
21352 }
21353 else
21354 {
21355 Set(listen_sock->ReverseAcceptEvent);
21356 }
21357 }
21358
21359 // Create a listening socket for the reverse socket
ListenReverse()21360 SOCK *ListenReverse()
21361 {
21362 SOCK *s = NewSock();
21363
21364 s->Type = SOCK_REVERSE_LISTEN;
21365 s->ListenMode = true;
21366 s->ReverseAcceptQueue = NewQueue();
21367 s->ReverseAcceptEvent = NewEvent();
21368 s->Connected = true;
21369
21370 return s;
21371 }
21372
21373 // Accept on the reverse socket
AcceptReverse(SOCK * s)21374 SOCK *AcceptReverse(SOCK *s)
21375 {
21376 // Validate arguments
21377 if (s == NULL || s->Type != SOCK_REVERSE_LISTEN || s->ListenMode == false)
21378 {
21379 return NULL;
21380 }
21381
21382 while (true)
21383 {
21384 SOCK *ret;
21385 if (s->Disconnecting || s->CancelAccept)
21386 {
21387 return NULL;
21388 }
21389
21390 LockQueue(s->ReverseAcceptQueue);
21391 {
21392 ret = GetNext(s->ReverseAcceptQueue);
21393 }
21394 UnlockQueue(s->ReverseAcceptQueue);
21395
21396 if (ret != NULL)
21397 {
21398 StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_AZURE);
21399
21400 AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails), "VPNAzure");
21401
21402 return ret;
21403 }
21404
21405 Wait(s->ReverseAcceptEvent, INFINITE);
21406 }
21407 }
21408
21409 // Start listening on the in-process socket
ListenInProc()21410 SOCK *ListenInProc()
21411 {
21412 SOCK *s = NewSock();
21413
21414 s->Type = SOCK_INPROC;
21415 s->ListenMode = true;
21416 s->InProcAcceptQueue = NewQueue();
21417 s->InProcAcceptEvent = NewEvent();
21418 s->Connected = true;
21419
21420 return s;
21421 }
21422
21423 // Accept at the in-process socket
AcceptInProc(SOCK * s)21424 SOCK *AcceptInProc(SOCK *s)
21425 {
21426 // Validate arguments
21427 if (s == NULL || s->Type != SOCK_INPROC || s->ListenMode == false)
21428 {
21429 return NULL;
21430 }
21431
21432 while (true)
21433 {
21434 SOCK *ret;
21435 if (s->Disconnecting || s->CancelAccept)
21436 {
21437 return NULL;
21438 }
21439
21440 LockQueue(s->InProcAcceptQueue);
21441 {
21442 ret = GetNext(s->InProcAcceptQueue);
21443 }
21444 UnlockQueue(s->InProcAcceptQueue);
21445
21446 if (ret != NULL)
21447 {
21448 StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_INPROC);
21449
21450 AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails), "InProc");
21451
21452 return ret;
21453 }
21454
21455 Wait(s->InProcAcceptEvent, INFINITE);
21456 }
21457 }
21458
21459 // Connect by the in-process socket
ConnectInProc(SOCK * listen_sock,IP * client_ip,UINT client_port,IP * server_ip,UINT server_port)21460 SOCK *ConnectInProc(SOCK *listen_sock, IP *client_ip, UINT client_port, IP *server_ip, UINT server_port)
21461 {
21462 SOCK *ss, *sc;
21463 bool ok = false;
21464 // Validate arguments
21465 if (listen_sock == NULL || listen_sock->Type != SOCK_INPROC || listen_sock->ListenMode == false)
21466 {
21467 return NULL;
21468 }
21469
21470 NewSocketPair(&sc, &ss, client_ip, client_port, server_ip, server_port);
21471
21472 LockQueue(listen_sock->InProcAcceptQueue);
21473 {
21474 if (listen_sock->CancelAccept == false && listen_sock->Disconnecting == false)
21475 {
21476 InsertQueue(listen_sock->InProcAcceptQueue, ss);
21477
21478 ok = true;
21479 }
21480 }
21481 UnlockQueue(listen_sock->InProcAcceptQueue);
21482
21483 if (ok == false)
21484 {
21485 ReleaseSock(ss);
21486 ReleaseSock(sc);
21487 return NULL;
21488 }
21489
21490 Set(listen_sock->InProcAcceptEvent);
21491
21492 return sc;
21493 }
21494
21495 // Creating a new socket pair
NewSocketPair(SOCK ** client,SOCK ** server,IP * client_ip,UINT client_port,IP * server_ip,UINT server_port)21496 void NewSocketPair(SOCK **client, SOCK **server, IP *client_ip, UINT client_port, IP *server_ip, UINT server_port)
21497 {
21498 IP iptmp;
21499 TUBE *t1, *t2;
21500 SOCK *sc, *ss;
21501 SOCK_EVENT *e1, *e2;
21502 // Validate arguments
21503 if (client == NULL || server == NULL)
21504 {
21505 return;
21506 }
21507
21508 SetIP(&iptmp, 127, 0, 0, 1);
21509 if (client_ip == NULL)
21510 {
21511 client_ip = &iptmp;
21512 }
21513 if (server_ip == NULL)
21514 {
21515 server_ip = &iptmp;
21516 }
21517
21518 // Creating a tube
21519 NewTubePair(&t1, &t2, 0); // t1: C -> S, t2: S -> C
21520
21521 // Creating a socket event
21522 e1 = NewSockEvent();
21523 e2 = NewSockEvent();
21524
21525 SetTubeSockEvent(t1, e1);
21526 SetTubeSockEvent(t2, e2);
21527
21528 sc = NewInProcSocket(t1, t2);
21529 ss = NewInProcSocket(t2, t1);
21530
21531 Copy(&sc->LocalIP, client_ip, sizeof(IP));
21532 sc->LocalPort = client_port;
21533 Copy(&sc->RemoteIP, server_ip, sizeof(IP));
21534 sc->RemotePort = server_port;
21535
21536 Copy(&ss->LocalIP, server_ip, sizeof(IP));
21537 ss->LocalPort = server_port;
21538 Copy(&ss->RemoteIP, client_ip, sizeof(IP));
21539 ss->RemotePort = client_port;
21540
21541 sc->Connected = true;
21542 sc->ServerMode = false;
21543
21544 ss->Connected = true;
21545 ss->ServerMode = true;
21546
21547 SetTimeout(sc, INFINITE);
21548 SetTimeout(ss, INFINITE);
21549
21550 QuerySocketInformation(sc);
21551 QuerySocketInformation(ss);
21552
21553 ReleaseSockEvent(e1);
21554 ReleaseSockEvent(e2);
21555
21556 ReleaseTube(t1);
21557 ReleaseTube(t2);
21558
21559 *client = sc;
21560 *server = ss;
21561 }
21562
21563 // Creating a new in-process socket
NewInProcSocket(TUBE * tube_send,TUBE * tube_recv)21564 SOCK *NewInProcSocket(TUBE *tube_send, TUBE *tube_recv)
21565 {
21566 SOCK *s;
21567 // Validate arguments
21568 if (tube_recv == NULL || tube_send == NULL)
21569 {
21570 return NULL;
21571 }
21572
21573 s = NewSock();
21574
21575 s->Type = SOCK_INPROC;
21576
21577 s->SendTube = tube_send;
21578 s->RecvTube = tube_recv;
21579
21580 AddRef(tube_send->Ref);
21581 AddRef(tube_recv->Ref);
21582
21583 s->InProcRecvFifo = NewFifo();
21584
21585 s->Connected = true;
21586
21587 return s;
21588 }
21589
21590 // Transmission process for the in-process socket
SendInProc(SOCK * sock,void * data,UINT size)21591 UINT SendInProc(SOCK *sock, void *data, UINT size)
21592 {
21593 if (sock == NULL || sock->Type != SOCK_INPROC || sock->Disconnecting || sock->Connected == false)
21594 {
21595 return 0;
21596 }
21597
21598 if (IsTubeConnected(sock->SendTube) == false)
21599 {
21600 return 0;
21601 }
21602
21603 if (TubeSend(sock->SendTube, data, size, NULL) == false)
21604 {
21605 return 0;
21606 }
21607
21608 return size;
21609 }
21610
21611 // Receiving process for the in-process socket
RecvInProc(SOCK * sock,void * data,UINT size)21612 UINT RecvInProc(SOCK *sock, void *data, UINT size)
21613 {
21614 FIFO *f;
21615 UINT ret;
21616 UINT timeout;
21617 UINT64 giveup_time;
21618 TUBEDATA *d = NULL;
21619 if (sock == NULL || sock->Type != SOCK_INPROC || sock->Disconnecting || sock->Connected == false)
21620 {
21621 return 0;
21622 }
21623
21624 if (IsTubeConnected(sock->SendTube) == false)
21625 {
21626 return 0;
21627 }
21628
21629 f = sock->InProcRecvFifo;
21630 if (f == NULL)
21631 {
21632 return 0;
21633 }
21634
21635 // If there is data in the FIFO, return it immediately
21636 ret = ReadFifo(f, data, size);
21637 if (ret != 0)
21638 {
21639 return ret;
21640 }
21641
21642 timeout = GetTimeout(sock);
21643
21644 giveup_time = Tick64() + (UINT)timeout;
21645
21646 // When there is no data in the FIFO, read the next data from the tube
21647 d = NULL;
21648
21649 while (true)
21650 {
21651 UINT64 now = 0;
21652 UINT interval;
21653
21654 if (sock->AsyncMode == false)
21655 {
21656 now = Tick64();
21657
21658 if (now >= giveup_time)
21659 {
21660 break;
21661 }
21662 }
21663
21664 d = TubeRecvAsync(sock->RecvTube);
21665
21666 if (d != NULL)
21667 {
21668 break;
21669 }
21670
21671 if (IsTubeConnected(sock->RecvTube) == false)
21672 {
21673 break;
21674 }
21675
21676 if (sock->AsyncMode)
21677 {
21678 break;
21679 }
21680
21681 interval = (UINT)(giveup_time - now);
21682
21683 Wait(sock->RecvTube->Event, interval);
21684 }
21685
21686 if (d == NULL)
21687 {
21688 if (IsTubeConnected(sock->RecvTube) == false)
21689 {
21690 return 0;
21691 }
21692
21693 if (sock->AsyncMode == false)
21694 {
21695 // If a timeout occurs in synchronous mode, disconnect ir
21696 Disconnect(sock);
21697
21698 return 0;
21699 }
21700 else
21701 {
21702 // If a timeout occurs in asynchronous mode, returns the blocking error
21703 return SOCK_LATER;
21704 }
21705 }
21706 else
21707 {
21708 // If the received data is larger than the requested size, write the rest to FIFO
21709 if (d->DataSize > size)
21710 {
21711 WriteFifo(f, ((UCHAR *)d->Data) + size, d->DataSize - size);
21712 ret = size;
21713 }
21714 else
21715 {
21716 ret = d->DataSize;
21717 }
21718
21719 Copy(data, d->Data, ret);
21720
21721 FreeTubeData(d);
21722
21723 return ret;
21724 }
21725 }
21726
21727 // Wait for the arrival of data on multiple tubes
WaitForTubes(TUBE ** tubes,UINT num,UINT timeout)21728 void WaitForTubes(TUBE **tubes, UINT num, UINT timeout)
21729 {
21730 // Validate arguments
21731 if (num != 0 && tubes == NULL)
21732 {
21733 return;
21734 }
21735 if (timeout == 0)
21736 {
21737 return;
21738 }
21739 if (num == 0)
21740 {
21741 SleepThread(timeout);
21742 return;
21743 }
21744
21745 #ifdef OS_WIN32
21746 Win32WaitForTubes(tubes, num, timeout);
21747 #else // OS_WIN32
21748 UnixWaitForTubes(tubes, num, timeout);
21749 #endif // OS_WIN32
21750 }
21751
21752 #ifdef OS_WIN32
Win32WaitForTubes(TUBE ** tubes,UINT num,UINT timeout)21753 void Win32WaitForTubes(TUBE **tubes, UINT num, UINT timeout)
21754 {
21755 HANDLE array[MAXIMUM_WAIT_OBJECTS];
21756 UINT i;
21757
21758 Zero(array, sizeof(array));
21759
21760 for (i = 0;i < num;i++)
21761 {
21762 TUBE *t = tubes[i];
21763
21764 array[i] = t->Event->pData;
21765 }
21766
21767 if (num == 1)
21768 {
21769 WaitForSingleObject(array[0], timeout);
21770 }
21771 else
21772 {
21773 WaitForMultipleObjects(num, array, false, timeout);
21774 }
21775 }
21776 #else // OS_WIN32
UnixWaitForTubes(TUBE ** tubes,UINT num,UINT timeout)21777 void UnixWaitForTubes(TUBE **tubes, UINT num, UINT timeout)
21778 {
21779 int *fds;
21780 UINT i;
21781 char tmp[MAX_SIZE];
21782 bool any_of_tubes_are_readable = false;
21783
21784 fds = ZeroMalloc(sizeof(int) * num);
21785
21786 for (i = 0;i < num;i++)
21787 {
21788 fds[i] = tubes[i]->SockEvent->pipe_read;
21789
21790 if (tubes[i]->SockEvent->current_pipe_data != 0)
21791 {
21792 any_of_tubes_are_readable = true;
21793 }
21794 }
21795
21796 if (any_of_tubes_are_readable == false)
21797 {
21798 UnixSelectInner(num, fds, 0, NULL, timeout);
21799 }
21800
21801 for (i = 0;i < num;i++)
21802 {
21803 int fd = fds[i];
21804 int readret;
21805
21806 tubes[i]->SockEvent->current_pipe_data = 0;
21807
21808 do
21809 {
21810 readret = read(fd, tmp, sizeof(tmp));
21811 }
21812 while (readret >= 1);
21813 }
21814
21815 Free(fds);
21816 }
21817 #endif // OS_WIN32
21818
21819 // Creating a Tube Flush List
NewTubeFlushList()21820 TUBE_FLUSH_LIST *NewTubeFlushList()
21821 {
21822 TUBE_FLUSH_LIST *f = ZeroMalloc(sizeof(TUBE_FLUSH_LIST));
21823
21824 f->List = NewListFast(NULL);
21825
21826 return f;
21827 }
21828
21829 // Release of the Tube Flush List
FreeTubeFlushList(TUBE_FLUSH_LIST * f)21830 void FreeTubeFlushList(TUBE_FLUSH_LIST *f)
21831 {
21832 UINT i;
21833 // Validate arguments
21834 if (f == NULL)
21835 {
21836 return;
21837 }
21838
21839 for (i = 0;i < LIST_NUM(f->List);i++)
21840 {
21841 TUBE *t = LIST_DATA(f->List, i);
21842
21843 ReleaseTube(t);
21844 }
21845
21846 ReleaseList(f->List);
21847
21848 Free(f);
21849 }
21850
21851 // Add a Tube to the Tube Flush List
AddTubeToFlushList(TUBE_FLUSH_LIST * f,TUBE * t)21852 void AddTubeToFlushList(TUBE_FLUSH_LIST *f, TUBE *t)
21853 {
21854 // Validate arguments
21855 if (f == NULL || t == NULL)
21856 {
21857 return;
21858 }
21859
21860 if (t->IsInFlushList)
21861 {
21862 return;
21863 }
21864
21865 if (IsInList(f->List, t) == false)
21866 {
21867 Add(f->List, t);
21868
21869 AddRef(t->Ref);
21870
21871 t->IsInFlushList = true;
21872 }
21873 }
21874
21875 // Flush the all tubes in the Tube Flush List
FlushTubeFlushList(TUBE_FLUSH_LIST * f)21876 void FlushTubeFlushList(TUBE_FLUSH_LIST *f)
21877 {
21878 UINT i;
21879 // Validate arguments
21880 if (f == NULL)
21881 {
21882 return;
21883 }
21884
21885 for (i = 0;i < LIST_NUM(f->List);i++)
21886 {
21887 TUBE *t = LIST_DATA(f->List, i);
21888
21889 TubeFlush(t);
21890 t->IsInFlushList = false;
21891
21892 ReleaseTube(t);
21893 }
21894
21895 DeleteAll(f->List);
21896 }
21897
21898 // The server receives a PACK from the client
HttpServerRecv(SOCK * s)21899 PACK *HttpServerRecv(SOCK *s)
21900 {
21901 return HttpServerRecvEx(s, 0);
21902 }
HttpServerRecvEx(SOCK * s,UINT max_data_size)21903 PACK *HttpServerRecvEx(SOCK *s, UINT max_data_size)
21904 {
21905 BUF *b;
21906 PACK *p;
21907 HTTP_HEADER *h;
21908 UINT size;
21909 UCHAR *tmp;
21910 HTTP_VALUE *v;
21911 UINT num_noop = 0;
21912 if (max_data_size == 0) max_data_size = HTTP_PACK_MAX_SIZE;
21913 // Validate arguments
21914 if (s == NULL)
21915 {
21916 return NULL;
21917 }
21918
21919 START:
21920
21921 h = RecvHttpHeader(s);
21922 if (h == NULL)
21923 {
21924 goto BAD_REQUEST;
21925 }
21926
21927 if (StrCmpi(h->Method, "POST") != 0 ||
21928 StrCmpi(h->Target, HTTP_VPN_TARGET) != 0 ||
21929 StrCmpi(h->Version, "HTTP/1.1") != 0)
21930 {
21931 FreeHttpHeader(h);
21932 goto BAD_REQUEST;
21933 }
21934
21935 v = GetHttpValue(h, "Content-Type");
21936 if (v == NULL || StrCmpi(v->Data, HTTP_CONTENT_TYPE2) != 0)
21937 {
21938 FreeHttpHeader(h);
21939 goto BAD_REQUEST;
21940 }
21941
21942 size = GetContentLength(h);
21943 if (size == 0 || (size > max_data_size))
21944 {
21945 FreeHttpHeader(h);
21946 goto BAD_REQUEST;
21947 }
21948
21949 tmp = MallocEx(size, true);
21950 if (RecvAll(s, tmp, size, s->SecureMode) == false)
21951 {
21952 Free(tmp);
21953 FreeHttpHeader(h);
21954 return NULL;
21955 }
21956
21957 b = NewBuf();
21958 WriteBuf(b, tmp, size);
21959 Free(tmp);
21960 FreeHttpHeader(h);
21961
21962 SeekBuf(b, 0, 0);
21963 p = BufToPack(b);
21964 FreeBuf(b);
21965
21966 // Determine whether it's a NOOP
21967 if (PackGetInt(p, "noop") != 0)
21968 {
21969 Debug("recv: noop\n");
21970 FreePack(p);
21971
21972 p = PackError(0);
21973 PackAddInt(p, "noop", 1);
21974 if (HttpServerSend(s, p) == false)
21975 {
21976 FreePack(p);
21977 return NULL;
21978 }
21979
21980 FreePack(p);
21981
21982 num_noop++;
21983
21984 if (num_noop > MAX_NOOP_PER_SESSION)
21985 {
21986 return NULL;
21987 }
21988
21989 goto START;
21990 }
21991
21992 return p;
21993
21994 BAD_REQUEST:
21995 // Return an error
21996
21997
21998 return NULL;
21999 }
22000
22001 // Store the error value into PACK
PackError(UINT error)22002 PACK *PackError(UINT error)
22003 {
22004 PACK *p;
22005
22006 p = NewPack();
22007 PackAddInt(p, "error", error);
22008
22009 return p;
22010 }
22011
22012 // Get the error value from PACK
GetErrorFromPack(PACK * p)22013 UINT GetErrorFromPack(PACK *p)
22014 {
22015 // Validate arguments
22016 if (p == NULL)
22017 {
22018 return 0;
22019 }
22020
22021 return PackGetInt(p, "error");
22022 }
22023
22024 // Client receives a PACK from the server
HttpClientRecv(SOCK * s)22025 PACK *HttpClientRecv(SOCK *s)
22026 {
22027 BUF *b;
22028 PACK *p;
22029 HTTP_HEADER *h;
22030 UINT size;
22031 UCHAR *tmp;
22032 HTTP_VALUE *v;
22033 // Validate arguments
22034 if (s == NULL)
22035 {
22036 return NULL;
22037 }
22038
22039 h = RecvHttpHeader(s);
22040 if (h == NULL)
22041 {
22042 return NULL;
22043 }
22044
22045 if (StrCmpi(h->Method, "HTTP/1.1") != 0 ||
22046 StrCmpi(h->Target, "200") != 0)
22047 {
22048 FreeHttpHeader(h);
22049 return NULL;
22050 }
22051
22052 v = GetHttpValue(h, "Content-Type");
22053 if (v == NULL || StrCmpi(v->Data, HTTP_CONTENT_TYPE2) != 0)
22054 {
22055 FreeHttpHeader(h);
22056 return NULL;
22057 }
22058
22059 size = GetContentLength(h);
22060 if (size == 0 || size > MAX_PACK_SIZE)
22061 {
22062 FreeHttpHeader(h);
22063 return NULL;
22064 }
22065
22066 tmp = MallocEx(size, true);
22067 if (RecvAll(s, tmp, size, s->SecureMode) == false)
22068 {
22069 Free(tmp);
22070 FreeHttpHeader(h);
22071 return NULL;
22072 }
22073
22074 b = NewBuf();
22075 WriteBuf(b, tmp, size);
22076 Free(tmp);
22077 FreeHttpHeader(h);
22078
22079 SeekBuf(b, 0, 0);
22080 p = BufToPack(b);
22081 FreeBuf(b);
22082
22083 return p;
22084 }
22085
22086 // Create an entry to PACK for the dummy
CreateDummyValue(PACK * p)22087 void CreateDummyValue(PACK *p)
22088 {
22089 UINT size;
22090 UCHAR *buf;
22091 // Validate arguments
22092 if (p == NULL)
22093 {
22094 return;
22095 }
22096
22097 size = Rand32() % HTTP_PACK_RAND_SIZE_MAX;
22098 buf = Malloc(size);
22099 Rand(buf, size);
22100
22101 PackAddData(p, "pencore", buf, size);
22102
22103 Free(buf);
22104 }
22105
22106 // Client sends a PACK to the server
HttpClientSend(SOCK * s,PACK * p)22107 bool HttpClientSend(SOCK *s, PACK *p)
22108 {
22109 BUF *b;
22110 bool ret;
22111 HTTP_HEADER *h;
22112 char date_str[MAX_SIZE];
22113 char ip_str[MAX_SIZE];
22114
22115 // Validate arguments
22116 if (s == NULL || p == NULL)
22117 {
22118 return false;
22119 }
22120
22121 IPToStr(ip_str, sizeof(ip_str), &s->RemoteIP);
22122
22123 CreateDummyValue(p);
22124
22125 b = PackToBuf(p);
22126 if (b == NULL)
22127 {
22128 return false;
22129 }
22130
22131 h = NewHttpHeader("POST", HTTP_VPN_TARGET, "HTTP/1.1");
22132
22133 GetHttpDateStr(date_str, sizeof(date_str), SystemTime64());
22134 AddHttpValue(h, NewHttpValue("Date", date_str));
22135 AddHttpValue(h, NewHttpValue("Host", ip_str));
22136 AddHttpValue(h, NewHttpValue("Keep-Alive", HTTP_KEEP_ALIVE));
22137 AddHttpValue(h, NewHttpValue("Connection", "Keep-Alive"));
22138 AddHttpValue(h, NewHttpValue("Content-Type", HTTP_CONTENT_TYPE2));
22139
22140 ret = PostHttp(s, h, b->Buf, b->Size);
22141
22142 FreeHttpHeader(h);
22143 FreeBuf(b);
22144
22145 return ret;
22146 }
22147
22148 // Server sends a PACK to the client
HttpServerSend(SOCK * s,PACK * p)22149 bool HttpServerSend(SOCK *s, PACK *p)
22150 {
22151 BUF *b;
22152 bool ret;
22153 HTTP_HEADER *h;
22154 char date_str[MAX_SIZE];
22155 // Validate arguments
22156 if (s == NULL || p == NULL)
22157 {
22158 return false;
22159 }
22160
22161 CreateDummyValue(p);
22162
22163 b = PackToBuf(p);
22164 if (b == NULL)
22165 {
22166 return false;
22167 }
22168
22169 h = NewHttpHeader("HTTP/1.1", "200", "OK");
22170
22171 GetHttpDateStr(date_str, sizeof(date_str), SystemTime64());
22172 AddHttpValue(h, NewHttpValue("Date", date_str));
22173 AddHttpValue(h, NewHttpValue("Keep-Alive", HTTP_KEEP_ALIVE));
22174 AddHttpValue(h, NewHttpValue("Connection", "Keep-Alive"));
22175 AddHttpValue(h, NewHttpValue("Content-Type", HTTP_CONTENT_TYPE2));
22176
22177 ret = PostHttp(s, h, b->Buf, b->Size);
22178
22179 FreeHttpHeader(h);
22180 FreeBuf(b);
22181
22182 return ret;
22183 }
22184
22185 // Replace unsafe characters in target
ReplaceUnsafeCharInTarget(char * target)22186 void ReplaceUnsafeCharInTarget(char *target){
22187 UINT i;
22188 for(i = 0; target[i] ; i++) {
22189 if(target[i] == '<')
22190 target[i] = '(';
22191 else if(target[i] == '>')
22192 target[i] = ')';
22193 }
22194 }
22195
22196 // Sending the 400 Bad Request: Invalid Hostname
HttpSendInvalidHostname(SOCK * s,char * method)22197 bool HttpSendInvalidHostname(SOCK *s, char *method)
22198 {
22199 HTTP_HEADER *h;
22200 char date_str[MAX_SIZE];
22201 char *str;
22202 bool ret;
22203 char host[MAX_SIZE];
22204 UINT port;
22205 // Validate arguments
22206 if (s == NULL)
22207 {
22208 return false;
22209 }
22210
22211 // Get the host name
22212 //GetMachineName(host, MAX_SIZE);
22213 Zero(host, sizeof(host));
22214 IPToStr(host, sizeof(host), &s->LocalIP);
22215 // Get the port number
22216 port = s->LocalPort;
22217
22218 // Creating a header
22219 GetHttpDateStr(date_str, sizeof(date_str), SystemTime64());
22220
22221 h = NewHttpHeader("HTTP/1.1", "400", "Bad Request");
22222
22223 AddHttpValue(h, NewHttpValue("Date", date_str));
22224 AddHttpValue(h, NewHttpValue("Keep-Alive", HTTP_KEEP_ALIVE));
22225 AddHttpValue(h, NewHttpValue("Connection", "Keep-Alive"));
22226 AddHttpValue(h, NewHttpValue("Content-Type", HTTP_CONTENT_TYPE));
22227
22228 // Creating a Data
22229 str = "<h1>Bad Request (Invalid Hostname)</h1>\n";
22230
22231 // Transmission
22232 ret = PostHttp(s, h, str, StrLen(str));
22233
22234 FreeHttpHeader(h);
22235
22236 return ret;
22237 }
22238
22239 // Sending the 501 Not Implemented error
HttpSendNotImplemented(SOCK * s,char * method,char * target,char * version)22240 bool HttpSendNotImplemented(SOCK *s, char *method, char *target, char *version)
22241 {
22242 HTTP_HEADER *h;
22243 char date_str[MAX_SIZE];
22244 char *str;
22245 UINT str_size;
22246 char port_str[MAX_SIZE];
22247 bool ret;
22248 char host[MAX_SIZE];
22249 UINT port;
22250 // Validate arguments
22251 if (s == NULL || target == NULL)
22252 {
22253 return false;
22254 }
22255
22256 // Get the host name
22257 //GetMachineName(host, MAX_SIZE);
22258 Zero(host, sizeof(host));
22259 IPToStr(host, sizeof(host), &s->LocalIP);
22260 // Get the port number
22261 port = s->LocalPort;
22262
22263 // Creating a header
22264 GetHttpDateStr(date_str, sizeof(date_str), SystemTime64());
22265
22266 h = NewHttpHeader("HTTP/1.1", "501", "Method Not Implemented");
22267
22268 AddHttpValue(h, NewHttpValue("Date", date_str));
22269 AddHttpValue(h, NewHttpValue("Keep-Alive", HTTP_KEEP_ALIVE));
22270 AddHttpValue(h, NewHttpValue("Connection", "Keep-Alive"));
22271 AddHttpValue(h, NewHttpValue("Content-Type", HTTP_CONTENT_TYPE));
22272
22273 // Creating a Data
22274 str_size = sizeof(http_501_str) * 2 + StrLen(target) + StrLen(host) + StrLen(method) + StrLen(version);
22275 str = Malloc(str_size);
22276 StrCpy(str, str_size, http_501_str);
22277
22278 // TARGET
22279 ReplaceUnsafeCharInTarget(target);
22280 ReplaceStri(str, str_size, str, "$TARGET$", target);
22281
22282 // HOST
22283 ReplaceStri(str, str_size, str, "$HOST$", host);
22284
22285 // PORT
22286 ToStr(port_str, port);
22287 ReplaceStri(str, str_size, str, "$PORT$", port_str);
22288
22289 // METHOD
22290 ReplaceStri(str, str_size, str, "$METHOD$", method);
22291
22292 // VERSION
22293 ReplaceStri(str, str_size, str, "$VERSION$", version);
22294
22295 // Transmission
22296 ret = PostHttp(s, h, str, StrLen(str));
22297
22298 FreeHttpHeader(h);
22299 Free(str);
22300
22301 return ret;
22302 }
22303
22304 // Sending a HTTP body contents
HttpSendBody(SOCK * s,void * data,UINT size,char * contents_type)22305 bool HttpSendBody(SOCK *s, void *data, UINT size, char *contents_type)
22306 {
22307 HTTP_HEADER *h;
22308 char date_str[MAX_SIZE];
22309 bool ret;
22310 if (s == NULL || (size != 0 && data == NULL))
22311 {
22312 return false;
22313 }
22314 if (contents_type == NULL)
22315 {
22316 contents_type = "application/octet-stream";
22317 }
22318 // Creating a header
22319 h = NewHttpHeader("HTTP/1.1", "200", "OK");
22320
22321 GetHttpDateStr(date_str, sizeof(date_str), SystemTime64());
22322 AddHttpValue(h, NewHttpValue("Date", date_str));
22323 AddHttpValue(h, NewHttpValue("Content-Type", contents_type));
22324 AddHttpValue(h, NewHttpValue("Cache-Control", "no-cache"));
22325
22326 ret = PostHttp(s, h, data, size);
22327
22328 FreeHttpHeader(h);
22329
22330 return ret;
22331 }
22332
22333 // Sending a 404 Not Found error
HttpSendNotFound(SOCK * s,char * target)22334 bool HttpSendNotFound(SOCK *s, char *target)
22335 {
22336 HTTP_HEADER *h;
22337 char date_str[MAX_SIZE];
22338 char *str;
22339 UINT str_size;
22340 char port_str[MAX_SIZE];
22341 bool ret;
22342 char host[MAX_SIZE];
22343 UINT port;
22344 // Validate arguments
22345 if (s == NULL || target == NULL)
22346 {
22347 return false;
22348 }
22349
22350 // Get the host name
22351 //GetMachineName(host, MAX_SIZE);
22352 Zero(host, sizeof(host));
22353 IPToStr(host, sizeof(host), &s->LocalIP);
22354 // Get the port number
22355 port = s->LocalPort;
22356
22357 // Creating a header
22358 GetHttpDateStr(date_str, sizeof(date_str), SystemTime64());
22359
22360 h = NewHttpHeader("HTTP/1.1", "404", "Not Found");
22361
22362 AddHttpValue(h, NewHttpValue("Date", date_str));
22363 AddHttpValue(h, NewHttpValue("Keep-Alive", HTTP_KEEP_ALIVE));
22364 AddHttpValue(h, NewHttpValue("Connection", "Keep-Alive"));
22365 AddHttpValue(h, NewHttpValue("Content-Type", HTTP_CONTENT_TYPE));
22366
22367 // Creating a Data
22368 str_size = sizeof(http_404_str) * 2 + StrLen(target) + StrLen(host);
22369 str = Malloc(str_size);
22370 StrCpy(str, str_size, http_404_str);
22371
22372 // TARGET
22373 ReplaceUnsafeCharInTarget(target);
22374 ReplaceStri(str, str_size, str, "$TARGET$", target);
22375
22376 // HOST
22377 ReplaceStri(str, str_size, str, "$HOST$", host);
22378
22379 // PORT
22380 ToStr(port_str, port);
22381 ReplaceStri(str, str_size, str, "$PORT$", port_str);
22382
22383 // Transmission
22384 ret = PostHttp(s, h, str, StrLen(str));
22385
22386 FreeHttpHeader(h);
22387 Free(str);
22388
22389 return ret;
22390 }
22391
22392 // Sending a 500 Server Error
HttpSendServerError(SOCK * s,char * target)22393 bool HttpSendServerError(SOCK *s, char *target)
22394 {
22395 HTTP_HEADER *h;
22396 char date_str[MAX_SIZE];
22397 char *str;
22398 UINT str_size;
22399 char port_str[MAX_SIZE];
22400 bool ret;
22401 char host[MAX_SIZE];
22402 UINT port;
22403 // Validate arguments
22404 if (s == NULL || target == NULL)
22405 {
22406 return false;
22407 }
22408
22409 // Get the host name
22410 //GetMachineName(host, MAX_SIZE);
22411 Zero(host, sizeof(host));
22412 IPToStr(host, sizeof(host), &s->LocalIP);
22413 // Get the port number
22414 port = s->LocalPort;
22415
22416 // Creating a header
22417 GetHttpDateStr(date_str, sizeof(date_str), SystemTime64());
22418
22419 h = NewHttpHeader("HTTP/1.1", "500", "Server Error");
22420
22421 AddHttpValue(h, NewHttpValue("Date", date_str));
22422 AddHttpValue(h, NewHttpValue("Keep-Alive", HTTP_KEEP_ALIVE));
22423 AddHttpValue(h, NewHttpValue("Connection", "Keep-Alive"));
22424 AddHttpValue(h, NewHttpValue("Content-Type", HTTP_CONTENT_TYPE));
22425
22426 // Creating a Data
22427 str_size = sizeof(http_500_str) * 2 + StrLen(target) + StrLen(host);
22428 str = Malloc(str_size);
22429 StrCpy(str, str_size, http_500_str);
22430
22431 // TARGET
22432 ReplaceUnsafeCharInTarget(target);
22433 ReplaceStri(str, str_size, str, "$TARGET$", target);
22434
22435 // HOST
22436 ReplaceStri(str, str_size, str, "$HOST$", host);
22437
22438 // PORT
22439 ToStr(port_str, port);
22440 ReplaceStri(str, str_size, str, "$PORT$", port_str);
22441
22442 // Transmission
22443 ret = PostHttp(s, h, str, StrLen(str));
22444
22445 FreeHttpHeader(h);
22446 Free(str);
22447
22448 return ret;
22449 }
22450
22451 // Sending a 403 Forbidden error
HttpSendForbidden(SOCK * s,char * target,char * server_id)22452 bool HttpSendForbidden(SOCK *s, char *target, char *server_id)
22453 {
22454 HTTP_HEADER *h;
22455 char date_str[MAX_SIZE];
22456 char *str;
22457 UINT str_size;
22458 char port_str[MAX_SIZE];
22459 bool ret;
22460 char host[MAX_SIZE];
22461 UINT port;
22462 // Validate arguments
22463 if (s == NULL || target == NULL)
22464 {
22465 return false;
22466 }
22467
22468 // Get the host name
22469 //GetMachineName(host, MAX_SIZE);
22470 Zero(host, sizeof(host));
22471 IPToStr(host, sizeof(host), &s->LocalIP);
22472 // Get the port number
22473 port = s->LocalPort;
22474
22475 // Creating a header
22476 GetHttpDateStr(date_str, sizeof(date_str), SystemTime64());
22477
22478 h = NewHttpHeader("HTTP/1.1", "403", "Forbidden");
22479
22480 AddHttpValue(h, NewHttpValue("Date", date_str));
22481 AddHttpValue(h, NewHttpValue("Keep-Alive", HTTP_KEEP_ALIVE));
22482 AddHttpValue(h, NewHttpValue("Connection", "Keep-Alive"));
22483 AddHttpValue(h, NewHttpValue("Content-Type", HTTP_CONTENT_TYPE));
22484
22485 // Creating a Data
22486 str_size = sizeof(http_403_str) * 2 + StrLen(target) + StrLen(host);
22487 str = Malloc(str_size);
22488 StrCpy(str, str_size, http_403_str);
22489
22490 // TARGET
22491 ReplaceUnsafeCharInTarget(target);
22492 ReplaceStri(str, str_size, str, "$TARGET$", target);
22493
22494 // HOST
22495 ReplaceStri(str, str_size, str, "$HOST$", host);
22496
22497 // PORT
22498 ToStr(port_str, port);
22499 ReplaceStri(str, str_size, str, "$PORT$", port_str);
22500
22501 // Transmission
22502 ret = PostHttp(s, h, str, StrLen(str));
22503
22504 FreeHttpHeader(h);
22505 Free(str);
22506
22507 return ret;
22508 }
22509
22510 // Get the date and time string for the HTTP header
GetHttpDateStr(char * str,UINT size,UINT64 t)22511 void GetHttpDateStr(char *str, UINT size, UINT64 t)
22512 {
22513 SYSTEMTIME s;
22514 static char *wday[] =
22515 {
22516 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
22517 };
22518 static char *month[] =
22519 {
22520 "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct",
22521 "Nov", "Dec",
22522 };
22523 // Validate arguments
22524 if (str == NULL)
22525 {
22526 return;
22527 }
22528 UINT64ToSystem(&s, t);
22529
22530 Format(str, size, "%s, %02u %s %04u %02u:%02u:%02u GMT",
22531 wday[s.wDayOfWeek], s.wDay, month[s.wMonth - 1], s.wYear,
22532 s.wHour, s.wMinute, s.wSecond);
22533 }
22534
22535 // Get the Content-Length from the HTTP header
GetContentLength(HTTP_HEADER * header)22536 UINT GetContentLength(HTTP_HEADER *header)
22537 {
22538 UINT ret;
22539 HTTP_VALUE *v;
22540 // Validate arguments
22541 if (header == NULL)
22542 {
22543 return 0;
22544 }
22545
22546 v = GetHttpValue(header, "Content-Length");
22547 if (v == NULL)
22548 {
22549 return 0;
22550 }
22551
22552 ret = ToInt(v->Data);
22553
22554 return ret;
22555 }
22556
22557 // Send the data in the HTTP
PostHttp(SOCK * s,HTTP_HEADER * header,void * post_data,UINT post_size)22558 bool PostHttp(SOCK *s, HTTP_HEADER *header, void *post_data, UINT post_size)
22559 {
22560 char *header_str;
22561 BUF *b;
22562 bool ret;
22563 // Validate arguments
22564 if (s == NULL || header == NULL || (post_size != 0 && post_data == NULL))
22565 {
22566 return false;
22567 }
22568
22569 // Check whether the Content-Lentgh exists?
22570 if (GetHttpValue(header, "Content-Length") == NULL)
22571 {
22572 char tmp[MAX_SIZE];
22573 // Add because it does not exist
22574 ToStr(tmp, post_size);
22575 AddHttpValue(header, NewHttpValue("Content-Length", tmp));
22576 }
22577
22578 // Convert the header to string
22579 header_str = HttpHeaderToStr(header);
22580 if (header_str == NULL)
22581 {
22582 return false;
22583 }
22584 b = NewBuf();
22585 WriteBuf(b, header_str, StrLen(header_str));
22586 Free(header_str);
22587
22588 // Append the data
22589 WriteBuf(b, post_data, post_size);
22590
22591 // Send
22592 ret = SendAll(s, b->Buf, b->Size, s->SecureMode);
22593
22594 FreeBuf(b);
22595
22596 return ret;
22597 }
22598
22599 // Convert a HTTP header to a string
HttpHeaderToStr(HTTP_HEADER * header)22600 char *HttpHeaderToStr(HTTP_HEADER *header)
22601 {
22602 BUF *b;
22603 char *tmp;
22604 UINT i;
22605 char *s;
22606 // Validate arguments
22607 if (header == NULL)
22608 {
22609 return NULL;
22610 }
22611
22612 tmp = Malloc(HTTP_HEADER_LINE_MAX_SIZE);
22613 b = NewBuf();
22614
22615 // Header
22616 Format(tmp, HTTP_HEADER_LINE_MAX_SIZE,
22617 "%s %s %s\r\n", header->Method, header->Target, header->Version);
22618 WriteBuf(b, tmp, StrLen(tmp));
22619
22620 // Value
22621 for (i = 0;i < LIST_NUM(header->ValueList);i++)
22622 {
22623 HTTP_VALUE *v = (HTTP_VALUE *)LIST_DATA(header->ValueList, i);
22624 Format(tmp, HTTP_HEADER_LINE_MAX_SIZE,
22625 "%s: %s\r\n", v->Name, v->Data);
22626 WriteBuf(b, tmp, StrLen(tmp));
22627 }
22628
22629 // Trailing newline
22630 WriteBuf(b, "\r\n", 2);
22631 s = Malloc(b->Size + 1);
22632 Copy(s, b->Buf, b->Size);
22633 s[b->Size] = 0;
22634
22635 FreeBuf(b);
22636 Free(tmp);
22637
22638 return s;
22639 }
22640
22641 // Send the HTTP header
SendHttpHeader(SOCK * s,HTTP_HEADER * header)22642 bool SendHttpHeader(SOCK *s, HTTP_HEADER *header)
22643 {
22644 char *str;
22645 bool ret;
22646 // Validate arguments
22647 if (s == NULL || header == NULL)
22648 {
22649 return false;
22650 }
22651
22652 // Convert to string
22653 str = HttpHeaderToStr(header);
22654
22655 // Transmission
22656 ret = SendAll(s, str, StrLen(str), s->SecureMode);
22657
22658 Free(str);
22659
22660 return ret;
22661 }
22662
22663 // Receive an HTTP header
RecvHttpHeader(SOCK * s)22664 HTTP_HEADER *RecvHttpHeader(SOCK *s)
22665 {
22666 TOKEN_LIST *token = NULL;
22667 char *str = NULL;
22668 HTTP_HEADER *header = NULL;
22669 // Validate arguments
22670 if (s == NULL)
22671 {
22672 return NULL;
22673 }
22674
22675 // Get the first line
22676 str = RecvLine(s, HTTP_HEADER_LINE_MAX_SIZE);
22677 if (str == NULL)
22678 {
22679 goto LABEL_ERROR;
22680 }
22681
22682 // Split into tokens
22683 token = ParseToken(str, " ");
22684 if (token->NumTokens < 3)
22685 {
22686 goto LABEL_ERROR;
22687 }
22688
22689 Free(str);
22690 str = NULL;
22691
22692 // Creating a header object
22693 header = NewHttpHeader(token->Token[0], token->Token[1], token->Token[2]);
22694
22695 if (StrCmpi(header->Version, "HTTP/0.9") == 0)
22696 {
22697 // The header ends with this line
22698 FreeToken(token);
22699 return header;
22700 }
22701
22702 // Get the subsequent lines
22703 while (true)
22704 {
22705 UINT pos;
22706 HTTP_VALUE *v;
22707 char *value_name, *value_data;
22708 str = RecvLine(s, HTTP_HEADER_LINE_MAX_SIZE);
22709 if (str == NULL)
22710 {
22711 goto LABEL_ERROR;
22712 }
22713 Trim(str);
22714
22715 if (StrLen(str) == 0)
22716 {
22717 // End of header
22718 Free(str);
22719 str = NULL;
22720 break;
22721 }
22722
22723 // Get the position of the colon
22724 pos = SearchStr(str, ":", 0);
22725 if (pos == INFINITE)
22726 {
22727 // The colon does not exist
22728 goto LABEL_ERROR;
22729 }
22730
22731 // Divide into the name and the data
22732 value_name = Malloc(pos + 1);
22733 Copy(value_name, str, pos);
22734 value_name[pos] = 0;
22735 value_data = &str[pos + 1];
22736
22737 v = NewHttpValue(value_name, value_data);
22738 if (v == NULL)
22739 {
22740 Free(value_name);
22741 goto LABEL_ERROR;
22742 }
22743
22744 Free(value_name);
22745
22746 AddHttpValue(header, v);
22747 Free(str);
22748 }
22749
22750 FreeToken(token);
22751
22752 return header;
22753
22754 LABEL_ERROR:
22755 // Memory release
22756 if (token)
22757 {
22758 FreeToken(token);
22759 }
22760 if (str)
22761 {
22762 Free(str);
22763 }
22764 if (header)
22765 {
22766 FreeHttpHeader(header);
22767 }
22768 return NULL;
22769 }
22770
22771 // Receive a line
RecvLine(SOCK * s,UINT max_size)22772 char *RecvLine(SOCK *s, UINT max_size)
22773 {
22774 BUF *b;
22775 char c;
22776 char *str;
22777 // Validate arguments
22778 if (s == NULL || max_size == 0)
22779 {
22780 return NULL;
22781 }
22782
22783 b = NewBuf();
22784 while (true)
22785 {
22786 UCHAR *buf;
22787 if (RecvAll(s, &c, sizeof(c), s->SecureMode) == false)
22788 {
22789 FreeBuf(b);
22790 return NULL;
22791 }
22792 WriteBuf(b, &c, sizeof(c));
22793 buf = (UCHAR *)b->Buf;
22794 if (b->Size > max_size)
22795 {
22796 FreeBuf(b);
22797 return NULL;
22798 }
22799 if (b->Size >= 1)
22800 {
22801 if (buf[b->Size - 1] == '\n')
22802 {
22803 b->Size--;
22804 if (b->Size >= 1)
22805 {
22806 if (buf[b->Size - 1] == '\r')
22807 {
22808 b->Size--;
22809 }
22810 }
22811 str = Malloc(b->Size + 1);
22812 Copy(str, b->Buf, b->Size);
22813 str[b->Size] = 0;
22814 FreeBuf(b);
22815
22816 return str;
22817 }
22818 }
22819 }
22820 }
22821
22822 // Creating a new HTTP value
NewHttpValue(char * name,char * data)22823 HTTP_VALUE *NewHttpValue(char *name, char *data)
22824 {
22825 HTTP_VALUE *v;
22826 // Validate arguments
22827 if (name == NULL || data == NULL)
22828 {
22829 return NULL;
22830 }
22831
22832 v = ZeroMalloc(sizeof(HTTP_VALUE));
22833
22834 v->Name = CopyStr(name);
22835 v->Data = CopyStr(data);
22836
22837 Trim(v->Name);
22838 Trim(v->Data);
22839
22840 return v;
22841 }
22842
22843 // Look for the HTTP value from the HTTP header
GetHttpValue(HTTP_HEADER * header,char * name)22844 HTTP_VALUE *GetHttpValue(HTTP_HEADER *header, char *name)
22845 {
22846 HTTP_VALUE *v, t;
22847 // Validate arguments
22848 if (header == NULL || name == NULL)
22849 {
22850 return NULL;
22851 }
22852
22853 t.Name = name;
22854 v = Search(header->ValueList, &t);
22855 if (v == NULL)
22856 {
22857 return NULL;
22858 }
22859
22860 return v;
22861 }
22862
22863 // Add a HTTP value to the HTTP header
AddHttpValue(HTTP_HEADER * header,HTTP_VALUE * value)22864 void AddHttpValue(HTTP_HEADER *header, HTTP_VALUE *value)
22865 {
22866 // Validate arguments
22867 if (header == NULL || value == NULL)
22868 {
22869 return;
22870 }
22871
22872 if (LIST_NUM(header->ValueList) < HTTP_HEADER_MAX_LINES)
22873 {
22874 Insert(header->ValueList, value);
22875 }
22876 else
22877 {
22878 FreeHttpValue(value);
22879 }
22880 }
22881
22882 // Create an HTTP header
NewHttpHeader(char * method,char * target,char * version)22883 HTTP_HEADER *NewHttpHeader(char *method, char *target, char *version)
22884 {
22885 return NewHttpHeaderEx(method, target, version, false);
22886 }
NewHttpHeaderEx(char * method,char * target,char * version,bool no_sort)22887 HTTP_HEADER *NewHttpHeaderEx(char *method, char *target, char *version, bool no_sort)
22888 {
22889 HTTP_HEADER *header;
22890 // Validate arguments
22891 if (method == NULL || target == NULL || version == NULL)
22892 {
22893 return NULL;
22894 }
22895
22896 header = ZeroMalloc(sizeof(HTTP_HEADER));
22897
22898 header->Method = CopyStr(method);
22899 header->Target = CopyStr(target);
22900 header->Version = CopyStr(version);
22901 header->ValueList = NewListFast(no_sort ? NULL : CompareHttpValue);
22902
22903 return header;
22904 }
22905
22906 // Comparison function of the HTTP value
CompareHttpValue(void * p1,void * p2)22907 int CompareHttpValue(void *p1, void *p2)
22908 {
22909 HTTP_VALUE *v1, *v2;
22910 if (p1 == NULL || p2 == NULL)
22911 {
22912 return 0;
22913 }
22914 v1 = *(HTTP_VALUE **)p1;
22915 v2 = *(HTTP_VALUE **)p2;
22916 if (v1 == NULL || v2 == NULL)
22917 {
22918 return 0;
22919 }
22920 return StrCmpi(v1->Name, v2->Name);
22921 }
22922
22923 // Release the HTTP value
FreeHttpValue(HTTP_VALUE * value)22924 void FreeHttpValue(HTTP_VALUE *value)
22925 {
22926 // Validate arguments
22927 if (value == NULL)
22928 {
22929 return;
22930 }
22931
22932 Free(value->Data);
22933 Free(value->Name);
22934
22935 Free(value);
22936 }
22937
22938 // Release the HTTP header
FreeHttpHeader(HTTP_HEADER * header)22939 void FreeHttpHeader(HTTP_HEADER *header)
22940 {
22941 UINT i;
22942 HTTP_VALUE **values;
22943 // Validate arguments
22944 if (header == NULL)
22945 {
22946 return;
22947 }
22948
22949 Free(header->Method);
22950 Free(header->Target);
22951 Free(header->Version);
22952
22953 values = ToArray(header->ValueList);
22954 for (i = 0;i < LIST_NUM(header->ValueList);i++)
22955 {
22956 FreeHttpValue(values[i]);
22957 }
22958 Free(values);
22959
22960 ReleaseList(header->ValueList);
22961
22962 Free(header);
22963 }
22964
22965 // Receive a PACK
RecvPack(SOCK * s)22966 PACK *RecvPack(SOCK *s)
22967 {
22968 PACK *p;
22969 BUF *b;
22970 void *data;
22971 UINT sz;
22972 // Validate arguments
22973 if (s == NULL || s->Type != SOCK_TCP)
22974 {
22975 return false;
22976 }
22977
22978 if (RecvAll(s, &sz, sizeof(UINT), s->SecureMode) == false)
22979 {
22980 return false;
22981 }
22982 sz = Endian32(sz);
22983 if (sz > MAX_PACK_SIZE)
22984 {
22985 return false;
22986 }
22987 data = MallocEx(sz, true);
22988 if (RecvAll(s, data, sz, s->SecureMode) == false)
22989 {
22990 Free(data);
22991 return false;
22992 }
22993
22994 b = NewBuf();
22995 WriteBuf(b, data, sz);
22996 SeekBuf(b, 0, 0);
22997 p = BufToPack(b);
22998 FreeBuf(b);
22999 Free(data);
23000
23001 return p;
23002 }
23003
23004 // Receive a PACK (with checking the hash)
RecvPackWithHash(SOCK * s)23005 PACK *RecvPackWithHash(SOCK *s)
23006 {
23007 PACK *p;
23008 BUF *b;
23009 void *data;
23010 UINT sz;
23011 UCHAR hash1[SHA1_SIZE];
23012 UCHAR hash2[SHA1_SIZE];
23013 // Validate arguments
23014 if (s == NULL || s->Type != SOCK_TCP)
23015 {
23016 return false;
23017 }
23018
23019 if (RecvAll(s, &sz, sizeof(UINT), s->SecureMode) == false)
23020 {
23021 return false;
23022 }
23023 sz = Endian32(sz);
23024 if (sz > MAX_PACK_SIZE)
23025 {
23026 return false;
23027 }
23028 data = MallocEx(sz, true);
23029 if (RecvAll(s, data, sz, s->SecureMode) == false)
23030 {
23031 Free(data);
23032 return false;
23033 }
23034
23035 HashSha1(hash1, data, sz);
23036 if (RecvAll(s, hash2, sizeof(hash2), s->SecureMode) == false)
23037 {
23038 Free(data);
23039 return false;
23040 }
23041
23042 if (Cmp(hash1, hash2, SHA1_SIZE) != 0)
23043 {
23044 Free(data);
23045 return false;
23046 }
23047
23048 b = NewBuf();
23049 WriteBuf(b, data, sz);
23050 SeekBuf(b, 0, 0);
23051 p = BufToPack(b);
23052 FreeBuf(b);
23053 Free(data);
23054
23055 return p;
23056 }
23057
23058 // Send a PACK
SendPack(SOCK * s,PACK * p)23059 bool SendPack(SOCK *s, PACK *p)
23060 {
23061 BUF *b;
23062 UINT sz;
23063 // Validate arguments
23064 if (s == NULL || p == NULL || s->Type != SOCK_TCP)
23065 {
23066 return false;
23067 }
23068
23069 b = PackToBuf(p);
23070 sz = Endian32(b->Size);
23071
23072 SendAdd(s, &sz, sizeof(UINT));
23073 SendAdd(s, b->Buf, b->Size);
23074 FreeBuf(b);
23075
23076 return SendNow(s, s->SecureMode);
23077 }
23078
23079 // Send a Pack (with adding a hash)
SendPackWithHash(SOCK * s,PACK * p)23080 bool SendPackWithHash(SOCK *s, PACK *p)
23081 {
23082 BUF *b;
23083 UINT sz;
23084 UCHAR hash[SHA1_SIZE];
23085 // Validate arguments
23086 if (s == NULL || p == NULL || s->Type != SOCK_TCP)
23087 {
23088 return false;
23089 }
23090
23091 b = PackToBuf(p);
23092 sz = Endian32(b->Size);
23093
23094 SendAdd(s, &sz, sizeof(UINT));
23095 SendAdd(s, b->Buf, b->Size);
23096 HashSha1(hash, b->Buf, b->Size);
23097 SendAdd(s, hash, sizeof(hash));
23098
23099 FreeBuf(b);
23100
23101 return SendNow(s, s->SecureMode);
23102 }
23103
23104 // Get SNI name from the data that has arrived to the TCP connection before accepting an SSL connection
GetSniNameFromPreSslConnection(SOCK * s,char * sni,UINT sni_size)23105 bool GetSniNameFromPreSslConnection(SOCK *s, char *sni, UINT sni_size)
23106 {
23107 UCHAR tmp[1500];
23108 UINT size;
23109 // Validate arguments
23110 if (s == NULL || sni == NULL)
23111 {
23112 return false;
23113 }
23114
23115 size = Peek(s, tmp, sizeof(tmp));
23116 if (size == 0)
23117 {
23118 return false;
23119 }
23120
23121 return GetSniNameFromSslPacket(tmp, size, sni, sni_size);
23122 }
23123
23124 // Get SNI name from the SSL packet
GetSniNameFromSslPacket(UCHAR * packet_buf,UINT packet_size,char * sni,UINT sni_size)23125 bool GetSniNameFromSslPacket(UCHAR *packet_buf, UINT packet_size, char *sni, UINT sni_size)
23126 {
23127 BUF *buf;
23128 bool ret = false;
23129 UCHAR content_type;
23130 USHORT version;
23131 USHORT handshake_length;
23132
23133 // Validate arguments
23134 if (packet_buf == NULL || packet_size <= 11)
23135 {
23136 return false;
23137 }
23138
23139 if (!(packet_buf[0] == 0x16 && packet_buf[1] >= 0x03 &&
23140 packet_buf[5] == 0x01 && packet_buf[6] == 0x00 &&
23141 packet_buf[9] >= 0x03))
23142 {
23143 return false;
23144 }
23145
23146 buf = NewBufFromMemory(packet_buf, packet_size);
23147
23148 if (ReadBuf(buf, &content_type, sizeof(UCHAR)) == sizeof(UCHAR) &&
23149 ReadBuf(buf, &version, sizeof(USHORT)) == sizeof(USHORT) &&
23150 ReadBuf(buf, &handshake_length, sizeof(USHORT)) == sizeof(USHORT))
23151 {
23152 version = Endian16(version);
23153 handshake_length = Endian16(handshake_length);
23154
23155 if (content_type == 0x16 && version >= 0x0301)
23156 {
23157 UCHAR *handshake_data = Malloc(handshake_length);
23158
23159 if (ReadBuf(buf, handshake_data, handshake_length) == handshake_length)
23160 {
23161 BUF *buf2 = NewBufFromMemory(handshake_data, handshake_length);
23162 USHORT handshake_type;
23163 USHORT handshake_length_2;
23164
23165 if (ReadBuf(buf2, &handshake_type, sizeof(USHORT)) == sizeof(USHORT) &&
23166 ReadBuf(buf2, &handshake_length_2, sizeof(USHORT)) == sizeof(USHORT))
23167 {
23168 handshake_type = Endian16(handshake_type);
23169 handshake_length_2 = Endian16(handshake_length_2);
23170
23171 if (handshake_type == 0x0100 && handshake_length_2 <= (handshake_length - 4))
23172 {
23173 USHORT version2;
23174
23175 if (ReadBuf(buf2, &version2, sizeof(USHORT)) == sizeof(USHORT))
23176 {
23177 version2 = Endian16(version2);
23178
23179 if (version2 >= 0x0301)
23180 {
23181 UCHAR rand[32];
23182
23183 if (ReadBuf(buf2, rand, sizeof(rand)) == sizeof(rand))
23184 {
23185 UCHAR session_id_len;
23186
23187 if (ReadBuf(buf2, &session_id_len, sizeof(UCHAR)) == sizeof(UCHAR))
23188 {
23189 if (ReadBuf(buf2, NULL, session_id_len) == session_id_len)
23190 {
23191 USHORT cipher_len;
23192
23193 if (ReadBuf(buf2, &cipher_len, sizeof(USHORT)) == sizeof(USHORT))
23194 {
23195 cipher_len = Endian16(cipher_len);
23196
23197 if (ReadBuf(buf2, NULL, cipher_len) == cipher_len)
23198 {
23199 UCHAR comps_len;
23200
23201 if (ReadBuf(buf2, &comps_len, sizeof(UCHAR)) == sizeof(UCHAR))
23202 {
23203 if (ReadBuf(buf2, NULL, comps_len) == comps_len)
23204 {
23205 USHORT ext_length;
23206
23207 if (ReadBuf(buf2, &ext_length, sizeof(USHORT)) == sizeof(USHORT))
23208 {
23209 UCHAR *ext_buf;
23210
23211 ext_length = Endian16(ext_length);
23212
23213 ext_buf = Malloc(ext_length);
23214
23215 if (ReadBuf(buf2, ext_buf, ext_length) == ext_length)
23216 {
23217 BUF *ebuf = NewBufFromMemory(ext_buf, ext_length);
23218
23219 while (ret == false)
23220 {
23221 USHORT type;
23222 USHORT data_len;
23223 UCHAR *data;
23224
23225 if (ReadBuf(ebuf, &type, sizeof(USHORT)) != sizeof(USHORT))
23226 {
23227 break;
23228 }
23229
23230 if (ReadBuf(ebuf, &data_len, sizeof(USHORT)) != sizeof(USHORT))
23231 {
23232 break;
23233 }
23234
23235 type = Endian16(type);
23236 data_len = Endian16(data_len);
23237
23238 data = Malloc(data_len);
23239
23240 if (ReadBuf(ebuf, data, data_len) != data_len)
23241 {
23242 Free(data);
23243 break;
23244 }
23245
23246 if (type == 0x0000)
23247 {
23248 BUF *dbuf = NewBufFromMemory(data, data_len);
23249
23250 USHORT total_len;
23251
23252 if (ReadBuf(dbuf, &total_len, sizeof(USHORT)) == sizeof(USHORT))
23253 {
23254 UCHAR c;
23255 total_len = Endian16(total_len);
23256
23257 if (ReadBuf(dbuf, &c, sizeof(UCHAR)) == sizeof(UCHAR))
23258 {
23259 if (c == 0)
23260 {
23261 USHORT name_len;
23262
23263 if (ReadBuf(dbuf, &name_len, sizeof(USHORT)) == sizeof(USHORT))
23264 {
23265 char *name_buf;
23266 name_len = Endian16(name_len);
23267
23268 name_buf = ZeroMalloc(name_len + 1);
23269
23270 if (ReadBuf(dbuf, name_buf, name_len) == name_len)
23271 {
23272 if (StrLen(name_buf) >= 1)
23273 {
23274 ret = true;
23275
23276 StrCpy(sni, sni_size, name_buf);
23277 }
23278 }
23279
23280 Free(name_buf);
23281 }
23282 }
23283 }
23284 }
23285
23286 FreeBuf(dbuf);
23287 }
23288
23289 Free(data);
23290 }
23291
23292 FreeBuf(ebuf);
23293 }
23294
23295 Free(ext_buf);
23296 }
23297 }
23298 }
23299 }
23300 }
23301 }
23302 }
23303 }
23304 }
23305 }
23306 }
23307 }
23308
23309 FreeBuf(buf2);
23310 }
23311
23312 Free(handshake_data);
23313 }
23314 }
23315
23316 FreeBuf(buf);
23317
23318 if (ret)
23319 {
23320 Trim(sni);
23321
23322 if (IsEmptyStr(sni))
23323 {
23324 ret = false;
23325 }
23326 }
23327
23328 return ret;
23329 }
23330