source: lab.git/Dev/utvpn/utvpn-unix-v101-7101-public/src/Cedar/Link.c @ 072e48b

trunk
Last change on this file since 072e48b 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: 15.0 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// Link.c
79// HUB 間リンク接続
80
81#include "CedarPch.h"
82
83// リンクサーバースレッド
84void LinkServerSessionThread(THREAD *t, void *param)
85{
86    LINK *k = (LINK *)param;
87    CONNECTION *c;
88    SESSION *s;
89    POLICY *policy;
90    wchar_t name[MAX_SIZE];
91    // 引数チェック
92    if (t == NULL || param == NULL)
93    {
94        return;
95    }
96
97    // サーバーコネクションの作成
98    c = NewServerConnection(k->Cedar, NULL, t);
99    c->Protocol = CONNECTION_HUB_LINK_SERVER;
100
101    // ポリシーの作成
102    policy = ZeroMalloc(sizeof(POLICY));
103    Copy(policy, k->Policy, sizeof(POLICY));
104
105    // サーバーセッションの作成
106    s = NewServerSession(k->Cedar, c, k->Hub, LINK_USER_NAME, policy);
107    s->LinkModeServer = true;
108    s->Link = k;
109    c->Session = s;
110    ReleaseConnection(c);
111
112    // ユーザー名
113    s->Username = CopyStr(LINK_USER_NAME_PRINT);
114
115    k->ServerSession = s;
116    AddRef(k->ServerSession->ref);
117
118    // 初期化完了を通知
119    NoticeThreadInit(t);
120
121    UniStrCpy(name, sizeof(name), k->Option->AccountName);
122    HLog(s->Hub, "LH_LINK_START", name, s->Name);
123
124    // セッションのメイン関数
125    SessionMain(s);
126
127    HLog(s->Hub, "LH_LINK_STOP", name);
128
129    ReleaseSession(s);
130}
131
132// パケットアダプタ初期化
133bool LinkPaInit(SESSION *s)
134{
135    LINK *k;
136    THREAD *t;
137    // 引数チェック
138    if (s == NULL || (k = (LINK *)s->PacketAdapter->Param) == NULL)
139    {
140        return false;
141    }
142
143    // 送信パケットキューの作成
144    k->SendPacketQueue = NewQueue();
145
146    // リンクサーバースレッドの作成
147    t = NewThread(LinkServerSessionThread, (void *)k);
148    WaitThreadInit(t);
149
150    ReleaseThread(t);
151
152    return true;
153}
154
155// キャンセルオブジェクトの取得
156CANCEL *LinkPaGetCancel(SESSION *s)
157{
158    LINK *k;
159    // 引数チェック
160    if (s == NULL || (k = (LINK *)s->PacketAdapter->Param) == NULL)
161    {
162        return NULL;
163    }
164
165    return NULL;
166}
167
168// 次のパケットを取得
169UINT LinkPaGetNextPacket(SESSION *s, void **data)
170{
171    LINK *k;
172    UINT ret = 0;
173    // 引数チェック
174    if (s == NULL || data == NULL || (k = (LINK *)s->PacketAdapter->Param) == NULL)
175    {
176        return INFINITE;
177    }
178
179    // キューにパケットが溜まっているかどうか調べる
180    LockQueue(k->SendPacketQueue);
181    {
182        BLOCK *block = GetNext(k->SendPacketQueue);
183
184        if (block != NULL)
185        {
186            // パケットがあった
187            *data = block->Buf;
188            ret = block->Size;
189            // 構造体のメモリは破棄する
190            Free(block);
191        }
192    }
193    UnlockQueue(k->SendPacketQueue);
194
195    return ret;
196}
197
198// 受信したパケットを書き込み
199bool LinkPaPutPacket(SESSION *s, void *data, UINT size)
200{
201    LINK *k;
202    BLOCK *block;
203    SESSION *server_session;
204    CONNECTION *server_connection;
205    // 引数チェック
206    if (s == NULL || (k = (LINK *)s->PacketAdapter->Param) == NULL)
207    {
208        return false;
209    }
210
211    server_session = k->ServerSession;
212    server_connection = server_session->Connection;
213
214    // ここにはリンク接続先の HUB から届いたパケットが来るので
215    // サーバーセッションの ReceivedBlocks に届けてあげる
216    if (data != NULL)
217    {
218        block = NewBlock(data, size, 0);
219
220        LockQueue(server_connection->ReceivedBlocks);
221        {
222            InsertQueue(server_connection->ReceivedBlocks, block);
223        }
224        UnlockQueue(server_connection->ReceivedBlocks);
225    }
226    else
227    {
228        // data == NULL のとき、すべてのパケットを格納し終わったので
229        // Cancel を発行する
230        Cancel(server_session->Cancel1);
231
232        if (k->Hub != NULL && k->Hub->Option != NULL && k->Hub->Option->YieldAfterStorePacket)
233        {
234            YieldCpu();
235        }
236    }
237
238    return true;
239}
240
241// パケットアダプタの解放
242void LinkPaFree(SESSION *s)
243{
244    LINK *k;
245    // 引数チェック
246    if (s == NULL || (k = (LINK *)s->PacketAdapter->Param) == NULL)
247    {
248        return;
249    }
250
251    // サーバーセッションの停止
252    StopSession(k->ServerSession);
253    ReleaseSession(k->ServerSession);
254
255    // 送信パケットキューの解放
256    LockQueue(k->SendPacketQueue);
257    {
258        BLOCK *block;
259        while (block = GetNext(k->SendPacketQueue))
260        {
261            FreeBlock(block);
262        }
263    }
264    UnlockQueue(k->SendPacketQueue);
265
266    ReleaseQueue(k->SendPacketQueue);
267}
268
269// パケットアダプタ
270PACKET_ADAPTER *LinkGetPacketAdapter()
271{
272    return NewPacketAdapter(LinkPaInit, LinkPaGetCancel, LinkPaGetNextPacket,
273        LinkPaPutPacket, LinkPaFree);
274}
275
276// すべてのリンクの解放
277void ReleaseAllLink(HUB *h)
278{
279    LINK **kk;
280    UINT num, i;
281    // 引数チェック
282    if (h == NULL)
283    {
284        return;
285    }
286
287    LockList(h->LinkList);
288    {
289        num = LIST_NUM(h->LinkList);
290        kk = ToArray(h->LinkList);
291        DeleteAll(h->LinkList);
292    }
293    UnlockList(h->LinkList);
294
295    for (i = 0;i < num;i++)
296    {
297        LINK *k = kk[i];
298
299        ReleaseLink(k);
300    }
301
302    Free(kk);
303}
304
305// リンクの解放
306void ReleaseLink(LINK *k)
307{
308    // 引数チェック
309    if (k == NULL)
310    {
311        return;
312    }
313
314    if (Release(k->ref) == 0)
315    {
316        CleanupLink(k);
317    }
318}
319
320// リンクのクリーンアップ
321void CleanupLink(LINK *k)
322{
323    // 引数チェック
324    if (k == NULL)
325    {
326        return;
327    }
328
329    DeleteLock(k->lock);
330    if (k->ClientSession)
331    {
332        ReleaseSession(k->ClientSession);
333    }
334    Free(k->Option);
335    CiFreeClientAuth(k->Auth);
336    Free(k->Policy);
337
338    if (k->ServerCert != NULL)
339    {
340        FreeX(k->ServerCert);
341    }
342
343    Free(k);
344}
345
346// リンクをオンラインにする
347void SetLinkOnline(LINK *k)
348{
349    // 引数チェック
350    if (k == NULL)
351    {
352        return;
353    }
354
355    if (k->Offline == false)
356    {
357        return;
358    }
359
360    k->Offline = false;
361    StartLink(k);
362}
363
364// リンクをオフラインにする
365void SetLinkOffline(LINK *k)
366{
367    // 引数チェック
368    if (k == NULL)
369    {
370        return;
371    }
372
373    if (k->Offline)
374    {
375        return;
376    }
377
378    StopLink(k);
379    k->Offline = true;
380}
381
382// リンクの削除
383void DelLink(HUB *hub, LINK *k)
384{
385    // 引数チェック
386    if (hub == NULL || k == NULL)
387    {
388        return;
389    }
390
391    LockList(hub->LinkList);
392    {
393        if (Delete(hub->LinkList, k))
394        {
395            ReleaseLink(k);
396        }
397    }
398    UnlockList(hub->LinkList);
399}
400
401// すべてのリンクの開始
402void StartAllLink(HUB *h)
403{
404    // 引数チェック
405    if (h == NULL)
406    {
407        return;
408    }
409
410    LockList(h->LinkList);
411    {
412        UINT i;
413        for (i = 0;i < LIST_NUM(h->LinkList);i++)
414        {
415            LINK *k = (LINK *)LIST_DATA(h->LinkList, i);
416
417            if (k->Offline == false)
418            {
419                StartLink(k);
420            }
421        }
422    }
423    UnlockList(h->LinkList);
424}
425
426// すべてのリンクの停止
427void StopAllLink(HUB *h)
428{
429    LINK **link_list;
430    UINT num_link;
431    UINT i;
432    // 引数チェック
433    if (h == NULL)
434    {
435        return;
436    }
437
438    LockList(h->LinkList);
439    {
440        link_list = ToArray(h->LinkList);
441        num_link = LIST_NUM(h->LinkList);
442        for (i = 0;i < num_link;i++)
443        {
444            AddRef(link_list[i]->ref);
445        }
446    }
447    UnlockList(h->LinkList);
448
449    for (i = 0;i < num_link;i++)
450    {
451        StopLink(link_list[i]);
452        ReleaseLink(link_list[i]);
453    }
454
455    Free(link_list);
456}
457
458// リンクの開始
459void StartLink(LINK *k)
460{
461    PACKET_ADAPTER *pa;
462    // 引数チェック
463    if (k == NULL)
464    {
465        return;
466    }
467
468    LockLink(k);
469    {
470        if (k->Started || k->Halting)
471        {
472            UnlockLink(k);
473            return;
474        }
475        k->Started = true;
476    }
477    UnlockLink(k);
478
479    // クライアントセッション接続
480    pa = LinkGetPacketAdapter();
481    pa->Param = (void *)k;
482    LockLink(k);
483    {
484        k->ClientSession = NewClientSession(k->Cedar, k->Option, k->Auth, pa);
485    }
486    UnlockLink(k);
487}
488
489// リンクの停止
490void StopLink(LINK *k)
491{
492    // 引数チェック
493    if (k == NULL)
494    {
495        return;
496    }
497
498    LockLink(k);
499    {
500        if (k->Started == false)
501        {
502            UnlockLink(k);
503            return;
504        }
505        k->Started = false;
506        k->Halting = true;
507    }
508    UnlockLink(k);
509
510    if (k->ClientSession != NULL)
511    {
512        // クライアントセッション切断
513        StopSession(k->ClientSession);
514
515        LockLink(k);
516        {
517            ReleaseSession(k->ClientSession);
518            k->ClientSession = NULL;
519        }
520        UnlockLink(k);
521    }
522
523    LockLink(k);
524    {
525        k->Halting = false;
526    }
527    UnlockLink(k);
528}
529
530// リンクのロック
531void LockLink(LINK *k)
532{
533    // 引数チェック
534    if (k == NULL)
535    {
536        return;
537    }
538
539    Lock(k->lock);
540}
541
542// ロックのリンク解除
543void UnlockLink(LINK *k)
544{
545    // 引数チェック
546    if (k == NULL)
547    {
548        return;
549    }
550
551    Unlock(k->lock);
552}
553
554// リンク用ポリシーの正規化
555void NormalizeLinkPolicy(POLICY *p)
556{
557    // 引数チェック
558    if (p == NULL)
559    {
560        return;
561    }
562
563    p->Access = true;
564    p->NoBridge = p->NoRouting = p->PrivacyFilter =
565        p->MonitorPort = false;
566    p->MaxConnection = 32;
567    p->TimeOut = 20;
568    p->FixPassword = false;
569}
570
571// リンクの作成
572LINK *NewLink(CEDAR *cedar, HUB *hub, CLIENT_OPTION *option, CLIENT_AUTH *auth, POLICY *policy)
573{
574    CLIENT_OPTION *o;
575    LINK *k;
576    CLIENT_AUTH *a;
577    // 引数チェック
578    if (cedar == NULL || hub == NULL || option == NULL || auth == NULL || policy == NULL)
579    {
580        return NULL;
581    }
582    if (hub->Halt)
583    {
584        return NULL;
585    }
586
587    if (LIST_NUM(hub->LinkList) >= MAX_HUB_LINKS)
588    {
589        return NULL;
590    }
591
592    if (UniIsEmptyStr(option->AccountName))
593    {
594        return NULL;
595    }
596
597    // 認証方法の制限
598    if (auth->AuthType != CLIENT_AUTHTYPE_ANONYMOUS && auth->AuthType != CLIENT_AUTHTYPE_PASSWORD &&
599        auth->AuthType != CLIENT_AUTHTYPE_PLAIN_PASSWORD && auth->AuthType != CLIENT_AUTHTYPE_CERT)
600    {
601        // 匿名認証、パスワード認証、プレーンパスワード、証明書認証以外の認証方法は使用できない
602        return NULL;
603    }
604
605    // クライアントオプションのコピー (改変用)
606    o = ZeroMalloc(sizeof(CLIENT_OPTION));
607    Copy(o, option, sizeof(CLIENT_OPTION));
608    StrCpy(o->DeviceName, sizeof(o->DeviceName), LINK_DEVICE_NAME);
609
610    o->RequireBridgeRoutingMode = true; // ブリッジモードを要求する
611    o->RequireMonitorMode = false;  // モニタモードは要求しない
612
613    o->NumRetry = INFINITE;         // 接続の再試行は無限に行う
614    o->RetryInterval = 10;          // 再試行間隔は 10 秒
615    o->NoRoutingTracking = true;    // ルーティング追跡停止
616
617    // 認証データのコピー
618    a = CopyClientAuth(auth);
619    a->SecureSignProc = NULL;
620    a->CheckCertProc = NULL;
621
622    // リンク オブジェクト
623    k = ZeroMalloc(sizeof(LINK));
624    k->lock = NewLock();
625    k->ref = NewRef();
626
627    k->Cedar = cedar;
628    k->Option = o;
629    k->Auth = a;
630    k->Hub = hub;
631
632    // ポリシーのコピー
633    k->Policy = ZeroMalloc(sizeof(POLICY));
634    Copy(k->Policy, policy, sizeof(POLICY));
635
636    // ポリシーの正規化
637    NormalizeLinkPolicy(k->Policy);
638
639    // HUB のリンクリストに登録する
640    LockList(hub->LinkList);
641    {
642        Add(hub->LinkList, k);
643        AddRef(k->ref);
644    }
645    UnlockList(hub->LinkList);
646
647    return k;
648}
649
Note: See TracBrowser for help on using the repository browser.