source: lab.git/Dev/utvpn/utvpn-unix-v101-7101-public/src/Cedar/Connection.c @ a1bae3e

trunk
Last change on this file since a1bae3e was a1bae3e, checked in by mitty <mitty@…>, 12 years ago
  • copy vendor drop to trunk

git-svn-id: https://lab.mitty.jp/svn/lab/trunk@147 7d2118f6-f56c-43e7-95a2-4bb3031d96e7

  • Property mode set to 100644
File size: 63.3 KB
Line 
1// SoftEther UT-VPN SourceCode
2//
3// Copyright (C) 2004-2010 SoftEther Corporation.
4// Copyright (C) 2004-2010 University of Tsukuba, Japan.
5// Copyright (C) 2003-2010 Daiyuu Nobori.
6// All Rights Reserved.
7//
8// http://utvpn.tsukuba.ac.jp/
9//
10// This program is free software; you can redistribute it and/or
11// modify it under the terms of the GNU General Public License
12// version 2 as published by the Free Software Foundation.
13//
14// This program is distributed in the hope that it will be useful,
15// but WITHOUT ANY WARRANTY; without even the implied warranty of
16// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17// GNU General Public License for more details.
18//
19// You should have received a copy of the GNU General Public License version 2
20// along with this program; if not, write to the Free Software
21// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22//
23// このファイルは GPL バージョン 2 ライセンスで公開されています。
24// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
25// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
26// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
27// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
28//
29// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
30// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
31// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
32// ホストされています。
33// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
34// および、試験または研究のために利用が行われることを想定して配布
35// しています。
36// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
37// あります。
38// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
39// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
40// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
41// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
42// に組み込みさせていただきます。
43//
44// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
45// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
46//
47// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
48// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
49// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
50// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
51// ください。
52//
53// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
54// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
55// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
56// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
57// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
58// 公益保護にご協力いただきますようお願い申し上げます。
59//
60// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
61// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
62// を保護するための努力を行います。
63//
64// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
65// 日本国内の脆弱性情報届出受付公的機関:
66//         独立行政法人 情報処理推進機構
67//         http://www.ipa.go.jp/security/vuln/report/
68//
69// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
70// 連絡先: http://www.softether.co.jp/jp/contact/
71
72// -----------------------------------------------
73// [ChangeLog]
74// 2010.05.20
75//  新規リリース by SoftEther
76// -----------------------------------------------
77
78// Connection.c
79// コネクションマネージャ
80
81#include "CedarPch.h"
82
83// 送信に使用するかどうかの判別
84#define IS_SEND_TCP_SOCK(ts)        \
85    ((ts->Direction == TCP_BOTH) || ((ts->Direction == TCP_SERVER_TO_CLIENT) && (s->ServerMode)) || ((ts->Direction == TCP_CLIENT_TO_SERVER) && (s->ServerMode == false)))
86
87// 受信に使用するかどうかの判別
88#define IS_RECV_TCP_SOCK(ts)        \
89    ((ts->Direction == TCP_BOTH) || ((ts->Direction == TCP_SERVER_TO_CLIENT) && (s->ServerMode == false)) || ((ts->Direction == TCP_CLIENT_TO_SERVER) && (s->ServerMode)))
90
91// SECURE_SIGN の変換
92void InRpcSecureSign(SECURE_SIGN *t, PACK *p)
93{
94    // 引数チェック
95    if (t == NULL || p == NULL)
96    {
97        return;
98    }
99
100    Zero(t, sizeof(SECURE_SIGN));
101    PackGetStr(p, "SecurePublicCertName", t->SecurePublicCertName, sizeof(t->SecurePublicCertName));
102    PackGetStr(p, "SecurePrivateKeyName", t->SecurePrivateKeyName, sizeof(t->SecurePrivateKeyName));
103    t->ClientCert = PackGetX(p, "ClientCert");
104    PackGetData2(p, "Random", t->Random, sizeof(t->Random));
105    PackGetData2(p, "Signature", t->Signature, sizeof(t->Signature));
106    t->UseSecureDeviceId = PackGetInt(p, "UseSecureDeviceId");
107    t->BitmapId = PackGetInt(p, "BitmapId");
108}
109void OutRpcSecureSign(PACK *p, SECURE_SIGN *t)
110{
111    // 引数チェック
112    if (p == NULL || t == NULL)
113    {
114        return;
115    }
116
117    PackAddStr(p, "SecurePublicCertName", t->SecurePublicCertName);
118    PackAddStr(p, "SecurePrivateKeyName", t->SecurePrivateKeyName);
119    PackAddX(p, "ClientCert", t->ClientCert);
120    PackAddData(p, "Random", t->Random, sizeof(t->Random));
121    PackAddData(p, "Signature", t->Signature, sizeof(t->Signature));
122    PackAddInt(p, "UseSecureDeviceId", t->UseSecureDeviceId);
123    PackAddInt(p, "BitmapId", t->BitmapId);
124}
125void FreeRpcSecureSign(SECURE_SIGN *t)
126{
127    // 引数チェック
128    if (t == NULL)
129    {
130        return;
131    }
132
133    FreeX(t->ClientCert);
134}
135
136// 次のパケットを生成する
137BUF *NewKeepPacket(bool server_mode)
138{
139    BUF *b = NewBuf();
140    char *string = KEEP_ALIVE_STRING;
141
142    WriteBuf(b, string, StrLen(string));
143
144    SeekBuf(b, 0, 0);
145
146    return b;
147}
148
149// KEEP スレッド
150void KeepThread(THREAD *thread, void *param)
151{
152    KEEP *k = (KEEP *)param;
153    SOCK *s;
154    char server_name[MAX_HOST_NAME_LEN + 1];
155    UINT server_port;
156    bool udp_mode;
157    bool enabled;
158    // 引数チェック
159    if (thread == NULL || k == NULL)
160    {
161        return;
162    }
163
164WAIT_FOR_ENABLE:
165    Wait(k->HaltEvent, KEEP_POLLING_INTERVAL);
166
167    // 有効になるまで待機する
168    while (true)
169    {
170        enabled = false;
171        Lock(k->lock);
172        {
173            if (k->Enable)
174            {
175                if (StrLen(k->ServerName) != 0 && k->ServerPort != 0 && k->Interval != 0)
176                {
177                    StrCpy(server_name, sizeof(server_name), k->ServerName);
178                    server_port = k->ServerPort;
179                    udp_mode = k->UdpMode;
180                    enabled = true;
181                }
182            }
183        }
184        Unlock(k->lock);
185        if (enabled)
186        {
187            break;
188        }
189        if (k->Halt)
190        {
191            return;
192        }
193        Wait(k->HaltEvent, KEEP_POLLING_INTERVAL);
194    }
195
196    if (udp_mode == false)
197    {
198        // TCP モード
199        // 接続に成功するまで試行する
200        while (true)
201        {
202            UINT64 connect_started_tick;
203            bool changed = false;
204            Lock(k->lock);
205            {
206                if (StrCmpi(k->ServerName, server_name) != 0 ||
207                    k->ServerPort != server_port || k->Enable == false ||
208                    k->UdpMode)
209                {
210                    changed = true;
211                }
212            }
213            Unlock(k->lock);
214            if (changed)
215            {
216                // 設定が変更された
217                goto WAIT_FOR_ENABLE;
218            }
219
220            if (k->Halt)
221            {
222                // 停止
223                return;
224            }
225
226            // サーバーへ接続を試行
227            connect_started_tick = Tick64();
228            s = ConnectEx2(server_name, server_port, KEEP_TCP_TIMEOUT, (bool *)&k->Halt);
229            if (s != NULL)
230            {
231                // 接続成功
232                break;
233            }
234
235            // 接続失敗 設定が変更されるかタイムアウトするまで待機する
236            while (true)
237            {
238                changed = false;
239                if (k->Halt)
240                {
241                    // 停止
242                    return;
243                }
244                Lock(k->lock);
245                {
246                    if (StrCmpi(k->ServerName, server_name) != 0 ||
247                        k->ServerPort != server_port || k->Enable == false ||
248                        k->UdpMode)
249                    {
250                        changed = true;
251                    }
252                }
253                Unlock(k->lock);
254
255                if (changed)
256                {
257                    // 設定が変更された
258                    goto WAIT_FOR_ENABLE;
259                }
260
261                if ((Tick64() - connect_started_tick) >= KEEP_RETRY_INTERVAL)
262                {
263                    break;
264                }
265
266                Wait(k->HaltEvent, KEEP_POLLING_INTERVAL);
267            }
268        }
269
270        // サーバーへの接続に成功した
271        // 一定時間ごとにパケットデータを送受信する
272        if (s != NULL)
273        {
274            UINT64 last_packet_sent_time = 0;
275            while (true)
276            {
277                SOCKSET set;
278                UINT ret;
279                UCHAR buf[MAX_SIZE];
280                bool changed;
281
282                InitSockSet(&set);
283                AddSockSet(&set, s);
284
285                Select(&set, KEEP_POLLING_INTERVAL, k->Cancel, NULL);
286
287                ret = Recv(s, buf, sizeof(buf), false);
288                if (ret == 0)
289                {
290                    // 切断された
291                    Disconnect(s);
292                    ReleaseSock(s);
293                    s = NULL;
294                }
295
296                if (s != NULL)
297                {
298                    if ((Tick64() - last_packet_sent_time) >= (UINT64)k->Interval)
299                    {
300                        BUF *b;
301
302                        // 次のパケットを送出する
303                        last_packet_sent_time = Tick64();
304
305                        b = NewKeepPacket(k->Server);
306
307                        ret = Send(s, b->Buf, b->Size, false);
308                        FreeBuf(b);
309
310                        if (ret == 0)
311                        {
312                            // 切断された
313                            Disconnect(s);
314                            ReleaseSock(s);
315                            s = NULL;
316                        }
317                    }
318                }
319
320                changed = false;
321
322                Lock(k->lock);
323                {
324                    if (StrCmpi(k->ServerName, server_name) != 0 ||
325                        k->ServerPort != server_port || k->Enable == false ||
326                        k->UdpMode)
327                    {
328                        changed = true;
329                    }
330                }
331                Unlock(k->lock);
332
333                if (changed || s == NULL)
334                {
335                    // 設定が変更された または 切断された
336                    Disconnect(s);
337                    ReleaseSock(s);
338                    s = NULL;
339                    goto WAIT_FOR_ENABLE;
340                }
341                else
342                {
343                    if (k->Halt)
344                    {
345                        // 停止
346                        Disconnect(s);
347                        ReleaseSock(s);
348                        return;
349                    }
350                }
351            }
352        }
353    }
354    else
355    {
356        IP dest_ip;
357        // UDP モード
358        // ソケット作成が成功するまで試行する
359        while (true)
360        {
361            UINT64 connect_started_tick;
362            bool changed = false;
363            Lock(k->lock);
364            {
365                if (StrCmpi(k->ServerName, server_name) != 0 ||
366                    k->ServerPort != server_port || k->Enable == false ||
367                    k->UdpMode == false)
368                {
369                    changed = true;
370                }
371            }
372            Unlock(k->lock);
373            if (changed)
374            {
375                // 設定が変更された
376                goto WAIT_FOR_ENABLE;
377            }
378
379            if (k->Halt)
380            {
381                // 停止
382                return;
383            }
384
385            // ソケット作成を試行
386            connect_started_tick = Tick64();
387
388            // まず名前解決を試行
389            if (GetIP(&dest_ip, server_name))
390            {
391                // 名前解決に成功したら、次にソケットを作成
392                s = NewUDP(0);
393                if (s != NULL)
394                {
395                    // 作成成功
396                    break;
397                }
398            }
399
400            // 作成失敗 設定が変更されるかタイムアウトするまで待機する
401            while (true)
402            {
403                changed = false;
404                if (k->Halt)
405                {
406                    // 停止
407                    return;
408                }
409                Lock(k->lock);
410                {
411                    if (StrCmpi(k->ServerName, server_name) != 0 ||
412                        k->ServerPort != server_port || k->Enable == false ||
413                        k->UdpMode)
414                    {
415                        changed = true;
416                    }
417                }
418                Unlock(k->lock);
419
420                if (changed)
421                {
422                    // 設定が変更された
423                    goto WAIT_FOR_ENABLE;
424                }
425
426                if ((Tick64() - connect_started_tick) >= KEEP_RETRY_INTERVAL)
427                {
428                    break;
429                }
430
431                Wait(k->HaltEvent, KEEP_POLLING_INTERVAL);
432            }
433        }
434
435        // 一定時間ごとにパケットデータを送信する
436        if (s != NULL)
437        {
438            UINT64 last_packet_sent_time = 0;
439            while (true)
440            {
441                SOCKSET set;
442                UINT ret;
443                UCHAR buf[MAX_SIZE];
444                bool changed;
445                IP src_ip;
446                UINT src_port;
447
448                InitSockSet(&set);
449                AddSockSet(&set, s);
450
451                Select(&set, KEEP_POLLING_INTERVAL, k->Cancel, NULL);
452
453                // 受信
454                ret = RecvFrom(s, &src_ip, &src_port, buf, sizeof(buf));
455                if (ret == 0 && s->IgnoreRecvErr == false)
456                {
457                    // 切断された
458                    Disconnect(s);
459                    ReleaseSock(s);
460                    s = NULL;
461                }
462
463                if (s != NULL)
464                {
465                    if ((Tick64() - last_packet_sent_time) >= (UINT64)k->Interval)
466                    {
467                        BUF *b;
468
469                        // 次のパケットを送出する
470                        last_packet_sent_time = Tick64();
471
472                        b = NewKeepPacket(k->Server);
473
474                        ret = SendTo(s, &dest_ip, server_port, b->Buf, b->Size);
475                        FreeBuf(b);
476
477                        if (ret == 0 && s->IgnoreSendErr == false)
478                        {
479                            // 切断された
480                            Disconnect(s);
481                            ReleaseSock(s);
482                            s = NULL;
483                        }
484                    }
485                }
486
487                changed = false;
488
489                Lock(k->lock);
490                {
491                    if (StrCmpi(k->ServerName, server_name) != 0 ||
492                        k->ServerPort != server_port || k->Enable == false ||
493                        k->UdpMode == false)
494                    {
495                        changed = true;
496                    }
497                }
498                Unlock(k->lock);
499
500                if (changed || s == NULL)
501                {
502                    // 設定が変更された または 切断された
503                    Disconnect(s);
504                    ReleaseSock(s);
505                    s = NULL;
506                    goto WAIT_FOR_ENABLE;
507                }
508                else
509                {
510                    if (k->Halt)
511                    {
512                        // 停止
513                        Disconnect(s);
514                        ReleaseSock(s);
515                        return;
516                    }
517                }
518            }
519        }
520    }
521}
522
523// KEEP 停止
524void StopKeep(KEEP *k)
525{
526    // 引数チェック
527    if (k == NULL)
528    {
529        return;
530    }
531
532    k->Halt = true;
533    Set(k->HaltEvent);
534    Cancel(k->Cancel);
535
536    WaitThread(k->Thread, INFINITE);
537    ReleaseThread(k->Thread);
538    DeleteLock(k->lock);
539
540    ReleaseCancel(k->Cancel);
541    ReleaseEvent(k->HaltEvent);
542
543    Free(k);
544}
545
546// KEEP 開始
547KEEP *StartKeep()
548{
549    KEEP *k = ZeroMalloc(sizeof(KEEP));
550
551    k->lock = NewLock();
552    k->HaltEvent = NewEvent();
553    k->Cancel = NewCancel();
554
555    // スレッド開始
556    k->Thread = NewThread(KeepThread, k);
557
558    return k;
559}
560
561// クライアント認証データのコピー
562CLIENT_AUTH *CopyClientAuth(CLIENT_AUTH *a)
563{
564    CLIENT_AUTH *ret;
565    // 引数チェック
566    if (a == NULL)
567    {
568        return NULL;
569    }
570
571    ret = ZeroMallocEx(sizeof(CLIENT_AUTH), true);
572
573    ret->AuthType = a->AuthType;
574    StrCpy(ret->Username, sizeof(ret->Username), a->Username);
575
576    switch (a->AuthType)
577    {
578    case CLIENT_AUTHTYPE_ANONYMOUS:
579        // 匿名認証
580        break;
581
582    case CLIENT_AUTHTYPE_PASSWORD:
583        // パスワード認証
584        Copy(ret->HashedPassword, a->HashedPassword, SHA1_SIZE);
585        break;
586
587    case CLIENT_AUTHTYPE_PLAIN_PASSWORD:
588        // 平文パスワード認証
589        StrCpy(ret->PlainPassword, sizeof(ret->PlainPassword), a->PlainPassword);
590        break;
591
592    case CLIENT_AUTHTYPE_CERT:
593        // 証明書認証
594        ret->ClientX = CloneX(a->ClientX);
595        ret->ClientK = CloneK(a->ClientK);
596        break;
597
598    case CLIENT_AUTHTYPE_SECURE:
599        // セキュアデバイス認証
600        StrCpy(ret->SecurePublicCertName, sizeof(ret->SecurePublicCertName), a->SecurePublicCertName);
601        StrCpy(ret->SecurePrivateKeyName, sizeof(ret->SecurePrivateKeyName), a->SecurePrivateKeyName);
602        break;
603    }
604
605    return ret;
606}
607
608// 送信 FIFO にデータを書き込む (自動暗号化)
609void WriteSendFifo(SESSION *s, TCPSOCK *ts, void *data, UINT size)
610{
611    // 引数チェック
612    if (s == NULL || ts == NULL || data == NULL)
613    {
614        return;
615    }
616
617    if (s->UseFastRC4)
618    {
619        Encrypt(ts->SendKey, data, data, size);
620    }
621
622    WriteFifo(ts->SendFifo, data, size);
623}
624
625// 受信 FIFO にデータを書き込む (自動解読)
626void WriteRecvFifo(SESSION *s, TCPSOCK *ts, void *data, UINT size)
627{
628    // 引数チェック
629    if (s == NULL || ts == NULL || data == NULL)
630    {
631        return;
632    }
633
634    if (s->UseFastRC4)
635    {
636        Encrypt(ts->RecvKey, data, data, size);
637    }
638
639    WriteFifo(ts->RecvFifo, data, size);
640}
641
642// TCP ソケット受信
643UINT TcpSockRecv(SESSION *s, TCPSOCK *ts, void *data, UINT size)
644{
645    // 受信
646    return Recv(ts->Sock, data, size, s->UseSSLDataEncryption);
647}
648
649// TCP ソケット送信
650UINT TcpSockSend(SESSION *s, TCPSOCK *ts, void *data, UINT size)
651{
652    // 送信
653    return Send(ts->Sock, data, size, s->UseSSLDataEncryption);
654}
655
656// データを UDP パケットとして送信する
657void SendDataWithUDP(SOCK *s, CONNECTION *c)
658{
659    UCHAR *buf;
660    BUF *b;
661    UINT64 dummy_64 = 0;
662    UCHAR dummy_buf[16];
663    UINT64 now = Tick64();
664    UINT ret;
665    bool force_flag = false;
666    bool packet_sent = false;
667    // 引数チェック
668    if (s == NULL || c == NULL)
669    {
670        return;
671    }
672
673    // 一時バッファをヒープから確保しておく
674    if (c->RecvBuf == NULL)
675    {
676        c->RecvBuf = Malloc(RECV_BUF_SIZE);
677    }
678    buf = c->RecvBuf;
679
680    if (c->Udp->NextKeepAliveTime == 0 || c->Udp->NextKeepAliveTime <= now)
681    {
682        force_flag = true;
683    }
684
685    // バッファの作成
686    while ((c->SendBlocks->num_item > 0) || force_flag)
687    {
688        UINT *key32;
689        UINT64 *seq;
690        char *sign;
691
692        force_flag = false;
693
694        // 現在のキューからバッファを組み立てる
695        b = NewBuf();
696
697        // パケットヘッダ (16バイト) 分の領域を確保
698        WriteBuf(b, dummy_buf, sizeof(dummy_buf));
699
700        // 送信キューのパケットを詰め込む
701        LockQueue(c->SendBlocks);
702        {
703            while (true)
704            {
705                BLOCK *block;
706
707                if (b->Size > UDP_BUF_SIZE)
708                {
709                    break;
710                }
711                block = GetNext(c->SendBlocks);
712                if (block == NULL)
713                {
714                    break;
715                }
716
717                if (block->Size != 0)
718                {
719                    WriteBufInt(b, block->Size);
720                    WriteBuf(b, block->Buf, block->Size);
721
722                    c->Session->TotalSendSize += (UINT64)block->SizeofData;
723                    c->Session->TotalSendSizeReal += (UINT64)block->Size;
724                }
725
726                FreeBlock(block);
727                break;
728            }
729        }
730        UnlockQueue(c->SendBlocks);
731
732        // セッションキーとシーケンス番号の書き込み
733        sign = (char *)(((UCHAR *)b->Buf));
734        key32 = (UINT *)(((UCHAR *)b->Buf + 4));
735        seq = (UINT64 *)(((UCHAR *)b->Buf + 8));
736        Copy(sign, SE_UDP_SIGN, 4);
737        *key32 = Endian32(c->Session->SessionKey32);
738        *seq = Endian64(c->Udp->Seq++); // シーケンス番号をインクリメントする
739
740//      InsertQueue(c->Udp->BufferQueue, b);
741
742        packet_sent = true;
743/*  }
744
745    // バッファの送信
746    while (c->Udp->BufferQueue->num_item != 0)
747    {
748        FIFO *f = c->Udp->BufferQueue->fifo;
749        BUF **pb = (BUF**)(((UCHAR *)f->p) + f->pos);
750        BUF *b = *pb;
751
752*/      ret = SendTo(s, &c->Udp->ip, c->Udp->port, b->Buf, b->Size);
753        if (ret == SOCK_LATER)
754        {
755            // ブロッキング
756            Debug(".");
757//          break;
758        }
759        if (ret != b->Size)
760        {
761            if (s->IgnoreSendErr == false)
762            {
763                // エラー
764                Debug("******* SendTo Error !!!\n");
765            }
766        }
767
768        // メモリ解放
769        FreeBuf(b);
770//      GetNext(c->Udp->BufferQueue);
771    }
772
773    if (packet_sent)
774    {
775        // KeepAlive 時刻更新
776        c->Udp->NextKeepAliveTime = now + (UINT64)GenNextKeepAliveSpan(c);
777    }
778}
779
780// UDP パケットのデータをコネクションに書き込む
781void PutUDPPacketData(CONNECTION *c, void *data, UINT size)
782{
783    BUF *b;
784    char sign[4];
785    // 引数チェック
786    if (c == NULL || data == NULL)
787    {
788        return;
789    }
790
791    // プロトコルを調べる
792    if (c->Protocol != CONNECTION_UDP)
793    {
794        // UDP プロトコルは利用されていない
795        return;
796    }
797
798    // バッファ構成
799    b = NewBuf();
800    WriteBuf(b, data, size);
801
802    SeekBuf(b, 0, 0);
803    ReadBuf(b, sign, 4);
804
805    // サイン確認
806    if (Cmp(sign, SE_UDP_SIGN, 4) == 0)
807    {
808        UINT key32;
809
810        // セッションキー番号
811        key32 = ReadBufInt(b);
812
813        if (c->Session->SessionKey32 == key32)
814        {
815            UINT64 seq;
816
817            // シーケンス番号読み込み
818            ReadBuf(b, &seq, sizeof(seq));
819            seq = Endian64(seq);
820
821            if ((UINT)(seq - c->Udp->RecvSeq - (UINT64)1))
822            {
823                //Debug("** UDP Seq Lost %u\n", (UINT)(seq - c->Udp->RecvSeq - (UINT64)1));
824            }
825            c->Udp->RecvSeq = seq;
826
827            //Debug("SEQ: %I32u\n", seq);
828
829            while (true)
830            {
831                UINT size;
832
833                size = ReadBufInt(b);
834                if (size == 0)
835                {
836                    break;
837                }
838                else if (size <= MAX_PACKET_SIZE)
839                {
840                    void *tmp;
841                    BLOCK *block;
842
843                    tmp = Malloc(size);
844                    if (ReadBuf(b, tmp, size) != size)
845                    {
846                        Free(tmp);
847                        break;
848                    }
849
850                    // ブロック構成
851                    block = NewBlock(tmp, size, 0);
852
853                    // ブロック挿入
854                    InsertReveicedBlockToQueue(c, block);
855                }
856            }
857
858            // 最終通信時刻を更新
859            c->Session->LastCommTime = Tick64();
860        }
861        else
862        {
863            Debug("Invalid SessionKey: 0x%X\n", key32);
864        }
865    }
866
867    FreeBuf(b);
868}
869
870// 受信キューにブロックを追加する
871void InsertReveicedBlockToQueue(CONNECTION *c, BLOCK *block)
872{
873    SESSION *s;
874    // 引数チェック
875    if (c == NULL || block == NULL)
876    {
877        return;
878    }
879
880    s = c->Session;
881   
882    if (c->Protocol == CONNECTION_TCP)
883    {
884        s->TotalRecvSizeReal += block->SizeofData;
885        s->TotalRecvSize += block->Size;
886    }
887
888    LockQueue(c->ReceivedBlocks);
889    {
890        InsertQueue(c->ReceivedBlocks, block);
891    }
892    UnlockQueue(c->ReceivedBlocks);
893}
894
895// 次の Keep-Alive パケットまでの間隔を生成 (ネットワーク負荷減少のため乱数にする)
896UINT GenNextKeepAliveSpan(CONNECTION *c)
897{
898    UINT a, b;
899    // 引数チェック
900    if (c == NULL)
901    {
902        return INFINITE;
903    }
904
905    a = c->Session->Timeout;
906    b = rand() % (a / 2);
907    b = MAX(b, a / 5);
908
909    return b;
910}
911
912// Keep-Alive パケットを送信する
913void SendKeepAlive(CONNECTION *c, TCPSOCK *ts)
914{
915    UINT size, i, num;
916    UINT size_be;
917    UCHAR *buf;
918    // 引数チェック
919    if (c == NULL || ts == NULL)
920    {
921        return;
922    }
923
924    size = rand() % MAX_KEEPALIVE_SIZE;
925    num = KEEP_ALIVE_MAGIC;
926    buf = MallocFast(size);
927
928    for (i = 0;i < size;i++)
929    {
930        buf[i] = rand();
931    }
932
933    num = Endian32(num);
934    size_be = Endian32(size);
935    WriteSendFifo(c->Session, ts, &num, sizeof(UINT));
936    WriteSendFifo(c->Session, ts, &size_be, sizeof(UINT));
937    WriteSendFifo(c->Session, ts, buf, size);
938
939    c->Session->TotalSendSize += sizeof(UINT) * 2 + size;
940    c->Session->TotalSendSizeReal += sizeof(UINT) * 2 + size;
941
942    Free(buf);
943}
944
945// ブロックの送信
946void ConnectionSend(CONNECTION *c)
947{
948    // このあたりは急いで実装したのでコードがあまり美しくない。
949    UINT i, num;
950    UINT64 now;
951    UINT min_count;
952    TCPSOCK **tcpsocks;
953    UINT size;
954    SESSION *s;
955    bool use_qos;
956    // 引数チェック
957    if (c == NULL)
958    {
959        return;
960    }
961
962    s = c->Session;
963    use_qos = s->QoS;
964
965    now = Tick64();
966
967    // プロトコル
968    if (c->Protocol == CONNECTION_TCP)
969    {
970        // TCP
971        TCP *tcp = c->Tcp;
972        TCPSOCK *ts;
973        TCPSOCK *ts_hp;
974        UINT num_available;
975        LockList(tcp->TcpSockList);
976        {
977            num = LIST_NUM(tcp->TcpSockList);
978            tcpsocks = ToArrayEx(tcp->TcpSockList, true);
979        }
980        UnlockList(tcp->TcpSockList);
981
982        // 送信に使用するソケットを選択する
983        // 遅延回数が最も少ないソケットを選出
984        min_count = INFINITE;
985        ts = NULL;
986        ts_hp = NULL;
987
988        num_available = 0;
989
990        for (i = 0;i < num;i++)
991        {
992            TCPSOCK *tcpsock = tcpsocks[i];
993            if (tcpsock->Sock->Connected && tcpsock->Sock->AsyncMode &&
994                IS_SEND_TCP_SOCK(tcpsock))
995            {
996                // KeepAlive の処理
997                if (now >= tcpsock->NextKeepAliveTime || tcpsock->NextKeepAliveTime == 0)
998                {
999                    // KeepAlive を打つ
1000                    SendKeepAlive(c, tcpsock);
1001                    tcpsock->NextKeepAliveTime = now + (UINT64)GenNextKeepAliveSpan(c);
1002                }
1003
1004                // 送信に利用可能なソケット数を計測する
1005                num_available++;
1006
1007                ts_hp = tcpsock;
1008            }
1009        }
1010
1011        for (i = 0;i < num;i++)
1012        {
1013            TCPSOCK *tcpsock = tcpsocks[i];
1014            if (tcpsock->Sock->Connected && tcpsock->Sock->AsyncMode &&
1015                IS_SEND_TCP_SOCK(tcpsock))
1016            {
1017                // ソケットの選出
1018                bool b = false;
1019
1020                if (use_qos == false)
1021                {
1022                    b = true;
1023                }
1024                else if (num_available < 2)
1025                {
1026                    b = true;
1027                }
1028                else if (tcpsock != ts_hp)
1029                {
1030                    b = true;
1031                }
1032
1033                if (b)
1034                {
1035                    if (tcpsock->LateCount <= min_count)
1036                    {
1037                        min_count = tcpsock->LateCount;
1038                        ts = tcpsock;
1039                    }
1040                }
1041            }
1042        }
1043
1044        if (use_qos == false)
1045        {
1046            ts_hp = ts;
1047        }
1048
1049        if (ts == NULL || ts_hp == NULL)
1050        {
1051            // 現在 送信可能なソケットが存在しない
1052        }
1053        else
1054        {
1055            TCPSOCK *tss;
1056            UINT j;
1057            QUEUE *q;
1058
1059            for (j = 0;j < 2;j++)
1060            {
1061                if (j == 0)
1062                {
1063                    q = c->SendBlocks2;
1064                    tss = ts_hp;
1065                }
1066                else
1067                {
1068                    q = c->SendBlocks;
1069                    tss = ts;
1070                }
1071                // 選択されたソケット ts に対して送信データを予約する
1072                LockQueue(c->SendBlocks);
1073                if (q->num_item != 0)
1074                {
1075                    UINT num_data;
1076                    BLOCK *b;
1077
1078                    if (tss->SendFifo->size >= MAX((MAX_SEND_SOCKET_QUEUE_SIZE / s->MaxConnection), MIN_SEND_SOCKET_QUEUE_SIZE))
1079                    {
1080                        // 送信ソケットキューのサイズが超過
1081                        // 送信できない
1082                        while (b = GetNext(q))
1083                        {
1084                            if (b != NULL)
1085                            {
1086                                c->CurrentSendQueueSize -= b->Size;
1087                                FreeBlock(b);
1088                            }
1089                        }
1090                    }
1091                    else
1092                    {
1093                        bool update_keepalive_timer = false;
1094                        // 個数データ
1095                        num_data = Endian32(q->num_item);
1096                        PROBE_DATA2("WriteSendFifo num", &num_data, sizeof(UINT));
1097                        WriteSendFifo(s, tss, &num_data, sizeof(UINT));
1098
1099                        s->TotalSendSize += sizeof(UINT);
1100                        s->TotalSendSizeReal += sizeof(UINT);
1101
1102                        while (b = GetNext(q))
1103                        {
1104                            // サイズデータ
1105                            UINT size_data;
1106                            size_data = Endian32(b->Size);
1107                            PROBE_DATA2("WriteSendFifo size", &size_data, sizeof(UINT));
1108                            WriteSendFifo(s, tss, &size_data, sizeof(UINT));
1109
1110                            c->CurrentSendQueueSize -= b->Size;
1111
1112                            s->TotalSendSize += sizeof(UINT);
1113                            s->TotalSendSizeReal += sizeof(UINT);
1114
1115                            // データ本体
1116                            PROBE_DATA2("WriteSendFifo data", b->Buf, b->Size);
1117                            WriteSendFifo(s, tss, b->Buf, b->Size);
1118
1119                            s->TotalSendSize += b->SizeofData;
1120                            s->TotalSendSizeReal += b->Size;
1121
1122                            update_keepalive_timer = true;
1123
1124                            // ブロック解放
1125                            FreeBlock(b);
1126                        }
1127
1128                        if (update_keepalive_timer)
1129                        {
1130                            // KeepAlive タイマを増加させる
1131                            tss->NextKeepAliveTime = now + (UINT64)GenNextKeepAliveSpan(c);
1132                        }
1133                    }
1134                }
1135                UnlockQueue(c->SendBlocks);
1136            }
1137        }
1138
1139        // 現在各ソケットに登録されている送信予約データを送信する
1140        for (i = 0;i < num;i++)
1141        {
1142            ts = tcpsocks[i];
1143
1144SEND_START:
1145            if (ts->Sock->Connected == false)
1146            {
1147                s->LastTryAddConnectTime = Tick64();
1148                // 通信が切断された
1149                LockList(tcp->TcpSockList);
1150                {
1151                    // ソケットリストからこのソケットを削除する
1152                    Delete(tcp->TcpSockList, ts);
1153                    // TCPSOCK の解放
1154                    FreeTcpSock(ts);
1155                    // 個数のデクリメント
1156                    Dec(c->CurrentNumConnection);
1157                    Debug("--- TCP Connection Decremented: %u (%s Line %u)\n", Count(c->CurrentNumConnection), __FILE__, __LINE__);
1158                    Debug("LIST_NUM(tcp->TcpSockList): %u\n", LIST_NUM(tcp->TcpSockList));
1159                }
1160                UnlockList(tcp->TcpSockList);
1161
1162                continue;
1163            }
1164
1165            // Fifo サイズを取得
1166            if (ts->SendFifo->size != 0)
1167            {
1168                UCHAR *buf;
1169                UINT want_send_size;
1170                // 1 バイト以上送信予定データが存在する場合のみ送信する
1171                // バッファへのポインタを取得
1172                buf = (UCHAR *)ts->SendFifo->p + ts->SendFifo->pos;
1173                want_send_size = ts->SendFifo->size;
1174
1175                PROBE_DATA2("TcpSockSend", buf, want_send_size);
1176                size = TcpSockSend(s, ts, buf, want_send_size);
1177                if (size == 0)
1178                {
1179                    // 切断された
1180                    continue;
1181                }
1182                else if (size == SOCK_LATER)
1183                {
1184                    // パケットが詰まっている
1185                    ts->LateCount++; // 遅延カウンタのインクリメント
1186                    PROBE_STR("ts->LateCount++;");
1187                }
1188                else
1189                {
1190                    // パケットが size だけ送信された
1191                    // FIFO を進める
1192                    ReadFifo(ts->SendFifo, NULL, size);
1193                    if (size < want_send_size)
1194                    {
1195                        // 予定されたデータのすべてを送信することができなかった
1196#ifdef  USE_PROBE
1197                        {
1198                            char tmp[MAX_SIZE];
1199
1200                            snprintf(tmp, sizeof(tmp), "size < want_send_size: %u < %u",
1201                                size, want_send_size);
1202
1203                            PROBE_STR(tmp);
1204                        }
1205#endif  // USE_PROBE
1206                    }
1207                    else
1208                    {
1209                        // すべてのパケットの送信が完了した (キューが無くなった)
1210                        // ので、遅延カウンタをリセットする
1211                        ts->LateCount = 0;
1212
1213                        PROBE_STR("TcpSockSend All Completed");
1214                    }
1215                    // 最終通信日時を更新
1216                    c->Session->LastCommTime = now;
1217
1218                    goto SEND_START;
1219                }
1220            }
1221        }
1222
1223        Free(tcpsocks);
1224    }
1225    else if (c->Protocol == CONNECTION_UDP)
1226    {
1227        // UDP
1228        UDP *udp = c->Udp;
1229        SOCK *sock = NULL;
1230
1231        Lock(c->lock);
1232        {
1233            sock = udp->s;
1234            if (sock != NULL)
1235            {
1236                AddRef(sock->ref);
1237            }
1238        }
1239        Unlock(c->lock);
1240
1241        if (sock != NULL)
1242        {
1243            // UDP で送信する
1244
1245            // KeepAlive 送信
1246            if ((udp->NextKeepAliveTime == 0 || udp->NextKeepAliveTime <= now) ||
1247                (c->SendBlocks->num_item != 0) || (udp->BufferQueue->num_item != 0))
1248            {
1249                // 現在のキューを UDP で送信
1250                SendDataWithUDP(sock, c);
1251            }
1252        }
1253
1254        if (sock != NULL)
1255        {
1256            ReleaseSock(sock);
1257        }
1258    }
1259    else if (c->Protocol == CONNECTION_HUB_SECURE_NAT)
1260    {
1261        // SecureNAT セッション
1262        SNAT *snat = s->SecureNAT;
1263        VH *v = snat->Nat->Virtual;
1264
1265        LockQueue(c->SendBlocks);
1266        {
1267            BLOCK *block;
1268            UINT num_packet = 0;
1269
1270            while (block = GetNext(c->SendBlocks))
1271            {
1272                num_packet++;
1273                c->CurrentSendQueueSize -= block->Size;
1274                VirtualPutPacket(v, block->Buf, block->Size);
1275                Free(block);
1276            }
1277
1278            if (num_packet != 0)
1279            {
1280                VirtualPutPacket(v, NULL, 0);
1281            }
1282        }
1283        UnlockQueue(c->SendBlocks);
1284    }
1285    else if (c->Protocol == CONNECTION_HUB_LAYER3)
1286    {
1287        // Layer-3 セッション
1288        L3IF *f = s->L3If;
1289
1290        LockQueue(c->SendBlocks);
1291        {
1292            BLOCK *block;
1293            UINT num_packet = 0;
1294
1295            while (block = GetNext(c->SendBlocks))
1296            {
1297                num_packet++;
1298                c->CurrentSendQueueSize -= block->Size;
1299                L3PutPacket(f, block->Buf, block->Size);
1300                Free(block);
1301            }
1302
1303            if (num_packet != 0)
1304            {
1305                L3PutPacket(f, NULL, 0);
1306            }
1307        }
1308        UnlockQueue(c->SendBlocks);
1309    }
1310    else if (c->Protocol == CONNECTION_HUB_LINK_SERVER)
1311    {
1312        // HUB リンク
1313        LINK *k = (LINK *)s->Link;
1314
1315        if (k != NULL)
1316        {
1317            LockQueue(c->SendBlocks);
1318            {
1319                UINT num_blocks = 0;
1320                LockQueue(k->SendPacketQueue);
1321                {
1322                    BLOCK *block;
1323
1324                    // パケットキューをクライアントスレッドに転送する
1325                    while (block = GetNext(c->SendBlocks))
1326                    {
1327                        num_blocks++;
1328                        c->CurrentSendQueueSize -= block->Size;
1329                        InsertQueue(k->SendPacketQueue, block);
1330                    }
1331                }
1332                UnlockQueue(k->SendPacketQueue);
1333
1334                if (num_blocks != 0)
1335                {
1336                    // キャンセルの発行
1337                    Cancel(k->ClientSession->Cancel1);
1338                }
1339            }
1340            UnlockQueue(c->SendBlocks);
1341        }
1342    }
1343    else if (c->Protocol == CONNECTION_HUB_BRIDGE)
1344    {
1345        // ローカルブリッジ
1346        BRIDGE *b = s->Bridge;
1347
1348        if (b != NULL)
1349        {
1350            if (b->Active)
1351            {
1352                LockQueue(c->SendBlocks);
1353                {
1354                    BLOCK *block;
1355                    UINT num_packet = c->SendBlocks->num_item; // パケット数
1356
1357                    if (num_packet != 0)
1358                    {
1359                        // パケットデータ配列
1360                        void **datas = MallocFast(sizeof(void *) * num_packet);
1361                        UINT *sizes = MallocFast(sizeof(UINT *) * num_packet);
1362                        UINT i;
1363
1364                        i = 0;
1365                        while (block = GetNext(c->SendBlocks))
1366                        {
1367                            datas[i] = block->Buf;
1368                            sizes[i] = block->Size;
1369
1370                            if (block->Size > 1514)
1371                            {
1372                                NormalizeEthMtu(b, c, block->Size);
1373                            }
1374
1375                            c->CurrentSendQueueSize -= block->Size;
1376                            Free(block);
1377                            i++;
1378                        }
1379
1380                        // パケットを書き込む
1381                        EthPutPackets(b->Eth, num_packet, datas, sizes);
1382
1383                        Free(datas);
1384                        Free(sizes);
1385                    }
1386                }
1387                UnlockQueue(c->SendBlocks);
1388            }
1389        }
1390    }
1391}
1392
1393// ブロックの受信
1394void ConnectionReceive(CONNECTION *c, CANCEL *c1, CANCEL *c2)
1395{
1396    // このあたりは急いで実装したのでコードがあまり美しくない。
1397    UINT i, num;
1398    SOCKSET set;
1399    SESSION *s;
1400    TCPSOCK **tcpsocks;
1401    UCHAR *buf;
1402    UINT size;
1403    UINT64 now;
1404    UINT time;
1405    UINT num_delayed = 0;
1406    bool no_spinlock_for_delay = false;
1407    // 引数チェック
1408    if (c == NULL)
1409    {
1410        return;
1411    }
1412
1413    PROBE_STR("ConnectionReceive");
1414
1415    s = c->Session;
1416
1417    if (s->Hub != NULL)
1418    {
1419        no_spinlock_for_delay = s->Hub->Option->NoSpinLockForPacketDelay;
1420    }
1421
1422    now = Tick64();
1423
1424    if (c->RecvBuf == NULL)
1425    {
1426        c->RecvBuf = Malloc(RECV_BUF_SIZE);
1427    }
1428    buf = c->RecvBuf;
1429
1430    // プロトコル
1431    if (c->Protocol == CONNECTION_TCP)
1432    {
1433        // TCP
1434        TCP *tcp = c->Tcp;
1435
1436        // コネクション切断間隔が指定されている場合はコネクションの切断を行う
1437        if (s->ServerMode == false)
1438        {
1439            if (s->ClientOption->ConnectionDisconnectSpan != 0)
1440            {
1441                LockList(tcp->TcpSockList);
1442                {
1443                    UINT i;
1444                    for (i = 0;i < LIST_NUM(tcp->TcpSockList);i++)
1445                    {
1446                        TCPSOCK *ts = LIST_DATA(tcp->TcpSockList, i);
1447                        if (ts->DisconnectTick != 0 &&
1448                            ts->DisconnectTick <= now)
1449                        {
1450                            Debug("ts->DisconnectTick <= now\n");
1451                            Disconnect(ts->Sock);
1452                        }
1453                    }
1454                }
1455                UnlockList(tcp->TcpSockList);
1456            }
1457        }
1458
1459        if (s->HalfConnection && (s->ServerMode == false))
1460        {
1461            // 現在の TCP コネクションの方向を調べ、
1462            // 一方向しか無く かつコネクション数が限界の場合は
1463            // 1 つ切断する
1464            LockList(tcp->TcpSockList);
1465            {
1466                UINT i, num;
1467                UINT c2s, s2c;
1468                c2s = s2c = 0;
1469                num = LIST_NUM(tcp->TcpSockList);
1470                if (num >= s->MaxConnection)
1471                {
1472                    TCPSOCK *ts;
1473                    for (i = 0;i < num;i++)
1474                    {
1475                        ts = LIST_DATA(tcp->TcpSockList, i);
1476                        if (ts->Direction == TCP_SERVER_TO_CLIENT)
1477                        {
1478                            s2c++;
1479                        }
1480                        else
1481                        {
1482                            c2s++;
1483                        }
1484                    }
1485                    if (s2c == 0 || c2s == 0)
1486                    {
1487                        // 最後のソケットを切断する
1488                        Disconnect(ts->Sock);
1489                        Debug("Disconnect (s2c=%u, c2s=%u)\n", s2c, c2s);
1490                    }
1491                }
1492            }
1493            UnlockList(tcp->TcpSockList);
1494        }
1495
1496        // ソケットセットの初期化
1497        InitSockSet(&set);
1498        LockList(tcp->TcpSockList);
1499        {
1500            num = LIST_NUM(tcp->TcpSockList);
1501            tcpsocks = ToArrayEx(tcp->TcpSockList, true);
1502        }
1503        UnlockList(tcp->TcpSockList);
1504
1505        for (i = 0;i < num;i++)
1506        {
1507            AddSockSet(&set, tcpsocks[i]->Sock);
1508        }
1509
1510        // Select
1511        time = SELECT_TIME;
1512        if (s->VirtualHost)
1513        {
1514            time = MIN(time, SELECT_TIME_FOR_NAT);
1515        }
1516        time = MIN(time, GetNextDelayedPacketTickDiff(s));
1517        num_delayed = LIST_NUM(s->DelayedPacketList);
1518
1519        PROBE_STR("ConnectionReceive: Select 0");
1520
1521        if (s->Flag1 != set.NumSocket)
1522        {
1523            Select(&set, (num_delayed == 0 ? time : 1), c1, c2);
1524            s->Flag1 = set.NumSocket;
1525        }
1526        else
1527        {
1528            if (no_spinlock_for_delay || time >= 50 || num_delayed == false)
1529            {
1530                Select(&set, (num_delayed == 0 ? time : (time > 100 ? (time - 100) : 1)), c1, c2);
1531                s->Flag1 = set.NumSocket;
1532            }
1533            else
1534            {
1535                YieldCpu();
1536            }
1537        }
1538
1539        PROBE_STR("ConnectionReceive: Select 1");
1540
1541        // TCP ソケットに到着しているデータをすべて読み込む
1542        for (i = 0;i < num;i++)
1543        {
1544            TCPSOCK *ts = tcpsocks[i];
1545            if (ts->WantSize == 0)
1546            {
1547                // 最初に必ず sizeof(UINT) だけ読み込む
1548                ts->WantSize = sizeof(UINT);
1549            }
1550
1551RECV_START:
1552            // 受信
1553            size = TcpSockRecv(s, ts, buf, RECV_BUF_SIZE);
1554            if (size == 0)
1555            {
1556DISCONNECT_THIS_TCP:
1557                s->LastTryAddConnectTime = Tick64();
1558                // 通信が切断された
1559                LockList(tcp->TcpSockList);
1560                {
1561                    // ソケットリストからこのソケットを削除する
1562                    Delete(tcp->TcpSockList, ts);
1563                    // TCPSOCK の解放
1564                    FreeTcpSock(ts);
1565                    // デクリメント
1566                    Dec(c->CurrentNumConnection);
1567                    Debug("--- TCP Connection Decremented: %u (%s Line %u)\n", Count(c->CurrentNumConnection), __FILE__, __LINE__);
1568                    Debug("LIST_NUM(tcp->TcpSockList): %u\n", LIST_NUM(tcp->TcpSockList));
1569                }
1570                UnlockList(tcp->TcpSockList);
1571
1572                continue;
1573            }
1574            else if (size == SOCK_LATER)
1575            {
1576                // 受信待ち状態: 何もしない
1577                if (IS_RECV_TCP_SOCK(ts))
1578                {
1579                    if ((now > ts->LastCommTime) && ((now - ts->LastCommTime) >= ((UINT64)s->Timeout)))
1580                    {
1581                        // このコネクションはタイムアウトした
1582                        Debug("Connection %u Timeouted.\n", i);
1583                        goto DISCONNECT_THIS_TCP;
1584                    }
1585                }
1586            }
1587            else
1588            {
1589                // 最終通信時刻を更新
1590                ts->LastCommTime = now;
1591                c->Session->LastCommTime = now;
1592
1593                // データが受信できたので FIFO に書き込む
1594                PROBE_DATA2("WriteRecvFifo", buf, size);
1595                WriteRecvFifo(s, ts, buf, size);
1596
1597                // 受信バッファがいっぱいになったら受信をやめる
1598                if (ts->RecvFifo->size < MAX_SEND_SOCKET_QUEUE_SIZE)
1599                {
1600                    goto RECV_START;
1601                }
1602            }
1603
1604            // FIFO に書き込まれたデータを処理する
1605            while (ts->RecvFifo->size >= ts->WantSize)
1606            {
1607                UCHAR *buf;
1608                void *data;
1609                BLOCK *block;
1610                UINT sz;
1611                // すでに十分な量のデータが格納されている
1612                // データのポインタを取得
1613                buf = (UCHAR *)ts->RecvFifo->p + ts->RecvFifo->pos;
1614
1615                switch (ts->Mode)
1616                {
1617                case 0:
1618                    // データブロック個数
1619                    ts->WantSize = sizeof(UINT);
1620                    Copy(&sz, buf, sizeof(UINT));
1621                    PROBE_DATA2("ReadFifo 0", buf, sizeof(UINT));
1622                    sz = Endian32(sz);
1623                    ts->NextBlockNum = sz;
1624                    ReadFifo(ts->RecvFifo, NULL, sizeof(UINT));
1625
1626                    s->TotalRecvSize += sizeof(UINT);
1627                    s->TotalRecvSizeReal += sizeof(UINT);
1628
1629                    ts->CurrentPacketNum = 0;
1630                    if (ts->NextBlockNum != 0)
1631                    {
1632                        if (ts->NextBlockNum == KEEP_ALIVE_MAGIC)
1633                        {
1634                            ts->Mode = 3;
1635                        }
1636                        else
1637                        {
1638                            ts->Mode = 1;
1639                        }
1640                    }
1641                    break;
1642
1643                case 1:
1644                    // データブロックサイズ
1645                    Copy(&sz, buf, sizeof(UINT));
1646                    sz = Endian32(sz);
1647                    PROBE_DATA2("ReadFifo 1", buf, sizeof(UINT));
1648                    if (sz > (MAX_PACKET_SIZE * 2))
1649                    {
1650                        // おかしなデータサイズを受信した
1651                        // TCP/IP 通信エラー?
1652                        Debug("%s %u sz > (MAX_PACKET_SIZE * 2)\n", __FILE__, __LINE__);
1653                        Disconnect(ts->Sock);
1654                    }
1655                    ts->NextBlockSize = MIN(sz, MAX_PACKET_SIZE * 2);
1656                    ReadFifo(ts->RecvFifo, NULL, sizeof(UINT));
1657
1658                    s->TotalRecvSize += sizeof(UINT);
1659                    s->TotalRecvSizeReal += sizeof(UINT);
1660
1661                    ts->WantSize = ts->NextBlockSize;
1662                    if (ts->WantSize != 0)
1663                    {
1664                        ts->Mode = 2;
1665                    }
1666                    else
1667                    {
1668                        ts->Mode = 1;
1669                        ts->WantSize = sizeof(UINT);
1670                        ts->CurrentPacketNum++;
1671                        if (ts->CurrentPacketNum >= ts->NextBlockNum)
1672                        {
1673                            ts->Mode = 0;
1674                        }
1675                    }
1676                    break;
1677
1678                case 2:
1679                    // データブロック本体
1680                    ts->WantSize = sizeof(UINT);
1681                    ts->CurrentPacketNum++;
1682                    data = MallocFast(ts->NextBlockSize);
1683                    Copy(data, buf, ts->NextBlockSize);
1684                    PROBE_DATA2("ReadFifo 2", buf, ts->NextBlockSize);
1685                    ReadFifo(ts->RecvFifo, NULL, ts->NextBlockSize);
1686                    block = NewBlock(data, ts->NextBlockSize, s->UseCompress ? -1 : 0);
1687
1688                    if (block->Size > MAX_PACKET_SIZE)
1689                    {
1690                        // パケットサイズ超過
1691                        FreeBlock(block);
1692                    }
1693                    else
1694                    {
1695                        // データブロックをキューに追加
1696                        InsertReveicedBlockToQueue(c, block);
1697                    }
1698
1699                    if (ts->CurrentPacketNum >= ts->NextBlockNum)
1700                    {
1701                        // すべてのデータブロックの受信が完了
1702                        ts->Mode = 0;
1703                    }
1704                    else
1705                    {
1706                        // 次のデータブロックサイズを受信
1707                        ts->Mode = 1;
1708                    }
1709                    break;
1710
1711                case 3:
1712                    // Keep-Alive パケットサイズ
1713                    ts->Mode = 4;
1714                    Copy(&sz, buf, sizeof(UINT));
1715                    PROBE_DATA2("ReadFifo 3", buf, sizeof(UINT));
1716                    sz = Endian32(sz);
1717                    if (sz > MAX_KEEPALIVE_SIZE)
1718                    {
1719                        // おかしなデータサイズを受信した
1720                        // TCP/IP 通信エラー?
1721                        Debug("%s %u sz > MAX_KEEPALIVE_SIZE\n", __FILE__, __LINE__);
1722                        Disconnect(ts->Sock);
1723                    }
1724                    ts->NextBlockSize = MIN(sz, MAX_KEEPALIVE_SIZE);
1725                    ReadFifo(ts->RecvFifo, NULL, sizeof(UINT));
1726
1727                    s->TotalRecvSize += sizeof(UINT);
1728                    s->TotalRecvSizeReal += sizeof(UINT);
1729
1730                    ts->WantSize = sz;
1731                    break;
1732
1733                case 4:
1734                    // Keep-Alive パケット本体
1735                    //Debug("KeepAlive Recved.\n");
1736                    ts->Mode = 0;
1737                    sz = ts->NextBlockSize;
1738                    PROBE_DATA2("ReadFifo 4", NULL, 0);
1739                    ReadFifo(ts->RecvFifo, NULL, sz);
1740
1741                    s->TotalRecvSize += sz;
1742                    s->TotalRecvSizeReal += sz;
1743
1744                    ts->WantSize = sizeof(UINT);
1745                    break;
1746                }
1747            }
1748        }
1749
1750        Free(tcpsocks);
1751    }
1752    else if (c->Protocol == CONNECTION_UDP)
1753    {
1754        // UDP
1755        UDP *udp = c->Udp;
1756        SOCK *sock = NULL;
1757
1758        if (s->ServerMode == false)
1759        {
1760            Lock(c->lock);
1761            {
1762                if (c->Udp->s != NULL)
1763                {
1764                    sock = c->Udp->s;
1765                    if (sock != NULL)
1766                    {
1767                        AddRef(sock->ref);
1768                    }
1769                }
1770            }
1771            Unlock(c->lock);
1772
1773            InitSockSet(&set);
1774
1775            if (sock != NULL)
1776            {
1777                AddSockSet(&set, sock);
1778            }
1779
1780            Select(&set, SELECT_TIME, c1, c2);
1781
1782            if (sock != NULL)
1783            {
1784                IP ip;
1785                UINT port;
1786                UCHAR *buf;
1787                UINT size;
1788
1789                while (true)
1790                {
1791                    buf = c->RecvBuf;
1792                    size = RecvFrom(sock, &ip, &port, buf, RECV_BUF_SIZE);
1793                    if (size == 0 && sock->IgnoreRecvErr == false)
1794                    {
1795                        Debug("UDP Socket Disconnected.\n");
1796                        Lock(c->lock);
1797                        {
1798                            ReleaseSock(udp->s);
1799                            udp->s = NULL;
1800                        }
1801                        Unlock(c->lock);
1802                        break;
1803                    }
1804                    else if (size == SOCK_LATER)
1805                    {
1806                        break;
1807                    }
1808                    else
1809                    {
1810                        if (size)
1811                        {
1812                            PutUDPPacketData(c, buf, size);
1813                        }
1814                    }
1815                }
1816            }
1817
1818            if (sock != NULL)
1819            {
1820                Release(sock->ref);
1821            }
1822        }
1823        else
1824        {
1825            Select(NULL, SELECT_TIME, c1, c2);
1826        }
1827    }
1828    else if (c->Protocol == CONNECTION_HUB_SECURE_NAT)
1829    {
1830        SNAT *snat = c->Session->SecureNAT;
1831        VH *v = snat->Nat->Virtual;
1832        UINT size;
1833        void *data;
1834        UINT num;
1835        UINT select_wait_time = SELECT_TIME_FOR_NAT;
1836
1837        if (snat->Nat != NULL && snat->Nat->Option.UseNat == false)
1838        {
1839            select_wait_time = SELECT_TIME;
1840        }
1841        else
1842        {
1843            if (snat->Nat != NULL)
1844            {
1845                LockList(v->NatTable);
1846                {
1847                    if (LIST_NUM(v->NatTable) == 0 && LIST_NUM(v->ArpWaitTable) == 0)
1848                    {
1849                        select_wait_time = SELECT_TIME;
1850                    }
1851                }
1852                UnlockList(v->NatTable);
1853            }
1854        }
1855
1856        select_wait_time = MIN(select_wait_time, GetNextDelayedPacketTickDiff(s));
1857        num_delayed = LIST_NUM(s->DelayedPacketList);
1858
1859        if (no_spinlock_for_delay || select_wait_time >= 50 || num_delayed == false)
1860        {
1861            Select(NULL, (num_delayed == 0 ? select_wait_time :
1862                (select_wait_time > 100 ? (select_wait_time - 100) : 1)), c1, c2);
1863        }
1864        else
1865        {
1866            YieldCpu();
1867        }
1868
1869        num = 0;
1870
1871        // 仮想マシンからパケットを受信する
1872        while (size = VirtualGetNextPacket(v, &data))
1873        {
1874            BLOCK *block;
1875
1876            // パケットブロックを生成
1877            block = NewBlock(data, size, 0);
1878            if (block->Size > MAX_PACKET_SIZE)
1879            {
1880                // パケットサイズ超過
1881                FreeBlock(block);
1882            }
1883            else
1884            {
1885                // データブロックをキューに追加
1886                InsertReveicedBlockToQueue(c, block);
1887            }
1888            num++;
1889            if (num >= MAX_SEND_SOCKET_QUEUE_NUM)
1890            {
1891//              WHERE;
1892                break;
1893            }
1894        }
1895    }
1896    else if (c->Protocol == CONNECTION_HUB_LINK_SERVER)
1897    {
1898        // HUB リンク
1899        // 単純に Cancel を待つだけ
1900        if (c->SendBlocks->num_item == 0)
1901        {
1902            UINT time = SELECT_TIME;
1903
1904            time = MIN(time, GetNextDelayedPacketTickDiff(s));
1905            num_delayed = LIST_NUM(s->DelayedPacketList);
1906
1907            if (no_spinlock_for_delay || time >= 50 || num_delayed == false)
1908            {
1909                Select(NULL, (num_delayed == 0 ? time : (time > 100 ? (time - 100) : 1)), c1, c2);
1910            }
1911            else
1912            {
1913                YieldCpu();
1914            }
1915        }
1916    }
1917    else if (c->Protocol == CONNECTION_HUB_LAYER3)
1918    {
1919        // Layer-3 スイッチ セッション
1920        L3IF *f = s->L3If;
1921        UINT size, num = 0;
1922        void *data;
1923
1924        if (f->SendQueue->num_item == 0)
1925        {
1926            UINT time = SELECT_TIME_FOR_NAT;
1927
1928            if (f->ArpWaitTable != NULL)
1929            {
1930                LockList(f->ArpWaitTable);
1931                {
1932                    if (LIST_NUM(f->ArpWaitTable) == 0)
1933                    {
1934                        time = SELECT_TIME;
1935                    }
1936                }
1937                UnlockList(f->ArpWaitTable);
1938            }
1939
1940            time = MIN(time, GetNextDelayedPacketTickDiff(s));
1941            num_delayed = LIST_NUM(s->DelayedPacketList);
1942
1943            if (no_spinlock_for_delay || time >= 50 || num_delayed == false)
1944            {
1945                Select(NULL, (num_delayed == 0 ? time : (time > 100 ? (time - 100) : 1)), c1, c2);
1946            }
1947            else
1948            {
1949                YieldCpu();
1950            }
1951        }
1952
1953        // 次のパケットを取得する
1954        while (size = L3GetNextPacket(f, &data))
1955        {
1956            BLOCK *block = NewBlock(data, size, 0);
1957            if (block->Size > MAX_PACKET_SIZE)
1958            {
1959                FreeBlock(block);
1960            }
1961            else
1962            {
1963                InsertReveicedBlockToQueue(c, block);
1964            }
1965
1966            num++;
1967            if (num >= MAX_SEND_SOCKET_QUEUE_NUM)
1968            {
1969                break;
1970            }
1971        }
1972    }
1973    else if (c->Protocol == CONNECTION_HUB_BRIDGE)
1974    {
1975        BRIDGE *b = c->Session->Bridge;
1976
1977        // Bridge セッション
1978        if (b->Active)
1979        {
1980            void *data;
1981            UINT ret;
1982            UINT num = 0;
1983            bool check_device_num = false;
1984            UINT time = SELECT_TIME;
1985
1986            time = MIN(time, GetNextDelayedPacketTickDiff(s));
1987            num_delayed = LIST_NUM(s->DelayedPacketList);
1988
1989            // ブリッジ動作中
1990            if (no_spinlock_for_delay || time >= 50 || num_delayed == false)
1991            {
1992                Select(NULL, (num_delayed == 0 ? time : (time > 100 ? (time - 100) : 1)), c1, c2);
1993            }
1994            else
1995            {
1996                YieldCpu();
1997            }
1998
1999            if ((b->LastNumDeviceCheck + BRIDGE_NUM_DEVICE_CHECK_SPAN) <= Tick64())
2000            {
2001                check_device_num = true;
2002                b->LastNumDeviceCheck = Tick64();
2003            }
2004
2005            // ブリッジから次のパケットを取得する
2006            while (true)
2007            {
2008                if (check_device_num && b->LastNumDevice != GetEthDeviceHash())
2009                {
2010                    ret = INFINITE;
2011                }
2012                else
2013                {
2014                    ret = EthGetPacket(b->Eth, &data);
2015                }
2016
2017#ifdef  OS_WIN32
2018                if (b->Eth != NULL && b->Eth->LoopbackBlock)
2019                {
2020                    // ブリッジにおける eth デバイスがループバックパケットを遮断
2021                    // する能力がある場合は CheckMac ポリシーを無効にする
2022                    if (c->Session != NULL && c->Session->Policy != NULL)
2023                    {
2024                        c->Session->Policy->CheckMac = false;
2025                    }
2026                }
2027#endif  // OS_WIN32
2028
2029                if (ret == INFINITE)
2030                {
2031                    // エラー発生 ブリッジを停止させる
2032                    CloseEth(b->Eth);
2033                    b->Eth = NULL;
2034                    b->Active = false;
2035                    ReleaseCancel(s->Cancel2);
2036                    s->Cancel2 = NULL;
2037
2038                    HLog(s->Hub, "LH_BRIDGE_2", s->Name, b->Name);
2039                    Debug("Bridge Device Error.\n");
2040
2041                    break;
2042                }
2043                else if (ret == 0)
2044                {
2045                    // これ以上パケットが無い
2046                    break;
2047                }
2048                else
2049                {
2050                    // パケットをキューに追加
2051                    BLOCK *block = NewBlock(data, ret, 0);
2052
2053                    PROBE_DATA2("ConnectionReceive: NewBlock", data, ret);
2054
2055                    if (ret > 1514)
2056                    {
2057                        NormalizeEthMtu(b, c, ret);
2058                    }
2059
2060                    if (block->Size > MAX_PACKET_SIZE)
2061                    {
2062                        // パケットサイズ超過
2063                        FreeBlock(block);
2064                    }
2065                    else
2066                    {
2067                        InsertReveicedBlockToQueue(c, block);
2068                    }
2069                    num++;
2070                    if (num >= MAX_SEND_SOCKET_QUEUE_NUM)
2071                    {
2072//                      WHERE;
2073                        break;
2074                    }
2075                }
2076            }
2077        }
2078        else
2079        {
2080            ETH *e;
2081            // 現在ブリッジは停止している
2082            Select(NULL, SELECT_TIME, c1, NULL);
2083
2084            if (b->LastBridgeTry == 0 || (b->LastBridgeTry + BRIDGE_TRY_SPAN) <= Tick64())
2085            {
2086                b->LastBridgeTry = Tick64();
2087
2088                // Ethernet デバイスを開こうとしてみる
2089                e = OpenEth(b->Name, b->Local, b->TapMode, b->TapMacAddress);
2090                if (e != NULL)
2091                {
2092                    // 成功
2093                    b->Eth = e;
2094                    b->Active = true;
2095                    b->LastNumDeviceCheck = Tick64();
2096                    b->LastNumDevice = GetEthDeviceHash();
2097
2098                    Debug("Bridge Open Succeed.\n");
2099
2100                    HLog(c->Session->Hub, "LH_BRIDGE_1", c->Session->Name, b->Name);
2101
2102                    s->Cancel2 = EthGetCancel(b->Eth);
2103                }
2104            }
2105        }
2106    }
2107}
2108
2109// Ethernet デバイスの MTU を正規化する
2110void NormalizeEthMtu(BRIDGE *b, CONNECTION *c, UINT packet_size)
2111{
2112    // 引数チェック
2113    if (packet_size == 0 || b == NULL || c == NULL)
2114    {
2115        return;
2116    }
2117
2118    // 現在の MTU を超えるパケットの場合は MTU を引き上げる
2119    if (EthIsChangeMtuSupported(b->Eth))
2120    {
2121        UINT currentMtu = EthGetMtu(b->Eth);
2122        if (currentMtu != 0)
2123        {
2124            if (packet_size > currentMtu)
2125            {
2126                bool ok = EthSetMtu(b->Eth, packet_size);
2127
2128                if (ok)
2129                {
2130                    HLog(c->Session->Hub, "LH_SET_MTU", c->Session->Name,
2131                        b->Name, currentMtu, packet_size, packet_size);
2132                }
2133                else
2134                {
2135                    UINT64 now = Tick64();
2136
2137                    if (b->LastChangeMtuError == 0 ||
2138                        now >= (b->LastChangeMtuError + 60000ULL))
2139                    {
2140                        HLog(c->Session->Hub, "LH_SET_MTU_ERROR", c->Session->Name,
2141                            b->Name, currentMtu, packet_size, packet_size);
2142
2143                        b->LastChangeMtuError = now;
2144                    }
2145                }
2146            }
2147        }
2148    }
2149}
2150
2151// ブロックの解放
2152void FreeBlock(BLOCK *b)
2153{
2154    // 引数チェック
2155    if (b == NULL)
2156    {
2157        return;
2158    }
2159
2160    Free(b->Buf);
2161    Free(b);
2162}
2163
2164// 新しいブロック作成
2165BLOCK *NewBlock(void *data, UINT size, int compress)
2166{
2167    BLOCK *b;
2168    // 引数チェック
2169    if (data == NULL)
2170    {
2171        return NULL;
2172    }
2173
2174    b = ZeroMallocFast(sizeof(BLOCK));
2175
2176    if (compress == 0)
2177    {
2178        // 非圧縮
2179        b->Compressed = FALSE;
2180        b->Buf = data;
2181        b->Size = size;
2182        b->SizeofData = size;
2183    }
2184    else if (compress == 1)
2185    {
2186        UINT max_size;
2187
2188        // 圧縮
2189        b->Compressed = TRUE;
2190        max_size = CalcCompress(size);
2191        b->Buf = MallocFast(max_size);
2192        b->Size = Compress(b->Buf, max_size, data, size);
2193        b->SizeofData = size;
2194
2195        // 古いデータブロックを破棄
2196        Free(data);
2197    }
2198    else
2199    {
2200        // 展開
2201        UINT max_size;
2202
2203        max_size = MAX_PACKET_SIZE;
2204        b->Buf = MallocFast(max_size);
2205        b->Size = Uncompress(b->Buf, max_size, data, size);
2206        b->SizeofData = size;
2207
2208        // 古いデータを破棄
2209        Free(data);
2210    }
2211
2212    return b;
2213}
2214
2215// TCP ソケットの作成
2216TCPSOCK *NewTcpSock(SOCK *s)
2217{
2218    TCPSOCK *ts;
2219    // 引数チェック
2220    if (s == NULL)
2221    {
2222        return NULL;
2223    }
2224
2225    ts = ZeroMalloc(sizeof(TCPSOCK));
2226
2227    ts->Sock = s;
2228    AddRef(s->ref);
2229
2230    ts->RecvFifo = NewFifo();
2231    ts->SendFifo = NewFifo();
2232    ts->LastCommTime = Tick64();
2233
2234    // タイムアウト値の解消
2235    SetTimeout(s, TIMEOUT_INFINITE);
2236
2237    return ts;
2238}
2239
2240// TCP ソケット用暗号化鍵の設定
2241void InitTcpSockRc4Key(TCPSOCK *ts, bool server_mode)
2242{
2243    RC4_KEY_PAIR *pair;
2244    CRYPT *c1, *c2;
2245    // 引数チェック
2246    if (ts == NULL)
2247    {
2248        return;
2249    }
2250
2251    pair = &ts->Rc4KeyPair;
2252
2253    c1 = NewCrypt(pair->ClientToServerKey, sizeof(pair->ClientToServerKey));
2254    c2 = NewCrypt(pair->ServerToClientKey, sizeof(pair->ServerToClientKey));
2255
2256    if (server_mode)
2257    {
2258        ts->RecvKey = c1;
2259        ts->SendKey = c2;
2260    }
2261    else
2262    {
2263        ts->SendKey = c1;
2264        ts->RecvKey = c2;
2265    }
2266}
2267
2268// TCP ソケットの解放
2269void FreeTcpSock(TCPSOCK *ts)
2270{
2271    // 引数チェック
2272    if (ts == NULL)
2273    {
2274        return;
2275    }
2276
2277    Disconnect(ts->Sock);
2278    ReleaseSock(ts->Sock);
2279    ReleaseFifo(ts->RecvFifo);
2280    ReleaseFifo(ts->SendFifo);
2281
2282    if (ts->SendKey)
2283    {
2284        FreeCrypt(ts->SendKey);
2285    }
2286    if (ts->RecvKey)
2287    {
2288        FreeCrypt(ts->RecvKey);
2289    }
2290
2291    Free(ts);
2292}
2293
2294// コネクションのトンネリングモードを終了する
2295void EndTunnelingMode(CONNECTION *c)
2296{
2297    // 引数チェック
2298    if (c == NULL)
2299    {
2300        return;
2301    }
2302
2303    // プロトコル
2304    if (c->Protocol == CONNECTION_TCP)
2305    {
2306        // TCP
2307        DisconnectTcpSockets(c);
2308    }
2309    else
2310    {
2311        // UDP
2312        DisconnectUDPSockets(c);
2313    }
2314}
2315
2316// コネクションをトンネリングモードに移行させる
2317void StartTunnelingMode(CONNECTION *c)
2318{
2319    SOCK *s;
2320    TCP *tcp;
2321    TCPSOCK *ts;
2322    IP ip;
2323    UINT port;
2324    // 引数チェック
2325    if (c == NULL)
2326    {
2327        return;
2328    }
2329
2330    tcp = c->Tcp;
2331
2332    // プロトコル
2333    if (c->Protocol == CONNECTION_TCP)
2334    {
2335        // TCP
2336        s = c->FirstSock;
2337
2338        ts = NewTcpSock(s);
2339
2340        if (c->ServerMode == false)
2341        {
2342            if (c->Session->ClientOption->ConnectionDisconnectSpan != 0)
2343            {
2344                ts->DisconnectTick = Tick64() + c->Session->ClientOption->ConnectionDisconnectSpan * (UINT64)1000;
2345            }
2346        }
2347
2348        LockList(tcp->TcpSockList);
2349        {
2350            Add(tcp->TcpSockList, ts);
2351        }
2352        UnlockList(tcp->TcpSockList);
2353        ReleaseSock(s);
2354        c->FirstSock = NULL;
2355    }
2356    else
2357    {
2358        // UDP
2359        s = c->FirstSock;
2360        Copy(&ip, &s->RemoteIP, sizeof(IP));
2361        // この時点で TCP コネクションは切断してよい
2362        c->FirstSock = NULL;
2363        Disconnect(s);
2364        ReleaseSock(s);
2365
2366        // UDP 構造体の初期化
2367        c->Udp = ZeroMalloc(sizeof(UDP));
2368
2369        if (c->ServerMode)
2370        {
2371            // サーバーモード
2372            // エントリの追加
2373            AddUDPEntry(c->Cedar, c->Session);
2374            c->Udp->s = NULL;
2375        }
2376        else
2377        {
2378            port = c->Session->ClientOption->PortUDP;
2379            // クライアントモード
2380            c->Udp->s = NewUDP(0);
2381            // IP アドレスとポート番号を書く
2382            Copy(&c->Udp->ip, &ip, sizeof(IP));
2383            c->Udp->port = port;
2384        }
2385
2386        // キュー
2387        c->Udp->BufferQueue = NewQueue();
2388    }
2389}
2390
2391// 新しいコネクションを受け付ける関数
2392void ConnectionAccept(CONNECTION *c)
2393{
2394    SOCK *s;
2395    X *x;
2396    K *k;
2397    char tmp[128];
2398    // 引数チェック
2399    if (c == NULL)
2400    {
2401        return;
2402    }
2403
2404    Debug("ConnectionAccept()\n");
2405
2406    // ソケットを取得する
2407    s = c->FirstSock;
2408    AddRef(s->ref);
2409
2410    Dec(c->Cedar->AcceptingSockets);
2411
2412    IPToStr(tmp, sizeof(tmp), &s->RemoteIP);
2413    SLog(c->Cedar, "LS_CONNECTION_START_1", tmp, s->RemoteHostname, s->RemotePort, c->Name);
2414
2415    // タイムアウト設定
2416    SetTimeout(s, CONNECTING_TIMEOUT);
2417
2418    // 暗号化アルゴリズムを指定する
2419    Lock(c->lock);
2420    {
2421        if (c->Cedar->CipherList != NULL)
2422        {
2423            SetWantToUseCipher(s, c->Cedar->CipherList);
2424        }
2425
2426        x = CloneX(c->Cedar->ServerX);
2427        k = CloneK(c->Cedar->ServerK);
2428    }
2429    Unlock(c->lock);
2430
2431    // SSL 通信を開始する
2432    Debug("StartSSL()\n");
2433    if (StartSSL(s, x, k) == false)
2434    {
2435        // 失敗
2436        Debug("Failed to StartSSL.\n");
2437        FreeX(x);
2438        FreeK(k);
2439        goto ERROR;
2440    }
2441
2442    FreeX(x);
2443    FreeK(k);
2444
2445    SLog(c->Cedar, "LS_SSL_START", c->Name, s->CipherName);
2446
2447    // 接続を受諾する
2448    if (ServerAccept(c) == false)
2449    {
2450        // 失敗
2451        Debug("ServerAccept Failed. Err = %u\n", c->Err);
2452        goto ERROR;
2453    }
2454
2455    if (c->flag1 == false)
2456    {
2457        Debug("%s %u c->flag1 == false\n", __FILE__, __LINE__);
2458        Disconnect(s);
2459    }
2460    DelConnection(c->Cedar, c);
2461    ReleaseSock(s);
2462    return;
2463
2464ERROR:
2465    Debug("ConnectionAccept() Error.\n");
2466    Disconnect(s);
2467    DelConnection(c->Cedar, c);
2468    ReleaseSock(s);
2469}
2470
2471// 現在動作しているすべての追加コネクションを張るスレッドを中断する
2472void StopAllAdditionalConnectThread(CONNECTION *c)
2473{
2474    UINT i, num;
2475    SOCK **socks;
2476    THREAD **threads;
2477    // 引数チェック
2478    if (c == NULL || c->ServerMode != false)
2479    {
2480        return;
2481    }
2482
2483    // まずソケットを切断する
2484    LockList(c->ConnectingSocks);
2485    {
2486        num = LIST_NUM(c->ConnectingSocks);
2487        socks = ToArray(c->ConnectingSocks);
2488        DeleteAll(c->ConnectingSocks);
2489    }
2490    UnlockList(c->ConnectingSocks);
2491    for (i = 0;i < num;i++)
2492    {
2493        Disconnect(socks[i]);
2494        ReleaseSock(socks[i]);
2495    }
2496    Free(socks);
2497
2498    // 次にスレッドの停止を待つ
2499    LockList(c->ConnectingThreads);
2500    {
2501        num = LIST_NUM(c->ConnectingThreads);
2502        Debug("c->ConnectingThreads: %u\n", num);
2503        threads = ToArray(c->ConnectingThreads);
2504        DeleteAll(c->ConnectingThreads);
2505    }
2506    UnlockList(c->ConnectingThreads);
2507    for (i = 0;i < num;i++)
2508    {
2509        WaitThread(threads[i], INFINITE);
2510        ReleaseThread(threads[i]);
2511    }
2512    Free(threads);
2513}
2514
2515// コネクションの停止
2516void StopConnection(CONNECTION *c, bool no_wait)
2517{
2518    // 引数チェック
2519    if (c == NULL)
2520    {
2521        return;
2522    }
2523
2524    Debug("Stop Connection: %s\n", c->Name);
2525
2526    // 停止フラグ
2527    c->Halt = true;
2528    Disconnect(c->FirstSock);
2529
2530    if (no_wait == false)
2531    {
2532        // スレッド停止まで待機
2533        WaitThread(c->Thread, INFINITE);
2534    }
2535}
2536
2537// UDP ソケットをすべて閉じる
2538void DisconnectUDPSockets(CONNECTION *c)
2539{
2540    // 引数チェック
2541    if (c == NULL)
2542    {
2543        return;
2544    }
2545    if (c->Protocol != CONNECTION_UDP)
2546    {
2547        return;
2548    }
2549
2550    // エントリの削除
2551    if (c->ServerMode)
2552    {
2553        DelUDPEntry(c->Cedar, c->Session);
2554    }
2555
2556    // UDP 構造体の削除
2557    if (c->Udp != NULL)
2558    {
2559        if (c->Udp->s != NULL)
2560        {
2561            ReleaseSock(c->Udp->s);
2562        }
2563        if (c->Udp->BufferQueue != NULL)
2564        {
2565            // キューの解放
2566            BUF *b;
2567            while (b = GetNext(c->Udp->BufferQueue))
2568            {
2569                FreeBuf(b);
2570            }
2571            ReleaseQueue(c->Udp->BufferQueue);
2572        }
2573        Free(c->Udp);
2574        c->Udp = NULL;
2575    }
2576
2577    if (c->FirstSock != NULL)
2578    {
2579        Disconnect(c->FirstSock);
2580        ReleaseSock(c->FirstSock);
2581        c->FirstSock = NULL;
2582    }
2583}
2584
2585// TCP コネクションをすべて閉じる
2586void DisconnectTcpSockets(CONNECTION *c)
2587{
2588    UINT i, num;
2589    TCP *tcp;
2590    TCPSOCK **tcpsocks;
2591    // 引数チェック
2592    if (c == NULL)
2593    {
2594        return;
2595    }
2596    if (c->Protocol != CONNECTION_TCP)
2597    {
2598        return;
2599    }
2600
2601    tcp = c->Tcp;
2602    LockList(tcp->TcpSockList);
2603    {
2604        tcpsocks = ToArray(tcp->TcpSockList);
2605        num = LIST_NUM(tcp->TcpSockList);
2606        DeleteAll(tcp->TcpSockList);
2607    }
2608    UnlockList(tcp->TcpSockList);
2609
2610    if (num != 0)
2611    {
2612        Debug("--- SOCKET STATUS ---\n");
2613        for (i = 0;i < num;i++)
2614        {
2615            TCPSOCK *ts = tcpsocks[i];
2616            Debug(" SOCK %2u: %u\n", i, ts->Sock->SendSize);
2617            FreeTcpSock(ts);
2618        }
2619    }
2620
2621    Free(tcpsocks);
2622}
2623
2624// コネクションのクリーンアップ
2625void CleanupConnection(CONNECTION *c)
2626{
2627    UINT i, num;
2628    // 引数チェック
2629    if (c == NULL)
2630    {
2631        return;
2632    }
2633
2634    DeleteLock(c->lock);
2635    ReleaseCedar(c->Cedar);
2636
2637    switch (c->Protocol)
2638    {
2639    case CONNECTION_TCP:
2640        // TCP コネクションリストの解放
2641        DisconnectTcpSockets(c);
2642        break;
2643
2644    case CONNECTION_UDP:
2645        break;
2646    }
2647
2648    ReleaseList(c->Tcp->TcpSockList);
2649    Free(c->Tcp);
2650
2651    ReleaseSock(c->FirstSock);
2652    c->FirstSock = NULL;
2653
2654    ReleaseThread(c->Thread);
2655    Free(c->Name);
2656
2657    // すべての送信ブロックと受信ブロックを解放
2658    if (c->SendBlocks)
2659    {
2660        LockQueue(c->SendBlocks);
2661        {
2662            BLOCK *b;
2663            while (b = GetNext(c->SendBlocks))
2664            {
2665                FreeBlock(b);
2666            }
2667        }
2668        UnlockQueue(c->SendBlocks);
2669    }
2670    if (c->SendBlocks2)
2671    {
2672        LockQueue(c->SendBlocks2);
2673        {
2674            BLOCK *b;
2675            while (b = GetNext(c->SendBlocks2))
2676            {
2677                FreeBlock(b);
2678            }
2679        }
2680        UnlockQueue(c->SendBlocks2);
2681    }
2682    if (c->ReceivedBlocks)
2683    {
2684        LockQueue(c->ReceivedBlocks);
2685        {
2686            BLOCK *b;
2687            while (b = GetNext(c->ReceivedBlocks))
2688            {
2689                FreeBlock(b);
2690            }
2691        }
2692        UnlockQueue(c->ReceivedBlocks);
2693    }
2694
2695    if (c->ConnectingThreads)
2696    {
2697        THREAD **threads;
2698        LockList(c->ConnectingThreads);
2699        {
2700            num = LIST_NUM(c->ConnectingThreads);
2701            threads = ToArray(c->ConnectingThreads);
2702            for (i = 0;i < num;i++)
2703            {
2704                ReleaseThread(threads[i]);
2705            }
2706            Free(threads);
2707        }
2708        UnlockList(c->ConnectingThreads);
2709        ReleaseList(c->ConnectingThreads);
2710    }
2711
2712    if (c->ConnectingSocks)
2713    {
2714        SOCK **socks;
2715        LockList(c->ConnectingSocks);
2716        {
2717            num = LIST_NUM(c->ConnectingSocks);
2718            socks = ToArray(c->ConnectingSocks);
2719            for (i = 0;i < num;i++)
2720            {
2721                Disconnect(socks[i]);
2722                ReleaseSock(socks[i]);
2723            }
2724            Free(socks);
2725        }
2726        UnlockList(c->ConnectingSocks);
2727        ReleaseList(c->ConnectingSocks);
2728    }
2729
2730    if (c->RecvBuf)
2731    {
2732        Free(c->RecvBuf);
2733    }
2734
2735    if (c->ServerX != NULL)
2736    {
2737        FreeX(c->ServerX);
2738    }
2739
2740    if (c->ClientX != NULL)
2741    {
2742        FreeX(c->ClientX);
2743    }
2744
2745    ReleaseQueue(c->ReceivedBlocks);
2746    ReleaseQueue(c->SendBlocks);
2747    ReleaseQueue(c->SendBlocks2);
2748
2749    DeleteCounter(c->CurrentNumConnection);
2750
2751    if (c->CipherName != NULL)
2752    {
2753        Free(c->CipherName);
2754    }
2755
2756    Free(c);
2757}
2758
2759// コネクションの解放
2760void ReleaseConnection(CONNECTION *c)
2761{
2762    // 引数チェック
2763    if (c == NULL)
2764    {
2765        return;
2766    }
2767
2768    if (Release(c->ref) == 0)
2769    {
2770        CleanupConnection(c);
2771    }
2772}
2773
2774// コネクションの比較
2775int CompareConnection(void *p1, void *p2)
2776{
2777    CONNECTION *c1, *c2;
2778    if (p1 == NULL || p2 == NULL)
2779    {
2780        return 0;
2781    }
2782    c1 = *(CONNECTION **)p1;
2783    c2 = *(CONNECTION **)p2;
2784    if (c1 == NULL || c2 == NULL)
2785    {
2786        return 0;
2787    }
2788
2789    return StrCmpi(c1->Name, c2->Name);
2790}
2791
2792// サーバーコネクションの作成
2793CONNECTION *NewServerConnection(CEDAR *cedar, SOCK *s, THREAD *t)
2794{
2795    CONNECTION *c;
2796    // 引数チェック
2797    if (cedar == NULL)
2798    {
2799        return NULL;
2800    }
2801
2802    c = ZeroMalloc(sizeof(CONNECTION));
2803    c->ConnectedTick = Tick64();
2804    c->lock = NewLock();
2805    c->ref = NewRef();
2806    c->Cedar = cedar;
2807    AddRef(c->Cedar->ref);
2808    c->Protocol = CONNECTION_TCP;
2809    c->Type = CONNECTION_TYPE_INIT;
2810    c->FirstSock = s;
2811    if (s != NULL)
2812    {
2813        AddRef(c->FirstSock->ref);
2814        Copy(&c->ClientIp, &s->RemoteIP, sizeof(IP));
2815        StrCpy(c->ClientHostname, sizeof(c->ClientHostname), s->RemoteHostname);
2816    }
2817    c->Tcp = ZeroMalloc(sizeof(TCP));
2818    c->Tcp->TcpSockList = NewList(NULL);
2819    c->ServerMode = true;
2820    c->Status = CONNECTION_STATUS_ACCEPTED;
2821    c->Name = CopyStr("INITING");
2822    c->Thread = t;
2823    AddRef(t->ref);
2824    c->CurrentNumConnection = NewCounter();
2825    Inc(c->CurrentNumConnection);
2826
2827    c->ServerVer = cedar->Version;
2828    c->ServerBuild = cedar->Build;
2829    StrCpy(c->ServerStr, sizeof(c->ServerStr), cedar->ServerStr);
2830    GetServerProductName(cedar->Server, c->ServerStr, sizeof(c->ServerStr));
2831
2832    if (s != NULL && s->RemoteX != NULL)
2833    {
2834        c->ServerX = CloneX(s->RemoteX);
2835    }
2836
2837    // キューの作成
2838    c->ReceivedBlocks = NewQueue();
2839    c->SendBlocks = NewQueue();
2840    c->SendBlocks2 = NewQueue();
2841
2842    return c;
2843}
2844
2845// クライアントコネクションの作成
2846CONNECTION *NewClientConnection(SESSION *s)
2847{
2848    return NewClientConnectionEx(s, NULL, 0, 0);
2849}
2850CONNECTION *NewClientConnectionEx(SESSION *s, char *client_str, UINT client_ver, UINT client_build)
2851{
2852    CONNECTION *c;
2853
2854    // CONNECTION オブジェクトの初期化
2855    c = ZeroMalloc(sizeof(CONNECTION));
2856    c->ConnectedTick = Tick64();
2857    c->lock = NewLock();
2858    c->ref = NewRef();
2859    c->Cedar = s->Cedar;
2860    AddRef(c->Cedar->ref);
2861    if (s->ClientOption->PortUDP == 0)
2862    {
2863        // TCP
2864        c->Protocol = CONNECTION_TCP;
2865        c->Tcp = ZeroMalloc(sizeof(TCP));
2866        c->Tcp->TcpSockList = NewList(NULL);
2867    }
2868    else
2869    {
2870        // UDP
2871        c->Protocol = CONNECTION_UDP;
2872    }
2873    c->ServerMode = false;
2874    c->Status = CONNECTION_STATUS_CONNECTING;
2875    c->Name = CopyStr("CLIENT_CONNECTION");
2876    c->Session = s;
2877    c->CurrentNumConnection = NewCounter();
2878    Inc(c->CurrentNumConnection);
2879
2880    c->ConnectingThreads = NewList(NULL);
2881    c->ConnectingSocks = NewList(NULL);
2882
2883    if (client_str == NULL)
2884    {
2885        c->ClientVer = s->Cedar->Version;
2886        c->ClientBuild = s->Cedar->Build;
2887
2888        if (c->Session->VirtualHost == false)
2889        {
2890            if (c->Session->LinkModeClient == false)
2891            {
2892                StrCpy(c->ClientStr, sizeof(c->ClientStr), CEDAR_CLIENT_STR);
2893            }
2894            else
2895            {
2896                StrCpy(c->ClientStr, sizeof(c->ClientStr), CEDAR_SERVER_LINK_STR);
2897            }
2898        }
2899        else
2900        {
2901            StrCpy(c->ClientStr, sizeof(c->ClientStr), CEDAR_ROUTER_STR);
2902        }
2903    }
2904    else
2905    {
2906        c->ClientVer = client_ver;
2907        c->ClientBuild = client_build;
2908        StrCpy(c->ClientStr, sizeof(c->ClientStr), client_str);
2909    }
2910
2911    // サーバー名とポート番号
2912    StrCpy(c->ServerName, sizeof(c->ServerName), s->ClientOption->Hostname);
2913    c->ServerPort = s->ClientOption->Port;
2914
2915    // TLS 1.0 使用フラグ
2916    c->DontUseTls1 = s->ClientOption->NoTls1;
2917
2918    // キューの作成
2919    c->ReceivedBlocks = NewQueue();
2920    c->SendBlocks = NewQueue();
2921    c->SendBlocks2 = NewQueue();
2922
2923    return c;
2924}
2925
2926
Note: See TracBrowser for help on using the repository browser.