1 // SoftEther VPN Source Code - Stable Edition Repository
2 // Cedar Communication Module
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 //
18 // License: The Apache License, Version 2.0
19 // https://www.apache.org/licenses/LICENSE-2.0
20 //
21 // DISCLAIMER
22 // ==========
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 // SOFTWARE.
31 //
32 // THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN, UNDER
33 // JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY, MERGE, PUBLISH,
34 // DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS SOFTWARE, THAT ANY
35 // JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS SOFTWARE OR ITS CONTENTS,
36 // AGAINST US (SOFTETHER PROJECT, SOFTETHER CORPORATION, DAIYUU NOBORI OR OTHER
37 // SUPPLIERS), OR ANY JURIDICAL DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND
38 // OF USING, COPYING, MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING,
39 // AND/OR SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
40 // CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO EXCLUSIVE
41 // JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO, JAPAN. YOU MUST WAIVE
42 // ALL DEFENSES OF LACK OF PERSONAL JURISDICTION AND FORUM NON CONVENIENS.
43 // PROCESS MAY BE SERVED ON EITHER PARTY IN THE MANNER AUTHORIZED BY APPLICABLE
44 // LAW OR COURT RULE.
45 //
46 // USE ONLY IN JAPAN. DO NOT USE THIS SOFTWARE IN ANOTHER COUNTRY UNLESS YOU HAVE
47 // A CONFIRMATION THAT THIS SOFTWARE DOES NOT VIOLATE ANY CRIMINAL LAWS OR CIVIL
48 // RIGHTS IN THAT PARTICULAR COUNTRY. USING THIS SOFTWARE IN OTHER COUNTRIES IS
49 // COMPLETELY AT YOUR OWN RISK. THE SOFTETHER VPN PROJECT HAS DEVELOPED AND
50 // DISTRIBUTED THIS SOFTWARE TO COMPLY ONLY WITH THE JAPANESE LAWS AND EXISTING
51 // CIVIL RIGHTS INCLUDING PATENTS WHICH ARE SUBJECTS APPLY IN JAPAN. OTHER
52 // COUNTRIES' LAWS OR CIVIL RIGHTS ARE NONE OF OUR CONCERNS NOR RESPONSIBILITIES.
53 // WE HAVE NEVER INVESTIGATED ANY CRIMINAL REGULATIONS, CIVIL LAWS OR
54 // INTELLECTUAL PROPERTY RIGHTS INCLUDING PATENTS IN ANY OF OTHER 200+ COUNTRIES
55 // AND TERRITORIES. BY NATURE, THERE ARE 200+ REGIONS IN THE WORLD, WITH
56 // DIFFERENT LAWS. IT IS IMPOSSIBLE TO VERIFY EVERY COUNTRIES' LAWS, REGULATIONS
57 // AND CIVIL RIGHTS TO MAKE THE SOFTWARE COMPLY WITH ALL COUNTRIES' LAWS BY THE
58 // PROJECT. EVEN IF YOU WILL BE SUED BY A PRIVATE ENTITY OR BE DAMAGED BY A
59 // PUBLIC SERVANT IN YOUR COUNTRY, THE DEVELOPERS OF THIS SOFTWARE WILL NEVER BE
60 // LIABLE TO RECOVER OR COMPENSATE SUCH DAMAGES, CRIMINAL OR CIVIL
61 // RESPONSIBILITIES. NOTE THAT THIS LINE IS NOT LICENSE RESTRICTION BUT JUST A
62 // STATEMENT FOR WARNING AND DISCLAIMER.
63 //
64 // READ AND UNDERSTAND THE 'WARNING.TXT' FILE BEFORE USING THIS SOFTWARE.
65 // SOME SOFTWARE PROGRAMS FROM THIRD PARTIES ARE INCLUDED ON THIS SOFTWARE WITH
66 // LICENSE CONDITIONS WHICH ARE DESCRIBED ON THE 'THIRD_PARTY.TXT' FILE.
67 //
68 //
69 // SOURCE CODE CONTRIBUTION
70 // ------------------------
71 //
72 // Your contribution to SoftEther VPN Project is much appreciated.
73 // Please send patches to us through GitHub.
74 // Read the SoftEther VPN Patch Acceptance Policy in advance:
75 // http://www.softether.org/5-download/src/9.patch
76 //
77 //
78 // DEAR SECURITY EXPERTS
79 // ---------------------
80 //
81 // If you find a bug or a security vulnerability please kindly inform us
82 // about the problem immediately so that we can fix the security problem
83 // to protect a lot of users around the world as soon as possible.
84 //
85 // Our e-mail address for security reports is:
86 // softether-vpn-security [at] softether.org
87 //
88 // Please note that the above e-mail address is not a technical support
89 // inquiry address. If you need technical assistance, please visit
90 // http://www.softether.org/ and ask your question on the users forum.
91 //
92 // Thank you for your cooperation.
93 //
94 //
95 // NO MEMORY OR RESOURCE LEAKS
96 // ---------------------------
97 //
98 // The memory-leaks and resource-leaks verification under the stress
99 // test has been passed before release this source code.
100 
101 
102 // Connection.c
103 // Connection Manager
104 
105 #include "CedarPch.h"
106 
107 // Determine whether the socket is to use to send
108 #define	IS_SEND_TCP_SOCK(ts)		\
109 	((ts->Direction == TCP_BOTH) || ((ts->Direction == TCP_SERVER_TO_CLIENT) && (s->ServerMode)) || ((ts->Direction == TCP_CLIENT_TO_SERVER) && (s->ServerMode == false)))
110 
111 // Determine whether the socket is to use to receive
112 #define	IS_RECV_TCP_SOCK(ts)		\
113 	((ts->Direction == TCP_BOTH) || ((ts->Direction == TCP_SERVER_TO_CLIENT) && (s->ServerMode == false)) || ((ts->Direction == TCP_CLIENT_TO_SERVER) && (s->ServerMode)))
114 
115 // Conversion of SECURE_SIGN
InRpcSecureSign(SECURE_SIGN * t,PACK * p)116 void InRpcSecureSign(SECURE_SIGN *t, PACK *p)
117 {
118 	// Validate arguments
119 	if (t == NULL || p == NULL)
120 	{
121 		return;
122 	}
123 
124 	Zero(t, sizeof(SECURE_SIGN));
125 	PackGetStr(p, "SecurePublicCertName", t->SecurePublicCertName, sizeof(t->SecurePublicCertName));
126 	PackGetStr(p, "SecurePrivateKeyName", t->SecurePrivateKeyName, sizeof(t->SecurePrivateKeyName));
127 	t->ClientCert = PackGetX(p, "ClientCert");
128 	PackGetData2(p, "Random", t->Random, sizeof(t->Random));
129 	PackGetData2(p, "Signature", t->Signature, sizeof(t->Signature));
130 	t->UseSecureDeviceId = PackGetInt(p, "UseSecureDeviceId");
131 	t->BitmapId = PackGetInt(p, "BitmapId");
132 }
OutRpcSecureSign(PACK * p,SECURE_SIGN * t)133 void OutRpcSecureSign(PACK *p, SECURE_SIGN *t)
134 {
135 	// Validate arguments
136 	if (p == NULL || t == NULL)
137 	{
138 		return;
139 	}
140 
141 	PackAddStr(p, "SecurePublicCertName", t->SecurePublicCertName);
142 	PackAddStr(p, "SecurePrivateKeyName", t->SecurePrivateKeyName);
143 	PackAddX(p, "ClientCert", t->ClientCert);
144 	PackAddData(p, "Random", t->Random, sizeof(t->Random));
145 	PackAddData(p, "Signature", t->Signature, sizeof(t->Signature));
146 	PackAddInt(p, "UseSecureDeviceId", t->UseSecureDeviceId);
147 	PackAddInt(p, "BitmapId", t->BitmapId);
148 }
FreeRpcSecureSign(SECURE_SIGN * t)149 void FreeRpcSecureSign(SECURE_SIGN *t)
150 {
151 	// Validate arguments
152 	if (t == NULL)
153 	{
154 		return;
155 	}
156 
157 	FreeX(t->ClientCert);
158 }
159 
160 // Generate the next packet
NewKeepPacket(bool server_mode)161 BUF *NewKeepPacket(bool server_mode)
162 {
163 	BUF *b = NewBuf();
164 	char *string = KEEP_ALIVE_STRING;
165 
166 	WriteBuf(b, string, StrLen(string));
167 
168 	SeekBuf(b, 0, 0);
169 
170 	return b;
171 }
172 
173 // KEEP thread
KeepThread(THREAD * thread,void * param)174 void KeepThread(THREAD *thread, void *param)
175 {
176 	KEEP *k = (KEEP *)param;
177 	SOCK *s;
178 	char server_name[MAX_HOST_NAME_LEN + 1];
179 	UINT server_port;
180 	bool udp_mode;
181 	bool enabled;
182 	// Validate arguments
183 	if (thread == NULL || k == NULL)
184 	{
185 		return;
186 	}
187 
188 WAIT_FOR_ENABLE:
189 	Wait(k->HaltEvent, KEEP_POLLING_INTERVAL);
190 
191 	// Wait until it becomes enabled
192 	while (true)
193 	{
194 		enabled = false;
195 		Lock(k->lock);
196 		{
197 			if (k->Enable)
198 			{
199 				if (StrLen(k->ServerName) != 0 && k->ServerPort != 0 && k->Interval != 0)
200 				{
201 					StrCpy(server_name, sizeof(server_name), k->ServerName);
202 					server_port = k->ServerPort;
203 					udp_mode = k->UdpMode;
204 					enabled = true;
205 				}
206 			}
207 		}
208 		Unlock(k->lock);
209 		if (enabled)
210 		{
211 			break;
212 		}
213 		if (k->Halt)
214 		{
215 			return;
216 		}
217 		Wait(k->HaltEvent, KEEP_POLLING_INTERVAL);
218 	}
219 
220 	if (udp_mode == false)
221 	{
222 		// TCP mode
223 		// Try until a success to connection
224 		while (true)
225 		{
226 			UINT64 connect_started_tick;
227 			bool changed = false;
228 			Lock(k->lock);
229 			{
230 				if (StrCmpi(k->ServerName, server_name) != 0 ||
231 					k->ServerPort != server_port || k->Enable == false ||
232 					k->UdpMode)
233 				{
234 					changed = true;
235 				}
236 			}
237 			Unlock(k->lock);
238 			if (changed)
239 			{
240 				// Settings are changed
241 				goto WAIT_FOR_ENABLE;
242 			}
243 
244 			if (k->Halt)
245 			{
246 				// Stop
247 				return;
248 			}
249 
250 			// Attempt to connect to the server
251 			connect_started_tick = Tick64();
252 			s = ConnectEx2(server_name, server_port, KEEP_TCP_TIMEOUT, (bool *)&k->Halt);
253 			if (s != NULL)
254 			{
255 				// Successful connection
256 				break;
257 			}
258 
259 			// Connection failure: Wait until timeout or the setting is changed
260 			while (true)
261 			{
262 				changed = false;
263 				if (k->Halt)
264 				{
265 					// Stop
266 					return;
267 				}
268 				Lock(k->lock);
269 				{
270 					if (StrCmpi(k->ServerName, server_name) != 0 ||
271 						k->ServerPort != server_port || k->Enable == false ||
272 						k->UdpMode)
273 					{
274 						changed = true;
275 					}
276 				}
277 				Unlock(k->lock);
278 
279 				if (changed)
280 				{
281 					// Settings are changed
282 					goto WAIT_FOR_ENABLE;
283 				}
284 
285 				if ((Tick64() - connect_started_tick) >= KEEP_RETRY_INTERVAL)
286 				{
287 					break;
288 				}
289 
290 				Wait(k->HaltEvent, KEEP_POLLING_INTERVAL);
291 			}
292 		}
293 
294 		// Success to connect the server
295 		// Send and receive packet data periodically
296 		if (s != NULL)
297 		{
298 			UINT64 last_packet_sent_time = 0;
299 			while (true)
300 			{
301 				SOCKSET set;
302 				UINT ret;
303 				UCHAR buf[MAX_SIZE];
304 				bool changed;
305 
306 				InitSockSet(&set);
307 				AddSockSet(&set, s);
308 
309 				Select(&set, KEEP_POLLING_INTERVAL, k->Cancel, NULL);
310 
311 				ret = Recv(s, buf, sizeof(buf), false);
312 				if (ret == 0)
313 				{
314 					// Disconnected
315 					Disconnect(s);
316 					ReleaseSock(s);
317 					s = NULL;
318 				}
319 
320 				if (s != NULL)
321 				{
322 					if ((Tick64() - last_packet_sent_time) >= (UINT64)k->Interval)
323 					{
324 						BUF *b;
325 
326 						// Send the next packet
327 						last_packet_sent_time = Tick64();
328 
329 						b = NewKeepPacket(k->Server);
330 
331 						ret = Send(s, b->Buf, b->Size, false);
332 						FreeBuf(b);
333 
334 						if (ret == 0)
335 						{
336 							// Disconnected
337 							Disconnect(s);
338 							ReleaseSock(s);
339 							s = NULL;
340 						}
341 					}
342 				}
343 
344 				changed = false;
345 
346 				Lock(k->lock);
347 				{
348 					if (StrCmpi(k->ServerName, server_name) != 0 ||
349 						k->ServerPort != server_port || k->Enable == false ||
350 						k->UdpMode)
351 					{
352 						changed = true;
353 					}
354 				}
355 				Unlock(k->lock);
356 
357 				if (changed || s == NULL)
358 				{
359 					// Setting has been changed or disconnected
360 					Disconnect(s);
361 					ReleaseSock(s);
362 					s = NULL;
363 					goto WAIT_FOR_ENABLE;
364 				}
365 				else
366 				{
367 					if (k->Halt)
368 					{
369 						// Stop
370 						Disconnect(s);
371 						ReleaseSock(s);
372 						return;
373 					}
374 				}
375 			}
376 		}
377 	}
378 	else
379 	{
380 		IP dest_ip;
381 		// UDP mode
382 		// Try to create socket until it successes
383 		while (true)
384 		{
385 			UINT64 connect_started_tick;
386 			bool changed = false;
387 			Lock(k->lock);
388 			{
389 				if (StrCmpi(k->ServerName, server_name) != 0 ||
390 					k->ServerPort != server_port || k->Enable == false ||
391 					k->UdpMode == false)
392 				{
393 					changed = true;
394 				}
395 			}
396 			Unlock(k->lock);
397 			if (changed)
398 			{
399 				// Settings are changed
400 				goto WAIT_FOR_ENABLE;
401 			}
402 
403 			if (k->Halt)
404 			{
405 				// Stop
406 				return;
407 			}
408 
409 			// Attempt to create a socket
410 			connect_started_tick = Tick64();
411 
412 			// Attempt to resolve the name first
413 			if (GetIP(&dest_ip, server_name))
414 			{
415 				// After successful name resolution, create a socket
416 				s = NewUDP(0);
417 				if (s != NULL)
418 				{
419 					// Creating success
420 					break;
421 				}
422 			}
423 
424 			// Failure to create: wait until timeout or the setting is changed
425 			while (true)
426 			{
427 				changed = false;
428 				if (k->Halt)
429 				{
430 					// Stop
431 					return;
432 				}
433 				Lock(k->lock);
434 				{
435 					if (StrCmpi(k->ServerName, server_name) != 0 ||
436 						k->ServerPort != server_port || k->Enable == false ||
437 						k->UdpMode)
438 					{
439 						changed = true;
440 					}
441 				}
442 				Unlock(k->lock);
443 
444 				if (changed)
445 				{
446 					// Settings are changed
447 					goto WAIT_FOR_ENABLE;
448 				}
449 
450 				if ((Tick64() - connect_started_tick) >= KEEP_RETRY_INTERVAL)
451 				{
452 					break;
453 				}
454 
455 				Wait(k->HaltEvent, KEEP_POLLING_INTERVAL);
456 			}
457 		}
458 
459 		// Send the packet data periodically
460 		if (s != NULL)
461 		{
462 			UINT64 last_packet_sent_time = 0;
463 			UINT num_ignore_errors = 0;
464 			while (true)
465 			{
466 				SOCKSET set;
467 				UINT ret;
468 				UCHAR buf[MAX_SIZE];
469 				bool changed;
470 				IP src_ip;
471 				UINT src_port;
472 
473 				InitSockSet(&set);
474 				AddSockSet(&set, s);
475 
476 				Select(&set, KEEP_POLLING_INTERVAL, k->Cancel, NULL);
477 
478 				// Receive
479 				ret = RecvFrom(s, &src_ip, &src_port, buf, sizeof(buf));
480 				if (ret == 0)
481 				{
482 					if (s->IgnoreRecvErr == false)
483 					{
484 LABEL_DISCONNECTED:
485 						// Disconnected
486 						Disconnect(s);
487 						ReleaseSock(s);
488 						s = NULL;
489 					}
490 					else
491 					{
492 						if ((num_ignore_errors++) >= MAX_NUM_IGNORE_ERRORS)
493 						{
494 							goto LABEL_DISCONNECTED;
495 						}
496 					}
497 				}
498 
499 				if (s != NULL)
500 				{
501 					if ((Tick64() - last_packet_sent_time) >= (UINT64)k->Interval)
502 					{
503 						BUF *b;
504 
505 						// Send the next packet
506 						last_packet_sent_time = Tick64();
507 
508 						b = NewKeepPacket(k->Server);
509 
510 						ret = SendTo(s, &dest_ip, server_port, b->Buf, b->Size);
511 						FreeBuf(b);
512 
513 						if (ret == 0 && s->IgnoreSendErr == false)
514 						{
515 							// Disconnected
516 							Disconnect(s);
517 							ReleaseSock(s);
518 							s = NULL;
519 						}
520 					}
521 				}
522 
523 				changed = false;
524 
525 				Lock(k->lock);
526 				{
527 					if (StrCmpi(k->ServerName, server_name) != 0 ||
528 						k->ServerPort != server_port || k->Enable == false ||
529 						k->UdpMode == false)
530 					{
531 						changed = true;
532 					}
533 				}
534 				Unlock(k->lock);
535 
536 				if (changed || s == NULL)
537 				{
538 					// Setting has been changed or disconnected
539 					Disconnect(s);
540 					ReleaseSock(s);
541 					s = NULL;
542 					goto WAIT_FOR_ENABLE;
543 				}
544 				else
545 				{
546 					if (k->Halt)
547 					{
548 						// Stop
549 						Disconnect(s);
550 						ReleaseSock(s);
551 						return;
552 					}
553 				}
554 			}
555 		}
556 	}
557 }
558 
559 // Stop the KEEP
StopKeep(KEEP * k)560 void StopKeep(KEEP *k)
561 {
562 	// Validate arguments
563 	if (k == NULL)
564 	{
565 		return;
566 	}
567 
568 	k->Halt = true;
569 	Set(k->HaltEvent);
570 	Cancel(k->Cancel);
571 
572 	WaitThread(k->Thread, INFINITE);
573 	ReleaseThread(k->Thread);
574 	DeleteLock(k->lock);
575 
576 	ReleaseCancel(k->Cancel);
577 	ReleaseEvent(k->HaltEvent);
578 
579 	Free(k);
580 }
581 
582 // Start the KEEP
StartKeep()583 KEEP *StartKeep()
584 {
585 	KEEP *k = ZeroMalloc(sizeof(KEEP));
586 
587 	k->lock = NewLock();
588 	k->HaltEvent = NewEvent();
589 	k->Cancel = NewCancel();
590 
591 	// Thread start
592 	k->Thread = NewThread(KeepThread, k);
593 
594 	return k;
595 }
596 
597 // Copy the client authentication data
CopyClientAuth(CLIENT_AUTH * a)598 CLIENT_AUTH *CopyClientAuth(CLIENT_AUTH *a)
599 {
600 	CLIENT_AUTH *ret;
601 	// Validate arguments
602 	if (a == NULL)
603 	{
604 		return NULL;
605 	}
606 
607 	ret = ZeroMallocEx(sizeof(CLIENT_AUTH), true);
608 
609 	ret->AuthType = a->AuthType;
610 	StrCpy(ret->Username, sizeof(ret->Username), a->Username);
611 
612 	switch (a->AuthType)
613 	{
614 	case CLIENT_AUTHTYPE_ANONYMOUS:
615 		// Anonymous authentication
616 		break;
617 
618 	case CLIENT_AUTHTYPE_PASSWORD:
619 		// Password authentication
620 		Copy(ret->HashedPassword, a->HashedPassword, SHA1_SIZE);
621 		break;
622 
623 	case CLIENT_AUTHTYPE_PLAIN_PASSWORD:
624 		// Plaintext password authentication
625 		StrCpy(ret->PlainPassword, sizeof(ret->PlainPassword), a->PlainPassword);
626 		break;
627 
628 	case CLIENT_AUTHTYPE_CERT:
629 		// Certificate authentication
630 		ret->ClientX = CloneX(a->ClientX);
631 		ret->ClientK = CloneK(a->ClientK);
632 		break;
633 
634 	case CLIENT_AUTHTYPE_SECURE:
635 		// Secure device authentication
636 		StrCpy(ret->SecurePublicCertName, sizeof(ret->SecurePublicCertName), a->SecurePublicCertName);
637 		StrCpy(ret->SecurePrivateKeyName, sizeof(ret->SecurePrivateKeyName), a->SecurePrivateKeyName);
638 		break;
639 	}
640 
641 	return ret;
642 }
643 
644 // Write data to the transmit FIFO (automatic encryption)
WriteSendFifo(SESSION * s,TCPSOCK * ts,void * data,UINT size)645 void WriteSendFifo(SESSION *s, TCPSOCK *ts, void *data, UINT size)
646 {
647 	// Validate arguments
648 	if (s == NULL || ts == NULL || data == NULL)
649 	{
650 		return;
651 	}
652 
653 	if (s->UseFastRC4)
654 	{
655 		Encrypt(ts->SendKey, data, data, size);
656 	}
657 
658 	WriteFifo(ts->SendFifo, data, size);
659 }
660 
661 // Write data to the reception FIFO (automatic deccyption)
WriteRecvFifo(SESSION * s,TCPSOCK * ts,void * data,UINT size)662 void WriteRecvFifo(SESSION *s, TCPSOCK *ts, void *data, UINT size)
663 {
664 	// Validate arguments
665 	if (s == NULL || ts == NULL || data == NULL)
666 	{
667 		return;
668 	}
669 
670 	if (s->UseFastRC4)
671 	{
672 		Encrypt(ts->RecvKey, data, data, size);
673 	}
674 
675 	WriteFifo(ts->RecvFifo, data, size);
676 }
677 
678 // TCP socket receive
TcpSockRecv(SESSION * s,TCPSOCK * ts,void * data,UINT size)679 UINT TcpSockRecv(SESSION *s, TCPSOCK *ts, void *data, UINT size)
680 {
681 	// Receive
682 	return Recv(ts->Sock, data, size, s->UseSSLDataEncryption);
683 }
684 
685 // TCP socket send
TcpSockSend(SESSION * s,TCPSOCK * ts,void * data,UINT size)686 UINT TcpSockSend(SESSION *s, TCPSOCK *ts, void *data, UINT size)
687 {
688 	// Transmission
689 	return Send(ts->Sock, data, size, s->UseSSLDataEncryption);
690 }
691 
692 // Send the data as UDP packet
SendDataWithUDP(SOCK * s,CONNECTION * c)693 void SendDataWithUDP(SOCK *s, CONNECTION *c)
694 {
695 	UCHAR *buf;
696 	BUF *b;
697 	UINT64 dummy_64 = 0;
698 	UCHAR dummy_buf[16];
699 	UINT64 now = Tick64();
700 	UINT ret;
701 	bool force_flag = false;
702 	bool packet_sent = false;
703 	// Validate arguments
704 	if (s == NULL || c == NULL)
705 	{
706 		return;
707 	}
708 
709 	// Allocate the temporary buffer in heap
710 	if (c->RecvBuf == NULL)
711 	{
712 		c->RecvBuf = Malloc(RECV_BUF_SIZE);
713 	}
714 	buf = c->RecvBuf;
715 
716 	if (c->Udp->NextKeepAliveTime == 0 || c->Udp->NextKeepAliveTime <= now)
717 	{
718 		force_flag = true;
719 	}
720 
721 	// Creating a buffer
722 	while ((c->SendBlocks->num_item > 0) || force_flag)
723 	{
724 		UINT *key32;
725 		UINT64 *seq;
726 		char *sign;
727 
728 		force_flag = false;
729 
730 		// Assemble a buffer from the current queue
731 		b = NewBuf();
732 
733 		// Keep an area for packet header (16 bytes)
734 		WriteBuf(b, dummy_buf, sizeof(dummy_buf));
735 
736 		// Pack the packets in transmission queue
737 		while (true)
738 		{
739 			BLOCK *block;
740 
741 			if (b->Size > UDP_BUF_SIZE)
742 			{
743 				break;
744 			}
745 			block = GetNext(c->SendBlocks);
746 			if (block == NULL)
747 			{
748 				break;
749 			}
750 
751 			if (block->Size != 0)
752 			{
753 				WriteBufInt(b, block->Size);
754 				WriteBuf(b, block->Buf, block->Size);
755 
756 				c->Session->TotalSendSize += (UINT64)block->SizeofData;
757 				c->Session->TotalSendSizeReal += (UINT64)block->Size;
758 			}
759 
760 			FreeBlock(block);
761 			break;
762 		}
763 
764 		// Write sequence number and session key
765 		sign = (char *)(((UCHAR *)b->Buf));
766 		key32 = (UINT *)(((UCHAR *)b->Buf + 4));
767 		seq = (UINT64 *)(((UCHAR *)b->Buf + 8));
768 		Copy(sign, SE_UDP_SIGN, 4);
769 		*key32 = Endian32(c->Session->SessionKey32);
770 		*seq = Endian64(c->Udp->Seq++); // Increment the sequence number
771 
772 //		InsertQueue(c->Udp->BufferQueue, b);
773 
774 		packet_sent = true;
775 /*	}
776 
777 	// Send a buffer
778 	while (c->Udp->BufferQueue->num_item != 0)
779 	{
780 		FIFO *f = c->Udp->BufferQueue->fifo;
781 		BUF **pb = (BUF**)(((UCHAR *)f->p) + f->pos);
782 		BUF *b = *pb;
783 
784 */		ret = SendTo(s, &c->Udp->ip, c->Udp->port, b->Buf, b->Size);
785 		if (ret == SOCK_LATER)
786 		{
787 			// Blocking
788 			Debug(".");
789 //			break;
790 		}
791 		if (ret != b->Size)
792 		{
793 			if (s->IgnoreSendErr == false)
794 			{
795 				// Error
796 				Debug("******* SendTo Error !!!\n");
797 			}
798 		}
799 
800 		// Memory release
801 		FreeBuf(b);
802 //		GetNext(c->Udp->BufferQueue);
803 	}
804 
805 	if (packet_sent)
806 	{
807 		// KeepAlive time update
808 		c->Udp->NextKeepAliveTime = now + (UINT64)GenNextKeepAliveSpan(c);
809 	}
810 }
811 
812 // Write the data of the UDP packet to the connection
PutUDPPacketData(CONNECTION * c,void * data,UINT size)813 void PutUDPPacketData(CONNECTION *c, void *data, UINT size)
814 {
815 	BUF *b;
816 	char sign[4];
817 	// Validate arguments
818 	if (c == NULL || data == NULL)
819 	{
820 		return;
821 	}
822 
823 	// Examine the protocol
824 	if (c->Protocol != CONNECTION_UDP)
825 	{
826 		// UDP protocol is not used
827 		return;
828 	}
829 
830 	// Buffer configuration
831 	b = NewBuf();
832 	WriteBuf(b, data, size);
833 
834 	SeekBuf(b, 0, 0);
835 	ReadBuf(b, sign, 4);
836 
837 	// Signature confirmation
838 	if (Cmp(sign, SE_UDP_SIGN, 4) == 0)
839 	{
840 		UINT key32;
841 
842 		// Session key number
843 		key32 = ReadBufInt(b);
844 
845 		if (c->Session->SessionKey32 == key32)
846 		{
847 			UINT64 seq;
848 
849 			// Read the Sequence number
850 			ReadBuf(b, &seq, sizeof(seq));
851 			seq = Endian64(seq);
852 
853 			if ((UINT)(seq - c->Udp->RecvSeq - (UINT64)1))
854 			{
855 				//Debug("** UDP Seq Lost %u\n", (UINT)(seq - c->Udp->RecvSeq - (UINT64)1));
856 			}
857 			c->Udp->RecvSeq = seq;
858 
859 			//Debug("SEQ: %I32u\n", seq);
860 
861 			while (true)
862 			{
863 				UINT size;
864 
865 				size = ReadBufInt(b);
866 				if (size == 0)
867 				{
868 					break;
869 				}
870 				else if (size <= MAX_PACKET_SIZE)
871 				{
872 					void *tmp;
873 					BLOCK *block;
874 
875 					tmp = Malloc(size);
876 					if (ReadBuf(b, tmp, size) != size)
877 					{
878 						Free(tmp);
879 						break;
880 					}
881 
882 					// Block configuration
883 					block = NewBlock(tmp, size, 0);
884 
885 					// Insert Block
886 					InsertReveicedBlockToQueue(c, block, false);
887 				}
888 			}
889 
890 			// Update the last communication time
891 			c->Session->LastCommTime = Tick64();
892 		}
893 		else
894 		{
895 			Debug("Invalid SessionKey: 0x%X\n", key32);
896 		}
897 	}
898 
899 	FreeBuf(b);
900 }
901 
902 // Add a block to the receive queue
InsertReveicedBlockToQueue(CONNECTION * c,BLOCK * block,bool no_lock)903 void InsertReveicedBlockToQueue(CONNECTION *c, BLOCK *block, bool no_lock)
904 {
905 	SESSION *s;
906 	// Validate arguments
907 	if (c == NULL || block == NULL)
908 	{
909 		return;
910 	}
911 
912 	s = c->Session;
913 
914 	if (c->Protocol == CONNECTION_TCP)
915 	{
916 		s->TotalRecvSizeReal += block->SizeofData;
917 		s->TotalRecvSize += block->Size;
918 	}
919 
920 	if (no_lock == false)
921 	{
922 		LockQueue(c->ReceivedBlocks);
923 	}
924 
925 	if (c->ReceivedBlocks->num_item < MAX_STORED_QUEUE_NUM)
926 	{
927 		InsertQueue(c->ReceivedBlocks, block);
928 	}
929 	else
930 	{
931 		FreeBlock(block);
932 	}
933 
934 	if (no_lock == false)
935 	{
936 		UnlockQueue(c->ReceivedBlocks);
937 	}
938 }
939 
940 // Generate the interval to the next Keep-Alive packet
941 // (This should be a random number for the network load reduction)
GenNextKeepAliveSpan(CONNECTION * c)942 UINT GenNextKeepAliveSpan(CONNECTION *c)
943 {
944 	UINT a, b;
945 	// Validate arguments
946 	if (c == NULL)
947 	{
948 		return INFINITE;
949 	}
950 
951 	a = c->Session->Timeout;
952 	b = rand() % (a / 2);
953 	b = MAX(b, a / 5);
954 
955 	return b;
956 }
957 
958 // send a Keep-Alive packet
SendKeepAlive(CONNECTION * c,TCPSOCK * ts)959 void SendKeepAlive(CONNECTION *c, TCPSOCK *ts)
960 {
961 	UINT size, i, num;
962 	UINT size_be;
963 	SESSION *s;
964 	UCHAR *buf;
965 	bool insert_natt_port = false;
966 	// Validate arguments
967 	if (c == NULL || ts == NULL)
968 	{
969 		return;
970 	}
971 
972 	s = c->Session;
973 
974 	size = rand() % MAX_KEEPALIVE_SIZE;
975 	num = KEEP_ALIVE_MAGIC;
976 
977 	if (s != NULL && s->UseUdpAcceleration && s->UdpAccel != NULL)
978 	{
979 		if (s->UdpAccel->MyPortByNatTServer != 0)
980 		{
981 			size = MAX(size, (StrLen(UDP_NAT_T_PORT_SIGNATURE_IN_KEEP_ALIVE) + sizeof(USHORT)));
982 
983 			insert_natt_port = true;
984 		}
985 	}
986 
987 	buf = MallocFast(size);
988 
989 	for (i = 0;i < size;i++)
990 	{
991 		buf[i] = rand();
992 	}
993 
994 	if (insert_natt_port)
995 	{
996 		USHORT myport = Endian16((USHORT)s->UdpAccel->MyPortByNatTServer);
997 
998 		Copy(buf, UDP_NAT_T_PORT_SIGNATURE_IN_KEEP_ALIVE, StrLen(UDP_NAT_T_PORT_SIGNATURE_IN_KEEP_ALIVE));
999 		Copy(buf + StrLen(UDP_NAT_T_PORT_SIGNATURE_IN_KEEP_ALIVE), &myport, sizeof(USHORT));
1000 	}
1001 
1002 	num = Endian32(num);
1003 	size_be = Endian32(size);
1004 	WriteSendFifo(c->Session, ts, &num, sizeof(UINT));
1005 	WriteSendFifo(c->Session, ts, &size_be, sizeof(UINT));
1006 	WriteSendFifo(c->Session, ts, buf, size);
1007 
1008 	c->Session->TotalSendSize += sizeof(UINT) * 2 + size;
1009 	c->Session->TotalSendSizeReal += sizeof(UINT) * 2 + size;
1010 
1011 	Free(buf);
1012 }
1013 
1014 // Transmission of block
ConnectionSend(CONNECTION * c,UINT64 now)1015 void ConnectionSend(CONNECTION *c, UINT64 now)
1016 {
1017 	UINT i, num;
1018 	UINT min_count;
1019 	UINT64 max_recv_tick;
1020 	TCPSOCK **tcpsocks;
1021 	UINT size;
1022 	SESSION *s;
1023 	HUB *hub = NULL;
1024 	bool use_qos = false;
1025 	// Validate arguments
1026 	if (c == NULL)
1027 	{
1028 		return;
1029 	}
1030 
1031 	s = c->Session;
1032 
1033 	if (s != NULL)
1034 	{
1035 		hub = s->Hub;
1036 		use_qos = s->QoS;
1037 	}
1038 
1039 	// Protocol
1040 	if (c->Protocol == CONNECTION_TCP)
1041 	{
1042 		// TCP
1043 		TCP *tcp = c->Tcp;
1044 		TCPSOCK *ts;
1045 		TCPSOCK *ts_hp;
1046 		UINT num_available;
1047 		bool is_rudp = false;
1048 		UINT tcp_queue_size = 0;
1049 		int tcp_queue_size_diff = 0;
1050 		LockList(tcp->TcpSockList);
1051 		{
1052 			num = LIST_NUM(tcp->TcpSockList);
1053 			tcpsocks = ToArrayEx(tcp->TcpSockList, true);
1054 		}
1055 		UnlockList(tcp->TcpSockList);
1056 
1057 		if (s != NULL)
1058 		{
1059 			is_rudp = s->IsRUDPSession;
1060 		}
1061 
1062 		// Select the socket that will be used to send
1063 		// Select a socket which have least delay count
1064 		min_count = INFINITE;
1065 		max_recv_tick = 0;
1066 		ts = NULL;
1067 		ts_hp = NULL;
1068 
1069 		num_available = 0;
1070 
1071 		if (c->IsInProc == false)
1072 		{
1073 			for (i = 0;i < num;i++)
1074 			{
1075 				TCPSOCK *tcpsock = tcpsocks[i];
1076 				if (s != NULL && tcpsock->Sock->Connected && tcpsock->Sock->AsyncMode &&
1077 					IS_SEND_TCP_SOCK(tcpsock))
1078 				{
1079 					// Processing of KeepAlive
1080 					if (now >= tcpsock->NextKeepAliveTime || tcpsock->NextKeepAliveTime == 0 ||
1081 						(s->UseUdpAcceleration && s->UdpAccel != NULL && s->UdpAccel->MyPortByNatTServerChanged))
1082 					{
1083 						// Send the KeepAlive
1084 						SendKeepAlive(c, tcpsock);
1085 						tcpsock->NextKeepAliveTime = now + (UINT64)GenNextKeepAliveSpan(c);
1086 
1087 						if (s->UseUdpAcceleration && s->UdpAccel != NULL)
1088 						{
1089 							s->UdpAccel->MyPortByNatTServerChanged = false;
1090 						}
1091 					}
1092 
1093 					// Count the number of available sockets to send
1094 					num_available++;
1095 
1096 					ts_hp = tcpsock;
1097 				}
1098 			}
1099 		}
1100 
1101 		for (i = 0;i < num;i++)
1102 		{
1103 			TCPSOCK *tcpsock = tcpsocks[i];
1104 			if (tcpsock->Sock->Connected && tcpsock->Sock->AsyncMode &&
1105 				IS_SEND_TCP_SOCK(tcpsock))
1106 			{
1107 				// Selection of the socket
1108 				bool b = false;
1109 
1110 				if (use_qos == false)
1111 				{
1112 					b = true;
1113 				}
1114 				else if (num_available < 2)
1115 				{
1116 					b = true;
1117 				}
1118 				else if (tcpsock != ts_hp)
1119 				{
1120 					b = true;
1121 				}
1122 
1123 				if (b)
1124 				{
1125 					if (is_rudp == false)
1126 					{
1127 						// Use a socket which have minimum delay occurrences in the case of such as a TCP socket
1128 						if (tcpsock->LateCount <= min_count)
1129 						{
1130 							min_count = tcpsock->LateCount;
1131 							ts = tcpsock;
1132 						}
1133 					}
1134 					else
1135 					{
1136 						// Use socket which have the largest last received time in the case of R-UDP socket
1137 						if (tcpsock->LastRecvTime >= max_recv_tick)
1138 						{
1139 							max_recv_tick = tcpsock->LastRecvTime;
1140 							ts = tcpsock;
1141 						}
1142 					}
1143 				}
1144 			}
1145 
1146 			tcp_queue_size += tcpsock->SendFifo->size;
1147 		}
1148 
1149 		tcp_queue_size_diff = ((int)tcp_queue_size) - ((int)c->LastTcpQueueSize);
1150 
1151 		CedarAddCurrentTcpQueueSize(c->Cedar, tcp_queue_size_diff);
1152 
1153 		c->LastTcpQueueSize = tcp_queue_size;
1154 
1155 		if (ts_hp == NULL)
1156 		{
1157 			ts_hp = ts;
1158 		}
1159 
1160 		if (use_qos == false)
1161 		{
1162 			ts_hp = ts;
1163 		}
1164 
1165 		if (ts == NULL || ts_hp == NULL)
1166 		{
1167 			// The socket available to send doesn't currently exist
1168 		}
1169 		else
1170 		{
1171 			TCPSOCK *tss;
1172 			UINT j;
1173 			QUEUE *q;
1174 
1175 			if (s != NULL && s->UdpAccel != NULL)
1176 			{
1177 				UdpAccelSetTick(s->UdpAccel, now);
1178 			}
1179 
1180 			for (j = 0;j < 2;j++)
1181 			{
1182 				if (j == 0)
1183 				{
1184 					q = c->SendBlocks2;
1185 					tss = ts_hp;
1186 				}
1187 				else
1188 				{
1189 					q = c->SendBlocks;
1190 					tss = ts;
1191 				}
1192 				// I reserve the data to send on the selected socket ts
1193 				if (q->num_item != 0)
1194 				{
1195 					UINT num_data;
1196 					BLOCK *b;
1197 					UINT size_quota_v1 = MAX_SEND_SOCKET_QUEUE_SIZE / s->MaxConnection;
1198 					UINT size_quota_v2 = MIN_SEND_SOCKET_QUEUE_SIZE;
1199 					UINT size_quota = MAX(size_quota_v1, size_quota_v2);
1200 
1201 					if (tss->SendFifo->size >= size_quota)
1202 					{
1203 						// The size of the socket send queue is exceeded
1204 						// Unable to send
1205 						while (b = GetNext(q))
1206 						{
1207 							if (b != NULL)
1208 							{
1209 								c->CurrentSendQueueSize -= b->Size;
1210 								FreeBlock(b);
1211 							}
1212 						}
1213 					}
1214 					else
1215 					{
1216 						if (c->IsInProc == false)
1217 						{
1218 							if (s->UseUdpAcceleration && s->UdpAccel != NULL && UdpAccelIsSendReady(s->UdpAccel, true))
1219 							{
1220 								// UDP acceleration mode
1221 								while (b = GetNext(q))
1222 								{
1223 									UdpAccelSendBlock(s->UdpAccel, b);
1224 
1225 									s->TotalSendSize += b->Size;
1226 									s->TotalSendSizeReal += b->Size;
1227 
1228 									c->CurrentSendQueueSize -= b->Size;
1229 
1230 									FreeBlock(b);
1231 								}
1232 							}
1233 							else if (s->IsRUDPSession && s->EnableBulkOnRUDP && ts->Sock != NULL && ts->Sock->BulkSendTube != NULL)
1234 							{
1235 								// R-UDP bulk transfer
1236 								TUBE *t = ts->Sock->BulkSendTube;
1237 								bool flush = false;
1238 								TCP_PAIR_HEADER h;
1239 
1240 								Zero(&h, sizeof(h));
1241 								h.EnableHMac = s->EnableHMacOnBulkOfRUDP;
1242 
1243 								while (b = GetNext(q))
1244 								{
1245 									if (b->Compressed == false)
1246 									{
1247 										// Uncompressed
1248 										TubeSendEx(t, b->Buf, b->Size, &h, true);
1249 
1250 										s->TotalSendSize += b->Size;
1251 										s->TotalSendSizeReal += b->Size;
1252 
1253 										c->CurrentSendQueueSize -= b->Size;
1254 									}
1255 									else
1256 									{
1257 										// Compressed
1258 										UCHAR *new_buf = Malloc(b->Size + sizeof(UINT64));
1259 
1260 										WRITE_UINT64(new_buf, CONNECTION_BULK_COMPRESS_SIGNATURE);
1261 
1262 										Copy(new_buf + sizeof(UINT64), b->Buf, b->Size);
1263 
1264 										TubeSendEx(t, new_buf, b->Size + sizeof(UINT64), &h, true);
1265 
1266 										s->TotalSendSize += b->SizeofData;
1267 										s->TotalSendSizeReal += b->Size;
1268 
1269 										c->CurrentSendQueueSize -= b->Size;
1270 
1271 										Free(new_buf);
1272 									}
1273 
1274 									FreeBlock(b);
1275 
1276 									flush = true;
1277 								}
1278 
1279 								if (flush)
1280 								{
1281 									TubeFlush(t);
1282 								}
1283 							}
1284 							else
1285 							{
1286 								// TCP/IP socket
1287 								bool update_keepalive_timer = false;
1288 								// Number of data
1289 								num_data = Endian32(q->num_item);
1290 								PROBE_DATA2("WriteSendFifo num", &num_data, sizeof(UINT));
1291 								WriteSendFifo(s, tss, &num_data, sizeof(UINT));
1292 
1293 								s->TotalSendSize += sizeof(UINT);
1294 								s->TotalSendSizeReal += sizeof(UINT);
1295 
1296 								while (b = GetNext(q))
1297 								{
1298 									// Size data
1299 									UINT size_data;
1300 									size_data = Endian32(b->Size);
1301 									PROBE_DATA2("WriteSendFifo size", &size_data, sizeof(UINT));
1302 									WriteSendFifo(s, tss, &size_data, sizeof(UINT));
1303 
1304 									c->CurrentSendQueueSize -= b->Size;
1305 
1306 									s->TotalSendSize += sizeof(UINT);
1307 									s->TotalSendSizeReal += sizeof(UINT);
1308 
1309 									// Data body
1310 									PROBE_DATA2("WriteSendFifo data", b->Buf, b->Size);
1311 									WriteSendFifo(s, tss, b->Buf, b->Size);
1312 
1313 									s->TotalSendSize += b->SizeofData;
1314 									s->TotalSendSizeReal += b->Size;
1315 
1316 									update_keepalive_timer = true;
1317 
1318 									// Block release
1319 									FreeBlock(b);
1320 								}
1321 
1322 								if (s->UseUdpAcceleration && s->UdpAccel != NULL && UdpAccelIsSendReady(s->UdpAccel, false))
1323 								{
1324 									update_keepalive_timer = false;
1325 								}
1326 
1327 								if (update_keepalive_timer)
1328 								{
1329 									// Increase the KeepAlive timer
1330 									tss->NextKeepAliveTime = now + (UINT64)GenNextKeepAliveSpan(c);
1331 								}
1332 							}
1333 						}
1334 						else
1335 						{
1336 							bool flush = false;
1337 							// In-process socket
1338 							while (b = GetNext(q))
1339 							{
1340 								TubeSendEx(ts->Sock->SendTube, b->Buf, b->Size, NULL, true);
1341 								flush = true;
1342 
1343 								s->TotalSendSize += b->Size;
1344 								s->TotalSendSizeReal += b->Size;
1345 
1346 								c->CurrentSendQueueSize -= b->Size;
1347 
1348 								FreeBlock(b);
1349 							}
1350 
1351 							if (flush)
1352 							{
1353 								TubeFlush(ts->Sock->SendTube);
1354 							}
1355 						}
1356 					}
1357 				}
1358 			}
1359 		}
1360 
1361 		// Send the reserved data to send registered in each socket now
1362 		if (c->IsInProc == false)
1363 		{
1364 			for (i = 0;i < num;i++)
1365 			{
1366 				ts = tcpsocks[i];
1367 
1368 SEND_START:
1369 				if (ts->Sock->Connected == false)
1370 				{
1371 					s->LastTryAddConnectTime = Tick64();
1372 					// Communication is disconnected
1373 					LockList(tcp->TcpSockList);
1374 					{
1375 						// Remove the socket from socket list
1376 						Delete(tcp->TcpSockList, ts);
1377 						// Release of TCPSOCK
1378 						FreeTcpSock(ts);
1379 						// Decrement the count
1380 						Dec(c->CurrentNumConnection);
1381 						Debug("--- TCP Connection Decremented: %u (%s Line %u)\n", Count(c->CurrentNumConnection), __FILE__, __LINE__);
1382 						Debug("LIST_NUM(tcp->TcpSockList): %u\n", LIST_NUM(tcp->TcpSockList));
1383 					}
1384 					UnlockList(tcp->TcpSockList);
1385 
1386 					continue;
1387 				}
1388 
1389 				// Get Fifo size
1390 				if (ts->SendFifo->size != 0)
1391 				{
1392 					UCHAR *buf;
1393 					UINT want_send_size;
1394 					// Send only if the data to send exists by 1 byte or more
1395 					// Get the pointer to the buffer
1396 					buf = (UCHAR *)ts->SendFifo->p + ts->SendFifo->pos;
1397 					want_send_size = ts->SendFifo->size;
1398 
1399 					PROBE_DATA2("TcpSockSend", buf, want_send_size);
1400 					size = TcpSockSend(s, ts, buf, want_send_size);
1401 
1402 					if (size == 0)
1403 					{
1404 						// Disconnected
1405 						continue;
1406 					}
1407 					else if (size == SOCK_LATER)
1408 					{
1409 						// Packet is jammed
1410 						ts->LateCount++; // Increment of the delay counter
1411 						PROBE_STR("ts->LateCount++;");
1412 					}
1413 					else
1414 					{
1415 						// Packet is sent only by 'size'
1416 						// Advance FIFO
1417 						ReadFifo(ts->SendFifo, NULL, size);
1418 						if (size < want_send_size)
1419 						{
1420 							// Fail to transmit all of the data that has been scheduled
1421 #ifdef	USE_PROBE
1422 							{
1423 								char tmp[MAX_SIZE];
1424 
1425 								snprintf(tmp, sizeof(tmp), "size < want_send_size: %u < %u",
1426 									size, want_send_size);
1427 
1428 								PROBE_STR(tmp);
1429 							}
1430 #endif	// USE_PROBE
1431 						}
1432 						else
1433 						{
1434 							// Because sending all the packets is completed
1435 							// (The queue is exhausted), reset the delay counter
1436 							ts->LateCount = 0;
1437 
1438 							PROBE_STR("TcpSockSend All Completed");
1439 						}
1440 						// Updated the last communication date and time
1441 						UPDATE_LAST_COMM_TIME(c->Session->LastCommTime, now);
1442 
1443 						goto SEND_START;
1444 					}
1445 				}
1446 			}
1447 		}
1448 
1449 		Free(tcpsocks);
1450 	}
1451 	else if (c->Protocol == CONNECTION_UDP)
1452 	{
1453 		// UDP
1454 		UDP *udp = c->Udp;
1455 		SOCK *sock = NULL;
1456 
1457 		Lock(c->lock);
1458 		{
1459 			sock = udp->s;
1460 			if (sock != NULL)
1461 			{
1462 				AddRef(sock->ref);
1463 			}
1464 		}
1465 		Unlock(c->lock);
1466 
1467 		if (sock != NULL)
1468 		{
1469 			// Send with UDP
1470 
1471 			// KeepAlive sending
1472 			if ((udp->NextKeepAliveTime == 0 || udp->NextKeepAliveTime <= now) ||
1473 				(c->SendBlocks->num_item != 0) || (udp->BufferQueue->num_item != 0))
1474 			{
1475 				// Send the current queue with UDP
1476 				SendDataWithUDP(sock, c);
1477 			}
1478 		}
1479 
1480 		if (sock != NULL)
1481 		{
1482 			ReleaseSock(sock);
1483 		}
1484 	}
1485 	else if (c->Protocol == CONNECTION_HUB_SECURE_NAT)
1486 	{
1487 		// SecureNAT session
1488 		SNAT *snat = s->SecureNAT;
1489 		VH *v = snat->Nat->Virtual;
1490 		BLOCK *block;
1491 		UINT num_packet = 0;
1492 
1493 		if (hub != NULL)
1494 		{
1495 			NatSetHubOption(v, hub->Option);
1496 		}
1497 
1498 		while (block = GetNext(c->SendBlocks))
1499 		{
1500 			num_packet++;
1501 			c->CurrentSendQueueSize -= block->Size;
1502 			VirtualPutPacket(v, block->Buf, block->Size);
1503 			Free(block);
1504 		}
1505 
1506 		if (num_packet != 0)
1507 		{
1508 			VirtualPutPacket(v, NULL, 0);
1509 		}
1510 	}
1511 	else if (c->Protocol == CONNECTION_HUB_LAYER3)
1512 	{
1513 		// Layer-3 session
1514 		L3IF *f = s->L3If;
1515 		BLOCK *block;
1516 		UINT num_packet = 0;
1517 
1518 		while (block = GetNext(c->SendBlocks))
1519 		{
1520 			num_packet++;
1521 			c->CurrentSendQueueSize -= block->Size;
1522 			L3PutPacket(f, block->Buf, block->Size);
1523 			Free(block);
1524 		}
1525 
1526 		if (num_packet != 0)
1527 		{
1528 			L3PutPacket(f, NULL, 0);
1529 		}
1530 	}
1531 	else if (c->Protocol == CONNECTION_HUB_LINK_SERVER)
1532 	{
1533 		// HUB Link
1534 		LINK *k = (LINK *)s->Link;
1535 
1536 		if (k != NULL)
1537 		{
1538 			UINT num_blocks = 0;
1539 			LockQueue(k->SendPacketQueue);
1540 			{
1541 				BLOCK *block;
1542 
1543 				// Transfer the packet queue to the client thread
1544 				while (block = GetNext(c->SendBlocks))
1545 				{
1546 					c->CurrentSendQueueSize -= block->Size;
1547 
1548 					if (k->SendPacketQueue->num_item >= MAX_STORED_QUEUE_NUM)
1549 					{
1550 						FreeBlock(block);
1551 					}
1552 					else
1553 					{
1554 						num_blocks++;
1555 						k->CurrentSendPacketQueueSize += block->Size;
1556 						InsertQueue(k->SendPacketQueue, block);
1557 					}
1558 				}
1559 			}
1560 			UnlockQueue(k->SendPacketQueue);
1561 
1562 			if (num_blocks != 0)
1563 			{
1564 				// Issue of cancellation
1565 				Cancel(k->ClientSession->Cancel1);
1566 			}
1567 		}
1568 	}
1569 	else if (c->Protocol == CONNECTION_HUB_BRIDGE)
1570 	{
1571 		// Local bridge
1572 		BRIDGE *b = s->Bridge;
1573 
1574 		if (b != NULL)
1575 		{
1576 			if (b->Active)
1577 			{
1578 				BLOCK *block;
1579 				UINT num_packet = c->SendBlocks->num_item; // Packet count
1580 
1581 				if (num_packet != 0)
1582 				{
1583 					// Packet data array
1584 					void **datas = MallocFast(sizeof(void *) * num_packet);
1585 					UINT *sizes = MallocFast(sizeof(UINT) * num_packet);
1586 					UINT i;
1587 
1588 					i = 0;
1589 					while (block = GetNext(c->SendBlocks))
1590 					{
1591 						if (hub != NULL && hub->Option != NULL && hub->Option->DisableUdpFilterForLocalBridgeNic == false &&
1592 							b->Eth != NULL && IsDhcpPacketForSpecificMac(block->Buf, block->Size, b->Eth->MacAddress))
1593 						{
1594 							// DHCP Packet is filtered
1595 							datas[i] = NULL;
1596 							sizes[i] = 0;
1597 
1598 							Free(block->Buf);
1599 						}
1600 						else
1601 						{
1602 							datas[i] = block->Buf;
1603 							sizes[i] = block->Size;
1604 
1605 							if (block->Size > 1514)
1606 							{
1607 								NormalizeEthMtu(b, c, block->Size);
1608 							}
1609 						}
1610 
1611 						c->CurrentSendQueueSize -= block->Size;
1612 						Free(block);
1613 						i++;
1614 					}
1615 
1616 					// Write the packet
1617 					EthPutPackets(b->Eth, num_packet, datas, sizes);
1618 
1619 					Free(datas);
1620 					Free(sizes);
1621 				}
1622 			}
1623 		}
1624 	}
1625 }
1626 
1627 // Reception of the block
ConnectionReceive(CONNECTION * c,CANCEL * c1,CANCEL * c2)1628 void ConnectionReceive(CONNECTION *c, CANCEL *c1, CANCEL *c2)
1629 {
1630 	UINT i, num;
1631 	SOCKSET set;
1632 	SESSION *s;
1633 	TCPSOCK **tcpsocks;
1634 	UCHAR *buf;
1635 	UINT size;
1636 	UINT time;
1637 	UINT num_delayed = 0;
1638 	bool no_spinlock_for_delay = false;
1639 	UINT64 now = Tick64();
1640 	HUB *hub = NULL;
1641 	// Validate arguments
1642 	if (c == NULL)
1643 	{
1644 		return;
1645 	}
1646 
1647 	PROBE_STR("ConnectionReceive");
1648 
1649 	s = c->Session;
1650 
1651 	if (s != NULL)
1652 	{
1653 		hub = s->Hub;
1654 	}
1655 
1656 	if (hub != NULL)
1657 	{
1658 		no_spinlock_for_delay = hub->Option->NoSpinLockForPacketDelay;
1659 	}
1660 
1661 	if (c->RecvBuf == NULL)
1662 	{
1663 		c->RecvBuf = Malloc(RECV_BUF_SIZE);
1664 	}
1665 	buf = c->RecvBuf;
1666 
1667 	// Protocol
1668 	if (c->Protocol == CONNECTION_TCP)
1669 	{
1670 		// TCP
1671 		TCP *tcp = c->Tcp;
1672 		UINT next_delay_packet_diff = 0;
1673 		UINT current_recv_fifo_size = 0;
1674 		int recv_fifo_size_middle_update = 0;
1675 
1676 		// Disconnect if disconnection interval is specified
1677 		if (s->ServerMode == false)
1678 		{
1679 			if (s->ClientOption->ConnectionDisconnectSpan != 0)
1680 			{
1681 				LockList(tcp->TcpSockList);
1682 				{
1683 					UINT i;
1684 					for (i = 0;i < LIST_NUM(tcp->TcpSockList);i++)
1685 					{
1686 						TCPSOCK *ts = LIST_DATA(tcp->TcpSockList, i);
1687 						if (ts->DisconnectTick != 0 &&
1688 							ts->DisconnectTick <= now)
1689 						{
1690 							Debug("ts->DisconnectTick <= now\n");
1691 							Disconnect(ts->Sock);
1692 						}
1693 					}
1694 				}
1695 				UnlockList(tcp->TcpSockList);
1696 			}
1697 		}
1698 
1699 		if (s->HalfConnection && (s->ServerMode == false))
1700 		{
1701 			// Check the direction of the current TCP connections.
1702 			//  Disconnect one if the number of connections reaches
1703 			// the limit and has only one direction
1704 			LockList(tcp->TcpSockList);
1705 			{
1706 				UINT i, num;
1707 				UINT c2s, s2c;
1708 				c2s = s2c = 0;
1709 				num = LIST_NUM(tcp->TcpSockList);
1710 				if (num >= s->MaxConnection)
1711 				{
1712 					TCPSOCK *ts = NULL;
1713 					for (i = 0;i < num;i++)
1714 					{
1715 						ts = LIST_DATA(tcp->TcpSockList, i);
1716 						if (ts->Direction == TCP_SERVER_TO_CLIENT)
1717 						{
1718 							s2c++;
1719 						}
1720 						else
1721 						{
1722 							c2s++;
1723 						}
1724 					}
1725 					if (ts != NULL)
1726 					{
1727 						if (s2c == 0 || c2s == 0)
1728 						{
1729 							// Disconnect the last socket
1730 							Disconnect(ts->Sock);
1731 							Debug("Disconnect (s2c=%u, c2s=%u)\n", s2c, c2s);
1732 						}
1733 					}
1734 				}
1735 			}
1736 			UnlockList(tcp->TcpSockList);
1737 		}
1738 
1739 		// Initializing the socket set
1740 		InitSockSet(&set);
1741 		LockList(tcp->TcpSockList);
1742 		{
1743 			num = LIST_NUM(tcp->TcpSockList);
1744 			tcpsocks = ToArrayEx(tcp->TcpSockList, true);
1745 		}
1746 		UnlockList(tcp->TcpSockList);
1747 
1748 		for (i = 0;i < num;i++)
1749 		{
1750 			AddSockSet(&set, tcpsocks[i]->Sock);
1751 		}
1752 
1753 		if (s->UseUdpAcceleration && s->UdpAccel != NULL)
1754 		{
1755 			if (s->UdpAccel->UdpSock != NULL)
1756 			{
1757 				AddSockSet(&set, s->UdpAccel->UdpSock);
1758 			}
1759 		}
1760 
1761 		// Select
1762 		time = SELECT_TIME;
1763 		if (s->VirtualHost)
1764 		{
1765 			time = MIN(time, SELECT_TIME_FOR_NAT);
1766 		}
1767 		next_delay_packet_diff = GetNextDelayedPacketTickDiff(s);
1768 		time = MIN(time, next_delay_packet_diff);
1769 		num_delayed = LIST_NUM(s->DelayedPacketList);
1770 
1771 		PROBE_STR("ConnectionReceive: Select 0");
1772 
1773 		if (s->Flag1 != set.NumSocket)
1774 		{
1775 			Select(&set, (num_delayed == 0 ? time : 1), c1, c2);
1776 			s->Flag1 = set.NumSocket;
1777 		}
1778 		else
1779 		{
1780 			if (no_spinlock_for_delay || time >= 50 || num_delayed == false)
1781 			{
1782 				Select(&set, (num_delayed == 0 ? time : (time > 100 ? (time - 100) : 1)), c1, c2);
1783 				s->Flag1 = set.NumSocket;
1784 			}
1785 			else
1786 			{
1787 				YieldCpu();
1788 			}
1789 		}
1790 
1791 		now = Tick64();
1792 
1793 		PROBE_STR("ConnectionReceive: Select 1");
1794 
1795 		if (s->UseUdpAcceleration && s->UdpAccel != NULL)
1796 		{
1797 			// Read the data received by the UDP If using the UDP acceleration mode
1798 			UdpAccelSetTick(s->UdpAccel, now);
1799 			UdpAccelPoll(s->UdpAccel);
1800 
1801 			if (s->UdpAccelMss == 0)
1802 			{
1803 				s->UdpAccelMss = UdpAccelCalcMss(s->UdpAccel);
1804 			}
1805 
1806 			while (true)
1807 			{
1808 				UINT current_packet_index = 0;
1809 				BLOCK *b = GetNext(s->UdpAccel->RecvBlockQueue);
1810 
1811 				if (b == NULL)
1812 				{
1813 					break;
1814 				}
1815 
1816 				if (b->Size > MAX_PACKET_SIZE)
1817 				{
1818 					// Packet size exceeded
1819 					FreeBlock(b);
1820 				}
1821 				else
1822 				{
1823 					if (CedarGetQueueBudgetBalance(c->Cedar) == 0)
1824 					{
1825 						FreeBlock(b);
1826 					}
1827 					else
1828 					{
1829 						// Add the data block to queue
1830 						InsertReveicedBlockToQueue(c, b, true);
1831 
1832 						if ((current_packet_index % 32) == 0)
1833 						{
1834 							UINT current_recv_block_num = c->ReceivedBlocks->num_item;
1835 							int diff = (int)current_recv_block_num - (int)c->LastRecvBlocksNum;
1836 
1837 							CedarAddQueueBudget(c->Cedar, diff);
1838 
1839 							c->LastRecvBlocksNum = current_recv_block_num;
1840 						}
1841 
1842 						current_packet_index++;
1843 					}
1844 				}
1845 			}
1846 		}
1847 
1848 		{
1849 			bool new_status = UdpAccelIsSendReady(s->UdpAccel, true);
1850 
1851 			if (s->IsUsingUdpAcceleration != new_status)
1852 			{
1853 				Debug("UDP Status Changed: %u\n", new_status);
1854 			}
1855 
1856 			s->IsUsingUdpAcceleration = new_status;
1857 		}
1858 
1859 		// Read all the data that has arrived to the TCP socket
1860 		for (i = 0;i < num;i++)
1861 		{
1862 			TCPSOCK *ts = tcpsocks[i];
1863 			SOCK *sock = ts->Sock;
1864 
1865 			if (s->IsRUDPSession)
1866 			{
1867 				TUBE *t = sock->BulkRecvTube;
1868 
1869 				//for testing purpose
1870 				//if (sock->test_tmp1 == 0) sock->test_tmp1 = now;
1871 				//if ((sock->test_tmp1 + 5000ULL) <= now)
1872 				//{
1873 				//	// bugbug
1874 				//	if (c->ServerMode == false)
1875 				//	{
1876 				//		WHERE;
1877 				//		Disconnect(sock);
1878 				//	}
1879 				//}
1880 
1881 				if (s->EnableBulkOnRUDP)
1882 				{
1883 					// R-UDP bulk transfer data reception
1884 					if (t != NULL && IsTubeConnected(t))
1885 					{
1886 						UINT current_packet_index = 0;
1887 						while (true)
1888 						{
1889 							TUBEDATA *d = TubeRecvAsync(t);
1890 							BLOCK *block;
1891 							if (d == NULL)
1892 							{
1893 								// All reception complete
1894 								break;
1895 							}
1896 
1897 							if (d->DataSize > sizeof(UINT64) && READ_UINT64(d->Data) == CONNECTION_BULK_COMPRESS_SIGNATURE)
1898 							{
1899 								// Compression
1900 								block = NewBlock(Clone(((UCHAR *)d->Data) + sizeof(UINT64),
1901 									d->DataSize - sizeof(UINT64)),
1902 									d->DataSize - sizeof(UINT64),
1903 									-1);
1904 							}
1905 							else
1906 							{
1907 								// Uncompressed
1908 								block = NewBlock(Clone(d->Data, d->DataSize), d->DataSize, 0);
1909 							}
1910 
1911 							if (block->Size > MAX_PACKET_SIZE)
1912 							{
1913 								// Packet size exceeded
1914 								FreeBlock(block);
1915 							}
1916 							else
1917 							{
1918 								if (CedarGetQueueBudgetBalance(c->Cedar) == 0)
1919 								{
1920 									FreeBlock(block);
1921 								}
1922 								else
1923 								{
1924 									// Add the data block to queue
1925 									InsertReveicedBlockToQueue(c, block, true);
1926 
1927 									if ((current_packet_index % 32) == 0)
1928 									{
1929 										UINT current_recv_block_num = c->ReceivedBlocks->num_item;
1930 										int diff = (int)current_recv_block_num - (int)c->LastRecvBlocksNum;
1931 
1932 										CedarAddQueueBudget(c->Cedar, diff);
1933 
1934 										c->LastRecvBlocksNum = current_recv_block_num;
1935 									}
1936 
1937 									current_packet_index++;
1938 								}
1939 							}
1940 
1941 							FreeTubeData(d);
1942 
1943 							UPDATE_LAST_COMM_TIME(ts->LastCommTime, now);
1944 							UPDATE_LAST_COMM_TIME(ts->LastRecvTime, now);
1945 							UPDATE_LAST_COMM_TIME(c->Session->LastCommTime, now);
1946 						}
1947 					}
1948 				}
1949 			}
1950 
1951 			if (c->IsInProc)
1952 			{
1953 				TUBEDATA *d;
1954 				UINT current_packet_index = 0;
1955 
1956 				// Socket for in-process connection
1957 				if (IsTubeConnected(sock->RecvTube) == false)
1958 				{
1959 					// Communication is disconnected
1960 					goto DISCONNECT_THIS_TCP;
1961 				}
1962 
1963 				while (true)
1964 				{
1965 					BLOCK *block;
1966 					// Get the packet data from the tube
1967 					d = TubeRecvAsync(sock->RecvTube);
1968 					if (d == NULL)
1969 					{
1970 						// All acquisition completed
1971 						break;
1972 					}
1973 
1974 					block = NewBlock(Clone(d->Data, d->DataSize), d->DataSize, 0);
1975 
1976 					if (block->Size > MAX_PACKET_SIZE)
1977 					{
1978 						// Packet size exceeded
1979 						FreeBlock(block);
1980 					}
1981 					else
1982 					{
1983 						if (CedarGetQueueBudgetBalance(c->Cedar) == 0)
1984 						{
1985 							FreeBlock(block);
1986 						}
1987 						else
1988 						{
1989 							// Add the data block to queue
1990 							InsertReveicedBlockToQueue(c, block, true);
1991 
1992 							if ((current_packet_index % 32) == 0)
1993 							{
1994 								UINT current_recv_block_num = c->ReceivedBlocks->num_item;
1995 								int diff = (int)current_recv_block_num - (int)c->LastRecvBlocksNum;
1996 
1997 								CedarAddQueueBudget(c->Cedar, diff);
1998 
1999 								c->LastRecvBlocksNum = current_recv_block_num;
2000 							}
2001 
2002 							current_packet_index++;
2003 						}
2004 					}
2005 
2006 					FreeTubeData(d);
2007 				}
2008 
2009 				UPDATE_LAST_COMM_TIME(c->Session->LastCommTime, now);
2010 			}
2011 			else
2012 			{
2013 				UINT current_fifo_budget = 0;
2014 				UINT current_packet_index = 0;
2015 				// A normal socket (Not in-process)
2016 				if (ts->WantSize == 0)
2017 				{
2018 					// Read for sizeof(UINT) first
2019 					ts->WantSize = sizeof(UINT);
2020 				}
2021 
2022 				now = Tick64();
2023 
2024 RECV_START:
2025 				current_fifo_budget = CedarGetFifoBudgetBalance(c->Cedar);
2026 				// Receive
2027 				if (ts->RecvFifo->size < current_fifo_budget)
2028 				{
2029 					UINT recv_buf_size = current_fifo_budget - ts->RecvFifo->size;
2030 
2031 					recv_buf_size = MIN(recv_buf_size, RECV_BUF_SIZE);
2032 
2033 					size = TcpSockRecv(s, ts, buf, recv_buf_size);
2034 				}
2035 				else
2036 				{
2037 					size = SOCK_LATER;
2038 
2039 					UPDATE_LAST_COMM_TIME(c->Session->LastCommTime, now);
2040 					UPDATE_LAST_COMM_TIME(ts->LastCommTime, now);
2041 				}
2042 
2043 				/*
2044 				// Experiment
2045 				if (c->ServerMode)
2046 				{
2047 					if ((ts->EstablishedTick + (UINT64)3000) <= now)
2048 					{
2049 						size = 0;
2050 						WHERE;
2051 					}
2052 				}*/
2053 
2054 				if (size == 0)
2055 				{
2056 DISCONNECT_THIS_TCP:
2057 					s->LastTryAddConnectTime = Tick64();
2058 					s->NumDisconnected++;
2059 					// Communication is disconnected
2060 					LockList(tcp->TcpSockList);
2061 					{
2062 						// Remove the socket from socket list
2063 						Delete(tcp->TcpSockList, ts);
2064 						// Release of TCPSOCK
2065 						FreeTcpSock(ts);
2066 						// Decrement
2067 						Dec(c->CurrentNumConnection);
2068 						Debug("--- TCP Connection Decremented: %u (%s Line %u)\n", Count(c->CurrentNumConnection), __FILE__, __LINE__);
2069 						Debug("LIST_NUM(tcp->TcpSockList): %u\n", LIST_NUM(tcp->TcpSockList));
2070 					}
2071 					UnlockList(tcp->TcpSockList);
2072 
2073 					continue;
2074 				}
2075 				else if (size == SOCK_LATER)
2076 				{
2077 					// State of waiting reception : don't do anything
2078 					if (IS_RECV_TCP_SOCK(ts))
2079 					{
2080 						if ((now > ts->LastCommTime) && ((now - ts->LastCommTime) >= ((UINT64)s->Timeout)))
2081 						{
2082 							// The connection has timed out
2083 							Debug("Connection %u Timeouted.\n", i);
2084 							goto DISCONNECT_THIS_TCP;
2085 						}
2086 					}
2087 				}
2088 				else
2089 				{
2090 					UINT budget_balance = CedarGetFifoBudgetBalance(c->Cedar);
2091 					UINT fifo_size_limit = budget_balance;
2092 
2093 					if (fifo_size_limit > MAX_BUFFERING_PACKET_SIZE)
2094 					{
2095 						fifo_size_limit = MAX_BUFFERING_PACKET_SIZE;
2096 					}
2097 
2098 					// Update the last communication time
2099 					UPDATE_LAST_COMM_TIME(c->Session->LastCommTime, now);
2100 					UPDATE_LAST_COMM_TIME(ts->LastRecvTime, now);
2101 
2102 					CedarAddFifoBudget(c->Cedar, (int)size);
2103 					recv_fifo_size_middle_update += (int)size;
2104 
2105 					// Write the received data into the FIFO
2106 					PROBE_DATA2("WriteRecvFifo", buf, size);
2107 					WriteRecvFifo(s, ts, buf, size);
2108 
2109 					// Stop receiving  when the receive buffer is full
2110 					if (ts->RecvFifo->size < fifo_size_limit)
2111 					{
2112 						goto RECV_START;
2113 					}
2114 				}
2115 
2116 				current_recv_fifo_size += FifoSize(ts->RecvFifo);
2117 
2118 				// process the data written to FIFO
2119 				while (ts->RecvFifo->size >= ts->WantSize)
2120 				{
2121 					UCHAR *buf;
2122 					void *data;
2123 					BLOCK *block;
2124 					UINT sz;
2125 					// A sufficient amount of data is already stored
2126 					// Get the pointer of the data
2127 					buf = (UCHAR *)ts->RecvFifo->p + ts->RecvFifo->pos;
2128 
2129 					switch (ts->Mode)
2130 					{
2131 					case 0:
2132 						// The number of Data blocks
2133 						ts->WantSize = sizeof(UINT);
2134 						Copy(&sz, buf, sizeof(UINT));
2135 						PROBE_DATA2("ReadFifo 0", buf, sizeof(UINT));
2136 						sz = Endian32(sz);
2137 						ts->NextBlockNum = sz;
2138 						ReadFifo(ts->RecvFifo, NULL, sizeof(UINT));
2139 
2140 						s->TotalRecvSize += sizeof(UINT);
2141 						s->TotalRecvSizeReal += sizeof(UINT);
2142 
2143 						ts->CurrentPacketNum = 0;
2144 						if (ts->NextBlockNum != 0)
2145 						{
2146 							if (ts->NextBlockNum == KEEP_ALIVE_MAGIC)
2147 							{
2148 								ts->Mode = 3;
2149 							}
2150 							else
2151 							{
2152 								ts->Mode = 1;
2153 							}
2154 						}
2155 						break;
2156 
2157 					case 1:
2158 						// Data block size
2159 						Copy(&sz, buf, sizeof(UINT));
2160 						sz = Endian32(sz);
2161 						PROBE_DATA2("ReadFifo 1", buf, sizeof(UINT));
2162 						if (sz > (MAX_PACKET_SIZE * 2))
2163 						{
2164 							// received a strange data size
2165 							// TCP/IP Error?
2166 							Debug("%s %u sz > (MAX_PACKET_SIZE * 2)\n", __FILE__, __LINE__);
2167 							Disconnect(ts->Sock);
2168 						}
2169 						ts->NextBlockSize = MIN(sz, MAX_PACKET_SIZE * 2);
2170 						ReadFifo(ts->RecvFifo, NULL, sizeof(UINT));
2171 
2172 						s->TotalRecvSize += sizeof(UINT);
2173 						s->TotalRecvSizeReal += sizeof(UINT);
2174 
2175 						ts->WantSize = ts->NextBlockSize;
2176 						if (ts->WantSize != 0)
2177 						{
2178 							ts->Mode = 2;
2179 						}
2180 						else
2181 						{
2182 							ts->Mode = 1;
2183 							ts->WantSize = sizeof(UINT);
2184 							ts->CurrentPacketNum++;
2185 							if (ts->CurrentPacketNum >= ts->NextBlockNum)
2186 							{
2187 								ts->Mode = 0;
2188 							}
2189 						}
2190 						break;
2191 
2192 					case 2:
2193 						// Data block body
2194 						ts->WantSize = sizeof(UINT);
2195 						ts->CurrentPacketNum++;
2196 						data = MallocFast(ts->NextBlockSize);
2197 						Copy(data, buf, ts->NextBlockSize);
2198 						PROBE_DATA2("ReadFifo 2", buf, ts->NextBlockSize);
2199 						ReadFifo(ts->RecvFifo, NULL, ts->NextBlockSize);
2200 						block = NewBlock(data, ts->NextBlockSize, s->UseCompress ? -1 : 0);
2201 
2202 						UPDATE_LAST_COMM_TIME(c->Session->LastCommTime, now);
2203 						UPDATE_LAST_COMM_TIME(ts->LastCommTime, now);
2204 
2205 						if (block->Size > MAX_PACKET_SIZE)
2206 						{
2207 							// Packet size exceeded
2208 							FreeBlock(block);
2209 						}
2210 						else
2211 						{
2212 							if (CedarGetQueueBudgetBalance(c->Cedar) == 0)
2213 							{
2214 								FreeBlock(block);
2215 							}
2216 							else
2217 							{
2218 								// Add the data block to queue
2219 								InsertReveicedBlockToQueue(c, block, true);
2220 
2221 								if ((current_packet_index % 32) == 0)
2222 								{
2223 									UINT current_recv_block_num = c->ReceivedBlocks->num_item;
2224 									int diff = (int)current_recv_block_num - (int)c->LastRecvBlocksNum;
2225 
2226 									CedarAddQueueBudget(c->Cedar, diff);
2227 
2228 									c->LastRecvBlocksNum = current_recv_block_num;
2229 								}
2230 
2231 								current_packet_index++;
2232 							}
2233 						}
2234 
2235 						if (ts->CurrentPacketNum >= ts->NextBlockNum)
2236 						{
2237 							// Reception of all the data blocks completed
2238 							ts->Mode = 0;
2239 						}
2240 						else
2241 						{
2242 							// Receive next data block size
2243 							ts->Mode = 1;
2244 						}
2245 						break;
2246 
2247 					case 3:
2248 						// Keep-Alive packet size
2249 						ts->Mode = 4;
2250 						Copy(&sz, buf, sizeof(UINT));
2251 						PROBE_DATA2("ReadFifo 3", buf, sizeof(UINT));
2252 						sz = Endian32(sz);
2253 						if (sz > MAX_KEEPALIVE_SIZE)
2254 						{
2255 							// received a strange data size
2256 							// TCP/IP Error?
2257 							Debug("%s %u sz > MAX_KEEPALIVE_SIZE\n", __FILE__, __LINE__);
2258 							Disconnect(ts->Sock);
2259 						}
2260 						ts->NextBlockSize = MIN(sz, MAX_KEEPALIVE_SIZE);
2261 						ReadFifo(ts->RecvFifo, NULL, sizeof(UINT));
2262 
2263 						UPDATE_LAST_COMM_TIME(c->Session->LastCommTime, now);
2264 						UPDATE_LAST_COMM_TIME(ts->LastCommTime, now);
2265 
2266 						s->TotalRecvSize += sizeof(UINT);
2267 						s->TotalRecvSizeReal += sizeof(UINT);
2268 
2269 						ts->WantSize = sz;
2270 						break;
2271 
2272 					case 4:
2273 						// Keep-Alive packet body
2274 						//Debug("KeepAlive Recved.\n");
2275 						ts->Mode = 0;
2276 						sz = ts->NextBlockSize;
2277 
2278 						if (sz >= (StrLen(UDP_NAT_T_PORT_SIGNATURE_IN_KEEP_ALIVE) + sizeof(USHORT)))
2279 						{
2280 							UCHAR *keep_alive_buffer = FifoPtr(ts->RecvFifo);
2281 
2282 							if (Cmp(keep_alive_buffer, UDP_NAT_T_PORT_SIGNATURE_IN_KEEP_ALIVE, StrLen(UDP_NAT_T_PORT_SIGNATURE_IN_KEEP_ALIVE)) == 0)
2283 							{
2284 								USHORT us = READ_USHORT(keep_alive_buffer + StrLen(UDP_NAT_T_PORT_SIGNATURE_IN_KEEP_ALIVE));
2285 
2286 								if (us != 0)
2287 								{
2288 									if (s->UseUdpAcceleration && s->UdpAccel != NULL)
2289 									{
2290 										UINT port = (UINT)us;
2291 
2292 										if (s->UdpAccel->YourPortByNatTServer != port)
2293 										{
2294 											s->UdpAccel->YourPortByNatTServer = port;
2295 											s->UdpAccel->YourPortByNatTServerChanged = true;
2296 
2297 											Debug("s->UdpAccel->YourPortByNatTServer: %u\n",
2298 												s->UdpAccel->YourPortByNatTServer);
2299 										}
2300 									}
2301 								}
2302 							}
2303 						}
2304 
2305 						PROBE_DATA2("ReadFifo 4", NULL, 0);
2306 						ReadFifo(ts->RecvFifo, NULL, sz);
2307 
2308 						UPDATE_LAST_COMM_TIME(c->Session->LastCommTime, now);
2309 						UPDATE_LAST_COMM_TIME(ts->LastCommTime, now);
2310 
2311 						s->TotalRecvSize += sz;
2312 						s->TotalRecvSizeReal += sz;
2313 
2314 						ts->WantSize = sizeof(UINT);
2315 						break;
2316 					}
2317 				}
2318 
2319 				ShrinkFifoMemory(ts->RecvFifo);
2320 				//printf("Fifo: %u\n", ts->RecvFifo->memsize);
2321 			}
2322 		}
2323 
2324 		if (true)
2325 		{
2326 			int diff;
2327 
2328 			diff = (int)current_recv_fifo_size - (int)c->LastRecvFifoTotalSize;
2329 
2330 			CedarAddFifoBudget(c->Cedar, (diff - recv_fifo_size_middle_update));
2331 
2332 			c->LastRecvFifoTotalSize = current_recv_fifo_size;
2333 		}
2334 
2335 		if (true)
2336 		{
2337 			UINT current_recv_block_num = c->ReceivedBlocks->num_item;
2338 			int diff = (int)current_recv_block_num - (int)c->LastRecvBlocksNum;
2339 
2340 			CedarAddQueueBudget(c->Cedar, diff);
2341 
2342 			c->LastRecvBlocksNum = current_recv_block_num;
2343 		}
2344 
2345 		Free(tcpsocks);
2346 	}
2347 	else if (c->Protocol == CONNECTION_UDP)
2348 	{
2349 		// UDP
2350 		UDP *udp = c->Udp;
2351 		SOCK *sock = NULL;
2352 
2353 		if (s->ServerMode == false)
2354 		{
2355 			Lock(c->lock);
2356 			{
2357 				if (c->Udp->s != NULL)
2358 				{
2359 					sock = c->Udp->s;
2360 					if (sock != NULL)
2361 					{
2362 						AddRef(sock->ref);
2363 					}
2364 				}
2365 			}
2366 			Unlock(c->lock);
2367 
2368 			InitSockSet(&set);
2369 
2370 			if (sock != NULL)
2371 			{
2372 				AddSockSet(&set, sock);
2373 			}
2374 
2375 			Select(&set, SELECT_TIME, c1, c2);
2376 
2377 			if (sock != NULL)
2378 			{
2379 				IP ip;
2380 				UINT port;
2381 				UCHAR *buf;
2382 				UINT size;
2383 
2384 				while (true)
2385 				{
2386 					buf = c->RecvBuf;
2387 					size = RecvFrom(sock, &ip, &port, buf, RECV_BUF_SIZE);
2388 					if (size == 0 && sock->IgnoreRecvErr == false)
2389 					{
2390 						Debug("UDP Socket Disconnected.\n");
2391 						Lock(c->lock);
2392 						{
2393 							ReleaseSock(udp->s);
2394 							udp->s = NULL;
2395 						}
2396 						Unlock(c->lock);
2397 						break;
2398 					}
2399 					else if (size == SOCK_LATER)
2400 					{
2401 						break;
2402 					}
2403 					else
2404 					{
2405 						if (size)
2406 						{
2407 							PutUDPPacketData(c, buf, size);
2408 						}
2409 					}
2410 				}
2411 			}
2412 
2413 			if (sock != NULL)
2414 			{
2415 				Release(sock->ref);
2416 			}
2417 		}
2418 		else
2419 		{
2420 			Select(NULL, SELECT_TIME, c1, c2);
2421 		}
2422 	}
2423 	else if (c->Protocol == CONNECTION_HUB_SECURE_NAT)
2424 	{
2425 		SNAT *snat = c->Session->SecureNAT;
2426 		VH *v = snat->Nat->Virtual;
2427 		UINT size;
2428 		void *data;
2429 		UINT num;
2430 		UINT select_wait_time = SELECT_TIME_FOR_NAT;
2431 		UINT next_delay_packet_diff = 0;
2432 
2433 		if (snat->Nat != NULL && snat->Nat->Option.UseNat == false)
2434 		{
2435 			select_wait_time = SELECT_TIME;
2436 		}
2437 		else
2438 		{
2439 			if (snat->Nat != NULL)
2440 			{
2441 				LockList(v->NatTable);
2442 				{
2443 					if (LIST_NUM(v->NatTable) == 0 && LIST_NUM(v->ArpWaitTable) == 0)
2444 					{
2445 						select_wait_time = SELECT_TIME;
2446 					}
2447 				}
2448 				UnlockList(v->NatTable);
2449 			}
2450 		}
2451 
2452 		next_delay_packet_diff = GetNextDelayedPacketTickDiff(s);
2453 		select_wait_time = MIN(select_wait_time, next_delay_packet_diff);
2454 		num_delayed = LIST_NUM(s->DelayedPacketList);
2455 
2456 		if (no_spinlock_for_delay || select_wait_time >= 50 || num_delayed == false)
2457 		{
2458 			Select(NULL, (num_delayed == 0 ? select_wait_time :
2459 				(select_wait_time > 100 ? (select_wait_time - 100) : 1)), c1, c2);
2460 		}
2461 		else
2462 		{
2463 			YieldCpu();
2464 		}
2465 
2466 		num = 0;
2467 
2468 		if (hub != NULL)
2469 		{
2470 			NatSetHubOption(v, hub->Option);
2471 		}
2472 
2473 		// Receive a packet from the virtual machine
2474 		while (size = VirtualGetNextPacket(v, &data))
2475 		{
2476 			BLOCK *block;
2477 
2478 			// Generate packet block
2479 			block = NewBlock(data, size, 0);
2480 			if (block->Size > MAX_PACKET_SIZE)
2481 			{
2482 				// Packet size exceeded
2483 				FreeBlock(block);
2484 			}
2485 			else
2486 			{
2487 				// Add the data block to queue
2488 				InsertReveicedBlockToQueue(c, block, true);
2489 			}
2490 			num++;
2491 			if (num >= MAX_SEND_SOCKET_QUEUE_NUM)
2492 			{
2493 //				WHERE;
2494 				break;
2495 			}
2496 		}
2497 	}
2498 	else if (c->Protocol == CONNECTION_HUB_LINK_SERVER)
2499 	{
2500 		// HUB Link
2501 		// Waiting Cancel simply
2502 		if (c->SendBlocks->num_item == 0)
2503 		{
2504 			UINT time = SELECT_TIME;
2505 			UINT next_delay_packet_diff = 0;
2506 
2507 			next_delay_packet_diff = GetNextDelayedPacketTickDiff(s);
2508 			time = MIN(time, next_delay_packet_diff);
2509 			num_delayed = LIST_NUM(s->DelayedPacketList);
2510 
2511 			if (no_spinlock_for_delay || time >= 50 || num_delayed == false)
2512 			{
2513 				Select(NULL, (num_delayed == 0 ? time : (time > 100 ? (time - 100) : 1)), c1, c2);
2514 			}
2515 			else
2516 			{
2517 				YieldCpu();
2518 			}
2519 		}
2520 	}
2521 	else if (c->Protocol == CONNECTION_HUB_LAYER3)
2522 	{
2523 		// Layer-3 switch session
2524 		L3IF *f = s->L3If;
2525 		UINT size, num = 0;
2526 		void *data;
2527 
2528 		if (f->SendQueue->num_item == 0)
2529 		{
2530 			UINT time = SELECT_TIME_FOR_NAT;
2531 			UINT next_delay_packet_diff = 0;
2532 
2533 			if (f->ArpWaitTable != NULL)
2534 			{
2535 				LockList(f->ArpWaitTable);
2536 				{
2537 					if (LIST_NUM(f->ArpWaitTable) == 0)
2538 					{
2539 						time = SELECT_TIME;
2540 					}
2541 				}
2542 				UnlockList(f->ArpWaitTable);
2543 			}
2544 
2545 			next_delay_packet_diff = GetNextDelayedPacketTickDiff(s);
2546 			time = MIN(time, next_delay_packet_diff);
2547 			num_delayed = LIST_NUM(s->DelayedPacketList);
2548 
2549 			if (no_spinlock_for_delay || time >= 50 || num_delayed == false)
2550 			{
2551 				Select(NULL, (num_delayed == 0 ? time : (time > 100 ? (time - 100) : 1)), c1, c2);
2552 			}
2553 			else
2554 			{
2555 				YieldCpu();
2556 			}
2557 		}
2558 
2559 		// Get the next packet
2560 		while (size = L3GetNextPacket(f, &data))
2561 		{
2562 			BLOCK *block = NewBlock(data, size, 0);
2563 			if (block->Size > MAX_PACKET_SIZE)
2564 			{
2565 				FreeBlock(block);
2566 			}
2567 			else
2568 			{
2569 				InsertReveicedBlockToQueue(c, block, true);
2570 			}
2571 
2572 			num++;
2573 			if (num >= MAX_SEND_SOCKET_QUEUE_NUM)
2574 			{
2575 				break;
2576 			}
2577 		}
2578 	}
2579 	else if (c->Protocol == CONNECTION_HUB_BRIDGE)
2580 	{
2581 		BRIDGE *b = c->Session->Bridge;
2582 
2583 		// Bridge session
2584 		if (b->Active)
2585 		{
2586 			void *data;
2587 			UINT ret;
2588 			UINT num = 0;
2589 			bool check_device_num = false;
2590 			UINT time = SELECT_TIME;
2591 			UINT next_delay_packet_diff = 0;
2592 
2593 			next_delay_packet_diff = GetNextDelayedPacketTickDiff(s);
2594 			time = MIN(time, next_delay_packet_diff);
2595 			num_delayed = LIST_NUM(s->DelayedPacketList);
2596 
2597 			// Bridge is operating
2598 			if (no_spinlock_for_delay || time >= 50 || num_delayed == false)
2599 			{
2600 				Select(NULL, (num_delayed == 0 ? time : (time > 100 ? (time - 100) : 1)), c1, c2);
2601 			}
2602 			else
2603 			{
2604 				YieldCpu();
2605 			}
2606 
2607 			if ((b->LastNumDeviceCheck + BRIDGE_NUM_DEVICE_CHECK_SPAN) <= Tick64())
2608 			{
2609 #ifdef	OS_WIN32
2610 				check_device_num = true;
2611 #endif	// OS_WIN32
2612 				b->LastNumDeviceCheck = Tick64();
2613 			}
2614 
2615 			// Get the next packet from the bridge
2616 			while (true)
2617 			{
2618 				if (check_device_num && b->LastNumDevice != GetEthDeviceHash())
2619 				{
2620 					ret = INFINITE;
2621 				}
2622 				else
2623 				{
2624 					ret = EthGetPacket(b->Eth, &data);
2625 				}
2626 
2627 #ifdef	OS_WIN32
2628 				if (c->Session != NULL)
2629 				{
2630 					c->Session->BridgeIsEthLoopbackBlock = false;
2631 					if (b->Eth != NULL && b->Eth->LoopbackBlock)
2632 					{
2633 						// Check whether The Ethernet device in the bridge
2634 						// has the ability to block the loopback packet
2635 						c->Session->BridgeIsEthLoopbackBlock = true;
2636 					}
2637 				}
2638 #endif	// OS_WIN32
2639 
2640 				if (ret == INFINITE)
2641 				{
2642 					// Error occured: stop the bridge
2643 					CloseEth(b->Eth);
2644 					b->Eth = NULL;
2645 					b->Active = false;
2646 					ReleaseCancel(s->Cancel2);
2647 					s->Cancel2 = NULL;
2648 
2649 					HLog(s->Hub, "LH_BRIDGE_2", s->Name, b->Name);
2650 					Debug("Bridge Device Error.\n");
2651 
2652 					break;
2653 				}
2654 				else if (ret == 0)
2655 				{
2656 					// There is no more packet to receive
2657 					break;
2658 				}
2659 				else
2660 				{
2661 					if (hub != NULL && hub->Option != NULL && hub->Option->DisableUdpFilterForLocalBridgeNic == false &&
2662 						b->Eth != NULL && IsDhcpPacketForSpecificMac(data, ret, b->Eth->MacAddress))
2663 					{
2664 						// DHCP Packet is filtered.
2665 						Free(data);
2666 					}
2667 					else
2668 					{
2669 						// Add the packet to queue
2670 						BLOCK *block = NewBlock(data, ret, 0);
2671 
2672 						PROBE_DATA2("ConnectionReceive: NewBlock", data, ret);
2673 
2674 						if (ret > 1514)
2675 						{
2676 							NormalizeEthMtu(b, c, ret);
2677 						}
2678 
2679 						if (block->Size > MAX_PACKET_SIZE)
2680 						{
2681 							// Packet size exceeded
2682 							FreeBlock(block);
2683 						}
2684 						else
2685 						{
2686 							InsertReveicedBlockToQueue(c, block, true);
2687 						}
2688 						num++;
2689 						if (num >= MAX_SEND_SOCKET_QUEUE_NUM)
2690 						{
2691 	//						WHERE;
2692 							break;
2693 						}
2694 					}
2695 				}
2696 			}
2697 		}
2698 		else
2699 		{
2700 			ETH *e;
2701 			// Bridge is stopped cureently
2702 			Select(NULL, SELECT_TIME, c1, NULL);
2703 
2704 			if (b->LastBridgeTry == 0 || (b->LastBridgeTry + BRIDGE_TRY_SPAN) <= Tick64())
2705 			{
2706 				b->LastBridgeTry = Tick64();
2707 
2708 				// Try to open an Ethernet device
2709 				e = OpenEth(b->Name, b->Local, b->TapMode, b->TapMacAddress);
2710 				if (e != NULL)
2711 				{
2712 					// Success
2713 					b->Eth = e;
2714 					b->Active = true;
2715 					b->LastNumDeviceCheck = Tick64();
2716 					b->LastNumDevice = GetEthDeviceHash();
2717 
2718 					// Update the NIC name of the bridge
2719 #ifdef	OS_WIN32
2720 					if (IsEmptyStr(e->Title) == false)
2721 					{
2722 						StrCpy(b->Name, sizeof(b->Name), e->Title);
2723 
2724 						if (b->ParentLocalBridge != NULL)
2725 						{
2726 							StrCpy(b->ParentLocalBridge->DeviceName, sizeof(b->ParentLocalBridge->DeviceName), e->Title);
2727 						}
2728 					}
2729 #endif	// OS_WIN32
2730 
2731 					Debug("Bridge Open Succeed.\n");
2732 
2733 					HLog(c->Session->Hub, "LH_BRIDGE_1", c->Session->Name, b->Name);
2734 
2735 					s->Cancel2 = EthGetCancel(b->Eth);
2736 				}
2737 			}
2738 		}
2739 	}
2740 }
2741 
2742 // Normalize the MTU of the Ethernet device
NormalizeEthMtu(BRIDGE * b,CONNECTION * c,UINT packet_size)2743 void NormalizeEthMtu(BRIDGE *b, CONNECTION *c, UINT packet_size)
2744 {
2745 	// Validate arguments
2746 	if (packet_size == 0 || b == NULL || c == NULL)
2747 	{
2748 		return;
2749 	}
2750 
2751 	// Raise the MTU when the packet exceeds the current MTU
2752 	if (EthIsChangeMtuSupported(b->Eth))
2753 	{
2754 		UINT currentMtu = EthGetMtu(b->Eth);
2755 		if (currentMtu != 0)
2756 		{
2757 			if (packet_size > currentMtu)
2758 			{
2759 				bool ok = EthSetMtu(b->Eth, packet_size);
2760 
2761 				if (ok)
2762 				{
2763 					HLog(c->Session->Hub, "LH_SET_MTU", c->Session->Name,
2764 						b->Name, currentMtu, packet_size, packet_size);
2765 				}
2766 				else
2767 				{
2768 					UINT64 now = Tick64();
2769 
2770 					if (b->LastChangeMtuError == 0 ||
2771 						now >= (b->LastChangeMtuError + 60000ULL))
2772 					{
2773 						HLog(c->Session->Hub, "LH_SET_MTU_ERROR", c->Session->Name,
2774 							b->Name, currentMtu, packet_size, packet_size);
2775 
2776 						b->LastChangeMtuError = now;
2777 					}
2778 				}
2779 			}
2780 		}
2781 	}
2782 }
2783 
2784 // Release of the block
FreeBlock(BLOCK * b)2785 void FreeBlock(BLOCK *b)
2786 {
2787 	// Validate arguments
2788 	if (b == NULL)
2789 	{
2790 		return;
2791 	}
2792 
2793 	Free(b->Buf);
2794 	Free(b);
2795 }
2796 
2797 // Create a new block
NewBlock(void * data,UINT size,int compress)2798 BLOCK *NewBlock(void *data, UINT size, int compress)
2799 {
2800 	BLOCK *b;
2801 	// Validate arguments
2802 	if (data == NULL)
2803 	{
2804 		return NULL;
2805 	}
2806 
2807 	b = MallocFast(sizeof(BLOCK));
2808 
2809 	b->RawFlagRetUdpAccel = 0;
2810 
2811 	b->IsFlooding = false;
2812 
2813 	b->PriorityQoS = b->Ttl = b->Param1 = 0;
2814 
2815 	if (compress == 0)
2816 	{
2817 		// Uncompressed
2818 		b->Compressed = FALSE;
2819 		b->Buf = data;
2820 		b->Size = size;
2821 		b->SizeofData = size;
2822 	}
2823 	else if (compress == 1)
2824 	{
2825 		UINT max_size;
2826 
2827 		// Compressed
2828 		b->Compressed = TRUE;
2829 		max_size = CalcCompress(size);
2830 		b->Buf = MallocFast(max_size);
2831 		b->Size = Compress(b->Buf, max_size, data, size);
2832 		b->SizeofData = size;
2833 
2834 		// Discard old data block
2835 		Free(data);
2836 	}
2837 	else
2838 	{
2839 		// Expand
2840 		UINT max_size;
2841 
2842 		b->Compressed = FALSE;
2843 		max_size = MAX_PACKET_SIZE;
2844 		b->Buf = MallocFast(max_size);
2845 		b->Size = Uncompress(b->Buf, max_size, data, size);
2846 		b->SizeofData = size;
2847 
2848 		// Discard old data
2849 		Free(data);
2850 	}
2851 
2852 	return b;
2853 }
2854 
2855 // Create a TCP socket
NewTcpSock(SOCK * s)2856 TCPSOCK *NewTcpSock(SOCK *s)
2857 {
2858 	TCPSOCK *ts;
2859 	// Validate arguments
2860 	if (s == NULL)
2861 	{
2862 		return NULL;
2863 	}
2864 
2865 	ts = ZeroMalloc(sizeof(TCPSOCK));
2866 
2867 	ts->Sock = s;
2868 	AddRef(s->ref);
2869 
2870 	ts->RecvFifo = NewFifo();
2871 	ts->SendFifo = NewFifo();
2872 	ts->EstablishedTick = ts->LastRecvTime = ts->LastCommTime = Tick64();
2873 
2874 	// Unset the time-out value
2875 	SetTimeout(s, TIMEOUT_INFINITE);
2876 
2877 	return ts;
2878 }
2879 
2880 // Set a encryption key for the TCP socket
InitTcpSockRc4Key(TCPSOCK * ts,bool server_mode)2881 void InitTcpSockRc4Key(TCPSOCK *ts, bool server_mode)
2882 {
2883 	RC4_KEY_PAIR *pair;
2884 	CRYPT *c1, *c2;
2885 	// Validate arguments
2886 	if (ts == NULL)
2887 	{
2888 		return;
2889 	}
2890 
2891 	pair = &ts->Rc4KeyPair;
2892 
2893 	c1 = NewCrypt(pair->ClientToServerKey, sizeof(pair->ClientToServerKey));
2894 	c2 = NewCrypt(pair->ServerToClientKey, sizeof(pair->ServerToClientKey));
2895 
2896 	if (server_mode)
2897 	{
2898 		ts->RecvKey = c1;
2899 		ts->SendKey = c2;
2900 	}
2901 	else
2902 	{
2903 		ts->SendKey = c1;
2904 		ts->RecvKey = c2;
2905 	}
2906 }
2907 
2908 // Release of TCP socket
FreeTcpSock(TCPSOCK * ts)2909 void FreeTcpSock(TCPSOCK *ts)
2910 {
2911 	// Validate arguments
2912 	if (ts == NULL)
2913 	{
2914 		return;
2915 	}
2916 
2917 	Disconnect(ts->Sock);
2918 	ReleaseSock(ts->Sock);
2919 	ReleaseFifo(ts->RecvFifo);
2920 	ReleaseFifo(ts->SendFifo);
2921 
2922 	if (ts->SendKey)
2923 	{
2924 		FreeCrypt(ts->SendKey);
2925 	}
2926 	if (ts->RecvKey)
2927 	{
2928 		FreeCrypt(ts->RecvKey);
2929 	}
2930 
2931 	Free(ts);
2932 }
2933 
2934 // Exit the tunneling mode of connection
EndTunnelingMode(CONNECTION * c)2935 void EndTunnelingMode(CONNECTION *c)
2936 {
2937 	// Validate arguments
2938 	if (c == NULL)
2939 	{
2940 		return;
2941 	}
2942 
2943 	// Protocol
2944 	if (c->Protocol == CONNECTION_TCP)
2945 	{
2946 		// TCP
2947 		DisconnectTcpSockets(c);
2948 	}
2949 	else
2950 	{
2951 		// UDP
2952 		DisconnectUDPSockets(c);
2953 	}
2954 }
2955 
2956 // Shift the connection to tunneling mode
StartTunnelingMode(CONNECTION * c)2957 void StartTunnelingMode(CONNECTION *c)
2958 {
2959 	SOCK *s;
2960 	TCP *tcp;
2961 	TCPSOCK *ts;
2962 	IP ip;
2963 	UINT port;
2964 	// Validate arguments
2965 	if (c == NULL)
2966 	{
2967 		return;
2968 	}
2969 
2970 	tcp = c->Tcp;
2971 
2972 	// Protocol
2973 	if (c->Protocol == CONNECTION_TCP)
2974 	{
2975 		// TCP
2976 		s = c->FirstSock;
2977 
2978 		if (c->IsInProc)
2979 		{
2980 			AddRef(s->ref);
2981 			c->TubeSock = s;
2982 		}
2983 
2984 		ts = NewTcpSock(s);
2985 
2986 		if (c->ServerMode == false)
2987 		{
2988 			if (c->Session->ClientOption->ConnectionDisconnectSpan != 0)
2989 			{
2990 				ts->DisconnectTick = Tick64() + c->Session->ClientOption->ConnectionDisconnectSpan * (UINT64)1000;
2991 			}
2992 		}
2993 
2994 		LockList(tcp->TcpSockList);
2995 		{
2996 			Add(tcp->TcpSockList, ts);
2997 		}
2998 		UnlockList(tcp->TcpSockList);
2999 		ReleaseSock(s);
3000 		c->FirstSock = NULL;
3001 	}
3002 	else
3003 	{
3004 		// UDP
3005 		s = c->FirstSock;
3006 		Copy(&ip, &s->RemoteIP, sizeof(IP));
3007 		// May disconnect TCP connection at this point
3008 		c->FirstSock = NULL;
3009 		Disconnect(s);
3010 		ReleaseSock(s);
3011 
3012 		// Initialization of UDP structure
3013 		c->Udp = ZeroMalloc(sizeof(UDP));
3014 
3015 		if (c->ServerMode)
3016 		{
3017 			// Server mode
3018 			// Add an UDP Entry
3019 			AddUDPEntry(c->Cedar, c->Session);
3020 			c->Udp->s = NULL;
3021 		}
3022 		else
3023 		{
3024 			port = c->Session->ClientOption->PortUDP;
3025 			// Client mode
3026 			c->Udp->s = NewUDP(0);
3027 			// Write the IP address and port number
3028 			Copy(&c->Udp->ip, &ip, sizeof(IP));
3029 			c->Udp->port = port;
3030 		}
3031 
3032 		// Queue
3033 		c->Udp->BufferQueue = NewQueue();
3034 	}
3035 }
3036 
3037 // Generate a random value that depends on each machine
GetMachineRand()3038 UINT GetMachineRand()
3039 {
3040 	char pcname[MAX_SIZE];
3041 	UCHAR hash[SHA1_SIZE];
3042 
3043 	Zero(pcname, sizeof(pcname));
3044 	GetMachineName(pcname, sizeof(pcname));
3045 
3046 	HashSha1(hash, pcname, StrLen(pcname));
3047 
3048 	return READ_UINT(hash);
3049 }
3050 
3051 // Function that accepts a new connection
ConnectionAccept(CONNECTION * c)3052 void ConnectionAccept(CONNECTION *c)
3053 {
3054 	SOCK *s;
3055 	X *x;
3056 	K *k;
3057 	char tmp[128];
3058 	UCHAR openssl_check_buf[2];
3059 	char *error_details = NULL;
3060 	SERVER *server;
3061 	UCHAR *peek_buf = NULL;
3062 	UINT peek_buf_size = 1500;
3063 	char sni[256] = {0};
3064 	bool native1 = false;
3065 	bool native2 = false;
3066 	bool native3 = false;
3067 	bool no_native = false;
3068 	UINT peek_size = 0;
3069 	UINT initial_timeout = CONNECTING_TIMEOUT;
3070 	bool no_peek_log = false;
3071 	UCHAR ctoken_hash[SHA1_SIZE];
3072 	bool no_write_ctoken_log = false;
3073 
3074 	// Validate arguments
3075 	if (c == NULL)
3076 	{
3077 		return;
3078 	}
3079 
3080 	Zero(ctoken_hash, sizeof(ctoken_hash));
3081 
3082 	peek_buf = ZeroMalloc(peek_buf_size);
3083 
3084 	Debug("ConnectionAccept()\n");
3085 
3086 	server = c->Cedar->Server;
3087 
3088 	// get a socket
3089 	s = c->FirstSock;
3090 	AddRef(s->ref);
3091 
3092 	Dec(c->Cedar->AcceptingSockets);
3093 
3094 	IPToStr(tmp, sizeof(tmp), &s->RemoteIP);
3095 
3096 	SLog(c->Cedar, "LS_CONNECTION_START_1", tmp, s->RemoteHostname, (IS_SPECIAL_PORT(s->RemotePort) ? 0 : s->RemotePort), c->Name);
3097 
3098 	// Timeout setting
3099 	initial_timeout += GetMachineRand() % (CONNECTING_TIMEOUT / 2);
3100 	SetTimeout(s, initial_timeout);
3101 
3102 
3103 	// Peek whether OpenSSL packet
3104 	if (s->IsReverseAcceptedSocket == false)
3105 	{
3106 		if (s->Type == SOCK_TCP && (c->Cedar != NULL && c->Cedar->Server != NULL && c->Cedar->Server->DisableOpenVPNServer == false))
3107 		{
3108 			if (Peek(s, openssl_check_buf, sizeof(openssl_check_buf)) == sizeof(openssl_check_buf))
3109 			{
3110 				if (OvsCheckTcpRecvBufIfOpenVPNProtocol(openssl_check_buf, sizeof(openssl_check_buf)))
3111 				{
3112 					// Detect OpenSSL packet
3113 					Debug("Detect OpenSSL on TCP!\n");
3114 
3115 					no_native = true;
3116 
3117 					if (OvsGetNoOpenVpnTcp() == false)
3118 					{
3119 						// Do OpenSSL processing
3120 						c->Type = CONNECTION_TYPE_OPENVPN;
3121 						if (OvsPerformTcpServer(c->Cedar, s) == false)
3122 						{
3123 							error_details = "OpenVPN_TCP_Aborted";
3124 						}
3125 					}
3126 
3127 					goto ERROR;
3128 				}
3129 			}
3130 		}
3131 
3132 
3133 	}
3134 
3135 	// Specify the encryption algorithm
3136 	Lock(c->Cedar->lock);
3137 	{
3138 		if (c->Cedar->CipherList != NULL)
3139 		{
3140 			SetWantToUseCipher(s, c->Cedar->CipherList);
3141 		}
3142 
3143 		x = CloneX(c->Cedar->ServerX);
3144 		k = CloneK(c->Cedar->ServerK);
3145 	}
3146 	Unlock(c->Cedar->lock);
3147 
3148 	// Start the SSL communication
3149 	Debug("StartSSL()\n");
3150 	Copy(&s->SslAcceptSettings, &c->Cedar->SslAcceptSettings, sizeof(SSL_ACCEPT_SETTINGS));
3151 	if (StartSSL(s, x, k) == false)
3152 	{
3153 		// Failed
3154 		AddNoSsl(c->Cedar, &s->RemoteIP);
3155 		Debug("Failed to StartSSL.\n");
3156 		FreeX(x);
3157 		FreeK(k);
3158 
3159 		error_details = "StartSSL";
3160 
3161 		goto ERROR;
3162 	}
3163 
3164 
3165 	FreeX(x);
3166 	FreeK(k);
3167 
3168 	SLog(c->Cedar, "LS_SSL_START", c->Name, s->CipherName);
3169 
3170 	Copy(c->CToken_Hash, ctoken_hash, SHA1_SIZE);
3171 
3172 	// Accept the connection
3173 	if (ServerAccept(c) == false)
3174 	{
3175 		// Failed
3176 		Debug("ServerAccept Failed. Err = %u\n", c->Err);
3177 		goto ERROR;
3178 	}
3179 
3180 	if (c->flag1 == false)
3181 	{
3182 		Debug("%s %u c->flag1 == false\n", __FILE__, __LINE__);
3183 		Disconnect(s);
3184 	}
3185 	DelConnection(c->Cedar, c);
3186 	ReleaseSock(s);
3187 
3188 	Free(peek_buf);
3189 	return;
3190 
3191 ERROR:
3192 	Debug("ConnectionAccept() Error.\n");
3193 
3194 
3195 	Disconnect(s);
3196 	DelConnection(c->Cedar, c);
3197 	ReleaseSock(s);
3198 	Free(peek_buf);
3199 }
3200 
3201 // Stop the threads putting additional connection of all that are currently running
StopAllAdditionalConnectThread(CONNECTION * c)3202 void StopAllAdditionalConnectThread(CONNECTION *c)
3203 {
3204 	UINT i, num;
3205 	SOCK **socks;
3206 	THREAD **threads;
3207 	// Validate arguments
3208 	if (c == NULL || c->ServerMode != false)
3209 	{
3210 		return;
3211 	}
3212 
3213 	// Disconnect the socket first
3214 	LockList(c->ConnectingSocks);
3215 	{
3216 		num = LIST_NUM(c->ConnectingSocks);
3217 		socks = ToArray(c->ConnectingSocks);
3218 		DeleteAll(c->ConnectingSocks);
3219 	}
3220 	UnlockList(c->ConnectingSocks);
3221 	for (i = 0;i < num;i++)
3222 	{
3223 		Disconnect(socks[i]);
3224 		ReleaseSock(socks[i]);
3225 	}
3226 	Free(socks);
3227 
3228 	// Then, wait for the suspension of the thread
3229 	LockList(c->ConnectingThreads);
3230 	{
3231 		num = LIST_NUM(c->ConnectingThreads);
3232 		Debug("c->ConnectingThreads: %u\n", num);
3233 		threads = ToArray(c->ConnectingThreads);
3234 		DeleteAll(c->ConnectingThreads);
3235 	}
3236 	UnlockList(c->ConnectingThreads);
3237 	for (i = 0;i < num;i++)
3238 	{
3239 		WaitThread(threads[i], INFINITE);
3240 		ReleaseThread(threads[i]);
3241 	}
3242 	Free(threads);
3243 }
3244 
3245 // Stop the connection
StopConnection(CONNECTION * c,bool no_wait)3246 void StopConnection(CONNECTION *c, bool no_wait)
3247 {
3248 	// Validate arguments
3249 	if (c == NULL)
3250 	{
3251 		return;
3252 	}
3253 
3254 	Debug("Stop Connection: %s\n", c->Name);
3255 
3256 	// Stop flag
3257 	c->Halt = true;
3258 	Disconnect(c->FirstSock);
3259 
3260 	if (no_wait == false)
3261 	{
3262 		// Wait until the thread terminates
3263 		WaitThread(c->Thread, INFINITE);
3264 	}
3265 }
3266 
3267 // Close all the UDP socket
DisconnectUDPSockets(CONNECTION * c)3268 void DisconnectUDPSockets(CONNECTION *c)
3269 {
3270 	// Validate arguments
3271 	if (c == NULL)
3272 	{
3273 		return;
3274 	}
3275 	if (c->Protocol != CONNECTION_UDP)
3276 	{
3277 		return;
3278 	}
3279 
3280 	// Delete entry
3281 	if (c->ServerMode)
3282 	{
3283 		DelUDPEntry(c->Cedar, c->Session);
3284 	}
3285 
3286 	// Delete the UDP structure
3287 	if (c->Udp != NULL)
3288 	{
3289 		if (c->Udp->s != NULL)
3290 		{
3291 			ReleaseSock(c->Udp->s);
3292 		}
3293 		if (c->Udp->BufferQueue != NULL)
3294 		{
3295 			// Release of the queue
3296 			BUF *b;
3297 			while (b = GetNext(c->Udp->BufferQueue))
3298 			{
3299 				FreeBuf(b);
3300 			}
3301 			ReleaseQueue(c->Udp->BufferQueue);
3302 		}
3303 		Free(c->Udp);
3304 		c->Udp = NULL;
3305 	}
3306 
3307 	if (c->FirstSock != NULL)
3308 	{
3309 		Disconnect(c->FirstSock);
3310 		ReleaseSock(c->FirstSock);
3311 		c->FirstSock = NULL;
3312 	}
3313 }
3314 
3315 // Close all TCP connections
DisconnectTcpSockets(CONNECTION * c)3316 void DisconnectTcpSockets(CONNECTION *c)
3317 {
3318 	UINT i, num;
3319 	TCP *tcp;
3320 	TCPSOCK **tcpsocks;
3321 	// Validate arguments
3322 	if (c == NULL)
3323 	{
3324 		return;
3325 	}
3326 	if (c->Protocol != CONNECTION_TCP)
3327 	{
3328 		return;
3329 	}
3330 
3331 	tcp = c->Tcp;
3332 	LockList(tcp->TcpSockList);
3333 	{
3334 		tcpsocks = ToArray(tcp->TcpSockList);
3335 		num = LIST_NUM(tcp->TcpSockList);
3336 		DeleteAll(tcp->TcpSockList);
3337 	}
3338 	UnlockList(tcp->TcpSockList);
3339 
3340 	if (num != 0)
3341 	{
3342 		Debug("--- SOCKET STATUS ---\n");
3343 		for (i = 0;i < num;i++)
3344 		{
3345 			TCPSOCK *ts = tcpsocks[i];
3346 			Debug(" SOCK %2u: %u\n", i, ts->Sock->SendSize);
3347 			FreeTcpSock(ts);
3348 		}
3349 	}
3350 
3351 	Free(tcpsocks);
3352 }
3353 
3354 // Clean up of the connection
CleanupConnection(CONNECTION * c)3355 void CleanupConnection(CONNECTION *c)
3356 {
3357 	UINT i, num;
3358 	// Validate arguments
3359 	if (c == NULL)
3360 	{
3361 		return;
3362 	}
3363 
3364 	if (c->LastRecvFifoTotalSize != 0)
3365 	{
3366 		CedarAddFifoBudget(c->Cedar, -((int)c->LastRecvFifoTotalSize));
3367 		c->LastRecvFifoTotalSize = 0;
3368 	}
3369 
3370 	if (c->LastRecvBlocksNum != 0)
3371 	{
3372 		CedarAddQueueBudget(c->Cedar, -((int)c->LastRecvBlocksNum));
3373 		c->LastRecvBlocksNum = 0;
3374 	}
3375 
3376 	if (c->LastTcpQueueSize != 0)
3377 	{
3378 		int diff = -((int)c->LastTcpQueueSize);
3379 		CedarAddCurrentTcpQueueSize(c->Cedar, diff);
3380 		c->LastTcpQueueSize = 0;
3381 	}
3382 
3383 	if (c->LastPacketQueueSize != 0)
3384 	{
3385 		int diff = -((int)c->LastPacketQueueSize);
3386 		CedarAddCurrentTcpQueueSize(c->Cedar, diff);
3387 		c->LastPacketQueueSize = 0;
3388 	}
3389 
3390 	DeleteLock(c->lock);
3391 	ReleaseCedar(c->Cedar);
3392 
3393 	switch (c->Protocol)
3394 	{
3395 	case CONNECTION_TCP:
3396 		// Release of TCP connection list
3397 		DisconnectTcpSockets(c);
3398 		break;
3399 
3400 	case CONNECTION_UDP:
3401 		break;
3402 	}
3403 
3404 	ReleaseList(c->Tcp->TcpSockList);
3405 	Free(c->Tcp);
3406 
3407 	ReleaseSock(c->FirstSock);
3408 	c->FirstSock = NULL;
3409 
3410 	ReleaseSock(c->TubeSock);
3411 	c->TubeSock = NULL;
3412 
3413 	ReleaseThread(c->Thread);
3414 	Free(c->Name);
3415 
3416 	// Release all the receive block and send block
3417 	if (c->SendBlocks)
3418 	{
3419 		LockQueue(c->SendBlocks);
3420 		{
3421 			BLOCK *b;
3422 			while (b = GetNext(c->SendBlocks))
3423 			{
3424 				FreeBlock(b);
3425 			}
3426 		}
3427 		UnlockQueue(c->SendBlocks);
3428 	}
3429 	if (c->SendBlocks2)
3430 	{
3431 		LockQueue(c->SendBlocks2);
3432 		{
3433 			BLOCK *b;
3434 			while (b = GetNext(c->SendBlocks2))
3435 			{
3436 				FreeBlock(b);
3437 			}
3438 		}
3439 		UnlockQueue(c->SendBlocks2);
3440 	}
3441 	if (c->ReceivedBlocks)
3442 	{
3443 		LockQueue(c->ReceivedBlocks);
3444 		{
3445 			BLOCK *b;
3446 			while (b = GetNext(c->ReceivedBlocks))
3447 			{
3448 				FreeBlock(b);
3449 			}
3450 		}
3451 		UnlockQueue(c->ReceivedBlocks);
3452 	}
3453 
3454 	if (c->ConnectingThreads)
3455 	{
3456 		THREAD **threads;
3457 		LockList(c->ConnectingThreads);
3458 		{
3459 			num = LIST_NUM(c->ConnectingThreads);
3460 			threads = ToArray(c->ConnectingThreads);
3461 			for (i = 0;i < num;i++)
3462 			{
3463 				ReleaseThread(threads[i]);
3464 			}
3465 			Free(threads);
3466 		}
3467 		UnlockList(c->ConnectingThreads);
3468 		ReleaseList(c->ConnectingThreads);
3469 	}
3470 
3471 	if (c->ConnectingSocks)
3472 	{
3473 		SOCK **socks;
3474 		LockList(c->ConnectingSocks);
3475 		{
3476 			num = LIST_NUM(c->ConnectingSocks);
3477 			socks = ToArray(c->ConnectingSocks);
3478 			for (i = 0;i < num;i++)
3479 			{
3480 				Disconnect(socks[i]);
3481 				ReleaseSock(socks[i]);
3482 			}
3483 			Free(socks);
3484 		}
3485 		UnlockList(c->ConnectingSocks);
3486 		ReleaseList(c->ConnectingSocks);
3487 	}
3488 
3489 	if (c->RecvBuf)
3490 	{
3491 		Free(c->RecvBuf);
3492 	}
3493 
3494 	if (c->ServerX != NULL)
3495 	{
3496 		FreeX(c->ServerX);
3497 	}
3498 
3499 	if (c->ClientX != NULL)
3500 	{
3501 		FreeX(c->ClientX);
3502 	}
3503 
3504 	ReleaseQueue(c->ReceivedBlocks);
3505 	ReleaseQueue(c->SendBlocks);
3506 	ReleaseQueue(c->SendBlocks2);
3507 
3508 	DeleteCounter(c->CurrentNumConnection);
3509 
3510 	if (c->CipherName != NULL)
3511 	{
3512 		Free(c->CipherName);
3513 	}
3514 
3515 	Free(c);
3516 }
3517 
3518 // Release of the connection
ReleaseConnection(CONNECTION * c)3519 void ReleaseConnection(CONNECTION *c)
3520 {
3521 	// Validate arguments
3522 	if (c == NULL)
3523 	{
3524 		return;
3525 	}
3526 
3527 	if (Release(c->ref) == 0)
3528 	{
3529 		CleanupConnection(c);
3530 	}
3531 }
3532 
3533 // Comparison of connection
CompareConnection(void * p1,void * p2)3534 int CompareConnection(void *p1, void *p2)
3535 {
3536 	CONNECTION *c1, *c2;
3537 	if (p1 == NULL || p2 == NULL)
3538 	{
3539 		return 0;
3540 	}
3541 	c1 = *(CONNECTION **)p1;
3542 	c2 = *(CONNECTION **)p2;
3543 	if (c1 == NULL || c2 == NULL)
3544 	{
3545 		return 0;
3546 	}
3547 
3548 	return StrCmpi(c1->Name, c2->Name);
3549 }
3550 
3551 // Creating a server connection
NewServerConnection(CEDAR * cedar,SOCK * s,THREAD * t)3552 CONNECTION *NewServerConnection(CEDAR *cedar, SOCK *s, THREAD *t)
3553 {
3554 	CONNECTION *c;
3555 	// Validate arguments
3556 	if (cedar == NULL)
3557 	{
3558 		return NULL;
3559 	}
3560 
3561 	c = ZeroMalloc(sizeof(CONNECTION));
3562 	c->ConnectedTick = Tick64();
3563 	c->lock = NewLock();
3564 	c->ref = NewRef();
3565 	c->Cedar = cedar;
3566 	AddRef(c->Cedar->ref);
3567 	c->Protocol = CONNECTION_TCP;
3568 	c->Type = CONNECTION_TYPE_INIT;
3569 	c->FirstSock = s;
3570 	if (s != NULL)
3571 	{
3572 		AddRef(c->FirstSock->ref);
3573 		Copy(&c->ClientIp, &s->RemoteIP, sizeof(IP));
3574 		c->ClientPort = s->RemotePort;
3575 		StrCpy(c->ClientHostname, sizeof(c->ClientHostname), s->RemoteHostname);
3576 	}
3577 	c->Tcp = ZeroMalloc(sizeof(TCP));
3578 	c->Tcp->TcpSockList = NewList(NULL);
3579 	c->ServerMode = true;
3580 	c->Status = CONNECTION_STATUS_ACCEPTED;
3581 	c->Name = CopyStr("INITING");
3582 	c->Thread = t;
3583 	AddRef(t->ref);
3584 	c->CurrentNumConnection = NewCounter();
3585 	Inc(c->CurrentNumConnection);
3586 
3587 	c->ServerVer = cedar->Version;
3588 	c->ServerBuild = cedar->Build;
3589 	StrCpy(c->ServerStr, sizeof(c->ServerStr), cedar->ServerStr);
3590 	GetServerProductName(cedar->Server, c->ServerStr, sizeof(c->ServerStr));
3591 
3592 	if (s != NULL && s->RemoteX != NULL)
3593 	{
3594 		c->ServerX = CloneX(s->RemoteX);
3595 	}
3596 
3597 	if (s != NULL && s->Type == SOCK_INPROC)
3598 	{
3599 		// In-process socket
3600 		c->IsInProc = true;
3601 	}
3602 
3603 	// Creating a Queue
3604 	c->ReceivedBlocks = NewQueue();
3605 	c->SendBlocks = NewQueue();
3606 	c->SendBlocks2 = NewQueue();
3607 
3608 	return c;
3609 }
3610 
3611 // Creating a Client Connection
NewClientConnection(SESSION * s)3612 CONNECTION *NewClientConnection(SESSION *s)
3613 {
3614 	return NewClientConnectionEx(s, NULL, 0, 0);
3615 }
NewClientConnectionEx(SESSION * s,char * client_str,UINT client_ver,UINT client_build)3616 CONNECTION *NewClientConnectionEx(SESSION *s, char *client_str, UINT client_ver, UINT client_build)
3617 {
3618 	CONNECTION *c;
3619 
3620 	// Initialization of CONNECTION object
3621 	c = ZeroMalloc(sizeof(CONNECTION));
3622 	c->ConnectedTick = Tick64();
3623 	c->lock = NewLock();
3624 	c->ref = NewRef();
3625 	c->Cedar = s->Cedar;
3626 	AddRef(c->Cedar->ref);
3627 	c->Protocol = CONNECTION_TCP;
3628 	c->Tcp = ZeroMalloc(sizeof(TCP));
3629 	c->Tcp->TcpSockList = NewList(NULL);
3630 	c->ServerMode = false;
3631 	c->Status = CONNECTION_STATUS_CONNECTING;
3632 	c->Name = CopyStr("CLIENT_CONNECTION");
3633 	c->Session = s;
3634 	c->CurrentNumConnection = NewCounter();
3635 	c->LastCounterResetTick = Tick64();
3636 	Inc(c->CurrentNumConnection);
3637 
3638 	c->ConnectingThreads = NewList(NULL);
3639 	c->ConnectingSocks = NewList(NULL);
3640 
3641 	if (client_str == NULL)
3642 	{
3643 		c->ClientVer = s->Cedar->Version;
3644 		c->ClientBuild = s->Cedar->Build;
3645 
3646 		if (c->Session->VirtualHost == false)
3647 		{
3648 			if (c->Session->LinkModeClient == false)
3649 			{
3650 				StrCpy(c->ClientStr, sizeof(c->ClientStr), CEDAR_CLIENT_STR);
3651 			}
3652 			else
3653 			{
3654 				StrCpy(c->ClientStr, sizeof(c->ClientStr), CEDAR_SERVER_LINK_STR);
3655 			}
3656 		}
3657 		else
3658 		{
3659 			StrCpy(c->ClientStr, sizeof(c->ClientStr), CEDAR_ROUTER_STR);
3660 		}
3661 	}
3662 	else
3663 	{
3664 		c->ClientVer = client_ver;
3665 		c->ClientBuild = client_build;
3666 		StrCpy(c->ClientStr, sizeof(c->ClientStr), client_str);
3667 	}
3668 
3669 	// Server name and port number
3670 	StrCpy(c->ServerName, sizeof(c->ServerName), s->ClientOption->Hostname);
3671 	c->ServerPort = s->ClientOption->Port;
3672 
3673 	// TLS 1.0 using flag
3674 	c->DontUseTls1 = s->ClientOption->NoTls1;
3675 
3676 	// Create queues
3677 	c->ReceivedBlocks = NewQueue();
3678 	c->SendBlocks = NewQueue();
3679 	c->SendBlocks2 = NewQueue();
3680 
3681 	return c;
3682 }
3683