1 // SoftEther UT-VPN SourceCode
\r
3 // Copyright (C) 2004-2010 SoftEther Corporation.
\r
4 // Copyright (C) 2004-2010 University of Tsukuba, Japan.
\r
5 // Copyright (C) 2003-2010 Daiyuu Nobori.
\r
6 // All Rights Reserved.
\r
8 // http://utvpn.tsukuba.ac.jp/
\r
10 // This program is free software; you can redistribute it and/or
\r
11 // modify it under the terms of the GNU General Public License
\r
12 // version 2 as published by the Free Software Foundation.
\r
14 // This program is distributed in the hope that it will be useful,
\r
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
17 // GNU General Public License for more details.
\r
19 // You should have received a copy of the GNU General Public License version 2
\r
20 // along with this program; if not, write to the Free Software
\r
21 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
\r
23 // このファイルは GPL バージョン 2 ライセンスで公開されています。
\r
24 // 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
\r
25 // することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
\r
26 // を除去することはできません。改変した著作物を配布する場合は、改変実施者の
\r
27 // 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
\r
29 // この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
\r
30 // ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
\r
31 // および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
\r
33 // 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
\r
34 // および、試験または研究のために利用が行われることを想定して配布
\r
36 // SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
\r
38 // 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
\r
39 // の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
\r
40 // いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
\r
41 // ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
\r
44 // GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
\r
45 // 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
\r
47 // 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
\r
48 // (SoftEther Corporation) およびその他の著作権保持者が保有しています。
\r
49 // ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
\r
50 // 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
\r
53 // お願い: どのような通信ソフトウェアにも通常は必ず未発見の
\r
54 // セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
\r
55 // UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
\r
56 // 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
\r
57 // および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
\r
58 // 公益保護にご協力いただきますようお願い申し上げます。
\r
60 // ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
\r
61 // 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
\r
64 // ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
\r
65 // 日本国内の脆弱性情報届出受付公的機関:
\r
67 // http://www.ipa.go.jp/security/vuln/report/
\r
69 // 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
\r
70 // 連絡先: http://www.softether.co.jp/jp/contact/
\r
72 // -----------------------------------------------
\r
75 // 新規リリース by SoftEther
\r
76 // -----------------------------------------------
\r
81 #include "CedarPch.h"
\r
84 void SessionMain(SESSION *s)
\r
91 bool pa_inited = false;
\r
95 bool pa_fail = false;
\r
97 bool update_hub_last_comm = false;
\r
98 UINT err = ERR_SESSION_TIMEOUT;
\r
99 UINT64 next_update_hub_last_comm = 0;
\r
100 UINT64 auto_disconnect_tick = 0;
\r
102 SOCK *msgdlg_sock = NULL;
\r
103 SOCK *nicinfo_sock = NULL;
\r
109 Debug("SessionMain: %s\n", s->Name);
\r
111 Notify(s, CLIENT_NOTIFY_ACCOUNT_CHANGED);
\r
114 s->CurrentRetryCount = 0;
\r
115 s->ConnectSucceed = true;
\r
116 s->SessionTimeOuted = false;
\r
119 policy = s->Policy;
\r
122 pa = s->PacketAdapter;
\r
123 if (pa->Init(s) == false)
\r
126 if (s->VLanDeviceErrorCount >= 2)
\r
128 s->ForceStopFlag = true;
\r
132 s->VLanDeviceErrorCount++;
\r
134 err = ERR_DEVICE_DRIVER_ERROR;
\r
139 if (s->BridgeMode == false)
\r
141 s->Cancel2 = pa->GetCancel(s);
\r
145 CANCEL *c = pa->GetCancel(s);
\r
146 CANCEL *old = s->Cancel1;
\r
148 ReleaseCancel(old);
\r
151 s->RetryFlag = false;
\r
153 s->LastCommTime = Tick64();
\r
154 if (s->ServerMode == false)
\r
156 s->NextConnectionTime = Tick64() + (UINT64)(s->ClientOption->AdditionalConnectionInterval * 1000);
\r
159 s->NumConnectionsEatablished++;
\r
160 s->CurrentConnectionEstablishTime = Tick64();
\r
161 if (s->FirstConnectionEstablisiedTime == 0)
\r
163 s->FirstConnectionEstablisiedTime = Tick64();
\r
166 if (s->ServerMode == false && s->Cedar->Client != NULL)
\r
168 if (s->Policy != NULL)
\r
170 if (s->Policy->AutoDisconnect)
\r
172 auto_disconnect_tick = s->CurrentConnectionEstablishTime +
\r
173 (UINT64)s->Policy->AutoDisconnect * 1000ULL;
\r
178 s->LastIncrementTraffic = Tick64();
\r
180 c->Err = ERR_SESSION_TIMEOUT;
\r
181 s->VLanDeviceErrorCount = 0;
\r
183 s->LastTryAddConnectTime = Tick64();
\r
185 Notify(s, CLIENT_NOTIFY_ACCOUNT_CHANGED);
\r
187 if (policy != NULL)
\r
189 // ポリシーの内容を見てモードを決定する
\r
190 if (policy->MonitorPort)
\r
192 s->IsMonitorMode = true;
\r
195 if (policy->NoRouting == false || policy->NoBridge == false)
\r
197 s->IsBridgeMode = true;
\r
201 if (s->ServerMode == false && s->Cedar->Client != NULL)
\r
203 if (IsEmptyUniStr(s->Client_Message) == false)
\r
207 Zero(&dlg, sizeof(dlg));
\r
208 if (s->ClientOption != NULL)
\r
210 StrCpy(dlg.HubName, sizeof(dlg.HubName), s->ClientOption->HubName);
\r
211 StrCpy(dlg.ServerName, sizeof(dlg.ServerName), s->ClientOption->Hostname);
\r
214 dlg.Msg = s->Client_Message;
\r
216 msgdlg_sock = CncMsgDlg(&dlg);
\r
219 if (s->Win32HideNicInfoWindow == false)
\r
223 Zero(&info, sizeof(info));
\r
224 if (s->ClientOption != NULL)
\r
226 StrCpy(info.NicName, sizeof(info.NicName), s->ClientOption->DeviceName);
\r
227 UniStrCpy(info.AccountName, sizeof(info.AccountName), s->ClientOption->AccountName);
\r
230 nicinfo_sock = CncNicInfo(&info);
\r
236 Zero(&t, sizeof(t));
\r
238 if (next_update_hub_last_comm == 0 ||
\r
239 (next_update_hub_last_comm <= Tick64()))
\r
241 next_update_hub_last_comm = Tick64() + 1000;
\r
243 if (s->Hub != NULL)
\r
245 if (update_hub_last_comm)
\r
247 Lock(s->Hub->lock);
\r
249 s->Hub->LastCommTime = SystemTime64();
\r
251 Unlock(s->Hub->lock);
\r
253 update_hub_last_comm = false;
\r
259 ClientAdditionalConnectChance(s);
\r
262 ConnectionReceive(c, s->Cancel1, s->Cancel2);
\r
264 // 受信したブロックを PacketAdapter に渡す
\r
265 LockQueue(c->ReceivedBlocks);
\r
268 packet_put = false;
\r
271 b = GetNext(c->ReceivedBlocks);
\r
277 PROBE_DATA2("GetNext", b->Buf, b->Size);
\r
279 update_hub_last_comm = true;
\r
281 if (s->ServerMode == false && b->Size >= 14)
\r
283 if (b->Buf[0] & 0x40)
\r
285 t.Recv.BroadcastCount++;
\r
286 t.Recv.BroadcastBytes += (UINT64)b->Size;
\r
290 t.Recv.UnicastCount++;
\r
291 t.Recv.UnicastBytes += (UINT64)b->Size;
\r
296 PROBE_DATA2("pa->PutPacket", b->Buf, b->Size);
\r
297 if (pa->PutPacket(s, b->Buf, b->Size) == false)
\r
300 err = ERR_DEVICE_DRIVER_ERROR;
\r
302 Debug(" Error: pa->PutPacket(Packet) Failed.\n");
\r
307 if (packet_put || s->ServerMode)
\r
309 PROBE_DATA2("pa->PutPacket", NULL, 0);
\r
310 if (pa->PutPacket(s, NULL, 0) == false)
\r
312 Debug(" Error: pa->PutPacket(NULL) Failed.\n");
\r
314 err = ERR_DEVICE_DRIVER_ERROR;
\r
318 UnlockQueue(c->ReceivedBlocks);
\r
320 // 送信するべきパケットを PacketAdapter から取得して SendBlocks に追加
\r
321 LockQueue(c->SendBlocks);
\r
323 UINT i, max_num = MAX_SEND_SOCKET_QUEUE_NUM;
\r
325 while (packet_size = pa->GetNextPacket(s, &packet))
\r
328 if (packet_size == INFINITE)
\r
330 err = ERR_DEVICE_DRIVER_ERROR;
\r
332 Debug(" Error: pa->GetNextPacket() Failed.\n");
\r
336 update_hub_last_comm = true;
\r
338 if ((c->CurrentSendQueueSize > MAX_BUFFERING_PACKET_SIZE))
\r
341 // バッファリングサイズ制限値を超過しているので破棄
\r
348 if (s->ServerMode == false && packet_size >= 14)
\r
350 UCHAR *buf = (UCHAR *)packet;
\r
353 t.Send.BroadcastCount++;
\r
354 t.Send.BroadcastBytes += (UINT64)packet_size;
\r
358 t.Send.UnicastCount++;
\r
359 t.Send.UnicastBytes += (UINT64)packet_size;
\r
362 priority = IsPriorityHighestPacketForQoS(packet, packet_size);
\r
363 b = NewBlock(packet, packet_size, s->UseCompress ? 1 : 0);
\r
364 b->PriorityQoS = priority;
\r
365 c->CurrentSendQueueSize += b->Size;
\r
367 if (b->PriorityQoS && c->Protocol == CONNECTION_TCP && s->QoS)
\r
369 InsertQueue(c->SendBlocks2, b);
\r
373 InsertQueue(c->SendBlocks, b);
\r
383 UnlockQueue(c->SendBlocks);
\r
385 AddTrafficForSession(s, &t);
\r
391 if (auto_disconnect_tick != 0 && auto_disconnect_tick <= Tick64())
\r
393 err = ERR_AUTO_DISCONNECTED;
\r
394 s->CurrentRetryCount = INFINITE;
\r
401 if (s->ForceStopFlag)
\r
403 err = ERR_USER_CANCEL;
\r
415 // ユーザーのトラフィックデータの更新
\r
416 if ((s->LastIncrementTraffic + INCREMENT_TRAFFIC_INTERVAL) <= now)
\r
418 IncrementUserTraffic(s->Hub, s->UserNameReal, s);
\r
419 s->LastIncrementTraffic = now;
\r
428 if ((hub->LastIncrementTraffic + INCREMENT_TRAFFIC_INTERVAL) <= now)
\r
430 IncrementHubTraffic(s->Hub);
\r
431 hub->LastIncrementTraffic = now;
\r
438 // リンクモードサーバーセッションの場合はタイムアウトしない
\r
439 // それ以外のセッションの場合はタイムアウトを判定する
\r
440 if (s->LinkModeServer == false && s->SecureNATMode == false && s->BridgeMode == false && s->L3SwitchMode == false)
\r
442 bool timeouted = false;
\r
444 if ((now > s->LastCommTime) && ((now - s->LastCommTime) >= ((UINT64)s->Timeout)))
\r
450 if (s->ServerMode == false && s->ClientOption != NULL && s->ClientOption->ConnectionDisconnectSpan == 0)
\r
452 if (LIST_NUM(s->Connection->Tcp->TcpSockList) < s->MaxConnection)
\r
454 if ((s->LastTryAddConnectTime +
\r
455 (UINT64)(s->ClientOption->AdditionalConnectionInterval * 1000 * 2 + CONNECTING_TIMEOUT * 2))
\r
466 Debug("** Session Timeouted.\n");
\r
467 s->SessionTimeOuted = true;
\r
468 err = ERR_SESSION_TIMEOUT;
\r
473 if (pa_fail || s->SessionTimeOuted)
\r
476 s->RetryFlag = true; // リトライフラグ
\r
482 Debug("Session %s Finishing...\n", s->Name);
\r
484 // HUB のセッション一覧から削除する
\r
488 IncrementUserTraffic(s->Hub, s->UserNameReal, s);
\r
490 DelSession(s->Hub, s);
\r
493 s->ConnectSucceed = false;
\r
494 Notify(s, CLIENT_NOTIFY_ACCOUNT_CHANGED);
\r
498 s->Connection->Halt = true;
\r
507 if (s->ServerMode == false)
\r
509 // すべての追加コネクションの作成をキャンセルする
\r
510 StopAllAdditionalConnectThread(s->Connection);
\r
516 if (s->Bridge->Active)
\r
518 CloseEth(s->Bridge->Eth);
\r
519 s->Bridge->Eth = NULL;
\r
523 if (s->Cancel2 != NULL)
\r
526 ReleaseCancel(s->Cancel2);
\r
531 EndTunnelingMode(c);
\r
533 if (nicinfo_sock != NULL)
\r
535 CncNicInfoFree(nicinfo_sock);
\r
538 if (msgdlg_sock != NULL)
\r
540 CndMsgDlgFree(msgdlg_sock);
\r
546 // 次の遅延パケットまでの時間を取得する
\r
547 UINT GetNextDelayedPacketTickDiff(SESSION *s)
\r
550 UINT ret = 0x7fffffff;
\r
558 if (LIST_NUM(s->DelayedPacketList) >= 1)
\r
560 now = TickHighres64();
\r
562 LockList(s->DelayedPacketList);
\r
564 for (i = 0;i < LIST_NUM(s->DelayedPacketList);i++)
\r
566 PKT *p = LIST_DATA(s->DelayedPacketList, i);
\r
567 UINT64 t = p->DelayedForwardTick;
\r
568 UINT d = 0x7fffffff;
\r
576 d = (UINT)(t - now);
\r
582 UnlockList(s->DelayedPacketList);
\r
588 // VoIP / QoS 機能で優先すべきパケットかどうか判定する
\r
589 bool IsPriorityHighestPacketForQoS(void *data, UINT size)
\r
598 buf = (UCHAR *)data;
\r
601 if (buf[12] == 0x08 && buf[13] == 0x00 && buf[15] != 0x00 && buf[15] != 0x08)
\r
603 // IPv4 パケットかつ ToS != 0
\r
607 if (size >= 34 && size <= 128)
\r
609 if (buf[12] == 0x08 && buf[13] == 0x00 && buf[23] == 0x01)
\r
620 // ユーザーのトラフィック情報を更新する
\r
621 void IncrementUserTraffic(HUB *hub, char *username, SESSION *s)
\r
623 TRAFFIC report_traffic;
\r
625 if (hub == NULL || username == NULL || s == NULL)
\r
630 Lock(s->TrafficLock);
\r
632 // 報告するトラフィック情報 (前回との差分) を計算する
\r
633 Zero(&report_traffic, sizeof(report_traffic));
\r
634 report_traffic.Send.BroadcastBytes =
\r
635 s->Traffic->Send.BroadcastBytes - s->OldTraffic->Send.BroadcastBytes;
\r
636 report_traffic.Send.BroadcastCount =
\r
637 s->Traffic->Send.BroadcastCount - s->OldTraffic->Send.BroadcastCount;
\r
638 report_traffic.Send.UnicastBytes =
\r
639 s->Traffic->Send.UnicastBytes - s->OldTraffic->Send.UnicastBytes;
\r
640 report_traffic.Send.UnicastCount =
\r
641 s->Traffic->Send.UnicastCount - s->OldTraffic->Send.UnicastCount;
\r
642 report_traffic.Recv.BroadcastBytes =
\r
643 s->Traffic->Recv.BroadcastBytes - s->OldTraffic->Recv.BroadcastBytes;
\r
644 report_traffic.Recv.BroadcastCount =
\r
645 s->Traffic->Recv.BroadcastCount - s->OldTraffic->Recv.BroadcastCount;
\r
646 report_traffic.Recv.UnicastBytes =
\r
647 s->Traffic->Recv.UnicastBytes - s->OldTraffic->Recv.UnicastBytes;
\r
648 report_traffic.Recv.UnicastCount =
\r
649 s->Traffic->Recv.UnicastCount - s->OldTraffic->Recv.UnicastCount;
\r
650 Copy(s->OldTraffic, s->Traffic, sizeof(TRAFFIC));
\r
652 if (hub->FarmMember == false)
\r
654 // ファームメンバーでない場合はローカルデータベースのユーザー情報を更新する
\r
657 USER *u = AcGetUser(hub, username);
\r
662 AddTraffic(u->Traffic, &report_traffic);
\r
665 if (u->Group != NULL)
\r
667 Lock(u->Group->lock);
\r
669 AddTraffic(u->Group->Traffic, &report_traffic);
\r
671 Unlock(u->Group->lock);
\r
680 // ファームメンバの場合はトラフィック差分報告リストを更新する
\r
681 AddTrafficDiff(hub, username, TRAFFIC_DIFF_USER, &report_traffic);
\r
684 Unlock(s->TrafficLock);
\r
687 // コネクションのトラフィック情報を加算
\r
688 void AddTrafficForSession(SESSION *s, TRAFFIC *t)
\r
693 if (s == NULL || t == NULL)
\r
698 Lock(s->TrafficLock);
\r
700 AddTraffic(s->Traffic, t);
\r
702 Unlock(s->TrafficLock);
\r
706 Zero(&t2, sizeof(t2));
\r
707 Copy(&t2.Recv, &t->Send, sizeof(TRAFFIC_ENTRY));
\r
708 Copy(&t2.Send, &t->Recv, sizeof(TRAFFIC_ENTRY));
\r
709 Lock(s->Cedar->TrafficLock);
\r
711 AddTraffic(s->Cedar->Traffic, &t2);
\r
713 Unlock(s->Cedar->TrafficLock);
\r
716 Lock(h->TrafficLock);
\r
718 AddTraffic(h->Traffic, &t2);
\r
720 Unlock(h->TrafficLock);
\r
724 // クライアントの追加コネクション確立のチャンス
\r
725 void ClientAdditionalConnectChance(SESSION *s)
\r
735 // サーバーモードの場合は追加接続しない
\r
738 if (s->Connection->Protocol != CONNECTION_TCP)
\r
740 // TCP プロトコル以外の場合は追加接続しない
\r
750 // 追加コネクションを張る必要があるかどうかを
\r
751 // 現在張っている または 張ろうとしているコネクション数と
\r
752 // MaxConnection プロパティを見て検討する。
\r
753 if (Count(s->Connection->CurrentNumConnection) < s->MaxConnection)
\r
756 UINT64 now = Tick64();
\r
758 // NextConnectionTime を調べてその時刻を過ぎていればコネクションを
\r
760 if (s->NextConnectionTime == 0 ||
\r
761 s->ClientOption->AdditionalConnectionInterval == 0 ||
\r
762 (s->NextConnectionTime <= now))
\r
764 // 追加コネクションを張る作業を開始する
\r
765 s->NextConnectionTime = now + (UINT64)(s->ClientOption->AdditionalConnectionInterval * 1000);
\r
766 SessionAdditionalConnect(s);
\r
781 void FreePacketAdapter(PACKET_ADAPTER *pa)
\r
793 PACKET_ADAPTER *NewPacketAdapter(PA_INIT *init, PA_GETCANCEL *getcancel, PA_GETNEXTPACKET *getnext,
\r
794 PA_PUTPACKET *put, PA_FREE *free)
\r
796 PACKET_ADAPTER *pa;
\r
798 if (init == NULL || getcancel == NULL || getnext == NULL || put == NULL || free == NULL)
\r
803 pa = ZeroMalloc(sizeof(PACKET_ADAPTER));
\r
807 pa->GetCancel = getcancel;
\r
808 pa->GetNextPacket = getnext;
\r
809 pa->PutPacket = put;
\r
814 // 追加コネクションを張るためのスレッド
\r
815 void ClientAdditionalThread(THREAD *t, void *param)
\r
820 if (t == NULL || param == NULL)
\r
825 s = (SESSION *)param;
\r
827 // s->LastTryAddConnectTime = Tick64();
\r
831 Inc(c->CurrentNumConnection);
\r
832 LockList(c->ConnectingThreads);
\r
835 Add(c->ConnectingThreads, t);
\r
838 UnlockList(c->ConnectingThreads);
\r
841 NoticeThreadInit(t);
\r
843 Debug("Additional Connection #%u\n", Count(c->CurrentNumConnection));
\r
846 if (ClientAdditionalConnect(c, t) == false)
\r
848 // 現在処理中のカウンタをデクリメントする
\r
849 Dec(c->CurrentNumConnection);
\r
853 s->LastTryAddConnectTime = Tick64();
\r
857 LockList(c->ConnectingThreads);
\r
860 if (Delete(c->ConnectingThreads, t))
\r
865 UnlockList(c->ConnectingThreads);
\r
869 // クライアントからサーバーに追加コネクションを張る
\r
870 void SessionAdditionalConnect(SESSION *s)
\r
879 // s->LastTryAddConnectTime = Tick64();
\r
882 t = NewThread(ClientAdditionalThread, (void *)s);
\r
887 // クライアントセッションをサーバーに接続する
\r
888 bool SessionConnect(SESSION *s)
\r
898 s->ClientStatus = CLIENT_STATUS_CONNECTING;
\r
900 Debug("SessionConnect() Started.\n");
\r
905 s->Err = ERR_NO_ERROR;
\r
906 if (s->Policy != NULL)
\r
914 s->CancelConnect = false;
\r
917 c = NewClientConnection(s);
\r
920 // クライアントをサーバーに接続する
\r
921 ret = ClientConnect(c);
\r
924 s->CancelConnect = false;
\r
926 if (s->Cedar->Client != NULL)
\r
928 if (s->Policy != NULL)
\r
930 if (s->Policy->NoSavePassword)
\r
932 s->Client_NoSavePassword = true;
\r
934 if (s->Account != NULL)
\r
936 Lock(s->Account->lock);
\r
938 if (s->Account->ClientAuth != NULL)
\r
940 if (s->Account->ClientAuth->AuthType == AUTHTYPE_PASSWORD ||
\r
941 s->Account->ClientAuth->AuthType == AUTHTYPE_RADIUS)
\r
943 Zero(s->Account->ClientAuth->HashedPassword, sizeof(s->Account->ClientAuth->HashedPassword));
\r
944 Zero(s->Account->ClientAuth->PlainPassword, sizeof(s->Account->ClientAuth->PlainPassword));
\r
948 Unlock(s->Account->lock);
\r
950 CiSaveConfigurationFile(s->Cedar->Client);
\r
956 if (c->ClientConnectError_NoSavePassword)
\r
958 s->Client_NoSavePassword = true;
\r
962 s->Connection = NULL;
\r
963 ReleaseConnection(c);
\r
967 if (s->Policy != NULL)
\r
979 void StopSession(SESSION *s)
\r
981 StopSessionEx(s, false);
\r
983 void StopSessionEx(SESSION *s, bool no_wait)
\r
992 s->UserCanceled = true;
\r
993 s->CancelConnect = true;
\r
996 Debug("Stop Session %s\n", s->Name);
\r
999 Cancel(s->Cancel1);
\r
1002 Set(s->HaltEvent);
\r
1004 if (s->ServerMode == false)
\r
1007 if (s->Connection)
\r
1009 StopConnection(s->Connection, no_wait);
\r
1015 if (s->Connection)
\r
1017 StopConnection(s->Connection, no_wait);
\r
1022 if (no_wait == false)
\r
1026 s->ForceStopFlag = true;
\r
1028 if (WaitThread(s->Thread, 20))
\r
1036 s->ForceStopFlag = true;
\r
1042 void CleanupSession(SESSION *s)
\r
1051 if (s->DelayedPacketList != NULL)
\r
1054 for (i = 0;i < LIST_NUM(s->DelayedPacketList);i++)
\r
1056 PKT *p = LIST_DATA(s->DelayedPacketList, i);
\r
1058 Free(p->PacketData);
\r
1062 ReleaseList(s->DelayedPacketList);
\r
1065 // クライアント接続オプションの解放
\r
1066 if (s->ClientOption != NULL)
\r
1068 Free(s->ClientOption);
\r
1072 if (s->ClientAuth != NULL)
\r
1074 if (s->ClientAuth->ClientX != NULL)
\r
1076 FreeX(s->ClientAuth->ClientX);
\r
1078 if (s->ClientAuth->ClientX != NULL)
\r
1080 FreeK(s->ClientAuth->ClientK);
\r
1082 Free(s->ClientAuth);
\r
1085 FreeTraffic(s->Traffic);
\r
1088 if (s->Thread != NULL)
\r
1090 ReleaseThread(s->Thread);
\r
1093 DeleteLock(s->lock);
\r
1095 ReleaseEvent(s->HaltEvent);
\r
1099 ReleaseCancel(s->Cancel1);
\r
1104 ReleaseCancel(s->Cancel2);
\r
1112 if (s->Connection)
\r
1114 ReleaseConnection(s->Connection);
\r
1117 Free(s->Username);
\r
1119 if (s->PacketAdapter)
\r
1121 FreePacketAdapter(s->PacketAdapter);
\r
1124 if (s->OldTraffic != NULL)
\r
1126 FreeTraffic(s->OldTraffic);
\r
1129 DeleteLock(s->TrafficLock);
\r
1131 if (s->CancelList != NULL)
\r
1133 ReleaseCancelList(s->CancelList);
\r
1136 if (s->Client_Message != NULL)
\r
1138 Free(s->Client_Message);
\r
1141 DeleteCounter(s->LoggingRecordCount);
\r
1147 void ReleaseSession(SESSION *s)
\r
1155 if (Release(s->ref) == 0)
\r
1157 CleanupSession(s);
\r
1161 // セッションの転送データサイズ合計を表示する
\r
1162 void PrintSessionTotalDataSize(SESSION *s)
\r
1171 "-- SESSION TOTAL PKT INFORMATION --\n\n"
\r
1172 " TotalSendSize: %I64u\n"
\r
1173 " TotalSendSizeReal: %I64u\n"
\r
1174 " TotalRecvSize: %I64u\n"
\r
1175 " TotalRecvSizeReal: %I64u\n"
\r
1176 " Compression Rate: %.2f%% (Send)\n"
\r
1177 " %.2f%% (Recv)\n",
\r
1178 s->TotalSendSize, s->TotalSendSizeReal,
\r
1179 s->TotalRecvSize, s->TotalRecvSizeReal,
\r
1180 (float)((double)s->TotalSendSizeReal / (double)s->TotalSendSize * 100.0f),
\r
1181 (float)((double)s->TotalRecvSizeReal / (double)s->TotalRecvSize * 100.0f)
\r
1187 void ClientThread(THREAD *t, void *param)
\r
1190 bool use_password_dlg;
\r
1191 bool no_save_password = false;
\r
1193 if (t == NULL || param == NULL)
\r
1198 Debug("ClientThread 0x%x Started.\n", t);
\r
1200 s = (SESSION *)param;
\r
1204 NoticeThreadInit(t);
\r
1206 s->ClientStatus = CLIENT_STATUS_CONNECTING;
\r
1207 s->RetryFlag = true;
\r
1208 s->CurrentRetryCount = 0;
\r
1210 Notify(s, CLIENT_NOTIFY_ACCOUNT_CHANGED);
\r
1212 if (s->Cedar->Client != NULL)
\r
1214 no_save_password = s->Cedar->Client->DontSavePassword;
\r
1217 s->Win32HideConnectWindow = s->ClientOption->HideStatusWindow;
\r
1218 s->Win32HideNicInfoWindow = s->ClientOption->HideNicInfoWindow;
\r
1222 CLog(s->Cedar->Client, "LC_CONNECT_1", s->ClientOption->AccountName, s->CurrentRetryCount + 1);
\r
1223 if (s->LinkModeClient && s->Link != NULL)
\r
1225 HLog(s->Link->Hub, "LH_CONNECT_1", s->ClientOption->AccountName, s->CurrentRetryCount + 1);
\r
1228 Debug("Trying to Connect to Server... (%u / %u)\n", s->CurrentRetryCount + 0,
\r
1229 s->ClientOption->NumRetry);
\r
1232 // s->TotalRecvSize = s->TotalRecvSizeReal =
\r
1233 // s->TotalSendSize = s->TotalSendSizeReal = 0;
\r
1234 s->NextConnectionTime = 0;
\r
1237 s->ClientStatus = CLIENT_STATUS_CONNECTING;
\r
1239 SessionConnect(s);
\r
1240 if (s->UserCanceled)
\r
1242 s->Err = ERR_USER_CANCEL;
\r
1244 Debug("Disconnected. Err = %u : %S\n", s->Err, _E(s->Err));
\r
1246 PrintSessionTotalDataSize(s);
\r
1248 CLog(s->Cedar->Client, "LC_CONNECT_ERROR", s->ClientOption->AccountName,
\r
1249 GetUniErrorStr(s->Err), s->Err);
\r
1251 if (s->LinkModeClient && s->Link != NULL)
\r
1253 HLog(s->Link->Hub, "LH_CONNECT_ERROR", s->ClientOption->AccountName,
\r
1254 GetUniErrorStr(s->Err), s->Err);
\r
1257 s->ClientStatus = CLIENT_STATUS_RETRY;
\r
1259 if (s->Link != NULL)
\r
1261 ((LINK *)s->Link)->LastError = s->Err;
\r
1264 if (s->Halt && (s->RetryFlag == false) || s->ForceStopFlag)
\r
1267 if (s->Err == ERR_DEVICE_DRIVER_ERROR)
\r
1270 wchar_t tmp[MAX_SIZE];
\r
1271 if (s->Account != NULL && s->Cedar->Client != NULL)
\r
1273 UniFormat(tmp, sizeof(tmp), _UU("ERRDLG_DEVICE_ERROR"), s->ClientOption->DeviceName,
\r
1274 s->Err, _E(s->Err));
\r
1275 MsgBox(NULL, 0x10000 | 0x40000 | 0x200000 | 0x30, tmp);
\r
1277 #endif // OS_WIN32
\r
1281 // パスワード再入力ダイアログを表示するかどうか判断する
\r
1282 use_password_dlg = false;
\r
1284 if (s->Account != NULL && s->Cedar->Client != NULL)
\r
1287 if (s->ClientAuth->AuthType == CLIENT_AUTHTYPE_PASSWORD || s->ClientAuth->AuthType == CLIENT_AUTHTYPE_PLAIN_PASSWORD)
\r
1289 if (s->Err == ERR_AUTH_FAILED || s->Err == ERR_PROXY_AUTH_FAILED)
\r
1291 use_password_dlg = true;
\r
1294 #endif // OS_WIN32
\r
1297 // 接続に失敗した または接続が切断された
\r
1300 if (use_password_dlg == false)
\r
1302 UINT retry_interval = s->RetryInterval;
\r
1304 if (s->Err == ERR_HUB_IS_BUSY || s->Err == ERR_LICENSE_ERROR ||
\r
1305 s->Err == ERR_HUB_STOPPING || s->Err == ERR_TOO_MANY_USER_SESSION)
\r
1307 retry_interval = RETRY_INTERVAL_SPECIAL;
\r
1310 if (s->CurrentRetryCount >= s->ClientOption->NumRetry)
\r
1320 if (s->Win32HideConnectWindow == false &&
\r
1321 s->Cedar->Client != NULL && s->Account != NULL)
\r
1324 UI_CONNECTERROR_DLG p;
\r
1325 Zero(&p, sizeof(p));
\r
1326 UniStrCpy(p.AccountName, sizeof(p.AccountName), s->ClientOption->AccountName);
\r
1327 StrCpy(p.ServerName, sizeof(p.ServerName), s->ClientOption->Hostname);
\r
1329 p.CurrentRetryCount = s->CurrentRetryCount + 1;
\r
1332 p.RetryIntervalSec = 0;
\r
1333 p.CancelEvent = s->HaltEvent;
\r
1334 p.HideWindow = s->Win32HideConnectWindow;
\r
1335 if (CncConnectErrorDlg(s, &p) == false)
\r
1342 s->Win32HideConnectWindow = p.HideWindow;
\r
1357 Wait(s->HaltEvent, retry_interval);
\r
1361 if (s->Win32HideConnectWindow == false &&
\r
1362 s->Cedar->Client != NULL && s->Account != NULL)
\r
1365 UI_CONNECTERROR_DLG p;
\r
1366 Zero(&p, sizeof(p));
\r
1367 UniStrCpy(p.AccountName, sizeof(p.AccountName), s->ClientOption->AccountName);
\r
1368 StrCpy(p.ServerName, sizeof(p.ServerName), s->ClientOption->Hostname);
\r
1370 p.CurrentRetryCount = s->CurrentRetryCount + 1;
\r
1371 p.RetryLimit = s->ClientOption->NumRetry;
\r
1372 p.RetryIntervalSec = retry_interval;
\r
1373 p.CancelEvent = s->HaltEvent;
\r
1375 p.HideWindow = s->Win32HideConnectWindow;
\r
1376 if (CncConnectErrorDlg(s, &p) == false)
\r
1381 s->Win32HideConnectWindow = p.HideWindow;
\r
1386 Wait(s->HaltEvent, s->RetryInterval);
\r
1389 #endif // OS_WIN32
\r
1394 // パスワードの再入力を求めて待機
\r
1395 UI_PASSWORD_DLG p;
\r
1396 Zero(&p, sizeof(p));
\r
1397 if (s->Client_NoSavePassword == false)
\r
1399 p.ShowNoSavePassword = true;
\r
1401 p.NoSavePassword = no_save_password;
\r
1402 p.CancelEvent = s->HaltEvent;
\r
1403 if (s->Err == ERR_PROXY_AUTH_FAILED)
\r
1405 p.ProxyServer = true;
\r
1408 if (p.ProxyServer)
\r
1410 StrCpy(p.Username, sizeof(p.Username), s->ClientOption->ProxyUsername);
\r
1411 StrCpy(p.Password, sizeof(p.Password), s->ClientOption->ProxyPassword);
\r
1412 StrCpy(p.ServerName, sizeof(p.ServerName), s->ClientOption->ProxyName);
\r
1416 bool empty = false;
\r
1418 StrCpy(p.Username, sizeof(p.Username), s->ClientAuth->Username);
\r
1419 if (s->ClientAuth->AuthType == AUTHTYPE_RADIUS)
\r
1421 if (StrLen(s->ClientAuth->PlainPassword) == 0)
\r
1426 else if (s->ClientAuth->AuthType == AUTHTYPE_PASSWORD)
\r
1428 if (IsZero(s->ClientAuth->HashedPassword, sizeof(s->ClientAuth->HashedPassword)))
\r
1434 StrCpy(p.Password, sizeof(p.Password), empty ? "" : HIDDEN_PASSWORD);
\r
1435 StrCpy(p.ServerName, sizeof(p.ServerName), s->ClientOption->Hostname);
\r
1438 p.RetryIntervalSec = s->RetryInterval / 1000;
\r
1439 p.Type = s->ClientAuth->AuthType;
\r
1441 // パスワード再入力ダイアログを表示する
\r
1442 if (CncPasswordDlg(s, &p) == false)
\r
1450 if (p.ProxyServer)
\r
1453 StrCpy(s->ClientOption->ProxyUsername, sizeof(s->ClientOption->ProxyUsername), p.Username);
\r
1457 // Server への接続のためのユーザー名
\r
1458 StrCpy(s->ClientAuth->Username, sizeof(s->ClientAuth->Username), p.Username);
\r
1459 s->ClientAuth->AuthType = p.Type;
\r
1462 if (StrCmp(p.Password, HIDDEN_PASSWORD) != 0)
\r
1465 if (p.ProxyServer)
\r
1468 StrCpy(s->ClientOption->ProxyPassword, sizeof(s->ClientOption->ProxyPassword), p.Password);
\r
1472 if (s->ClientAuth->AuthType == CLIENT_AUTHTYPE_PLAIN_PASSWORD)
\r
1475 StrCpy(s->ClientAuth->PlainPassword, sizeof(s->ClientAuth->PlainPassword), p.Password);
\r
1480 HashPassword(s->ClientAuth->HashedPassword, s->ClientAuth->Username, p.Password);
\r
1485 no_save_password = p.NoSavePassword;
\r
1487 if (s->Account != NULL && s->Cedar->Client != NULL)
\r
1489 s->Cedar->Client->DontSavePassword = no_save_password;
\r
1490 if (p.NoSavePassword == false)
\r
1492 // クライアントのアカウントデータベースを更新する
\r
1493 if (p.ProxyServer == false)
\r
1496 ACCOUNT *a = s->Account;
\r
1499 CiFreeClientAuth(a->ClientAuth);
\r
1500 a->ClientAuth = CopyClientAuth(s->ClientAuth);
\r
1503 CiSaveConfigurationFile(s->Cedar->Client);
\r
1508 ACCOUNT *a = s->Account;
\r
1511 Copy(a->ClientOption, s->ClientOption, sizeof(CLIENT_OPTION));
\r
1514 CiSaveConfigurationFile(s->Cedar->Client);
\r
1519 #endif // OS_WIN32
\r
1524 if (s->ConnectSucceed == false)
\r
1526 s->CurrentRetryCount++;
\r
1529 if (s->ForceStopFlag)
\r
1535 Debug("Session Halt.\n");
\r
1537 s->ClientStatus = CLIENT_STATUS_IDLE;
\r
1539 // ここでセッションは終了したとみなす
\r
1540 if (s->Account != NULL)
\r
1542 s->Account->ClientSession = NULL;
\r
1543 ReleaseSession(s);
\r
1546 Notify(s, CLIENT_NOTIFY_ACCOUNT_CHANGED);
\r
1548 ReleaseSession(s);
\r
1552 int CompareSession(void *p1, void *p2)
\r
1555 if (p1 == NULL || p2 == NULL)
\r
1559 s1 = *(SESSION **)p1;
\r
1560 s2 = *(SESSION **)p2;
\r
1561 if (s1 == NULL || s2 == NULL)
\r
1565 return StrCmpi(s1->Name, s2->Name);
\r
1569 SESSION *NewRpcSession(CEDAR *cedar, CLIENT_OPTION *option)
\r
1571 return NewRpcSessionEx(cedar, option, NULL, NULL);
\r
1573 SESSION *NewRpcSessionEx(CEDAR *cedar, CLIENT_OPTION *option, UINT *err, char *client_str)
\r
1575 return NewRpcSessionEx2(cedar, option, err, client_str, NULL);
\r
1577 SESSION *NewRpcSessionEx2(CEDAR *cedar, CLIENT_OPTION *option, UINT *err, char *client_str, void *hWnd)
\r
1583 if (cedar == NULL || option == NULL)
\r
1588 s = ZeroMalloc(sizeof(SESSION));
\r
1590 s->LoggingRecordCount = NewCounter();
\r
1591 s->lock = NewLock();
\r
1592 s->ref = NewRef();
\r
1594 s->ServerMode = false;
\r
1595 s->Name = CopyStr("CLIENT_RPC_SESSION");
\r
1596 s->CreatedTime = s->LastCommTime = Tick64();
\r
1597 s->Traffic = NewTraffic();
\r
1598 s->HaltEvent = NewEvent();
\r
1599 s->TrafficLock = NewLock();
\r
1600 s->Cancel1 = NewCancel();
\r
1602 // クライアント接続オプションのコピー
\r
1603 s->ClientOption = Malloc(sizeof(CLIENT_OPTION));
\r
1604 Copy(s->ClientOption, option, sizeof(CLIENT_OPTION));
\r
1606 s->MaxConnection = option->MaxConnection;
\r
1607 s->UseEncrypt = option->UseEncrypt;
\r
1608 s->UseCompress = option->UseCompress;
\r
1611 c = s->Connection = NewClientConnectionEx(s, client_str, cedar->Version, cedar->Build);
\r
1612 c->hWndForUI = hWnd;
\r
1615 sock = ClientConnectToServer(c);
\r
1623 ReleaseSession(s);
\r
1628 if (ClientUploadSignature(sock) == false)
\r
1635 ReleaseSession(s);
\r
1640 if (ClientDownloadHello(c, sock) == false)
\r
1647 ReleaseSession(s);
\r
1655 SESSION *NewClientSessionEx(CEDAR *cedar, CLIENT_OPTION *option, CLIENT_AUTH *auth, PACKET_ADAPTER *pa, ACCOUNT *account)
\r
1660 if (cedar == NULL || option == NULL || auth == NULL || pa == NULL ||
\r
1661 (auth->AuthType == CLIENT_AUTHTYPE_SECURE && auth->SecureSignProc == NULL))
\r
1666 // SESSION オブジェクトの初期化
\r
1667 s = ZeroMalloc(sizeof(SESSION));
\r
1669 s->LoggingRecordCount = NewCounter();
\r
1671 s->lock = NewLock();
\r
1672 s->ref = NewRef();
\r
1674 s->ServerMode = false;
\r
1675 s->Name = CopyStr("CLIENT_SESSION");
\r
1676 s->CreatedTime = s->LastCommTime = Tick64();
\r
1677 s->Traffic = NewTraffic();
\r
1678 s->HaltEvent = NewEvent();
\r
1679 s->PacketAdapter = pa;
\r
1680 s->TrafficLock = NewLock();
\r
1681 s->OldTraffic = NewTraffic();
\r
1682 s->Cancel1 = NewCancel();
\r
1683 s->CancelList = NewCancelList();
\r
1685 // クライアント接続オプションのコピー
\r
1686 s->ClientOption = Malloc(sizeof(CLIENT_OPTION));
\r
1687 Copy(s->ClientOption, option, sizeof(CLIENT_OPTION));
\r
1689 s->MaxConnection = option->MaxConnection;
\r
1690 s->UseEncrypt = option->UseEncrypt;
\r
1691 s->UseCompress = option->UseCompress;
\r
1694 s->RetryInterval = MAKESURE(option->RetryInterval, 0, 4000000) * 1000;
\r
1695 s->RetryInterval = MAKESURE(s->RetryInterval, MIN_RETRY_INTERVAL, MAX_RETRY_INTERVAL);
\r
1697 // 追加コネクション作成間隔は最低 1 秒
\r
1698 s->ClientOption->AdditionalConnectionInterval = MAX(s->ClientOption->AdditionalConnectionInterval, 1);
\r
1700 // クライアントモードで仮想 LAN カードを使用しているかどうか保持
\r
1701 s->ClientModeAndUseVLan = (StrLen(s->ClientOption->DeviceName) == 0) ? false : true;
\r
1702 if (s->ClientOption->NoRoutingTracking)
\r
1704 s->ClientModeAndUseVLan = false;
\r
1707 if (StrLen(option->DeviceName) == 0)
\r
1710 s->ClientModeAndUseVLan = false;
\r
1711 s->VirtualHost = true;
\r
1714 if (OS_IS_WINDOWS_9X(GetOsInfo()->OsType))
\r
1716 // Win9x の場合は半二重モードを禁止する
\r
1717 s->ClientOption->HalfConnection = false;
\r
1720 // クライアント認証データのコピー
\r
1721 s->ClientAuth = Malloc(sizeof(CLIENT_AUTH));
\r
1722 Copy(s->ClientAuth, auth, sizeof(CLIENT_AUTH));
\r
1725 if (s->ClientAuth->ClientX != NULL)
\r
1727 s->ClientAuth->ClientX = CloneX(s->ClientAuth->ClientX);
\r
1729 if (s->ClientAuth->ClientK != NULL)
\r
1731 s->ClientAuth->ClientK = CloneK(s->ClientAuth->ClientK);
\r
1734 if (StrCmpi(s->ClientOption->DeviceName, LINK_DEVICE_NAME) == 0)
\r
1737 s->LinkModeClient = true;
\r
1738 s->Link = (LINK *)s->PacketAdapter->Param;
\r
1741 if (StrCmpi(s->ClientOption->DeviceName, SNAT_DEVICE_NAME) == 0)
\r
1744 s->SecureNATMode = true;
\r
1747 if (StrCmpi(s->ClientOption->DeviceName, BRIDGE_DEVICE_NAME) == 0)
\r
1750 s->BridgeMode = true;
\r
1753 if (s->VirtualHost)
\r
1755 VH *v = (VH *)s->PacketAdapter->Param;
\r
1757 // セッションオブジェクトを VH に追加
\r
1762 s->Account = account;
\r
1764 if (s->ClientAuth->AuthType == CLIENT_AUTHTYPE_SECURE)
\r
1766 // スマートカード認証の場合はリトライしない
\r
1767 s->ClientOption->NumRetry = 0;
\r
1771 t = NewThread(ClientThread, (void *)s);
\r
1772 WaitThreadInit(t);
\r
1777 SESSION *NewClientSession(CEDAR *cedar, CLIENT_OPTION *option, CLIENT_AUTH *auth, PACKET_ADAPTER *pa)
\r
1779 return NewClientSessionEx(cedar, option, auth, pa, NULL);
\r
1782 // 32bit のセッションキーからセッションを取得
\r
1783 SESSION *GetSessionFromKey32(CEDAR *cedar, UINT key32)
\r
1788 if (cedar == NULL)
\r
1793 LockList(cedar->HubList);
\r
1795 for (i = 0;i < LIST_NUM(cedar->HubList);i++)
\r
1797 h = LIST_DATA(cedar->HubList, i);
\r
1798 LockList(h->SessionList);
\r
1800 for (j = 0;j < LIST_NUM(h->SessionList);j++)
\r
1802 SESSION *s = LIST_DATA(h->SessionList, j);
\r
1805 if (s->SessionKey32 == key32)
\r
1812 UnlockList(h->SessionList);
\r
1813 UnlockList(cedar->HubList);
\r
1820 UnlockList(h->SessionList);
\r
1823 UnlockList(cedar->HubList);
\r
1828 // セッションキーからセッションを取得
\r
1829 SESSION *GetSessionFromKey(CEDAR *cedar, UCHAR *session_key)
\r
1834 if (cedar == NULL || session_key == NULL)
\r
1839 LockList(cedar->HubList);
\r
1841 for (i = 0;i < LIST_NUM(cedar->HubList);i++)
\r
1843 h = LIST_DATA(cedar->HubList, i);
\r
1844 LockList(h->SessionList);
\r
1846 for (j = 0;j < LIST_NUM(h->SessionList);j++)
\r
1848 SESSION *s = LIST_DATA(h->SessionList, j);
\r
1851 if (Cmp(s->SessionKey, session_key, SHA1_SIZE) == 0)
\r
1858 UnlockList(h->SessionList);
\r
1859 UnlockList(cedar->HubList);
\r
1866 UnlockList(h->SessionList);
\r
1869 UnlockList(cedar->HubList);
\r
1875 void NewSessionKey(CEDAR *cedar, UCHAR *session_key, UINT *session_key_32)
\r
1878 if (cedar == NULL || session_key == NULL || session_key_32 == NULL)
\r
1883 Rand(session_key, SHA1_SIZE);
\r
1884 *session_key_32 = Rand32();
\r
1887 bool if_init(SESSION *s);
\r
1888 CANCEL *if_getcancel(SESSION *s);
\r
1889 UINT if_getnext(SESSION *s, void **data);
\r
1890 bool if_putpacket(SESSION *s, void *data, UINT size);
\r
1891 void if_free(SESSION *s);
\r
1895 SESSION *NewServerSession(CEDAR *cedar, CONNECTION *c, HUB *h, char *username, POLICY *policy)
\r
1898 char name[MAX_SIZE];
\r
1899 char hub_name_upper[MAX_SIZE];
\r
1900 char user_name_upper[MAX_USERNAME_LEN + 1];
\r
1902 if (cedar == NULL || c == NULL || h == NULL || username == NULL || policy == NULL)
\r
1907 // SESSION オブジェクトの初期化
\r
1908 s = ZeroMalloc(sizeof(SESSION));
\r
1910 s->LoggingRecordCount = NewCounter();
\r
1911 s->lock = NewLock();
\r
1912 s->ref = NewRef();
\r
1914 s->ServerMode = true;
\r
1915 s->CreatedTime = s->LastCommTime = Tick64();
\r
1916 s->Traffic = NewTraffic();
\r
1917 s->HaltEvent = NewEvent();
\r
1918 s->Cancel1 = NewCancel();
\r
1919 s->CancelList = NewCancelList();
\r
1920 s->Thread = c->Thread;
\r
1921 s->TrafficLock = NewLock();
\r
1922 s->OldTraffic = NewTraffic();
\r
1923 s->QoS = GetServerCapsBool(cedar->Server, "b_support_qos");
\r
1924 AddRef(s->Thread->ref);
\r
1926 s->ClientStatus = CLIENT_STATUS_ESTABLISHED;
\r
1929 s->DelayedPacketList = NewList(NULL);
\r
1932 s->PacketAdapter = GetHubPacketAdapter();
\r
1934 s->Connection = c;
\r
1938 StrCpy(hub_name_upper, sizeof(hub_name_upper), h->Name);
\r
1939 StrUpper(hub_name_upper);
\r
1940 StrCpy(user_name_upper, sizeof(user_name_upper), username);
\r
1941 StrUpper(user_name_upper);
\r
1943 if ((StrCmpi(username, ADMINISTRATOR_USERNAME) != 0) && (StrCmpi(username, BRIDGE_USER_NAME) != 0) || (cedar->Server == NULL || cedar->Server->ServerType == SERVER_TYPE_STANDALONE))
\r
1945 Format(name, sizeof(name), "SID-%s-%u", user_name_upper, Inc(h->SessionCounter));
\r
1949 UCHAR rand[SHA1_SIZE];
\r
1950 char tmp[MAX_SIZE];
\r
1951 Rand(rand, sizeof(rand));
\r
1952 BinToStr(tmp, sizeof(tmp), rand, 3);
\r
1954 if (StrCmpi(username, BRIDGE_USER_NAME) != 0)
\r
1956 Format(name, sizeof(name), "SID-%s-%s", user_name_upper,
\r
1961 char pc_name[MAX_SIZE];
\r
1964 GetMachineName(tmp, sizeof(tmp));
\r
1965 t = ParseToken(tmp, ".");
\r
1966 if (t->NumTokens >= 1)
\r
1968 StrCpy(pc_name, sizeof(pc_name), t->Token[0]);
\r
1972 StrCpy(pc_name, sizeof(pc_name), "pc");
\r
1976 StrUpper(pc_name);
\r
1978 Format(name, sizeof(name), "SID-%s-%s-%u", user_name_upper, pc_name,
\r
1979 Inc(h->SessionCounter));
\r
1983 s->Name = CopyStr(name);
\r
1984 s->Policy = policy;
\r
1986 // HUB に SESSION を追加
\r
1990 NewSessionKey(cedar, s->SessionKey, &s->SessionKey32);
\r
1995 // セッションキーをデバッグ用に表示
\r
1996 void DebugPrintSessionKey(UCHAR *session_key)
\r
1998 char tmp[MAX_SIZE];
\r
2000 if (session_key == NULL)
\r
2005 Bit160ToStr(tmp, session_key);
\r
2006 Debug("SessionKey: %s\n", tmp);
\r
2009 // クライアントにステータスを表示する
\r
2010 void PrintStatus(SESSION *s, wchar_t *str)
\r
2013 if (s == NULL || str == NULL || s->Account == NULL || s->Cedar->Client == NULL
\r
2014 || s->Account->StatusPrinter == NULL)
\r
2019 // コールバック関数に対してステータスを通知する
\r
2020 s->Account->StatusPrinter(s, str);
\r
2024 LIST *NewCancelList()
\r
2026 return NewList(NULL);
\r
2029 // キャンセルリストにキャンセルを追加
\r
2030 void AddCancelList(LIST *o, CANCEL *c)
\r
2034 if (o == NULL || c == NULL)
\r
2039 for (i = 0;i < LIST_NUM(o);i++)
\r
2041 CANCEL *t = LIST_DATA(o, i);
\r
2052 // キャンセルリスト内の全キャンセルの発行
\r
2053 void CancelList(LIST *o)
\r
2062 for (i = 0;i < LIST_NUM(o);i++)
\r
2064 CANCEL *c = LIST_DATA(o, i);
\r
2073 void ReleaseCancelList(LIST *o)
\r
2082 for (i = 0;i < LIST_NUM(o);i++)
\r
2084 CANCEL *c = LIST_DATA(o, i);
\r
2092 void Notify(SESSION *s, UINT code)
\r
2095 if (s == NULL || s->Account == NULL || s->Cedar->Client == NULL)
\r
2100 CiNotify(s->Cedar->Client);
\r