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