1 // SoftEther VPN Source Code - Developer Edition Master Branch
2 // Cedar Communication Module
3 
4 
5 // UdpAccel.c
6 // UDP acceleration function
7 
8 #include "UdpAccel.h"
9 
10 #include "Connection.h"
11 
12 #include "Mayaqua/DNS.h"
13 #include "Mayaqua/Kernel.h"
14 #include "Mayaqua/Memory.h"
15 #include "Mayaqua/Object.h"
16 #include "Mayaqua/Str.h"
17 #include "Mayaqua/TcpIp.h"
18 #include "Mayaqua/Tick64.h"
19 
20 #include <stdlib.h>
21 
22 // Polling process
UdpAccelPoll(UDP_ACCEL * a)23 void UdpAccelPoll(UDP_ACCEL *a)
24 {
25 	IP nat_t_ip;
26 	UINT num_ignore_errors = 0;
27 	UCHAR *tmp;
28 	// Validate arguments
29 	if (a == NULL)
30 	{
31 		return;
32 	}
33 
34 	tmp = a->TmpBuf;
35 
36 	Lock(a->NatT_Lock);
37 	{
38 		Copy(&nat_t_ip, &a->NatT_IP, sizeof(IP));
39 	}
40 	Unlock(a->NatT_Lock);
41 
42 	if (IsZeroIp(&nat_t_ip) == false)
43 	{
44 		// Release the thread which gets the IP address of the NAT-T server because it is no longer needed
45 		if (a->NatT_GetIpThread != NULL)
46 		{
47 			WaitThread(a->NatT_GetIpThread, INFINITE);
48 			ReleaseThread(a->NatT_GetIpThread);
49 			a->NatT_GetIpThread = NULL;
50 		}
51 	}
52 
53 	// Receive a new UDP packet
54 	while (true)
55 	{
56 		IP src_ip;
57 		UINT src_port;
58 		UINT ret;
59 
60 		ret = RecvFrom(a->UdpSock, &src_ip, &src_port, tmp, UDP_ACCELERATION_TMP_BUF_SIZE);
61 
62 		if (ret != 0 && ret != SOCK_LATER)
63 		{
64 			if (a->UseUdpIpQuery && a->UdpIpQueryPacketSize >= 8 && CmpIpAddr(&a->UdpIpQueryHost, &src_ip) == 0 &&
65 				src_port == a->UdpIpQueryPort)
66 			{
67 				/*
68 				// Receive a response of the query for IP and port number
69 				IP my_ip = {0};
70 				UINT myport = 0;
71 				BUF *b = MemToBuf(a->UdpIpQueryPacketData, a->UdpIpQueryPacketSize);
72 				FreeBuf(b);
73 				*/
74 			}
75 			else if (IsZeroIp(&nat_t_ip) == false && CmpIpAddr(&nat_t_ip, &src_ip) == 0 &&
76 				src_port == UDP_NAT_T_PORT)
77 			{
78 				// Receive a response from the NAT-T server
79 				IP ip;
80 				UINT port;
81 				if (RUDPParseIPAndPortStr(tmp, ret, &ip, &port))
82 				{
83 					if (a->MyPortNatT != port && port >= 1 && port <= 65535)
84 					{
85 						Debug("NAT-T: MyIP = %r, MyPort = %hu\n", &ip, port);
86 
87 						a->CommToNatT_NumFail = 0;
88 						Copy(&a->MyIpNatT, &ip, sizeof(a->MyIpNatT));
89 						a->MyPortNatT = port;
90 						a->MyIpOrPortNatTChanged = true;
91 					}
92 				}
93 /*
94 				BUF *b = NewBuf();
95 				PACK *p;
96 
97 				WriteBuf(b, tmp, ret);
98 				SeekBufToBegin(b);
99 
100 				p = BufToPack(b);
101 				if (p != NULL)
102 				{
103 					if (PackCmpStr(p, "opcode", "query_for_nat_traversal"))
104 					{
105 						if (PackGetBool(p, "ok"))
106 						{
107 							if (PackGetInt64(p, "tran_id") == a->NatT_TranId)
108 							{
109 								UINT myport = PackGetInt(p, "your_port");
110 
111 								if (myport >= 1 && myport <= 65535)
112 								{
113 									if (a->MyPortByNatTServer != myport)
114 									{
115 										a->MyPortByNatTServer = myport;
116 										a->MyPortByNatTServerChanged = true;
117 
118 										Debug("NAT-T: MyPort = %u\n", myport);
119 									}
120 								}
121 							}
122 						}
123 					}
124 
125 					FreePack(p);
126 				}
127 
128 				FreeBuf(b);*/
129 			}
130 			else
131 			{
132 				BLOCK *b = UdpAccelProcessRecvPacket(a, tmp, ret, &src_ip, src_port);
133 
134 				//Debug("UDP Recv: %u %u %u\n", ret, (b == NULL ? 0 : b->Size), (b == NULL ? 0 : b->Compressed));
135 
136 				/*if (b != NULL)
137 				{
138 					char tmp[MAX_SIZE * 10];
139 					BinToStr(tmp, sizeof(tmp), b->Buf, b->Size);
140 					Debug("Recv Pkt: %s\n", tmp);
141 				}*/
142 
143 				if (b != NULL)
144 				{
145 					// Receive a packet
146 					InsertQueue(a->RecvBlockQueue, b);
147 				}
148 			}
149 		}
150 		else
151 		{
152 			if (ret == 0)
153 			{
154 				if (a->UdpSock->IgnoreRecvErr == false)
155 				{
156 					// Serious UDP reception error occurs
157 					a->FatalError = true;
158 					break;
159 				}
160 
161 				if ((num_ignore_errors++) >= MAX_NUM_IGNORE_ERRORS)
162 				{
163 					a->FatalError = true;
164 					break;
165 				}
166 			}
167 			else
168 			{
169 				// SOCK_LATER
170 				break;
171 			}
172 		}
173 	}
174 
175 	// Send a Keep-Alive packet
176 	if (a->NextSendKeepAlive == 0 || (a->NextSendKeepAlive <= a->Now) || a->YourIpOrPortNatTChanged)
177 	{
178 		a->YourIpOrPortNatTChanged = false;
179 
180 		if (UdpAccelIsSendReady(a, false))
181 		{
182 			UINT rand_interval;
183 
184 			if (a->FastDetect == false)
185 			{
186 				rand_interval = rand() % (UDP_ACCELERATION_KEEPALIVE_INTERVAL_MAX - UDP_ACCELERATION_KEEPALIVE_INTERVAL_MIN) + UDP_ACCELERATION_KEEPALIVE_INTERVAL_MIN;
187 			}
188 			else
189 			{
190 				rand_interval = rand() % (UDP_ACCELERATION_KEEPALIVE_INTERVAL_MAX_FAST - UDP_ACCELERATION_KEEPALIVE_INTERVAL_MIN_FAST) + UDP_ACCELERATION_KEEPALIVE_INTERVAL_MIN_FAST;
191 			}
192 
193 			a->NextSendKeepAlive = a->Now + (UINT64)rand_interval;
194 
195 			//Debug("UDP KeepAlive\n");
196 
197 			UdpAccelSend(a, NULL, 0, false, 1000, false);
198 		}
199 	}
200 
201 	// Send a NAT-T request packet (Only if the connection by UDP has not be established yet)
202 	if (a->NoNatT == false)
203 	{
204 		// In the usual case
205 		if (IsZeroIp(&nat_t_ip) == false)
206 		{
207 			if (UdpAccelIsSendReady(a, true) == false)
208 			{
209 				if (a->NextPerformNatTTick == 0 || (a->NextPerformNatTTick <= a->Now))
210 				{
211 					UINT rand_interval;
212 					UCHAR c = 'B';
213 
214 					a->CommToNatT_NumFail++;
215 
216 					rand_interval = UDP_NAT_T_INTERVAL_INITIAL * MIN(a->CommToNatT_NumFail, UDP_NAT_T_INTERVAL_FAIL_MAX);
217 					//PACK *p = NewPack();
218 					//BUF *b;
219 
220 					if (a->MyPortNatT != 0)
221 					{
222 						rand_interval = GenRandInterval(UDP_NAT_T_INTERVAL_MIN, UDP_NAT_T_INTERVAL_MAX);
223 					}
224 
225 					a->NextPerformNatTTick = a->Now + (UINT64)rand_interval;
226 
227 					// Generate the request packet
228 					/*PackAddStr(p, "description", UDP_NAT_T_SIGNATURE);
229 					PackAddStr(p, "opcode", "query_for_nat_traversal");
230 					PackAddInt64(p, "tran_id", a->NatT_TranId);
231 					b = PackToBuf(p);
232 					FreePack(p);*/
233 
234 					// Send the request packet
235 					SendTo(a->UdpSock, &nat_t_ip, UDP_NAT_T_PORT, &c, 1);
236 
237 					//FreeBuf(b);
238 				}
239 			}
240 			else
241 			{
242 				a->NextPerformNatTTick = 0;
243 				a->CommToNatT_NumFail = 0;
244 			}
245 		}
246 	}
247 	else
248 	{
249 		// NAT_T is disabled, but there is a reference host (such as VGC)
250 		if (a->UseUdpIpQuery || a->UseSuperRelayQuery)
251 		{
252 		}
253 	}
254 }
255 
256 // Send a packet block
UdpAccelSendBlock(UDP_ACCEL * a,BLOCK * b)257 void UdpAccelSendBlock(UDP_ACCEL *a, BLOCK *b)
258 {
259 	// Validate arguments
260 	if (a == NULL || b == NULL)
261 	{
262 		return;
263 	}
264 
265 	UdpAccelSend(a, b->Buf, b->Size, b->Compressed ? 1 : 0, a->MaxUdpPacketSize, b->PriorityQoS);
266 }
267 
268 // Calculate the best MSS
UdpAccelCalcMss(UDP_ACCEL * a)269 UINT UdpAccelCalcMss(UDP_ACCEL *a)
270 {
271 	UINT ret;
272 
273 	// Validate arguments
274 	if (a == NULL)
275 	{
276 		return 0;
277 	}
278 
279 	ret = MTU_FOR_PPPOE;
280 
281 	// IPv4
282 	if (a->IsIPv6)
283 	{
284 		ret -= 40;
285 	}
286 	else
287 	{
288 		ret -= 20;
289 	}
290 
291 	// UDP
292 	ret -= 8;
293 
294 	if (a->PlainTextMode == false)
295 	{
296 		// IV
297 		ret -= UDP_ACCELERATION_PACKET_IV_SIZE_V1;
298 	}
299 
300 	// Cookie
301 	ret -= sizeof(UINT);
302 
303 	// My Tick
304 	ret -= sizeof(UINT64);
305 
306 	// Your Tick
307 	ret -= sizeof(UINT64);
308 
309 	// Size
310 	ret -= sizeof(USHORT);
311 
312 	// Compress Flag
313 	ret -= sizeof(UCHAR);
314 
315 	if (a->PlainTextMode == false)
316 	{
317 		// Verify
318 		ret -= UDP_ACCELERATION_PACKET_IV_SIZE_V1;
319 	}
320 
321 	// Ethernet header (communication packets)
322 	ret -= 14;
323 
324 	// IPv4 Header (communication packets)
325 	ret -= 20;
326 
327 	// TCP header (communication packet)
328 	ret -= 20;
329 
330 	return ret;
331 }
332 
333 // Send
UdpAccelSend(UDP_ACCEL * a,UCHAR * data,UINT data_size,UCHAR flag,UINT max_size,bool high_priority)334 void UdpAccelSend(UDP_ACCEL *a, UCHAR *data, UINT data_size, UCHAR flag, UINT max_size, bool high_priority)
335 {
336 	UCHAR buffer[UDP_ACCELERATION_TMP_BUF_SIZE];
337 	UCHAR *buf = buffer;
338 	UINT size = 0;
339 	UINT64 tmp;
340 	UINT ret;
341 	// Validate arguments
342 	if (a == NULL || (data_size != 0 && data == NULL))
343 	{
344 		return;
345 	}
346 	if (max_size == 0)
347 	{
348 		max_size = INFINITE;
349 	}
350 
351 	if (a->PlainTextMode == false)
352 	{
353 		if (a->Version > 1)
354 		{
355 			Copy(buf, a->NextIv_V2, UDP_ACCELERATION_PACKET_IV_SIZE_V2);
356 
357 			buf += UDP_ACCELERATION_PACKET_IV_SIZE_V2;
358 			size += UDP_ACCELERATION_PACKET_IV_SIZE_V2;
359 		}
360 		else
361 		{
362 			Copy(buf, a->NextIv, UDP_ACCELERATION_PACKET_IV_SIZE_V1);
363 
364 			buf += UDP_ACCELERATION_PACKET_IV_SIZE_V1;
365 			size += UDP_ACCELERATION_PACKET_IV_SIZE_V1;
366 		}
367 	}
368 
369 	// Cookie
370 	tmp = Endian32(a->YourCookie);
371 	Copy(buf, &tmp, sizeof(UINT));
372 	buf += sizeof(UINT);
373 	size += sizeof(UINT);
374 
375 	// My tick
376 	tmp = Endian64(a->Now == 0 ? 1ULL : a->Now);
377 	Copy(buf, &tmp, sizeof(UINT64));
378 	buf += sizeof(UINT64);
379 	size += sizeof(UINT64);
380 
381 	// Your tick
382 	tmp = Endian64(a->LastRecvYourTick);
383 	Copy(buf, &tmp, sizeof(UINT64));
384 	buf += sizeof(UINT64);
385 	size += sizeof(UINT64);
386 
387 	// Size
388 	tmp = Endian16(data_size);
389 	Copy(buf, &tmp, sizeof(USHORT));
390 	buf += sizeof(USHORT);
391 	size += sizeof(USHORT);
392 
393 	// Flag
394 	Copy(buf, &flag, sizeof(UCHAR));
395 	buf += sizeof(UCHAR);
396 	size += sizeof(UCHAR);
397 
398 	// Data
399 	Copy(buf, data, data_size);
400 	buf += data_size;
401 	size += data_size;
402 
403 	if (a->PlainTextMode == false)
404 	{
405 		// Add padding to make protocol identification harder to accomplish
406 		const UINT current_total_size = size + (a->Version > 1 ? UDP_ACCELERATION_PACKET_MAC_SIZE_V2 : UDP_ACCELERATION_PACKET_IV_SIZE_V1);
407 		if (current_total_size < max_size)
408 		{
409 			UCHAR pad[UDP_ACCELERATION_MAX_PADDING_SIZE];
410 			UINT pad_size = MIN(max_size - current_total_size, UDP_ACCELERATION_MAX_PADDING_SIZE);
411 			pad_size = rand() % pad_size;
412 			Zero(pad, sizeof(pad));
413 			Copy(buf, pad, pad_size);
414 			buf += pad_size;
415 			size += pad_size;
416 		}
417 
418 		if (a->Version > 1)
419 		{
420 			const UINT inner_size = size - UDP_ACCELERATION_PACKET_IV_SIZE_V2;
421 			UCHAR *inner = buffer + UDP_ACCELERATION_PACKET_IV_SIZE_V2;
422 
423 			ret = CipherProcessAead(a->CipherEncrypt, a->NextIv_V2, inner + inner_size, UDP_ACCELERATION_PACKET_MAC_SIZE_V2, inner, inner, inner_size, NULL, 0);
424 			if (ret == 0)
425 			{
426 				Debug("UdpAccelSend(): CipherProcessAead() failed!\n");
427 				return;
428 			}
429 
430 			Copy(a->NextIv_V2, inner, UDP_ACCELERATION_PACKET_IV_SIZE_V2);
431 
432 			// Tag (appended to the buffer by CipherProcessAead())
433 			size += UDP_ACCELERATION_PACKET_MAC_SIZE_V2;
434 		}
435 		else
436 		{
437 			UCHAR *inner = buffer + UDP_ACCELERATION_PACKET_IV_SIZE_V1;
438 			UCHAR key[UDP_ACCELERATION_PACKET_KEY_SIZE_V1];
439 			const UINT inner_size = size; // We don't have to subtract because we add below
440 			CRYPT *c;
441 
442 			// Simple integrity check system: we fill some bytes with zeroes.
443 			// The remote host verifies whether all the zeroes are present.
444 			Zero(buf, UDP_ACCELERATION_PACKET_IV_SIZE_V1);
445 			buf += UDP_ACCELERATION_PACKET_IV_SIZE_V1;
446 			size += UDP_ACCELERATION_PACKET_IV_SIZE_V1;
447 
448 			UdpAccelCalcKeyV1(key, a->MyKey, a->NextIv);
449 
450 			c = NewCrypt(key, UDP_ACCELERATION_PACKET_KEY_SIZE_V1);
451 			Encrypt(c, inner, inner, inner_size);
452 			FreeCrypt(c);
453 
454 			Copy(a->NextIv, buf - UDP_ACCELERATION_PACKET_IV_SIZE_V1, UDP_ACCELERATION_PACKET_IV_SIZE_V1);
455 		}
456 	}
457 
458 	SetSockHighPriority(a->UdpSock, high_priority);
459 
460 	if (SendTo(a->UdpSock, &a->YourIp, a->YourPort, buffer, size) == 0)
461 	{
462 		Debug("UdpAccelSend(): SendTo() failed! IP: %r, port: %u, size: %u\n", &a->YourIp, a->YourPort, size);
463 		if (a->UdpSock->IgnoreSendErr == false)
464 		{
465 			a->FatalError = true;
466 			return;
467 		}
468 	}
469 
470 	if (data_size > 0 || UdpAccelIsSendReady(a, true))
471 	{
472 		return;
473 	}
474 
475 	Debug("UdpAccelSend(): Peer has not replied in a while, sending keep-alive packet to alt destinations...\n");
476 
477 	IP *ips[3];
478 	ips[0] = &a->YourIp;
479 	ips[1] = CmpIpAddr(&a->YourIpReported, &a->YourIp) == 0 ? NULL : &a->YourIpReported;
480 	ips[2] = CmpIpAddr(&a->YourIpNatT, &a->YourIp) == 0 || CmpIpAddr(&a->YourIpNatT, &a->YourIpReported) == 0 ? NULL : &a->YourIpNatT;
481 
482 	USHORT ports[3];
483 	ports[0] = a->YourPort;
484 	ports[1] = a->YourPortReported == a->YourPort ? 0 : a->YourPortReported;
485 	ports[2] = a->YourPortNatT == a->YourPort || a->YourPortNatT == a->YourPortReported ? 0 : a->YourPortNatT;
486 
487 	for (BYTE i = 0; i < sizeof(ips) / sizeof(ips[0]); ++i)
488 	{
489 		if (IsZeroIP(ips[i]))
490 		{
491 			continue;
492 		}
493 
494 		for (BYTE j = 0; j < sizeof(ports) / sizeof(ports[0]); ++j)
495 		{
496 			if (ports[j] == 0)
497 			{
498 				continue;
499 			}
500 
501 			if (CmpIpAddr(ips[i], &a->YourIp) == 0 && ports[j] == a->YourPort)
502 			{
503 				continue;
504 			}
505 
506 			if (SendTo(a->UdpSock, ips[i], ports[j], buffer, size) == 0)
507 			{
508 				Debug("UdpAccelSend(): SendTo() failed! IP: %r, port: %u, size: %u\n", ips[i], ports[j], size);
509 				if (a->UdpSock->IgnoreSendErr == false)
510 				{
511 					a->FatalError = true;
512 					return;
513 				}
514 			}
515 
516 			if (UdpAccelIsSendReady(a, true))
517 			{
518 				break;
519 			}
520 		}
521 	}
522 }
523 
524 // Determine whether transmission is possible
UdpAccelIsSendReady(UDP_ACCEL * a,bool check_keepalive)525 bool UdpAccelIsSendReady(UDP_ACCEL *a, bool check_keepalive)
526 {
527 	UINT64 timeout_value;
528 	// Validate arguments
529 	if (a == NULL)
530 	{
531 		return false;
532 	}
533 
534 	if (a->Inited == false)
535 	{
536 		return false;
537 	}
538 
539 	if (a->YourPort == 0)
540 	{
541 		return false;
542 	}
543 
544 	if (IsZeroIp(&a->YourIp))
545 	{
546 		return false;
547 	}
548 
549 	timeout_value = UDP_ACCELERATION_KEEPALIVE_TIMEOUT;
550 
551 	if (a->FastDetect)
552 	{
553 		timeout_value = UDP_ACCELERATION_KEEPALIVE_TIMEOUT_FAST;
554 	}
555 
556 	if (check_keepalive)
557 	{
558 		if (a->LastRecvTick == 0 || ((a->LastRecvTick + timeout_value) < a->Now))
559 		{
560 			a->FirstStableReceiveTick = 0;
561 			return false;
562 		}
563 		else
564 		{
565 			if ((a->FirstStableReceiveTick + (UINT64)UDP_ACCELERATION_REQUIRE_CONTINUOUS) <= a->Now)
566 			{
567 				return true;
568 			}
569 			else
570 			{
571 				return false;
572 			}
573 		}
574 	}
575 
576 	return true;
577 }
578 
579 // Process the received packet
UdpAccelProcessRecvPacket(UDP_ACCEL * a,UCHAR * buf,UINT size,IP * src_ip,UINT src_port)580 BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip, UINT src_port)
581 {
582 	UINT64 my_tick, your_tick;
583 	UINT inner_size;
584 	UCHAR *inner_data = NULL;
585 	bool compress_flag;
586 	UCHAR raw_flag;
587 	BLOCK *b = NULL;
588 	UINT cookie;
589 	// Validate arguments
590 	if (a == NULL || buf == NULL || size == 0 || src_ip == NULL)
591 	{
592 		return NULL;
593 	}
594 
595 	if (a->PlainTextMode == false)
596 	{
597 		UCHAR *iv = buf;
598 
599 		if (a->Version > 1)
600 		{
601 			UINT data_size;
602 
603 			if (size < UDP_ACCELERATION_PACKET_IV_SIZE_V2)
604 			{
605 				return NULL;
606 			}
607 
608 			buf += UDP_ACCELERATION_PACKET_IV_SIZE_V2;
609 			size -= UDP_ACCELERATION_PACKET_IV_SIZE_V2;
610 
611 			if (size < UDP_ACCELERATION_PACKET_MAC_SIZE_V2)
612 			{
613 				return NULL;
614 			}
615 
616 			data_size = size - UDP_ACCELERATION_PACKET_MAC_SIZE_V2;
617 
618 			if (CipherProcessAead(a->CipherDecrypt, iv, buf + data_size, UDP_ACCELERATION_PACKET_MAC_SIZE_V2, buf, buf, data_size, NULL, 0) == 0)
619 			{
620 				Debug("UdpAccelProcessRecvPacket(): CipherProcessAead() failed!\n");
621 				return NULL;
622 			}
623 
624 			size -= UDP_ACCELERATION_PACKET_MAC_SIZE_V2;
625 		}
626 		else
627 		{
628 			UCHAR key[UDP_ACCELERATION_PACKET_KEY_SIZE_V1];
629 			CRYPT *c;
630 
631 			if (size < UDP_ACCELERATION_PACKET_IV_SIZE_V1)
632 			{
633 				return NULL;
634 			}
635 
636 			buf += UDP_ACCELERATION_PACKET_IV_SIZE_V1;
637 			size -= UDP_ACCELERATION_PACKET_IV_SIZE_V1;
638 
639 			UdpAccelCalcKeyV1(key, a->YourKey, iv);
640 
641 			c = NewCrypt(key, UDP_ACCELERATION_PACKET_KEY_SIZE_V1);
642 			Encrypt(c, buf, buf, size);
643 			FreeCrypt(c);
644 		}
645 	}
646 
647 	// Cookie
648 	if (size < sizeof(UINT))
649 	{
650 		return NULL;
651 	}
652 	cookie = READ_UINT(buf);
653 	buf += sizeof(UINT);
654 	size -= sizeof(UINT);
655 
656 	if (cookie != a->MyCookie)
657 	{
658 		return NULL;
659 	}
660 
661 	// My tick
662 	if (size < sizeof(UINT64))
663 	{
664 		return NULL;
665 	}
666 	my_tick = READ_UINT64(buf);
667 	buf += sizeof(UINT64);
668 	size -= sizeof(UINT64);
669 
670 	// Your tick
671 	if (size < sizeof(UINT64))
672 	{
673 		return NULL;
674 	}
675 	your_tick = READ_UINT64(buf);
676 	buf += sizeof(UINT64);
677 	size -= sizeof(UINT64);
678 
679 	// Inner data size
680 	if (size < sizeof(USHORT))
681 	{
682 		return NULL;
683 	}
684 	inner_size = READ_USHORT(buf);
685 	buf += sizeof(USHORT);
686 	size -= sizeof(USHORT);
687 
688 	// Flag
689 	if (size < sizeof(UCHAR))
690 	{
691 		return NULL;
692 	}
693 	if (a->ReadRawFlagMode == false)
694 	{
695 		compress_flag = *((UCHAR *)buf);
696 	}
697 	else
698 	{
699 		raw_flag = *((UCHAR *)buf);
700 	}
701 
702 	buf += sizeof(UCHAR);
703 	size -= sizeof(UCHAR);
704 
705 	if (size < inner_size)
706 	{
707 		return NULL;
708 	}
709 
710 	// Inner_data
711 	if (inner_size >= 1)
712 	{
713 		inner_data = buf;
714 		buf += inner_size;
715 		size -= inner_size;
716 	}
717 
718 	if (a->PlainTextMode == false)
719 	{
720 		// Verify packet integrity
721 		if (a->Version == 1)
722 		{
723 			UINT pad_size;
724 
725 			if (size < UDP_ACCELERATION_PACKET_IV_SIZE_V1)
726 			{
727 				return false;
728 			}
729 
730 			pad_size = size - UDP_ACCELERATION_PACKET_IV_SIZE_V1;
731 			buf += pad_size;
732 			size -= pad_size;
733 
734 			if (size != UDP_ACCELERATION_PACKET_IV_SIZE_V1)
735 			{
736 				return NULL;
737 			}
738 
739 			if (IsZero(buf, UDP_ACCELERATION_PACKET_IV_SIZE_V1) == false)
740 			{
741 				return NULL;
742 			}
743 		}
744 	}
745 
746 	if (my_tick < a->LastRecvYourTick)
747 	{
748 		if ((a->LastRecvYourTick - my_tick) >= ((UINT64)UDP_ACCELERATION_WINDOW_SIZE_MSEC))
749 		{
750 			return NULL;
751 		}
752 	}
753 
754 	a->LastRecvMyTick = MAX(a->LastRecvMyTick, your_tick);
755 	a->LastRecvYourTick = MAX(a->LastRecvYourTick, my_tick);
756 
757 	if (inner_size >= 1)
758 	{
759 		b = NewBlock(Clone(inner_data, inner_size), inner_size, a->ReadRawFlagMode == false ? (compress_flag ? -1 : 0) : 0);
760 		if (a->ReadRawFlagMode)
761 		{
762 			b->RawFlagRetUdpAccel = raw_flag;
763 		}
764 	}
765 
766 	if (a->LastSetSrcIpAndPortTick < a->LastRecvYourTick)
767 	{
768 		a->LastSetSrcIpAndPortTick = a->LastRecvYourTick;
769 
770 		Copy(&a->YourIp, src_ip, sizeof(IP));
771 		a->YourPort = src_port;
772 	}
773 
774 	if (a->LastRecvMyTick != 0)
775 	{
776 		if ((a->LastRecvMyTick + (UINT64)(UDP_ACCELERATION_WINDOW_SIZE_MSEC)) >= a->Now)
777 		{
778 			a->LastRecvTick = a->Now;
779 
780 			a->IsReachedOnce = true;
781 
782 			if (a->FirstStableReceiveTick == 0)
783 			{
784 				a->FirstStableReceiveTick = a->Now;
785 			}
786 		}
787 	}
788 
789 	return b;
790 }
791 
792 // Calculate V1 key
UdpAccelCalcKeyV1(UCHAR * key,UCHAR * common_key,UCHAR * iv)793 void UdpAccelCalcKeyV1(UCHAR *key, UCHAR *common_key, UCHAR *iv)
794 {
795 	UCHAR tmp[UDP_ACCELERATION_COMMON_KEY_SIZE_V1 + UDP_ACCELERATION_PACKET_IV_SIZE_V1];
796 	// Validate arguments
797 	if (key == NULL || common_key == NULL || iv == NULL)
798 	{
799 		return;
800 	}
801 
802 	Copy(tmp, common_key, UDP_ACCELERATION_COMMON_KEY_SIZE_V1);
803 	Copy(tmp + UDP_ACCELERATION_COMMON_KEY_SIZE_V1, iv, UDP_ACCELERATION_PACKET_IV_SIZE_V1);
804 
805 	Sha1(key, tmp, sizeof(tmp));
806 }
807 
808 // Set the current time
UdpAccelSetTick(UDP_ACCEL * a,UINT64 tick64)809 void UdpAccelSetTick(UDP_ACCEL *a, UINT64 tick64)
810 {
811 	// Validate arguments
812 	if (a == NULL)
813 	{
814 		return;
815 	}
816 
817 	a->Now = tick64;
818 }
819 
820 // Initialize the server-side
UdpAccelInitServer(UDP_ACCEL * a,UCHAR * key,IP * detected_ip,IP * reported_ip,USHORT port)821 bool UdpAccelInitServer(UDP_ACCEL *a, UCHAR *key, IP *detected_ip, IP *reported_ip, USHORT port)
822 {
823 	// Validate arguments
824 	if (a == NULL || key == NULL || detected_ip == NULL || port == 0)
825 	{
826 		return false;
827 	}
828 
829 	Debug("UdpAccelInitServer(): Version: %u, detected_ip: %r, reported_ip: %r, port: %hu, YourCookie: %u, MyCookie: %u\n",
830 		  a->Version, detected_ip, reported_ip, port, a->YourCookie, a->MyCookie);
831 
832 	if (IsIP6(detected_ip) != a->IsIPv6)
833 	{
834 		return false;
835 	}
836 
837 	if (a->Version > 1)
838 	{
839 		a->CipherEncrypt = NewCipher("ChaCha20-Poly1305");
840 		a->CipherDecrypt = NewCipher("ChaCha20-Poly1305");
841 
842 		SetCipherKey(a->CipherEncrypt, a->MyKey_V2, true);
843 		SetCipherKey(a->CipherDecrypt, key, false);
844 	}
845 	else
846 	{
847 		Copy(a->YourKey, key, sizeof(a->YourKey));
848 	}
849 
850 	Copy(&a->YourIp, detected_ip, sizeof(a->YourIp));
851 	Copy(&a->YourIpReported, reported_ip, sizeof(a->YourIpReported));
852 
853 	a->YourPort = a->YourPortReported = port;
854 
855 	a->Now = Tick64();
856 
857 	a->Inited = true;
858 
859 	return true;
860 }
861 
862 // Initialize the client-side
UdpAccelInitClient(UDP_ACCEL * a,UCHAR * key,IP * detected_ip,IP * reported_ip,USHORT port,UINT cookie,UINT my_cookie)863 bool UdpAccelInitClient(UDP_ACCEL *a, UCHAR *key, IP *detected_ip, IP *reported_ip, USHORT port, UINT cookie, UINT my_cookie)
864 {
865 	// Validate arguments
866 	if (a == NULL || key == NULL || detected_ip == NULL || port == 0)
867 	{
868 		return false;
869 	}
870 
871 	Debug("UdpAccelInitClient(): Version: %u, detected_ip: %s, reported_ip: %s, port: %hu, cookie: %u, my_cookie: %u\n",
872 		  a->Version, detected_ip, reported_ip, port, cookie, my_cookie);
873 
874 	if (IsIP6(detected_ip) != a->IsIPv6)
875 	{
876 		return false;
877 	}
878 
879 	if (a->Version > 1)
880 	{
881 		a->CipherEncrypt = NewCipher("ChaCha20-Poly1305");
882 		a->CipherDecrypt = NewCipher("ChaCha20-Poly1305");
883 
884 		SetCipherKey(a->CipherEncrypt, a->MyKey_V2, true);
885 		SetCipherKey(a->CipherDecrypt, key, false);
886 	}
887 	else
888 	{
889 		Copy(a->YourKey, key, sizeof(a->YourKey));
890 	}
891 
892 	Copy(&a->YourIp, detected_ip, sizeof(a->YourIp));
893 	Copy(&a->YourIpReported, reported_ip, sizeof(a->YourIpReported));
894 
895 	a->YourPort = a->YourPortReported = port;
896 
897 	a->Now = Tick64();
898 
899 	a->MyCookie = my_cookie;
900 	a->YourCookie = cookie;
901 
902 	a->Inited = true;
903 
904 	return true;
905 }
906 
907 // Create a new UDP acceleration function
NewUdpAccel(CEDAR * cedar,IP * ip,bool client_mode,bool random_port,bool no_nat_t)908 UDP_ACCEL *NewUdpAccel(CEDAR *cedar, IP *ip, bool client_mode, bool random_port, bool no_nat_t)
909 {
910 	UDP_ACCEL *a;
911 	SOCK *s;
912 	UINT max_udp_size;
913 	bool is_in_cedar_port_list = false;
914 
915 	if (IsZeroIP(ip))
916 	{
917 		ip = NULL;
918 	}
919 
920 	if (client_mode || random_port)
921 	{
922 		// Use a appropriate vacant port number in the case of using random port or client mode
923 		s = NewUDPEx3(0, ip);
924 	}
925 	else
926 	{
927 		// Specify in the range in the case of server mode
928 		UINT i;
929 		s = NULL;
930 
931 		LockList(cedar->UdpPortList);
932 		{
933 			for (i = UDP_SERVER_PORT_LOWER;i <= UDP_SERVER_PORT_HIGHER;i++)
934 			{
935 				if (IsIntInList(cedar->UdpPortList, i) == false)
936 				{
937 					s = NewUDPEx3(i, ip);
938 
939 					if (s != NULL)
940 					{
941 						is_in_cedar_port_list = true;
942 						break;
943 					}
944 				}
945 			}
946 
947 			if (s == NULL)
948 			{
949 				// Leave the port selection to the OS because the available port is not found within the range
950 				s = NewUDPEx3(0, ip);
951 			}
952 
953 			if (s != NULL && is_in_cedar_port_list)
954 			{
955 				AddIntDistinct(cedar->UdpPortList, i);
956 			}
957 		}
958 		UnlockList(cedar->UdpPortList);
959 	}
960 
961 	if (s == NULL)
962 	{
963 		return NULL;
964 	}
965 
966 	a = ZeroMalloc(sizeof(UDP_ACCEL));
967 
968 	a->Cedar = cedar;
969 	AddRef(a->Cedar->ref);
970 
971 	a->NoNatT = no_nat_t;
972 
973 	a->Version = 1;
974 
975 	a->NatT_TranId = Rand64();
976 
977 	a->CreatedTick = Tick64();
978 
979 	a->IsInCedarPortList = is_in_cedar_port_list;
980 
981 	a->ClientMode = client_mode;
982 
983 	a->Now = Tick64();
984 	a->UdpSock = s;
985 
986 	Rand(a->MyKey, sizeof(a->MyKey));
987 	Rand(a->MyKey_V2, sizeof(a->MyKey_V2));
988 
989 	Copy(&a->MyIp, ip, sizeof(a->MyIp));
990 	a->MyPort = s->LocalPort;
991 
992 	a->IsIPv6 = IsIP6(ip);
993 
994 	if (a->IsIPv6)
995 	{
996 		a->NoNatT = true;
997 	}
998 
999 	a->RecvBlockQueue = NewQueue();
1000 
1001 	Rand(a->NextIv, sizeof(a->NextIv));
1002 	Rand(a->NextIv_V2, sizeof(a->NextIv_V2));
1003 
1004 	do
1005 	{
1006 		a->MyCookie = Rand32();
1007 	}
1008 	while (a->MyCookie == 0);
1009 
1010 	do
1011 	{
1012 		a->YourCookie = Rand32();
1013 	}
1014 	while (a->MyCookie == 0 || a->MyCookie == a->YourCookie);
1015 
1016 	// Calculate the maximum transmittable UDP packet size
1017 	max_udp_size = MTU_FOR_PPPOE;
1018 
1019 	if (a->IsIPv6 == false)
1020 	{
1021 		// IPv4
1022 		max_udp_size -= 20;
1023 	}
1024 	else
1025 	{
1026 		// IPv6
1027 		max_udp_size -= 40;
1028 	}
1029 
1030 	// UDP
1031 	max_udp_size -= 8;
1032 
1033 	a->MaxUdpPacketSize = max_udp_size;
1034 
1035 	Debug("Udp Accel My Port = %u\n", a->MyPort);
1036 
1037 	// Initialize the NAT-T server IP address acquisition thread
1038 	a->NatT_Lock = NewLock();
1039 	a->NatT_HaltEvent = NewEvent();
1040 
1041 	if (a->NoNatT == false)
1042 	{
1043 		a->NatT_GetIpThread = NewThread(NatT_GetIpThread, a);
1044 	}
1045 
1046 	return a;
1047 }
1048 
1049 // NAT-T server IP address acquisition thread
NatT_GetIpThread(THREAD * thread,void * param)1050 void NatT_GetIpThread(THREAD *thread, void *param)
1051 {
1052 	UDP_ACCEL *a;
1053 	char hostname[MAX_SIZE];
1054 	static IP dummy_ip = {0};
1055 	UINT num_retry = 0;
1056 	// Validate arguments
1057 	if (thread == NULL || param == NULL)
1058 	{
1059 		return;
1060 	}
1061 
1062 	a = (UDP_ACCEL *)param;
1063 
1064 	if (IsZeroIP(&dummy_ip))
1065 	{
1066 		SetIP(&dummy_ip, 11, Rand8(), Rand8(), Rand8());
1067 	}
1068 
1069 	RUDPGetRegisterHostNameByIP(hostname, sizeof(hostname), &dummy_ip);
1070 
1071 	while (a->NatT_Halt == false)
1072 	{
1073 		IP ip;
1074 		UINT wait_time = UDP_NAT_T_GET_IP_INTERVAL;
1075 
1076 		// Get the IP address
1077 		bool ret = GetIP4Ex(&ip, hostname, 0, &a->NatT_Halt);
1078 
1079 		if (ret && (IsZeroIp(&ip) == false))
1080 		{
1081 			char tmp[128];
1082 
1083 			// Success to get
1084 			Lock(a->NatT_Lock);
1085 			{
1086 				Copy(&a->NatT_IP, &ip, sizeof(IP));
1087 			}
1088 			Unlock(a->NatT_Lock);
1089 
1090 			IPToStr(tmp, sizeof(tmp), &ip);
1091 			Debug("NAT-T IP Address Resolved: %s = %s\n", hostname, tmp);
1092 
1093 			a->NatT_IP_Changed = true;
1094 
1095 			break;
1096 		}
1097 
1098 		// Fail to get
1099 		num_retry++;
1100 
1101 		wait_time = (UINT)(MIN((UINT64)UDP_NAT_T_GET_IP_INTERVAL * (UINT64)num_retry, (UINT64)UDP_NAT_T_GET_IP_INTERVAL_MAX));
1102 
1103 		Wait(a->NatT_HaltEvent, wait_time);
1104 	}
1105 }
1106 
1107 // Release the UDP acceleration function
FreeUdpAccel(UDP_ACCEL * a)1108 void FreeUdpAccel(UDP_ACCEL *a)
1109 {
1110 	// Validate arguments
1111 	if (a == NULL)
1112 	{
1113 		return;
1114 	}
1115 
1116 	while (true)
1117 	{
1118 		BLOCK *b = GetNext(a->RecvBlockQueue);
1119 
1120 		if (b == NULL)
1121 		{
1122 			break;
1123 		}
1124 
1125 		FreeBlock(b);
1126 	}
1127 
1128 	ReleaseQueue(a->RecvBlockQueue);
1129 
1130 	ReleaseSock(a->UdpSock);
1131 
1132 	if (a->IsInCedarPortList)
1133 	{
1134 		LockList(a->Cedar->UdpPortList);
1135 		{
1136 			DelInt(a->Cedar->UdpPortList, a->MyPort);
1137 		}
1138 		UnlockList(a->Cedar->UdpPortList);
1139 	}
1140 
1141 	// Release of NAT-T related
1142 	a->NatT_Halt = true;
1143 	Set(a->NatT_HaltEvent);
1144 
1145 	if (a->NatT_GetIpThread != NULL)
1146 	{
1147 		WaitThread(a->NatT_GetIpThread, INFINITE);
1148 		ReleaseThread(a->NatT_GetIpThread);
1149 	}
1150 
1151 	ReleaseEvent(a->NatT_HaltEvent);
1152 	DeleteLock(a->NatT_Lock);
1153 
1154 	ReleaseCedar(a->Cedar);
1155 
1156 	FreeCipher(a->CipherEncrypt);
1157 	FreeCipher(a->CipherDecrypt);
1158 
1159 	Free(a);
1160 }
1161