* copy vendor drop to trunk
[lab.git] / Dev / utvpn / utvpn-unix-v101-7101-public / src / Cedar / Server.c
1 // SoftEther UT-VPN SourceCode\r
2 // \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
7 // \r
8 // http://utvpn.tsukuba.ac.jp/\r
9 // \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
13 // \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
18 // \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
22 // \r
23 // このファイルは GPL バージョン 2 ライセンスで公開されています。\r
24 // 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布\r
25 // することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示\r
26 // を除去することはできません。改変した著作物を配布する場合は、改変実施者の\r
27 // 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。\r
28 // \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
32 // ホストされています。\r
33 // 本プログラムの配布者は、本プログラムを、業としての利用以外のため、\r
34 // および、試験または研究のために利用が行われることを想定して配布\r
35 // しています。\r
36 // SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に\r
37 // あります。\r
38 // 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード\r
39 // の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して\r
40 // いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して\r
41 // ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース\r
42 // に組み込みさせていただきます。\r
43 // \r
44 // GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する\r
45 // 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。\r
46 // \r
47 // 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社\r
48 // (SoftEther Corporation) およびその他の著作権保持者が保有しています。\r
49 // ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの\r
50 // 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意\r
51 // ください。\r
52 // \r
53 // お願い: どのような通信ソフトウェアにも通常は必ず未発見の\r
54 // セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、\r
55 // UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの\r
56 // 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社\r
57 // および脆弱性情報の届出を受け付ける公的機関まで通報いただき、\r
58 // 公益保護にご協力いただきますようお願い申し上げます。\r
59 // \r
60 // ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を\r
61 // 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客\r
62 // を保護するための努力を行います。\r
63 // \r
64 // ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/\r
65 // 日本国内の脆弱性情報届出受付公的機関:\r
66 //         独立行政法人 情報処理推進機構\r
67 //         http://www.ipa.go.jp/security/vuln/report/\r
68 // \r
69 // 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。\r
70 // 連絡先: http://www.softether.co.jp/jp/contact/\r
71 \r
72 // -----------------------------------------------\r
73 // [ChangeLog]\r
74 // 2010.05.20\r
75 //  新規リリース by SoftEther\r
76 // -----------------------------------------------\r
77 \r
78 // Server.c\r
79 // サーバーマネージャ\r
80 \r
81 #include "CedarPch.h"\r
82 \r
83 static SERVER *server = NULL;\r
84 static LOCK *server_lock = NULL;\r
85 char *SERVER_CONFIG_FILE_NAME = "@vpn_server.config";\r
86 char *BRIDGE_CONFIG_FILE_NAME = "@vpn_bridge.config";\r
87 \r
88 static bool server_reset_setting = false;\r
89 \r
90 // VPN Server に登録されているユーザーオブジェクト数が多すぎるかどうか取得\r
91 bool SiTooManyUserObjectsInServer(SERVER *s, bool oneMore)\r
92 {\r
93         LICENSE_STATUS st;\r
94         UINT num;\r
95         // 引数チェック\r
96         if (s == NULL)\r
97         {\r
98                 return false;\r
99         }\r
100 \r
101         num = SiGetServerNumUserObjects(s);\r
102 \r
103         Zero(&st, sizeof(st));\r
104 \r
105         LiParseCurrentLicenseStatus(s->LicenseSystem, &st);\r
106 \r
107         if (st.NumUserLicense == INFINITE)\r
108         {\r
109                 return false;\r
110         }\r
111 \r
112         if (oneMore)\r
113         {\r
114                 st.NumUserLicense++;\r
115         }\r
116 \r
117         if (st.NumUserLicense <= num)\r
118         {\r
119                 return true;\r
120         }\r
121 \r
122         return false;\r
123 }\r
124 \r
125 // VPN Server に登録されているユーザーオブジェクト数を取得\r
126 UINT SiGetServerNumUserObjects(SERVER *s)\r
127 {\r
128         CEDAR *c;\r
129         UINT ret = 0;\r
130         // 引数チェック\r
131         if (s == NULL)\r
132         {\r
133                 return 0;\r
134         }\r
135 \r
136         c = s->Cedar;\r
137 \r
138         LockList(c->HubList);\r
139         {\r
140                 UINT i;\r
141                 for (i = 0;i < LIST_NUM(c->HubList);i++)\r
142                 {\r
143                         HUB *h = LIST_DATA(c->HubList, i);\r
144 \r
145                         if (h->HubDb != NULL)\r
146                         {\r
147                                 ret += LIST_NUM(h->HubDb->UserList);\r
148                         }\r
149                 }\r
150         }\r
151         UnlockList(c->HubList);\r
152 \r
153         return ret;\r
154 }\r
155 \r
156 \r
157 typedef struct SI_DEBUG_PROC_LIST\r
158 {\r
159         UINT Id;\r
160         char *Description;\r
161         char *Args;\r
162         SI_DEBUG_PROC *Proc;\r
163 } SI_DEBUG_PROC_LIST;\r
164 \r
165 // デバッグ機能\r
166 UINT SiDebug(SERVER *s, RPC_TEST *ret, UINT i, char *str)\r
167 {\r
168         SI_DEBUG_PROC_LIST proc_list[] =\r
169         {\r
170                 {1, "Hello World", "<test string>", SiDebugProcHelloWorld},\r
171                 {2, "Terminate process now", "", SiDebugProcExit},\r
172                 {3, "Write memory dumpfile", "", SiDebugProcDump},\r
173                 {4, "Restore process priority", "", SiDebugProcRestorePriority},\r
174                 {5, "Set the process priority high", "", SiDebugProcSetHighPriority},\r
175                 {6, "Get the .exe filename of the process", "", SiDebugProcGetExeFileName},\r
176                 {7, "Crash the process", "", SiDebugProcCrash},\r
177         };\r
178         UINT num_proc_list = sizeof(proc_list) / sizeof(proc_list[0]);\r
179         UINT j;\r
180         UINT ret_value = ERR_NO_ERROR;\r
181         // 引数チェック\r
182         if (s == NULL || ret == NULL)\r
183         {\r
184                 return ERR_INVALID_PARAMETER;\r
185         }\r
186 \r
187         if (i == 0)\r
188         {\r
189                 char tmp[MAX_SIZE];\r
190                 Zero(ret, sizeof(RPC_TEST));\r
191 \r
192                 StrCat(ret->StrValue, sizeof(ret->StrValue),\r
193                         "\n--- Debug Functions List --\n");\r
194 \r
195                 for (j = 0;j < num_proc_list;j++)\r
196                 {\r
197                         SI_DEBUG_PROC_LIST *p = &proc_list[j];\r
198 \r
199                         if (IsEmptyStr(p->Args) == false)\r
200                         {\r
201                                 Format(tmp, sizeof(tmp),\r
202                                         " %u: %s - Usage: %u /ARGS:\"%s\"\n",\r
203                                         p->Id, p->Description, p->Id, p->Args);\r
204                         }\r
205                         else\r
206                         {\r
207                                 Format(tmp, sizeof(tmp),\r
208                                         " %u: %s - Usage: %u\n",\r
209                                         p->Id, p->Description, p->Id);\r
210                         }\r
211 \r
212                         StrCat(ret->StrValue, sizeof(ret->StrValue), tmp);\r
213                 }\r
214         }\r
215         else\r
216         {\r
217                 ret_value = ERR_NOT_SUPPORTED;\r
218 \r
219                 for (j = 0;j < num_proc_list;j++)\r
220                 {\r
221                         SI_DEBUG_PROC_LIST *p = &proc_list[j];\r
222 \r
223                         if (p->Id == i)\r
224                         {\r
225                                 ret_value = p->Proc(s, str, ret->StrValue, sizeof(ret->StrValue));\r
226 \r
227                                 if (ret_value == ERR_NO_ERROR && IsEmptyStr(ret->StrValue))\r
228                                 {\r
229                                         StrCpy(ret->StrValue, sizeof(ret->StrValue), "Ok.");\r
230                                 }\r
231                                 break;\r
232                         }\r
233                 }\r
234         }\r
235 \r
236         return ret_value;\r
237 }\r
238 UINT SiDebugProcHelloWorld(SERVER *s, char *in_str, char *ret_str, UINT ret_str_size)\r
239 {\r
240         // 引数チェック\r
241         if (s == NULL || in_str == NULL || ret_str == NULL)\r
242         {\r
243                 return ERR_INVALID_PARAMETER;\r
244         }\r
245 \r
246         Format(ret_str, ret_str_size, "Hello World %s\n", in_str);\r
247 \r
248         return ERR_NO_ERROR;\r
249 }\r
250 UINT SiDebugProcExit(SERVER *s, char *in_str, char *ret_str, UINT ret_str_size)\r
251 {\r
252         // 引数チェック\r
253         if (s == NULL || in_str == NULL || ret_str == NULL)\r
254         {\r
255                 return ERR_INVALID_PARAMETER;\r
256         }\r
257 \r
258         _exit(1);\r
259 \r
260         return ERR_NO_ERROR;\r
261 }\r
262 UINT SiDebugProcDump(SERVER *s, char *in_str, char *ret_str, UINT ret_str_size)\r
263 {\r
264         // 引数チェック\r
265         if (s == NULL || in_str == NULL || ret_str == NULL)\r
266         {\r
267                 return ERR_INVALID_PARAMETER;\r
268         }\r
269 \r
270 #ifdef  OS_WIN32\r
271         MsWriteMinidump(NULL, NULL);\r
272 #else   // OS_WIN32\r
273         return ERR_NOT_SUPPORTED;\r
274 #endif  // OS_WIN32\r
275 \r
276         return ERR_NO_ERROR;\r
277 }\r
278 UINT SiDebugProcRestorePriority(SERVER *s, char *in_str, char *ret_str, UINT ret_str_size)\r
279 {\r
280         // 引数チェック\r
281         if (s == NULL || in_str == NULL || ret_str == NULL)\r
282         {\r
283                 return ERR_INVALID_PARAMETER;\r
284         }\r
285 \r
286         OSRestorePriority();\r
287 \r
288         return ERR_NO_ERROR;\r
289 }\r
290 UINT SiDebugProcSetHighPriority(SERVER *s, char *in_str, char *ret_str, UINT ret_str_size)\r
291 {\r
292         // 引数チェック\r
293         if (s == NULL || in_str == NULL || ret_str == NULL)\r
294         {\r
295                 return ERR_INVALID_PARAMETER;\r
296         }\r
297 \r
298         OSSetHighPriority();\r
299 \r
300         return ERR_NO_ERROR;\r
301 }\r
302 UINT SiDebugProcGetExeFileName(SERVER *s, char *in_str, char *ret_str, UINT ret_str_size)\r
303 {\r
304         // 引数チェック\r
305         if (s == NULL || in_str == NULL || ret_str == NULL)\r
306         {\r
307                 return ERR_INVALID_PARAMETER;\r
308         }\r
309 \r
310         GetExeName(ret_str, ret_str_size);\r
311 \r
312         return ERR_NO_ERROR;\r
313 }\r
314 UINT SiDebugProcCrash(SERVER *s, char *in_str, char *ret_str, UINT ret_str_size)\r
315 {\r
316         // 引数チェック\r
317         if (s == NULL || in_str == NULL || ret_str == NULL)\r
318         {\r
319                 return ERR_INVALID_PARAMETER;\r
320         }\r
321 \r
322         CrashNow();\r
323 \r
324         return ERR_NO_ERROR;\r
325 }\r
326 \r
327 // デバッグログの書き込み\r
328 void SiDebugLog(SERVER *s, char *msg)\r
329 {\r
330         // 引数チェック\r
331         if (s == NULL || msg == NULL)\r
332         {\r
333                 return;\r
334         }\r
335 \r
336         if (s->DebugLog != NULL)\r
337         {\r
338                 WriteTinyLog(s->DebugLog, msg);\r
339         }\r
340 }\r
341 \r
342 // デッドロック検査メイン\r
343 void SiCheckDeadLockMain(SERVER *s, UINT timeout)\r
344 {\r
345         CEDAR *cedar;\r
346         // 引数チェック\r
347         if (s == NULL)\r
348         {\r
349                 return;\r
350         }\r
351 \r
352         Debug("SiCheckDeadLockMain Start.\n");\r
353 \r
354         cedar = s->Cedar;\r
355 \r
356         if (s->ServerListenerList != NULL)\r
357         {\r
358                 CheckDeadLock(s->ServerListenerList->lock, timeout, "s->ServerListenerList->lock");\r
359         }\r
360 \r
361         CheckDeadLock(s->lock, timeout, "s->lock");\r
362 \r
363         if (s->FarmMemberList != NULL)\r
364         {\r
365                 CheckDeadLock(s->FarmMemberList->lock, timeout, "s->FarmMemberList->lock");\r
366         }\r
367 \r
368         if (s->HubCreateHistoryList != NULL)\r
369         {\r
370                 CheckDeadLock(s->HubCreateHistoryList->lock, timeout, "s->HubCreateHistoryList->lock");\r
371         }\r
372 \r
373         CheckDeadLock(s->CapsCacheLock, timeout, "s->CapsCacheLock");\r
374 \r
375         CheckDeadLock(s->TasksFromFarmControllerLock, timeout, "s->TasksFromFarmControllerLock");\r
376 \r
377         if (cedar != NULL)\r
378         {\r
379                 if (cedar->HubList != NULL)\r
380                 {\r
381                         CheckDeadLock(cedar->HubList->lock, timeout, "cedar->HubList->lock");\r
382                 }\r
383 \r
384                 if (cedar->ListenerList != NULL)\r
385                 {\r
386                         UINT i;\r
387                         LIST *o = NewListFast(NULL);\r
388 \r
389                         CheckDeadLock(cedar->ListenerList->lock, timeout, "cedar->ListenerList->lock");\r
390 \r
391                         LockList(cedar->ListenerList);\r
392                         {\r
393                                 for (i = 0;i < LIST_NUM(cedar->ListenerList);i++)\r
394                                 {\r
395                                         LISTENER *r = LIST_DATA(cedar->ListenerList, i);\r
396 \r
397                                         AddRef(r->ref);\r
398 \r
399                                         Add(o, r);\r
400                                 }\r
401                         }\r
402                         UnlockList(cedar->ListenerList);\r
403 \r
404                         for (i = 0;i < LIST_NUM(o);i++)\r
405                         {\r
406                                 LISTENER *r = LIST_DATA(o, i);\r
407 \r
408                                 ReleaseListener(r);\r
409                         }\r
410 \r
411                         ReleaseList(o);\r
412                 }\r
413 \r
414                 if (cedar->ConnectionList != NULL)\r
415                 {\r
416                         CheckDeadLock(cedar->ConnectionList->lock, timeout, "cedar->ConnectionList->lock");\r
417                 }\r
418 \r
419                 if (cedar->CaList != NULL)\r
420                 {\r
421                         CheckDeadLock(cedar->CaList->lock, timeout, "cedar->CaList->lock");\r
422                 }\r
423 \r
424                 if (cedar->TrafficLock != NULL)\r
425                 {\r
426                         CheckDeadLock(cedar->TrafficLock, timeout, "cedar->TrafficLock");\r
427                 }\r
428 \r
429                 if (cedar->TrafficDiffList != NULL)\r
430                 {\r
431                         CheckDeadLock(cedar->TrafficDiffList->lock, timeout, "cedar->TrafficDiffList->lock");\r
432                 }\r
433 \r
434                 if (cedar->LocalBridgeList != NULL)\r
435                 {\r
436                         CheckDeadLock(cedar->LocalBridgeList->lock, timeout, "cedar->LocalBridgeList->lock");\r
437                 }\r
438 \r
439                 if (cedar->L3SwList != NULL)\r
440                 {\r
441                         CheckDeadLock(cedar->L3SwList->lock, timeout, "cedar->L3SwList->lock");\r
442                 }\r
443         }\r
444 \r
445         Debug("SiCheckDeadLockMain Finish.\n");\r
446 }\r
447 \r
448 // デッドロックチェックスレッド\r
449 void SiDeadLockCheckThread(THREAD *t, void *param)\r
450 {\r
451         SERVER *s = (SERVER *)param;\r
452         // 引数チェック\r
453         if (s == NULL || t == NULL)\r
454         {\r
455                 return;\r
456         }\r
457 \r
458         while (true)\r
459         {\r
460                 Wait(s->DeadLockWaitEvent, SERVER_DEADLOCK_CHECK_SPAN);\r
461 \r
462                 if (s->HaltDeadLockThread)\r
463                 {\r
464                         break;\r
465                 }\r
466 \r
467                 SiCheckDeadLockMain(s, SERVER_DEADLOCK_CHECK_TIMEOUT);\r
468         }\r
469 }\r
470 \r
471 // デッドロックチェックの初期化\r
472 void SiInitDeadLockCheck(SERVER *s)\r
473 {\r
474         // 引数チェック\r
475         if (s == NULL)\r
476         {\r
477                 return;\r
478         }\r
479         if (s->DisableDeadLockCheck)\r
480         {\r
481                 return;\r
482         }\r
483 \r
484         s->HaltDeadLockThread = false;\r
485         s->DeadLockWaitEvent = NewEvent();\r
486         s->DeadLockCheckThread = NewThread(SiDeadLockCheckThread, s);\r
487 }\r
488 \r
489 // デッドロックチェックの解放\r
490 void SiFreeDeadLockCheck(SERVER *s)\r
491 {\r
492         // 引数チェック\r
493         if (s == NULL)\r
494         {\r
495                 return;\r
496         }\r
497 \r
498         if (s->DeadLockCheckThread == NULL)\r
499         {\r
500                 return;\r
501         }\r
502 \r
503         s->HaltDeadLockThread = true;\r
504         Set(s->DeadLockWaitEvent);\r
505 \r
506         WaitThread(s->DeadLockCheckThread, INFINITE);\r
507 \r
508         ReleaseThread(s->DeadLockCheckThread);\r
509         s->DeadLockCheckThread = NULL;\r
510 \r
511         ReleaseEvent(s->DeadLockWaitEvent);\r
512         s->DeadLockWaitEvent = NULL;\r
513 \r
514         s->HaltDeadLockThread = false;\r
515 }\r
516 \r
517 // 指定した仮想 HUB が作成履歴に登録されているかどうか調べる\r
518 bool SiIsHubRegistedOnCreateHistory(SERVER *s, char *name)\r
519 {\r
520         UINT i;\r
521         bool ret = false;\r
522         // 引数チェック\r
523         if (s == NULL || name == NULL)\r
524         {\r
525                 return false;\r
526         }\r
527 \r
528         SiDeleteOldHubCreateHistory(s);\r
529 \r
530         LockList(s->HubCreateHistoryList);\r
531         {\r
532                 for (i = 0;i < LIST_NUM(s->HubCreateHistoryList);i++)\r
533                 {\r
534                         SERVER_HUB_CREATE_HISTORY *h = LIST_DATA(s->HubCreateHistoryList, i);\r
535 \r
536                         if (StrCmpi(h->HubName, name) == 0)\r
537                         {\r
538                                 ret = true;\r
539                                 break;\r
540                         }\r
541                 }\r
542         }\r
543         UnlockList(s->HubCreateHistoryList);\r
544 \r
545         return ret;\r
546 }\r
547 \r
548 // 仮想 HUB 作成履歴の削除\r
549 void SiDelHubCreateHistory(SERVER *s, char *name)\r
550 {\r
551         UINT i;\r
552         // 引数チェック\r
553         if (s == NULL || name == NULL)\r
554         {\r
555                 return;\r
556         }\r
557 \r
558         LockList(s->HubCreateHistoryList);\r
559         {\r
560                 SERVER_HUB_CREATE_HISTORY *hh = NULL;\r
561                 for (i = 0;i < LIST_NUM(s->HubCreateHistoryList);i++)\r
562                 {\r
563                         SERVER_HUB_CREATE_HISTORY *h = LIST_DATA(s->HubCreateHistoryList, i);\r
564 \r
565                         if (StrCmpi(h->HubName, name) == 0)\r
566                         {\r
567                                 Delete(s->HubCreateHistoryList, h);\r
568                                 Free(h);\r
569                                 break;\r
570                         }\r
571                 }\r
572         }\r
573         UnlockList(s->HubCreateHistoryList);\r
574 \r
575         SiDeleteOldHubCreateHistory(s);\r
576 }\r
577 \r
578 // 仮想 HUB 作成履歴への登録\r
579 void SiAddHubCreateHistory(SERVER *s, char *name)\r
580 {\r
581         UINT i;\r
582         // 引数チェック\r
583         if (s == NULL || name == NULL)\r
584         {\r
585                 return;\r
586         }\r
587 \r
588         LockList(s->HubCreateHistoryList);\r
589         {\r
590                 SERVER_HUB_CREATE_HISTORY *hh = NULL;\r
591                 for (i = 0;i < LIST_NUM(s->HubCreateHistoryList);i++)\r
592                 {\r
593                         SERVER_HUB_CREATE_HISTORY *h = LIST_DATA(s->HubCreateHistoryList, i);\r
594 \r
595                         if (StrCmpi(h->HubName, name) == 0)\r
596                         {\r
597                                 hh = h;\r
598                                 break;\r
599                         }\r
600                 }\r
601 \r
602                 if (hh == NULL)\r
603                 {\r
604                         hh = ZeroMalloc(sizeof(SERVER_HUB_CREATE_HISTORY));\r
605                         StrCpy(hh->HubName, sizeof(hh->HubName), name);\r
606 \r
607                         Add(s->HubCreateHistoryList, hh);\r
608                 }\r
609 \r
610                 hh->CreatedTime = Tick64();\r
611         }\r
612         UnlockList(s->HubCreateHistoryList);\r
613 \r
614         SiDeleteOldHubCreateHistory(s);\r
615 }\r
616 \r
617 // 古くなった仮想 HUB 作成履歴の削除\r
618 void SiDeleteOldHubCreateHistory(SERVER *s)\r
619 {\r
620         UINT i;\r
621         LIST *o;\r
622         // 引数チェック\r
623         if (s == NULL)\r
624         {\r
625                 return;\r
626         }\r
627 \r
628         LockList(s->HubCreateHistoryList);\r
629         {\r
630                 o = NewListFast(NULL);\r
631 \r
632                 for (i = 0;i < LIST_NUM(s->HubCreateHistoryList);i++)\r
633                 {\r
634                         SERVER_HUB_CREATE_HISTORY *h = LIST_DATA(s->HubCreateHistoryList, i);\r
635 \r
636                         if ((h->CreatedTime + ((UINT64)TICKET_EXPIRES)) <= Tick64())\r
637                         {\r
638                                 // 有効期限切れ\r
639                                 Add(o, h);\r
640                         }\r
641                 }\r
642 \r
643                 for (i = 0;i < LIST_NUM(o);i++)\r
644                 {\r
645                         SERVER_HUB_CREATE_HISTORY *h = LIST_DATA(o, i);\r
646 \r
647                         Delete(s->HubCreateHistoryList, h);\r
648 \r
649                         Free(h);\r
650                 }\r
651 \r
652                 ReleaseList(o);\r
653         }\r
654         UnlockList(s->HubCreateHistoryList);\r
655 }\r
656 \r
657 // 仮想 HUB 作成履歴の初期化\r
658 void SiInitHubCreateHistory(SERVER *s)\r
659 {\r
660         // 引数チェック\r
661         if (s == NULL)\r
662         {\r
663                 return;\r
664         }\r
665 \r
666         s->HubCreateHistoryList = NewList(NULL);\r
667 }\r
668 \r
669 // 仮想 HUB 作成履歴の解放\r
670 void SiFreeHubCreateHistory(SERVER *s)\r
671 {\r
672         UINT i;\r
673         // 引数チェック\r
674         if (s == NULL)\r
675         {\r
676                 return;\r
677         }\r
678 \r
679         for (i = 0;i < LIST_NUM(s->HubCreateHistoryList);i++)\r
680         {\r
681                 SERVER_HUB_CREATE_HISTORY *h = LIST_DATA(s->HubCreateHistoryList, i);\r
682 \r
683                 Free(h);\r
684         }\r
685 \r
686         ReleaseList(s->HubCreateHistoryList);\r
687 \r
688         s->HubCreateHistoryList = NULL;\r
689 }\r
690 \r
691 // Admin Pack のインストーラ作成キットで作成した VPN Client が\r
692 // 接続可能なサーバーかどうか判別\r
693 bool IsAdminPackSupportedServerProduct(char *name)\r
694 {\r
695         // 引数チェック\r
696         if (name == NULL)\r
697         {\r
698                 return true;\r
699         }\r
700 \r
701         return true;\r
702 \r
703 #if     0\r
704         // SoftEther UT-VPN ではこの制限はなくなった\r
705         if (SearchStrEx(name, "home", 0, false) != INFINITE)\r
706         {\r
707                 return false;\r
708         }\r
709 \r
710         if (SearchStrEx(name, "soho", 0, false) != INFINITE)\r
711         {\r
712                 return false;\r
713         }\r
714 \r
715         if (SearchStrEx(name, "small business", 0, false) != INFINITE)\r
716         {\r
717                 return false;\r
718         }\r
719 \r
720         if (SearchStrEx(name, "standard", 0, false) != INFINITE)\r
721         {\r
722                 return false;\r
723         }\r
724 \r
725         return true;\r
726 #endif\r
727 }\r
728 \r
729 \r
730 // Server スナップショットの初期化\r
731 void InitServerSnapshot(SERVER *s)\r
732 {\r
733         // 引数チェック\r
734         if (s == NULL)\r
735         {\r
736                 return;\r
737         }\r
738 \r
739         if (s->Cedar->Bridge)\r
740         {\r
741                 return;\r
742         }\r
743 \r
744         if (s->ServerType == SERVER_TYPE_FARM_MEMBER)\r
745         {\r
746                 return;\r
747         }\r
748 \r
749         s->SnapshotLogger = NewLog(CE_SNAPSHOT_DIR_NAME, CE_SNAPSHOT_PREFIX, LOG_SWITCH_MONTH);\r
750         s->LastSnapshotTime = SystemTime64();\r
751         s->HaltSnapshot = false;\r
752         s->SnapshotHaltEvent = NewEvent();\r
753         s->SnapshotThread = NewThread(ServerSnapshotThread, s);\r
754         s->SnapshotInited = true;\r
755 }\r
756 \r
757 // Server スナップショットの解放\r
758 void FreeServerSnapshot(SERVER *s)\r
759 {\r
760         // 引数チェック\r
761         if (s == NULL)\r
762         {\r
763                 return;\r
764         }\r
765         if (s->SnapshotInited == false)\r
766         {\r
767                 return;\r
768         }\r
769 \r
770         s->HaltSnapshot = true;\r
771         Set(s->SnapshotHaltEvent);\r
772 \r
773         WaitThread(s->SnapshotThread, INFINITE);\r
774         ReleaseThread(s->SnapshotThread);\r
775 \r
776         FreeLog(s->SnapshotLogger);\r
777         ReleaseEvent(s->SnapshotHaltEvent);\r
778 }\r
779 \r
780 // スナップショットをバッファに書き出す\r
781 BUF *ServerSnapshotToBuf(SERVER_SNAPSHOT *t)\r
782 {\r
783         BUF *b = NewBuf();\r
784         char tmp[MAX_SIZE * 3];\r
785         char tmp2[MAX_SIZE];\r
786         UCHAR hash[SHA1_SIZE];\r
787         UCHAR hash2[SHA1_SIZE];\r
788         UINT i;\r
789         // 引数チェック\r
790         if (t == NULL)\r
791         {\r
792                 return NULL;\r
793         }\r
794 \r
795         WriteBufLine(b, "------------------------------------------------------");\r
796         WriteBufLine(b, "[RECORD_INFO]");\r
797 \r
798         GetDateTimeStr64(tmp2, sizeof(tmp2), SystemToLocal64(t->DateTime));\r
799         Format(tmp, sizeof(tmp), "DATETIME: %s", tmp2);\r
800         WriteBufLine(b, tmp);\r
801 \r
802         IPToStr(tmp2, sizeof(tmp2), &t->ServerIp);\r
803         Format(tmp, sizeof(tmp), "SERVER_IP: %s", tmp2);\r
804         WriteBufLine(b, tmp);\r
805 \r
806         Format(tmp, sizeof(tmp), "SERVER_HOSTNAME: %s", t->ServerHostname);\r
807         WriteBufLine(b, tmp);\r
808 \r
809         Format(tmp, sizeof(tmp), "SERVER_PRODUCT: %s", t->ServerProduct);\r
810         WriteBufLine(b, tmp);\r
811 \r
812         Format(tmp, sizeof(tmp), "SERVER_VERSION: %s", t->ServerVersion);\r
813         WriteBufLine(b, tmp);\r
814 \r
815         Format(tmp, sizeof(tmp), "SERVER_BUILD: %s", t->ServerBuild);\r
816         WriteBufLine(b, tmp);\r
817 \r
818         Format(tmp, sizeof(tmp), "SERVER_OS: %s", t->ServerOs);\r
819         WriteBufLine(b, tmp);\r
820 \r
821         Format(tmp, sizeof(tmp), "SERVER_LICENSE_ID: %I64u", t->ServerLicenseId);\r
822         WriteBufLine(b, tmp);\r
823 \r
824         if (t->ServerLicenseExpires != 0)\r
825         {\r
826                 GetDateTimeStr64(tmp2, sizeof(tmp2), SystemToLocal64(t->ServerLicenseExpires));\r
827         }\r
828         else\r
829         {\r
830                 StrCpy(tmp2, sizeof(tmp2), "None");\r
831         }\r
832         Format(tmp, sizeof(tmp), "SERVER_LICENSE_EXPIRES: %s", tmp2);\r
833         WriteBufLine(b, tmp);\r
834 \r
835         Format(tmp, sizeof(tmp), "SERVER_TYPE: %u", t->ServerType);\r
836         WriteBufLine(b, tmp);\r
837 \r
838         GetDateTimeStr64(tmp2, sizeof(tmp), SystemToLocal64(t->ServerStartupDatetime));\r
839         Format(tmp, sizeof(tmp), "SERVER_STARTUP_DATETIME: %s", tmp2);\r
840         WriteBufLine(b, tmp);\r
841 \r
842         Format(tmp, sizeof(tmp), "NUMBER_OF_CLUSTER_NODES: %u", t->NumClusterNodes);\r
843         WriteBufLine(b, tmp);\r
844 \r
845         Format(tmp, sizeof(tmp), "NUMBER_OF_HUBS: %u", LIST_NUM(t->HubList));\r
846         WriteBufLine(b, tmp);\r
847 \r
848         for (i = 0;i < LIST_NUM(t->HubList);i++)\r
849         {\r
850                 HUB_SNAPSHOT *h = LIST_DATA(t->HubList, i);\r
851                 Format(tmp, sizeof(tmp), "[HUB%u]", i);\r
852                 WriteBufLine(b, tmp);\r
853 \r
854                 Format(tmp, sizeof(tmp), "HUB_NAME: %s", h->HubName);\r
855                 WriteBufLine(b, tmp);\r
856 \r
857                 Format(tmp, sizeof(tmp), "HUB_STATUS: %s",\r
858                         h->HubStatus ? "Online" : "Offline");\r
859                 WriteBufLine(b, tmp);\r
860 \r
861                 Format(tmp, sizeof(tmp), "HUB_MAX_SESSIONS_CLIENT: %u",\r
862                         h->HubMaxSessionsClient);\r
863                 WriteBufLine(b, tmp);\r
864 \r
865                 Format(tmp, sizeof(tmp), "HUB_MAX_SESSIONS_BRIDGE: %u",\r
866                         h->HubMaxSessionsBridge);\r
867                 WriteBufLine(b, tmp);\r
868         }\r
869 \r
870         // ハッシュ計算\r
871         HashSha1(hash, b->Buf, b->Size);\r
872         HashSha1(hash2, hash, sizeof(hash));\r
873 \r
874         WriteBufLine(b, "[DIGITAL_SIGNATURE]");\r
875         BinToStr(tmp2, sizeof(tmp2), hash2, sizeof(hash2));\r
876         Format(tmp, sizeof(tmp), "SIGNATURE: %s", tmp2);\r
877         WriteBufLine(b, tmp);\r
878 \r
879         SeekBuf(b, 0, 0);\r
880 \r
881         return b;\r
882 }\r
883 \r
884 // スナップショットのログを書き込む\r
885 void WriteServerSnapshotLog(SERVER *s, SERVER_SNAPSHOT *t)\r
886 {\r
887         BUF *b;\r
888         LOG *g;\r
889         // 引数チェック\r
890         if (s == NULL || t == NULL)\r
891         {\r
892                 return;\r
893         }\r
894 \r
895         b = ServerSnapshotToBuf(t);\r
896         if (b == NULL)\r
897         {\r
898                 return;\r
899         }\r
900 \r
901         g = s->SnapshotLogger;\r
902 \r
903         WriteMultiLineLog(g, b);\r
904 \r
905         FreeBuf(b);\r
906 }\r
907 \r
908 // Server スナップショットスレッド\r
909 void ServerSnapshotThread(THREAD *t, void *param)\r
910 {\r
911         SERVER *s;\r
912         UINT64 last_check_license = 0;\r
913         LICENSE_STATUS license;\r
914         // 引数チェック\r
915         if (t == NULL || param == NULL)\r
916         {\r
917                 return;\r
918         }\r
919 \r
920         s = (SERVER *)param;\r
921 \r
922         Zero(&license, sizeof(license));\r
923 \r
924         while (true)\r
925         {\r
926                 UINT64 now;\r
927                 if (s->HaltSnapshot)\r
928                 {\r
929                         break;\r
930                 }\r
931 \r
932                 if (last_check_license == 0 || (last_check_license + (UINT64)(CE_SNAPSHOT_POLLING_INTERVAL_LICENSE)) <= Tick64())\r
933                 {\r
934                         last_check_license = Tick64();\r
935 \r
936                         LiParseCurrentLicenseStatus(s->LicenseSystem, &license);\r
937                 }\r
938 \r
939                 if (license.CarrierEdition)\r
940                 {\r
941                         now = SystemTime64();\r
942 \r
943                         if ((s->LastSnapshotTime / CE_SNAPSHOT_INTERVAL) !=\r
944                                 (now / CE_SNAPSHOT_INTERVAL))\r
945                         {\r
946                                 SERVER_SNAPSHOT t;\r
947                                 if (MakeServerSnapshot(s, 0, &t))\r
948                                 {\r
949                                         s->LastSnapshotTime = now;\r
950                                         WriteServerSnapshotLog(s, &t);\r
951 \r
952                                         FreeSnapshot(&t);\r
953                                 }\r
954                         }\r
955                 }\r
956 \r
957                 Wait(s->SnapshotHaltEvent, CE_SNAPSHOT_POLLING_INTERVAL);\r
958         }\r
959 }\r
960 \r
961 // Server のスナップショットの保存\r
962 bool MakeServerSnapshot(SERVER *s, UINT64 now, SERVER_SNAPSHOT *t)\r
963 {\r
964         LICENSE_STATUS license;\r
965         OS_INFO *os = GetOsInfo();\r
966         CEDAR *cedar;\r
967         HUB **hubs;\r
968         UINT i, num_hubs;\r
969         // 引数チェック\r
970         if (s == NULL || t == NULL)\r
971         {\r
972                 return false;\r
973         }\r
974         if (now == 0)\r
975         {\r
976                 now = SystemTime64();\r
977         }\r
978 \r
979         cedar = s->Cedar;\r
980 \r
981         if (s->ServerType == SERVER_TYPE_FARM_MEMBER)\r
982         {\r
983                 return false;\r
984         }\r
985 \r
986         Zero(&license, sizeof(license));\r
987         LiParseCurrentLicenseStatus(s->LicenseSystem, &license);\r
988 \r
989         if (license.CarrierEdition == false)\r
990         {\r
991                 return false;\r
992         }\r
993 \r
994         now = (now / CE_SNAPSHOT_INTERVAL) * CE_SNAPSHOT_INTERVAL;\r
995 \r
996         t->DateTime = now;\r
997         GetMachineIp(&t->ServerIp);\r
998         GetMachineName(t->ServerHostname, sizeof(t->ServerHostname));\r
999         StrCpy(t->ServerProduct, sizeof(t->ServerProduct), license.EditionStr);\r
1000         t->ServerLicenseId = license.SystemId;\r
1001         t->ServerLicenseExpires = license.Expires;\r
1002         t->ServerType = s->ServerType;\r
1003         if (t->ServerType == SERVER_TYPE_FARM_CONTROLLER)\r
1004         {\r
1005                 LockList(s->FarmMemberList);\r
1006                 {\r
1007                         t->NumClusterNodes = LIST_NUM(s->FarmMemberList);\r
1008                 }\r
1009                 UnlockList(s->FarmMemberList);\r
1010         }\r
1011 \r
1012         StrCpy(t->ServerVersion, sizeof(t->ServerVersion), s->Cedar->VerString);\r
1013         StrCpy(t->ServerBuild, sizeof(t->ServerBuild), s->Cedar->BuildInfo);\r
1014         Format(t->ServerOs, sizeof(t->ServerOs),\r
1015                 "%s %s %s",\r
1016                 os->OsVendorName, os->OsProductName, os->OsVersion);\r
1017 \r
1018         t->ServerStartupDatetime = s->StartTime;\r
1019 \r
1020         LockList(cedar->HubList);\r
1021         {\r
1022                 num_hubs = LIST_NUM(cedar->HubList);\r
1023                 hubs = ZeroMalloc(sizeof(HUB *) * num_hubs);\r
1024 \r
1025                 for (i = 0;i < num_hubs;i++)\r
1026                 {\r
1027                         HUB *h = LIST_DATA(cedar->HubList, i);\r
1028                         hubs[i] = h;\r
1029 \r
1030                         AddRef(h->ref);\r
1031                 }\r
1032         }\r
1033         UnlockList(cedar->HubList);\r
1034 \r
1035         t->HubList = NewListFast(NULL);\r
1036 \r
1037         for (i = 0;i < num_hubs;i++)\r
1038         {\r
1039                 HUB *h = hubs[i];\r
1040                 UINT client, bridge;\r
1041                 HUB_SNAPSHOT *sn;\r
1042 \r
1043                 client = GetHubAdminOption(h, "max_sessions_client");\r
1044                 bridge = GetHubAdminOption(h, "max_sessions_bridge");\r
1045 \r
1046                 sn = ZeroMalloc(sizeof(HUB_SNAPSHOT));\r
1047                 sn->HubMaxSessionsClient = client;\r
1048                 sn->HubMaxSessionsBridge = bridge;\r
1049                 StrCpy(sn->HubName, sizeof(sn->HubName), h->Name);\r
1050                 sn->HubStatus = h->Offline ? false : true;\r
1051 \r
1052                 Insert(t->HubList, sn);\r
1053 \r
1054                 ReleaseHub(h);\r
1055         }\r
1056 \r
1057         Free(hubs);\r
1058 \r
1059         return true;\r
1060 }\r
1061 \r
1062 // スナップショットの解放\r
1063 void FreeSnapshot(SERVER_SNAPSHOT *t)\r
1064 {\r
1065         UINT i;\r
1066         // 引数チェック\r
1067         if (t == NULL)\r
1068         {\r
1069                 return;\r
1070         }\r
1071 \r
1072         for (i = 0;i < LIST_NUM(t->HubList);i++)\r
1073         {\r
1074                 HUB_SNAPSHOT *h = LIST_DATA(t->HubList, i);\r
1075 \r
1076                 Free(h);\r
1077         }\r
1078 \r
1079         ReleaseList(t->HubList);\r
1080 \r
1081         Zero(t, sizeof(SERVER_SNAPSHOT));\r
1082 }\r
1083 \r
1084 // サーバーの現在のライセンスステータスを取得する\r
1085 void SiGetServerLicenseStatus(SERVER *s, LICENSE_STATUS *st)\r
1086 {\r
1087         // 引数チェック\r
1088         if (s == NULL || st == NULL)\r
1089         {\r
1090                 return;\r
1091         }\r
1092 \r
1093         if (s->LicenseSystem == NULL || s->LicenseSystem->Status == NULL)\r
1094         {\r
1095                 Zero(st, sizeof(LICENSE_STATUS));\r
1096                 return;\r
1097         }\r
1098 \r
1099         Copy(st, s->LicenseSystem->Status, sizeof(LICENSE_STATUS));\r
1100 }\r
1101 \r
1102 // サーバー製品名を取得する\r
1103 void GetServerProductName(SERVER *s, char *name, UINT size)\r
1104 {\r
1105         char *cpu;\r
1106         // 引数チェック\r
1107         if (s == NULL || name == NULL)\r
1108         {\r
1109                 return;\r
1110         }\r
1111 \r
1112         GetServerProductNameInternal(s, name, size);\r
1113 \r
1114 #ifdef  CPU_64\r
1115         cpu = " (64 bit)";\r
1116 #else   // CPU_64\r
1117         cpu = " (32 bit)";\r
1118 #endif  // CPU_64\r
1119 \r
1120         StrCat(name, size, cpu);\r
1121 }\r
1122 void GetServerProductNameInternal(SERVER *s, char *name, UINT size)\r
1123 {\r
1124         // 引数チェック\r
1125         if (s == NULL || name == NULL)\r
1126         {\r
1127                 return;\r
1128         }\r
1129 \r
1130 #ifdef  BETA_NUMBER\r
1131         if (s->Cedar->Bridge)\r
1132         {\r
1133                 StrCpy(name, size, CEDAR_BRIDGE_STR);\r
1134         }\r
1135         else\r
1136         {\r
1137                 StrCpy(name, size, CEDAR_BETA_SERVER);\r
1138         }\r
1139         return;\r
1140 #else   // BETA_NUMBER\r
1141         if (s->Cedar->Bridge)\r
1142         {\r
1143                 StrCpy(name, size, CEDAR_BRIDGE_STR);\r
1144         }\r
1145         else\r
1146         {\r
1147                 LICENSE_STATUS st;\r
1148 \r
1149                 LiParseCurrentLicenseStatus(s->LicenseSystem, &st);\r
1150 \r
1151                 StrCpy(name, size, st.EditionStr);\r
1152         }\r
1153 #endif  // BETA_NUMBER\r
1154 }\r
1155 \r
1156 // ログファイル列挙を結合する\r
1157 void AdjoinEnumLogFile(LIST *o, LIST *src)\r
1158 {\r
1159         UINT i;\r
1160         // 引数チェック\r
1161         if (o == NULL || src == NULL)\r
1162         {\r
1163                 return;\r
1164         }\r
1165 \r
1166         for (i = 0;i < LIST_NUM(src);i++)\r
1167         {\r
1168                 LOG_FILE *f = LIST_DATA(src, i);\r
1169 \r
1170                 Insert(o, Clone(f, sizeof(LOG_FILE)));\r
1171         }\r
1172 }\r
1173 \r
1174 // 指定した名前のログファイルが列挙リストに入っているかどうか確認する\r
1175 bool CheckLogFileNameFromEnumList(LIST *o, char *name, char *server_name)\r
1176 {\r
1177         LOG_FILE t;\r
1178         // 引数チェック\r
1179         if (o == NULL || name == NULL || server_name == NULL)\r
1180         {\r
1181                 return false;\r
1182         }\r
1183 \r
1184         Zero(&t, sizeof(t));\r
1185         StrCpy(t.Path, sizeof(t.Path), name);\r
1186         StrCpy(t.ServerName, sizeof(t.ServerName), server_name);\r
1187 \r
1188         if (Search(o, &t) == NULL)\r
1189         {\r
1190                 return false;\r
1191         }\r
1192 \r
1193         return true;\r
1194 }\r
1195 \r
1196 // ログファイル列挙を解放する\r
1197 void FreeEnumLogFile(LIST *o)\r
1198 {\r
1199         UINT i;\r
1200         // 引数チェック\r
1201         if (o == NULL)\r
1202         {\r
1203                 return;\r
1204         }\r
1205 \r
1206         for (i = 0;i < LIST_NUM(o);i++)\r
1207         {\r
1208                 LOG_FILE *f = LIST_DATA(o, i);\r
1209 \r
1210                 Free(f);\r
1211         }\r
1212 \r
1213         ReleaseList(o);\r
1214 }\r
1215 \r
1216 // 仮想 HUB に関連するログファイルを列挙する (サーバー管理者の場合はすべて列挙する)\r
1217 LIST *EnumLogFile(char *hubname)\r
1218 {\r
1219         char exe_dir[MAX_PATH];\r
1220         char tmp[MAX_PATH];\r
1221         LIST *o = NewListFast(CmpLogFile);\r
1222         DIRLIST *dir;\r
1223 \r
1224         if (StrLen(hubname) == 0)\r
1225         {\r
1226                 hubname = NULL;\r
1227         }\r
1228 \r
1229         GetExeDir(exe_dir, sizeof(exe_dir));\r
1230 \r
1231         // server_log の下を列挙する\r
1232         if (hubname == NULL)\r
1233         {\r
1234                 EnumLogFileDir(o, "server_log");\r
1235         }\r
1236 \r
1237         // packet_log の下を列挙する\r
1238         Format(tmp, sizeof(tmp), "%s/packet_log", exe_dir);\r
1239         dir = EnumDir(tmp);\r
1240         if (dir != NULL)\r
1241         {\r
1242                 UINT i;\r
1243                 for (i = 0;i < dir->NumFiles;i++)\r
1244                 {\r
1245                         DIRENT *e = dir->File[i];\r
1246 \r
1247                         if (e->Folder)\r
1248                         {\r
1249                                 char dir_name[MAX_PATH];\r
1250 \r
1251                                 if (hubname == NULL || StrCmpi(hubname, e->FileName) == 0)\r
1252                                 {\r
1253                                         Format(dir_name, sizeof(dir_name), "packet_log/%s", e->FileName);\r
1254                                         EnumLogFileDir(o, dir_name);\r
1255                                 }\r
1256                         }\r
1257                 }\r
1258 \r
1259                 FreeDir(dir);\r
1260         }\r
1261 \r
1262         // security_log の下を列挙する\r
1263         Format(tmp, sizeof(tmp), "%s/security_log", exe_dir);\r
1264         dir = EnumDir(tmp);\r
1265         if (dir != NULL)\r
1266         {\r
1267                 UINT i;\r
1268                 for (i = 0;i < dir->NumFiles;i++)\r
1269                 {\r
1270                         DIRENT *e = dir->File[i];\r
1271 \r
1272                         if (e->Folder)\r
1273                         {\r
1274                                 char dir_name[MAX_PATH];\r
1275 \r
1276                                 if (hubname == NULL || StrCmpi(hubname, e->FileName) == 0)\r
1277                                 {\r
1278                                         Format(dir_name, sizeof(dir_name), "security_log/%s", e->FileName);\r
1279                                         EnumLogFileDir(o, dir_name);\r
1280                                 }\r
1281                         }\r
1282                 }\r
1283 \r
1284                 FreeDir(dir);\r
1285         }\r
1286 \r
1287         return o;\r
1288 }\r
1289 \r
1290 // 指定した名前のディレクトリのログファイルを列挙する\r
1291 void EnumLogFileDir(LIST *o, char *dirname)\r
1292 {\r
1293         UINT i;\r
1294         char exe_dir[MAX_PATH];\r
1295         char dir_full_path[MAX_PATH];\r
1296         DIRLIST *dir;\r
1297         // 引数チェック\r
1298         if (o == NULL || dirname == NULL)\r
1299         {\r
1300                 return;\r
1301         }\r
1302 \r
1303         GetExeDir(exe_dir, sizeof(exe_dir));\r
1304         Format(dir_full_path, sizeof(dir_full_path), "%s/%s", exe_dir, dirname);\r
1305 \r
1306         dir = EnumDir(dir_full_path);\r
1307         if (dir == NULL)\r
1308         {\r
1309                 return;\r
1310         }\r
1311 \r
1312         for (i = 0;i < dir->NumFiles;i++)\r
1313         {\r
1314                 DIRENT *e = dir->File[i];\r
1315 \r
1316                 if (e->Folder == false && e->FileSize > 0)\r
1317                 {\r
1318                         char full_path[MAX_PATH];\r
1319                         char file_path[MAX_PATH];\r
1320 \r
1321                         Format(file_path, sizeof(file_path), "%s/%s", dirname, e->FileName);\r
1322                         Format(full_path, sizeof(full_path), "%s/%s", exe_dir, file_path);\r
1323 \r
1324                         if (EndWith(file_path, ".log"))\r
1325                         {\r
1326                                 LOG_FILE *f = ZeroMalloc(sizeof(LOG_FILE));\r
1327 \r
1328                                 StrCpy(f->Path, sizeof(f->Path), file_path);\r
1329                                 f->FileSize = (UINT)(MIN(e->FileSize, 0xffffffffUL));\r
1330                                 f->UpdatedTime = e->UpdateDate;\r
1331 \r
1332                                 GetMachineName(f->ServerName, sizeof(f->ServerName));\r
1333 \r
1334                                 Insert(o, f);\r
1335                         }\r
1336                 }\r
1337         }\r
1338 \r
1339         FreeDir(dir);\r
1340 }\r
1341 \r
1342 // ログファイルリストエントリ比較\r
1343 int CmpLogFile(void *p1, void *p2)\r
1344 {\r
1345         LOG_FILE *f1, *f2;\r
1346         UINT i;\r
1347         if (p1 == NULL || p2 == NULL)\r
1348         {\r
1349                 return 0;\r
1350         }\r
1351         f1 = *(LOG_FILE **)p1;\r
1352         f2 = *(LOG_FILE **)p2;\r
1353         if (f1 == NULL || f2 == NULL)\r
1354         {\r
1355                 return 0;\r
1356         }\r
1357 \r
1358         i = StrCmpi(f1->Path, f2->Path);\r
1359         if (i != 0)\r
1360         {\r
1361                 return i;\r
1362         }\r
1363 \r
1364         return StrCmpi(f1->ServerName, f2->ServerName);\r
1365 }\r
1366 \r
1367 // サーバーの Caps を取得する\r
1368 UINT GetServerCapsInt(SERVER *s, char *name)\r
1369 {\r
1370         CAPSLIST t;\r
1371         UINT ret;\r
1372         // 引数チェック\r
1373         if (s == NULL || name == NULL)\r
1374         {\r
1375                 return 0;\r
1376         }\r
1377 \r
1378         Zero(&t, sizeof(t));\r
1379         GetServerCaps(s, &t);\r
1380 \r
1381         ret = GetCapsInt(&t, name);\r
1382 \r
1383         return ret;\r
1384 }\r
1385 bool GetServerCapsBool(SERVER *s, char *name)\r
1386 {\r
1387         return (GetServerCapsInt(s, name) == 0) ? false : true;\r
1388 }\r
1389 \r
1390 // サーバーの Caps キャッシュの初期化\r
1391 void InitServerCapsCache(SERVER *s)\r
1392 {\r
1393         // 引数チェック\r
1394         if (s == NULL)\r
1395         {\r
1396                 return;\r
1397         }\r
1398 \r
1399         s->CapsCacheLock = NewLock();\r
1400         s->CapsListCache = NULL;\r
1401 }\r
1402 \r
1403 // サーバーの Caps キャッシュの解放\r
1404 void FreeServerCapsCache(SERVER *s)\r
1405 {\r
1406         // 引数チェック\r
1407         if (s == NULL)\r
1408         {\r
1409                 return;\r
1410         }\r
1411 \r
1412         if (s->CapsListCache != NULL)\r
1413         {\r
1414                 FreeCapsList(s->CapsListCache);\r
1415                 s->CapsListCache = NULL;\r
1416         }\r
1417         DeleteLock(s->CapsCacheLock);\r
1418 }\r
1419 \r
1420 // サーバーの Caps キャッシュの廃棄\r
1421 void DestroyServerCapsCache(SERVER *s)\r
1422 {\r
1423         // 引数チェック\r
1424         if (s == NULL)\r
1425         {\r
1426                 return;\r
1427         }\r
1428 \r
1429         Lock(s->CapsCacheLock);\r
1430         {\r
1431                 if (s->CapsListCache != NULL)\r
1432                 {\r
1433                         FreeCapsList(s->CapsListCache);\r
1434                         s->CapsListCache = NULL;\r
1435                 }\r
1436         }\r
1437         Unlock(s->CapsCacheLock);\r
1438 }\r
1439 \r
1440 // このサーバーの Caps リストを取得する\r
1441 void GetServerCaps(SERVER *s, CAPSLIST *t)\r
1442 {\r
1443         // 引数チェック\r
1444         if (s == NULL || t == NULL)\r
1445         {\r
1446                 return;\r
1447         }\r
1448 \r
1449         Lock(s->CapsCacheLock);\r
1450         {\r
1451                 if (s->CapsListCache == NULL)\r
1452                 {\r
1453                         s->CapsListCache = ZeroMalloc(sizeof(CAPSLIST));\r
1454                         GetServerCapsMain(s, s->CapsListCache);\r
1455                 }\r
1456 \r
1457                 Copy(t, s->CapsListCache, sizeof(s->CapsListCache));\r
1458         }\r
1459         Unlock(s->CapsCacheLock);\r
1460 }\r
1461 \r
1462 // サーバーの Caps 取得メイン\r
1463 void GetServerCapsMain(SERVER *s, CAPSLIST *t)\r
1464 {\r
1465         // 引数チェック\r
1466         if (s == NULL || t == NULL)\r
1467         {\r
1468                 return;\r
1469         }\r
1470 \r
1471         // 初期化\r
1472         InitCapsList(t);\r
1473 \r
1474         // 最大 Ethernet パケットサイズ\r
1475         AddCapsInt(t, "i_max_packet_size", MAX_PACKET_SIZE);\r
1476 \r
1477         if (s->Cedar->Bridge == false)\r
1478         {\r
1479                 LICENSE_STATUS st;\r
1480                 UINT max_sessions, max_clients, max_bridges, max_user_creations;\r
1481 \r
1482                 LiParseCurrentLicenseStatus(s->LicenseSystem, &st);\r
1483 \r
1484                 max_clients = st.NumClientLicense;\r
1485                 max_bridges = st.NumBridgeLicense;\r
1486                 max_sessions = st.MaxSessions;\r
1487                 max_user_creations = st.NumUserLicense;\r
1488 \r
1489                 // 最大仮想 HUB 数\r
1490                 AddCapsInt(t, "i_max_hubs", st.MaxHubs);\r
1491 \r
1492                 // 最大同時接続セッション数\r
1493                 AddCapsInt(t, "i_max_sessions", max_sessions);\r
1494 \r
1495                 // 最大作成可能ユーザー数\r
1496                 AddCapsInt(t, "i_max_user_creation", max_user_creations);\r
1497 \r
1498                 // 最大クライアント数\r
1499                 AddCapsInt(t, "i_max_clients", max_clients);\r
1500 \r
1501                 // 最大ブリッジ数\r
1502                 AddCapsInt(t, "i_max_bridges", max_bridges);\r
1503 \r
1504                 if (s->ServerType != SERVER_TYPE_FARM_MEMBER)\r
1505                 {\r
1506                         // 登録可能な最大ユーザー数 / 仮想 HUB\r
1507                         AddCapsInt(t, "i_max_users_per_hub", MAX_USERS);\r
1508 \r
1509                         // 登録可能な最大グループ数 / 仮想 HUB\r
1510                         AddCapsInt(t, "i_max_groups_per_hub", MAX_GROUPS);\r
1511 \r
1512                         // 登録可能な最大アクセスリスト数 / 仮想 HUB\r
1513                         AddCapsInt(t, "i_max_access_lists", MAX_ACCESSLISTS);\r
1514                 }\r
1515                 else\r
1516                 {\r
1517                         // 登録可能な最大ユーザー数 / 仮想 HUB\r
1518                         AddCapsInt(t, "i_max_users_per_hub", 0);\r
1519 \r
1520                         // 登録可能な最大グループ数 / 仮想 HUB\r
1521                         AddCapsInt(t, "i_max_groups_per_hub", 0);\r
1522 \r
1523                         // 登録可能な最大アクセスリスト数 / 仮想 HUB\r
1524                         AddCapsInt(t, "i_max_access_lists", 0);\r
1525                 }\r
1526 \r
1527                 // 多重ログインに関するポリシー\r
1528                 AddCapsBool(t, "b_support_limit_multilogin", true);\r
1529 \r
1530                 // QoS / VoIP\r
1531                 AddCapsBool(t, "b_support_qos", true);\r
1532         }\r
1533         else\r
1534         {\r
1535                 // 最大仮想 HUB 数\r
1536                 AddCapsInt(t, "i_max_hubs", 0);\r
1537 \r
1538                 // 最大同時接続セッション数\r
1539                 AddCapsInt(t, "i_max_sessions", 0);\r
1540 \r
1541                 // 最大クライアント数\r
1542                 AddCapsInt(t, "i_max_clients", 0);\r
1543 \r
1544                 // 最大ブリッジ数\r
1545                 AddCapsInt(t, "i_max_bridges", 0);\r
1546 \r
1547                 // 登録可能な最大ユーザー数 / 仮想 HUB\r
1548                 AddCapsInt(t, "i_max_users_per_hub", 0);\r
1549 \r
1550                 // 登録可能な最大グループ数 / 仮想 HUB\r
1551                 AddCapsInt(t, "i_max_groups_per_hub", 0);\r
1552 \r
1553                 // 登録可能な最大アクセスリスト数 / 仮想 HUB\r
1554                 AddCapsInt(t, "i_max_access_lists", 0);\r
1555 \r
1556                 // QoS / VoIP\r
1557                 AddCapsBool(t, "b_support_qos", true);\r
1558 \r
1559                 // syslog\r
1560                 AddCapsBool(t, "b_support_syslog", true);\r
1561         }\r
1562 \r
1563         // syslog は使用不可\r
1564         AddCapsBool(t, "b_support_syslog", false);\r
1565 \r
1566         // クラスタ内仮想 HUB の種類の変更が禁止されている\r
1567         AddCapsBool(t, "b_cluster_hub_type_fixed", true);\r
1568 \r
1569         // MAC アドレステーブル最大サイズ / 仮想 HUB\r
1570         AddCapsInt(t, "i_max_mac_tables", MAX_MAC_TABLES);\r
1571 \r
1572         // IP アドレステーブル最大サイズ / 仮想 HUB\r
1573         AddCapsInt(t, "i_max_ip_tables", MAX_IP_TABLES);\r
1574 \r
1575         // SecureNAT 機能が使用できる\r
1576         AddCapsBool(t, "b_support_securenat", true);\r
1577 \r
1578         if (s->ServerType != SERVER_TYPE_STANDALONE)\r
1579         {\r
1580                 AddCapsBool(t, "b_virtual_nat_disabled", true);\r
1581         }\r
1582 \r
1583         // NAT テーブル最大サイズ / 仮想 HUB\r
1584         AddCapsInt(t, "i_max_secnat_tables", NAT_MAX_SESSIONS);\r
1585 \r
1586         // カスケード接続\r
1587         if (s->ServerType == SERVER_TYPE_STANDALONE)\r
1588         {\r
1589                 AddCapsBool(t, "b_support_cascade", true);\r
1590         }\r
1591         else\r
1592         {\r
1593                 AddCapsBool(t, "b_support_cascade", false);\r
1594         }\r
1595 \r
1596         if (s->Cedar->Bridge)\r
1597         {\r
1598                 // ブリッジ モード\r
1599                 AddCapsBool(t, "b_bridge", true);\r
1600         }\r
1601         else if (s->ServerType == SERVER_TYPE_STANDALONE)\r
1602         {\r
1603                 // スタンドアロン モード\r
1604                 AddCapsBool(t, "b_standalone", true);\r
1605         }\r
1606         else if (s->ServerType == SERVER_TYPE_FARM_CONTROLLER)\r
1607         {\r
1608                 // クラスタ コントローラ モード\r
1609                 AddCapsBool(t, "b_cluster_controller", true);\r
1610         }\r
1611         else\r
1612         {\r
1613                 // クラスタ メンバ モード\r
1614                 AddCapsBool(t, "b_cluster_member", true);\r
1615         }\r
1616 \r
1617         // 仮想 HUB の設定変更が可能である\r
1618         AddCapsBool(t, "b_support_config_hub", s->ServerType != SERVER_TYPE_FARM_MEMBER &&\r
1619                 s->Cedar->Bridge == false);\r
1620 \r
1621         // VPN クライアントが接続可能である\r
1622         AddCapsBool(t, "b_vpn_client_connect", s->Cedar->Bridge == false ? true : false);\r
1623 \r
1624         // 外部認証サーバーは使用不可\r
1625         AddCapsBool(t, "b_support_radius", false);\r
1626 \r
1627         // ローカル ブリッジ機能が使用できる\r
1628         AddCapsBool(t, "b_local_bridge", IsBridgeSupported());\r
1629 \r
1630         if (OS_IS_WINDOWS(GetOsInfo()->OsType))\r
1631         {\r
1632                 // パケットキャプチャドライバが未インストール\r
1633                 AddCapsBool(t, "b_must_install_pcap", IsEthSupported() == false ? true : false);\r
1634         }\r
1635         else\r
1636         {\r
1637                 // Linux 版ではドライバはインストール済みとする\r
1638                 AddCapsBool(t, "b_must_install_pcap", false);\r
1639         }\r
1640 \r
1641         if (IsBridgeSupported())\r
1642         {\r
1643                 // tun/tap が使用可能 (Linux のみ)\r
1644                 AddCapsBool(t, "b_tap_supported", GetOsInfo()->OsType == OSTYPE_LINUX ? true : false);\r
1645         }\r
1646 \r
1647         // カスケード接続\r
1648         if (s->ServerType == SERVER_TYPE_STANDALONE)\r
1649         {\r
1650                 AddCapsBool(t, "b_support_cascade", true);\r
1651         }\r
1652         else\r
1653         {\r
1654                 AddCapsBool(t, "b_support_cascade", false);\r
1655         }\r
1656 \r
1657         // カスケード接続時のサーバー認証が使用できる\r
1658         AddCapsBool(t, "b_support_cascade_cert", true);\r
1659 \r
1660         // ログファイル設定の変更ができる\r
1661         AddCapsBool(t, "b_support_config_log", s->ServerType != SERVER_TYPE_FARM_MEMBER);\r
1662 \r
1663         // ログファイルの自動削除が使用可能である\r
1664         AddCapsBool(t, "b_support_autodelete", true);\r
1665 \r
1666         // config 操作が使用可能である\r
1667         AddCapsBool(t, "b_support_config_rw", true);\r
1668 \r
1669         // 仮想 HUB ごとの属性が設定可能である\r
1670         AddCapsBool(t, "b_support_hub_admin_option", true);\r
1671 \r
1672         // カスケード接続でクライアント証明書が設定可能である\r
1673         AddCapsBool(t, "b_support_cascade_client_cert", true);\r
1674 \r
1675         // 仮想 HUB を隠すことができる\r
1676         AddCapsBool(t, "b_support_hide_hub", true);\r
1677 \r
1678         // 統合管理\r
1679         AddCapsBool(t, "b_support_cluster_admin", true);\r
1680 \r
1681         if (s->Cedar->Bridge == false)\r
1682         {\r
1683                 LICENSE_STATUS status;\r
1684                 // 仮想レイヤ 3 スイッチ機能が使える\r
1685                 AddCapsBool(t, "b_support_layer3", true);\r
1686 \r
1687                 AddCapsInt(t, "i_max_l3_sw", MAX_NUM_L3_SWITCH);\r
1688                 AddCapsInt(t, "i_max_l3_if", MAX_NUM_L3_IF);\r
1689                 AddCapsInt(t, "i_max_l3_table", MAX_NUM_L3_TABLE);\r
1690 \r
1691                 LiParseCurrentLicenseStatus(s->LicenseSystem, &status);\r
1692 \r
1693                 if (status.AllowEnterpriseFunction || s->ServerType != SERVER_TYPE_STANDALONE)\r
1694                 {\r
1695                         // クラスタの一部として動作できる\r
1696                         AddCapsBool(t, "b_support_cluster", true);\r
1697                 }\r
1698                 else\r
1699                 {\r
1700                         // クラスタとして動作できない\r
1701                         AddCapsBool(t, "b_support_cluster", false);\r
1702                 }\r
1703         }\r
1704         else\r
1705         {\r
1706                 AddCapsBool(t, "b_support_layer3", false);\r
1707 \r
1708                 AddCapsInt(t, "i_max_l3_sw", 0);\r
1709                 AddCapsInt(t, "i_max_l3_if", 0);\r
1710                 AddCapsInt(t, "i_max_l3_table", 0);\r
1711 \r
1712                 AddCapsBool(t, "b_support_cluster", false);\r
1713         }\r
1714 \r
1715         if (s->ServerType != SERVER_TYPE_FARM_MEMBER && s->Cedar->Bridge == false)\r
1716         {\r
1717                 // CRL をサポート\r
1718                 AddCapsBool(t, "b_support_crl", true);\r
1719         }\r
1720 \r
1721         // AC は非サポート\r
1722         AddCapsBool(t, "b_support_ac", false);\r
1723 \r
1724         // ログ ファイルのダウンロードをサポート\r
1725         AddCapsBool(t, "b_support_read_log", true);\r
1726 \r
1727         // カスケード接続の名前の変更が可能である\r
1728         AddCapsBool(t, "b_support_rename_cascade", true);\r
1729 \r
1730         // ライセンス管理は不可能\r
1731         AddCapsBool(t, "b_support_license", false);\r
1732 \r
1733         if (s->Cedar->Beta)\r
1734         {\r
1735                 // ベータ版\r
1736                 AddCapsBool(t, "b_beta_version", true);\r
1737         }\r
1738 \r
1739         // ローカルブリッジにネットワーク接続の名前表示をサポート\r
1740 #ifdef  OS_WIN32\r
1741         if (IsBridgeSupported() && IsNt() && GetOsInfo()->OsType >= OSTYPE_WINDOWS_2000_PROFESSIONAL)\r
1742         {\r
1743                 AddCapsBool(t, "b_support_network_connection_name", true);\r
1744         }\r
1745 #else   // OS_WIN32\r
1746         if (IsBridgeSupported() && EthIsInterfaceDescriptionSupportedUnix())\r
1747         {\r
1748                 AddCapsBool(t, "b_support_network_connection_name", true);\r
1749         }\r
1750 #endif  // OS_WIN32\r
1751 \r
1752         // MAC アドレスフィルタリングをサポート\r
1753         AddCapsBool(t, "b_support_check_mac", true);\r
1754 \r
1755         // TCP コネクションの状態チェックをサポート\r
1756         AddCapsBool(t, "b_support_check_tcp_state", true);\r
1757 \r
1758         // Radius 認証は使用不可\r
1759         AddCapsBool(t, "b_support_radius_retry_interval_and_several_servers", false);\r
1760 \r
1761         // MAC アドレステーブルでタグ付き VLAN の ID を管理できる\r
1762         AddCapsBool(t, "b_support_vlan", true);\r
1763 \r
1764         // 仮想 HUB 拡張オプションをサポート\r
1765         if ((s->Cedar->Bridge == false) &&\r
1766                 (s->ServerType == SERVER_TYPE_STANDALONE || s->ServerType == SERVER_TYPE_FARM_CONTROLLER))\r
1767         {\r
1768                 AddCapsBool(t, "b_support_hub_ext_options", true);\r
1769         }\r
1770         else\r
1771         {\r
1772                 AddCapsBool(t, "b_support_hub_ext_options", false);\r
1773         }\r
1774 \r
1775         // セキュリティポリシー バージョン 3.0 をサポート\r
1776         AddCapsBool(t, "b_support_policy_ver_3", true);\r
1777 \r
1778         // IPv6 アクセスリストをサポート\r
1779         AddCapsBool(t, "b_support_ipv6_acl", true);\r
1780 \r
1781         // アクセスリストで遅延・ジッタ・パケットロスの設定をサポート\r
1782         AddCapsBool(t, "b_support_ex_acl", true);\r
1783 \r
1784         // アクセスリストでグループ名による指定をサポート\r
1785         AddCapsBool(t, "b_support_acl_group", true);\r
1786 \r
1787         // IPv6 接続元 IP 制限リストをサポート\r
1788         AddCapsBool(t, "b_support_ipv6_ac", true);\r
1789 \r
1790         // タグ付き VLAN パケット透過設定ツールをサポート\r
1791         AddCapsBool(t, "b_support_eth_vlan", (OS_IS_WINDOWS_NT(GetOsType()) && GET_KETA(GetOsType(), 100) >= 2));\r
1792 \r
1793         // 仮想 HUB への VPN 接続時のメッセージ表示機能をサポート\r
1794         AddCapsBool(t, "b_support_msg", true);\r
1795 \r
1796         // VPN3\r
1797         AddCapsBool(t, "b_vpn3", true);\r
1798 \r
1799         // オープンソース版\r
1800         AddCapsBool(t, "b_gpl", true);\r
1801 }\r
1802 \r
1803 // SYSLOG_SETTING\r
1804 void InRpcSysLogSetting(SYSLOG_SETTING *t, PACK *p)\r
1805 {\r
1806         // 引数チェック\r
1807         if (t == NULL || p == NULL)\r
1808         {\r
1809                 return;\r
1810         }\r
1811 \r
1812         Zero(t, sizeof(SYSLOG_SETTING));\r
1813         t->SaveType = PackGetInt(p, "SaveType");\r
1814         t->Port = PackGetInt(p, "Port");\r
1815         PackGetStr(p, "Hostname", t->Hostname, sizeof(t->Hostname));\r
1816 }\r
1817 void OutRpcSysLogSetting(PACK *p, SYSLOG_SETTING *t)\r
1818 {\r
1819         // 引数チェック\r
1820         if (t == NULL || p == NULL)\r
1821         {\r
1822                 return;\r
1823         }\r
1824 \r
1825         PackAddInt(p, "SaveType", t->SaveType);\r
1826         PackAddInt(p, "Port", t->Port);\r
1827         PackAddStr(p, "Hostname", t->Hostname);\r
1828 }\r
1829 \r
1830 // CAPSLIST\r
1831 void InitCapsList(CAPSLIST *t)\r
1832 {\r
1833         // 引数チェック\r
1834         if (t == NULL)\r
1835         {\r
1836                 return;\r
1837         }\r
1838 \r
1839         Zero(t, sizeof(CAPSLIST));\r
1840         t->CapsList = NewListFast(NULL);\r
1841 }\r
1842 void InRpcCapsList(CAPSLIST *t, PACK *p)\r
1843 {\r
1844         UINT i;\r
1845         // 引数チェック\r
1846         if (t == NULL || p == NULL)\r
1847         {\r
1848                 return;\r
1849         }\r
1850 \r
1851         Zero(t, sizeof(CAPSLIST));\r
1852         t->CapsList = NewListFast(CompareCaps);\r
1853 \r
1854         for (i = 0;i < LIST_NUM(p->elements);i++)\r
1855         {\r
1856                 ELEMENT *e = LIST_DATA(p->elements, i);\r
1857 \r
1858                 if (StartWith(e->name, "caps_") && e->type == VALUE_INT && e->num_value == 1)\r
1859                 {\r
1860                         CAPS *c = NewCaps(e->name + 5, e->values[0]->IntValue);\r
1861                         Insert(t->CapsList, c);\r
1862                 }\r
1863         }\r
1864 }\r
1865 void OutRpcCapsList(PACK *p, CAPSLIST *t)\r
1866 {\r
1867         UINT i;\r
1868         // 引数チェック\r
1869         if (t == NULL || p == NULL)\r
1870         {\r
1871                 return;\r
1872         }\r
1873 \r
1874         for (i = 0;i < LIST_NUM(t->CapsList);i++)\r
1875         {\r
1876                 char tmp[MAX_SIZE];\r
1877                 CAPS *c = LIST_DATA(t->CapsList, i);\r
1878 \r
1879                 Format(tmp, sizeof(tmp), "caps_%s", c->Name);\r
1880                 PackAddInt(p, tmp, c->Value);\r
1881         }\r
1882 }\r
1883 void FreeRpcCapsList(CAPSLIST *t)\r
1884 {\r
1885         UINT i;\r
1886         // 引数チェック\r
1887         if (t == NULL)\r
1888         {\r
1889                 return;\r
1890         }\r
1891 \r
1892         for (i = 0;i < LIST_NUM(t->CapsList);i++)\r
1893         {\r
1894                 CAPS *c = LIST_DATA(t->CapsList, i);\r
1895 \r
1896                 FreeCaps(c);\r
1897         }\r
1898 \r
1899         ReleaseList(t->CapsList);\r
1900 }\r
1901 \r
1902 // Caps リストに bool 型を追加\r
1903 void AddCapsBool(CAPSLIST *caps, char *name, bool b)\r
1904 {\r
1905         CAPS *c;\r
1906         // 引数チェック\r
1907         if (caps == NULL || name == NULL)\r
1908         {\r
1909                 return;\r
1910         }\r
1911 \r
1912         c = NewCaps(name, b == false ? 0 : 1);\r
1913         AddCaps(caps, c);\r
1914 }\r
1915 \r
1916 // Caps リストに int 型を追加\r
1917 void AddCapsInt(CAPSLIST *caps, char *name, UINT i)\r
1918 {\r
1919         CAPS *c;\r
1920         // 引数チェック\r
1921         if (caps == NULL || name == NULL)\r
1922         {\r
1923                 return;\r
1924         }\r
1925 \r
1926         c = NewCaps(name, i);\r
1927         AddCaps(caps, c);\r
1928 }\r
1929 \r
1930 // Caps リストから int 型を取得\r
1931 UINT GetCapsInt(CAPSLIST *caps, char *name)\r
1932 {\r
1933         CAPS *c;\r
1934         // 引数チェック\r
1935         if (caps == NULL || name == NULL)\r
1936         {\r
1937                 return 0;\r
1938         }\r
1939 \r
1940         c = GetCaps(caps, name);\r
1941         if (c == NULL)\r
1942         {\r
1943                 return 0;\r
1944         }\r
1945 \r
1946         return c->Value;\r
1947 }\r
1948 \r
1949 // Caps リストから bool 型を取得\r
1950 bool GetCapsBool(CAPSLIST *caps, char *name)\r
1951 {\r
1952         CAPS *c;\r
1953         // 引数チェック\r
1954         if (caps == NULL || name == NULL)\r
1955         {\r
1956                 return false;\r
1957         }\r
1958 \r
1959         c = GetCaps(caps, name);\r
1960         if (c == NULL)\r
1961         {\r
1962                 return false;\r
1963         }\r
1964 \r
1965         return c->Value == 0 ? false : true;\r
1966 }\r
1967 \r
1968 // Caps リストの解放\r
1969 void FreeCapsList(CAPSLIST *caps)\r
1970 {\r
1971         UINT i;\r
1972         // 引数チェック\r
1973         if (caps == NULL)\r
1974         {\r
1975                 return;\r
1976         }\r
1977 \r
1978         for (i = 0;i < LIST_NUM(caps->CapsList);i++)\r
1979         {\r
1980                 CAPS *c = LIST_DATA(caps->CapsList, i);\r
1981 \r
1982                 FreeCaps(c);\r
1983         }\r
1984 \r
1985         ReleaseList(caps->CapsList);\r
1986         Free(caps);\r
1987 }\r
1988 \r
1989 // Caps の取得\r
1990 CAPS *GetCaps(CAPSLIST *caps, char *name)\r
1991 {\r
1992         UINT i;\r
1993         // 引数チェック\r
1994         if (caps == NULL || name == NULL)\r
1995         {\r
1996                 return NULL;\r
1997         }\r
1998 \r
1999         for (i = 0;i < LIST_NUM(caps->CapsList);i++)\r
2000         {\r
2001                 CAPS *c = LIST_DATA(caps->CapsList, i);\r
2002 \r
2003                 if (StrCmpi(c->Name, name) == 0)\r
2004                 {\r
2005                         return c;\r
2006                 }\r
2007         }\r
2008 \r
2009         return NULL;\r
2010 }\r
2011 \r
2012 // Caps の追加\r
2013 void AddCaps(CAPSLIST *caps, CAPS *c)\r
2014 {\r
2015         // 引数チェック\r
2016         if (caps == NULL || c == NULL)\r
2017         {\r
2018                 return;\r
2019         }\r
2020 \r
2021         Insert(caps->CapsList, c);\r
2022 }\r
2023 \r
2024 // Caps の比較\r
2025 int CompareCaps(void *p1, void *p2)\r
2026 {\r
2027         CAPS *c1, *c2;\r
2028         if (p1 == NULL || p2 == NULL)\r
2029         {\r
2030                 return 0;\r
2031         }\r
2032         c1 = *(CAPS **)p1;\r
2033         c2 = *(CAPS **)p2;\r
2034         if (c1 == NULL || c2 == NULL)\r
2035         {\r
2036                 return 0;\r
2037         }\r
2038 \r
2039         return StrCmpi(c1->Name, c2->Name);\r
2040 }\r
2041 \r
2042 // Caps リストの作成\r
2043 CAPSLIST *NewCapsList()\r
2044 {\r
2045         CAPSLIST *caps = ZeroMalloc(sizeof(CAPSLIST));\r
2046 \r
2047         caps->CapsList = NewListFast(CompareCaps);\r
2048 \r
2049         return caps;\r
2050 }\r
2051 \r
2052 // Caps の解放\r
2053 void FreeCaps(CAPS *c)\r
2054 {\r
2055         // 引数チェック\r
2056         if (c == NULL)\r
2057         {\r
2058                 return;\r
2059         }\r
2060 \r
2061         Free(c->Name);\r
2062         Free(c);\r
2063 }\r
2064 \r
2065 // Caps の作成\r
2066 CAPS *NewCaps(char *name, UINT value)\r
2067 {\r
2068         CAPS *c;\r
2069         // 引数チェック\r
2070         if (name == NULL)\r
2071         {\r
2072                 return NULL;\r
2073         }\r
2074 \r
2075         c = ZeroMalloc(sizeof(CAPS));\r
2076         c->Name = CopyStr(name);\r
2077         c->Value = value;\r
2078 \r
2079         return c;\r
2080 }\r
2081 \r
2082 // 現在の接続数と重みから得点を計算する\r
2083 UINT SiCalcPoint(SERVER *s, UINT num, UINT weight)\r
2084 {\r
2085         UINT server_max_sessions = SERVER_MAX_SESSIONS;\r
2086         if (s == NULL)\r
2087         {\r
2088                 return 0;\r
2089         }\r
2090         if (weight == 0)\r
2091         {\r
2092                 weight = 100;\r
2093         }\r
2094 \r
2095         server_max_sessions = GetServerCapsInt(s, "i_max_sessions");\r
2096 \r
2097         return (UINT)(((double)server_max_sessions -\r
2098                 MIN((double)num * 100.0 / (double)weight, (double)server_max_sessions))\r
2099                 * (double)FARM_BASE_POINT / (double)server_max_sessions);\r
2100 }\r
2101 \r
2102 // サーバー得点の取得\r
2103 UINT SiGetPoint(SERVER *s)\r
2104 {\r
2105         UINT num_session;\r
2106         // 引数チェック\r
2107         if (s == NULL)\r
2108         {\r
2109                 return 0;\r
2110         }\r
2111 \r
2112         num_session = Count(s->Cedar->CurrentSessions);\r
2113 \r
2114         return SiCalcPoint(s, num_session, s->Weight);\r
2115 }\r
2116 \r
2117 // デフォルトの証明書を生成する\r
2118 void SiGenerateDefualtCert(X **server_x, K **server_k)\r
2119 {\r
2120         X *x;\r
2121         K *private_key, *public_key;\r
2122         NAME *name;\r
2123         char tmp[MAX_SIZE];\r
2124         wchar_t cn[MAX_SIZE];\r
2125         // 引数チェック\r
2126         if (server_x == NULL || server_k == NULL)\r
2127         {\r
2128                 return;\r
2129         }\r
2130 \r
2131         // 鍵ペアの作成\r
2132         RsaGen(&private_key, &public_key, 1024);\r
2133 \r
2134         // ホスト名の取得\r
2135         StrCpy(tmp, sizeof(tmp), "server.softether.vpn");\r
2136         GetMachineName(tmp, sizeof(tmp));\r
2137 \r
2138         StrToUni(cn, sizeof(cn), tmp);\r
2139         name = NewName(cn, L"Default Random Certification", L"VPN Server",\r
2140                 L"JP", NULL, NULL);\r
2141         x = NewRootX(public_key, private_key, name, MAX(GetDaysUntil2038(), SERVER_DEFAULT_CERT_DAYS), NULL);\r
2142 \r
2143         *server_x = x;\r
2144         *server_k = private_key;\r
2145 \r
2146         FreeName(name);\r
2147 \r
2148         FreeK(public_key);\r
2149 }\r
2150 \r
2151 // サーバー証明書をデフォルトにする\r
2152 void SiInitDefaultServerCert(SERVER *s)\r
2153 {\r
2154         X *x = NULL;\r
2155         K *k = NULL;\r
2156         // 引数チェック\r
2157         if (s == NULL)\r
2158         {\r
2159                 return;\r
2160         }\r
2161 \r
2162         // サーバー証明書と秘密鍵を生成する\r
2163         SiGenerateDefualtCert(&x, &k);\r
2164 \r
2165         // 設定する\r
2166         SetCedarCert(s->Cedar, x, k);\r
2167 \r
2168         FreeX(x);\r
2169         FreeK(k);\r
2170 }\r
2171 \r
2172 // 暗号化アルゴリズム名をデフォルトにする\r
2173 void SiInitCipherName(SERVER *s)\r
2174 {\r
2175         // 引数チェック\r
2176         if (s == NULL)\r
2177         {\r
2178                 return;\r
2179         }\r
2180 \r
2181         SetCedarCipherList(s->Cedar, SERVER_DEFAULT_CIPHER_NAME);\r
2182 }\r
2183 \r
2184 // リスナーリストを初期化する\r
2185 void SiInitListenerList(SERVER *s)\r
2186 {\r
2187         // 引数チェック\r
2188         if (s == NULL)\r
2189         {\r
2190                 return;\r
2191         }\r
2192 \r
2193         SiLockListenerList(s);\r
2194         {\r
2195                 // デフォルト ポートとして 443, 992, 5555 の 3 つのポートを登録する\r
2196                 SiAddListener(s, 443, true);\r
2197                 SiAddListener(s, 992, true);\r
2198                 SiAddListener(s, 5555, true);\r
2199         }\r
2200         SiUnlockListenerList(s);\r
2201 }\r
2202 \r
2203 // リスナーを削除する\r
2204 bool SiDeleteListener(SERVER *s, UINT port)\r
2205 {\r
2206         SERVER_LISTENER *e;\r
2207         // 引数チェック\r
2208         if (s == NULL || port == 0)\r
2209         {\r
2210                 return false;\r
2211         }\r
2212 \r
2213         e = SiGetListener(s, port);\r
2214         if (e == NULL)\r
2215         {\r
2216                 return false;\r
2217         }\r
2218 \r
2219         // まだ動作中であれば停止する\r
2220         SiDisableListener(s, port);\r
2221 \r
2222         if (e->Listener != NULL)\r
2223         {\r
2224                 ReleaseListener(e->Listener);\r
2225         }\r
2226 \r
2227         Delete(s->ServerListenerList, e);\r
2228         Free(e);\r
2229 \r
2230         return true;\r
2231 }\r
2232 \r
2233 // SERVER_LISTENER を比較する\r
2234 int CompareServerListener(void *p1, void *p2)\r
2235 {\r
2236         SERVER_LISTENER *s1, *s2;\r
2237         if (p1 == NULL || p2 == NULL)\r
2238         {\r
2239                 return 0;\r
2240         }\r
2241         s1 = *(SERVER_LISTENER **)p1;\r
2242         s2 = *(SERVER_LISTENER **)p2;\r
2243         if (s1 == NULL || s2 == NULL)\r
2244         {\r
2245                 return 0;\r
2246         }\r
2247 \r
2248         if (s1->Port > s2->Port)\r
2249         {\r
2250                 return 1;\r
2251         }\r
2252         else if (s1->Port < s2->Port)\r
2253         {\r
2254                 return -1;\r
2255         }\r
2256         else\r
2257         {\r
2258                 return 0;\r
2259         }\r
2260 }\r
2261 \r
2262 // リスナーを停止する\r
2263 bool SiDisableListener(SERVER *s, UINT port)\r
2264 {\r
2265         SERVER_LISTENER *e;\r
2266         // 引数チェック\r
2267         if (s == NULL || port == 0)\r
2268         {\r
2269                 return false;\r
2270         }\r
2271 \r
2272         // リスナーを取得する\r
2273         e = SiGetListener(s, port);\r
2274         if (e == NULL)\r
2275         {\r
2276                 return false;\r
2277         }\r
2278 \r
2279         if (e->Enabled == false || e->Listener == NULL)\r
2280         {\r
2281                 // 停止中である\r
2282                 return true;\r
2283         }\r
2284 \r
2285         // リスナーを停止する\r
2286         StopListener(e->Listener);\r
2287 \r
2288         // リスナーを解放する\r
2289         ReleaseListener(e->Listener);\r
2290         e->Listener = NULL;\r
2291 \r
2292         e->Enabled = false;\r
2293 \r
2294         return true;\r
2295 }\r
2296 \r
2297 // リスナーを開始する\r
2298 bool SiEnableListener(SERVER *s, UINT port)\r
2299 {\r
2300         SERVER_LISTENER *e;\r
2301         // 引数チェック\r
2302         if (s == NULL || port == 0)\r
2303         {\r
2304                 return false;\r
2305         }\r
2306 \r
2307         // リスナーを取得する\r
2308         e = SiGetListener(s, port);\r
2309         if (e == NULL)\r
2310         {\r
2311                 return false;\r
2312         }\r
2313 \r
2314         if (e->Enabled)\r
2315         {\r
2316                 // すでに開始されている\r
2317                 return true;\r
2318         }\r
2319 \r
2320         // リスナーを作成する\r
2321         e->Listener = NewListener(s->Cedar, LISTENER_TCP, e->Port);\r
2322         if (e->Listener == NULL)\r
2323         {\r
2324                 // 失敗\r
2325                 return false;\r
2326         }\r
2327 \r
2328         e->Enabled = true;\r
2329 \r
2330         return true;\r
2331 }\r
2332 \r
2333 // リスナーを取得する\r
2334 SERVER_LISTENER *SiGetListener(SERVER *s, UINT port)\r
2335 {\r
2336         UINT i;\r
2337         // 引数チェック\r
2338         if (s == NULL || port == 0)\r
2339         {\r
2340                 return NULL;\r
2341         }\r
2342 \r
2343         for (i = 0;i < LIST_NUM(s->ServerListenerList);i++)\r
2344         {\r
2345                 SERVER_LISTENER *e = LIST_DATA(s->ServerListenerList, i);\r
2346                 if (e->Port == port)\r
2347                 {\r
2348                         return e;\r
2349                 }\r
2350         }\r
2351 \r
2352         return NULL;\r
2353 }\r
2354 \r
2355 // リスナーを追加する\r
2356 bool SiAddListener(SERVER *s, UINT port, bool enabled)\r
2357 {\r
2358         SERVER_LISTENER *e;\r
2359         UINT i;\r
2360         // 引数チェック\r
2361         if (s == NULL || port == 0)\r
2362         {\r
2363                 return false;\r
2364         }\r
2365 \r
2366         // 既存のリスナーが存在していないかどうかチェックする\r
2367         for (i = 0;i < LIST_NUM(s->ServerListenerList);i++)\r
2368         {\r
2369                 e = LIST_DATA(s->ServerListenerList, i);\r
2370                 if (e->Port == port)\r
2371                 {\r
2372                         // すでに存在する\r
2373                         return false;\r
2374                 }\r
2375         }\r
2376 \r
2377         // 新しいリスナーを初期化して登録する\r
2378         e = ZeroMalloc(sizeof(SERVER_LISTENER));\r
2379         e->Enabled = enabled;\r
2380         e->Port = port;\r
2381 \r
2382         if (e->Enabled)\r
2383         {\r
2384                 // リスナーを作成する\r
2385                 e->Listener = NewListener(s->Cedar, LISTENER_TCP, e->Port);\r
2386         }\r
2387 \r
2388         Insert(s->ServerListenerList, e);\r
2389 \r
2390         return true;\r
2391 }\r
2392 \r
2393 // リスナーリストをロックする\r
2394 void SiLockListenerList(SERVER *s)\r
2395 {\r
2396         // 引数チェック\r
2397         if (s == NULL)\r
2398         {\r
2399                 return;\r
2400         }\r
2401 \r
2402         LockList(s->ServerListenerList);\r
2403 }\r
2404 \r
2405 // リスナーリストのロックを解除する\r
2406 void SiUnlockListenerList(SERVER *s)\r
2407 {\r
2408         // 引数チェック\r
2409         if (s == NULL)\r
2410         {\r
2411                 return;\r
2412         }\r
2413 \r
2414         UnlockList(s->ServerListenerList);\r
2415 }\r
2416 \r
2417 // Bridge の初期化\r
2418 void SiInitBridge(SERVER *s)\r
2419 {\r
2420         HUB *h;\r
2421         HUB_OPTION o;\r
2422         HUB_LOG g;\r
2423         // 引数チェック\r
2424         if (s == NULL)\r
2425         {\r
2426                 return;\r
2427         }\r
2428 \r
2429         Zero(&o, sizeof(o));\r
2430         o.MaxSession = 0;\r
2431 \r
2432         h = NewHub(s->Cedar, SERVER_DEFAULT_BRIDGE_NAME, &o);\r
2433         AddHub(s->Cedar, h);\r
2434 \r
2435         h->Offline = true;\r
2436         SetHubOnline(h);\r
2437 \r
2438         // ログ設定\r
2439         SiSetDefaultLogSetting(&g);\r
2440         SetHubLogSetting(h, &g);\r
2441 \r
2442         ReleaseHub(h);\r
2443 }\r
2444 \r
2445 // デフォルトの仮想 HUB を作成する\r
2446 void SiInitDefaultHubList(SERVER *s)\r
2447 {\r
2448         HUB *h;\r
2449         HUB_OPTION o;\r
2450         HUB_LOG g;\r
2451         // 引数チェック\r
2452         if (s == NULL)\r
2453         {\r
2454                 return;\r
2455         }\r
2456 \r
2457         Zero(&o, sizeof(o));\r
2458         o.MaxSession = 0;\r
2459         o.VlanTypeId = MAC_PROTO_TAGVLAN;\r
2460         o.NoIPv6DefaultRouterInRAWhenIPv6 = true;\r
2461         o.ManageOnlyPrivateIP = true;\r
2462         o.ManageOnlyLocalUnicastIPv6 = true;\r
2463         o.NoMacAddressLog = true;\r
2464 \r
2465         h = NewHub(s->Cedar, s->Cedar->Bridge == false ? SERVER_DEFAULT_HUB_NAME : SERVER_DEFAULT_BRIDGE_NAME, &o);\r
2466         h->CreatedTime = SystemTime64();\r
2467         AddHub(s->Cedar, h);\r
2468 \r
2469         if (s->Cedar->Bridge)\r
2470         {\r
2471                 // パスワードを乱数にする\r
2472                 Rand(h->HashedPassword, sizeof(h->HashedPassword));\r
2473                 Rand(h->SecurePassword, sizeof(h->SecurePassword));\r
2474         }\r
2475 \r
2476         h->Offline = true;\r
2477         SetHubOnline(h);\r
2478 \r
2479         // ログ設定\r
2480         SiSetDefaultLogSetting(&g);\r
2481         SetHubLogSetting(h, &g);\r
2482 \r
2483         {\r
2484                 UINT i;\r
2485                 for (i = 0;i < 0;i++)\r
2486                 {\r
2487                         char tmp[MAX_SIZE];\r
2488                         USER *u;\r
2489                         sprintf(tmp, "user%u", i);\r
2490                         AcLock(h);\r
2491                         u = NewUser(tmp, L"test", L"", AUTHTYPE_ANONYMOUS, NULL);\r
2492                         AcAddUser(h, u);\r
2493                         ReleaseUser(u);\r
2494                         AcUnlock(h);\r
2495                 }\r
2496         }\r
2497 \r
2498         ReleaseHub(h);\r
2499 }\r
2500 \r
2501 // ログ設定をデフォルトにする\r
2502 void SiSetDefaultLogSetting(HUB_LOG *g)\r
2503 {\r
2504         // 引数チェック\r
2505         if (g == NULL)\r
2506         {\r
2507                 return;\r
2508         }\r
2509 \r
2510         Zero(g, sizeof(HUB_LOG));\r
2511         g->SaveSecurityLog = true;\r
2512         g->SecurityLogSwitchType = LOG_SWITCH_DAY;\r
2513         g->SavePacketLog = false;\r
2514         g->PacketLogSwitchType = LOG_SWITCH_DAY;\r
2515         g->PacketLogConfig[PACKET_LOG_TCP_CONN] =\r
2516                 g->PacketLogConfig[PACKET_LOG_DHCP] = PACKET_LOG_HEADER;\r
2517 }\r
2518 \r
2519 // テスト\r
2520 void SiTest(SERVER *s)\r
2521 {\r
2522 #if     0\r
2523         USER *u;\r
2524         USERGROUP *g;\r
2525         HUB *h;\r
2526         LINK *k;\r
2527         CLIENT_OPTION o;\r
2528         CLIENT_AUTH a;\r
2529         ACCESS *ac;\r
2530         X *x;\r
2531         // 引数チェック\r
2532         if (s == NULL)\r
2533         {\r
2534                 return;\r
2535         }\r
2536 \r
2537         h = GetHub(s->Cedar, SERVER_DEFAULT_HUB_NAME);\r
2538         if (h == NULL)\r
2539         {\r
2540                 return;\r
2541         }\r
2542 \r
2543         // ユーザーを作成する\r
2544         g = NewGroup("test_group", L"テスト グループ", L"テストです。");\r
2545         AcAddGroup(h, g);\r
2546 \r
2547         u = NewUser("test", L"テスト", L"はむです", AUTHTYPE_ANONYMOUS, NULL);\r
2548         AcAddUser(h, u);\r
2549         JoinUserToGroup(u, g);\r
2550         ReleaseUser(u);\r
2551 \r
2552         u = NewUser("anonymous", L"匿名ユーザー", L"ソフトイーサ株式会社", AUTHTYPE_ANONYMOUS, NULL);\r
2553         AcAddUser(h, u);\r
2554         JoinUserToGroup(u, g);\r
2555         ReleaseUser(u);\r
2556 \r
2557         u = NewUser("password", L"パスワードユーザー", L"ソフトイーサ株式会社", AUTHTYPE_PASSWORD, NewPasswordAuthData("password", "microsoft"));\r
2558         AcAddUser(h, u);\r
2559         ReleaseUser(u);\r
2560 \r
2561         x = FileToX("mayaqua.cer");\r
2562         u = NewUser("usercert", L"ユーザー証明書テストユーザー", L"ソフトイーサ株式会社", AUTHTYPE_USERCERT, NewUserCertAuthData(x));\r
2563         AcAddUser(h, u);\r
2564         ReleaseUser(u);\r
2565         FreeX(x);\r
2566 \r
2567         u = NewUser("rootcert", L"ルート証明書テストユーザー", L"ソフトイーサ株式会社", AUTHTYPE_ROOTCERT, NewRootCertAuthData(NULL, NULL));\r
2568         AcAddUser(h, u);\r
2569         ReleaseUser(u);\r
2570 \r
2571         u = NewUser("*", L"*", L"すべて", AUTHTYPE_RADIUS, NewRadiusAuthData(L""));\r
2572         AcAddUser(h, u);\r
2573         ReleaseUser(u);\r
2574 \r
2575         ReleaseGroup(g);\r
2576 \r
2577         // Radius サーバーを設定する\r
2578         SetRadiusServer(h, "dc.sec.softether.co.jp", RADIUS_DEFAULT_PORT, "microsoft");\r
2579 \r
2580         // HUB 間リンクを作成する\r
2581         Zero(&o, sizeof(o));\r
2582         UniStrCpy(o.AccountName, sizeof(o.AccountName), L"テスト リンク");\r
2583         o.MaxConnection = 8;\r
2584         o.NumRetry = INFINITE;\r
2585         o.UseEncrypt = true;\r
2586         StrCpy(o.HubName, sizeof(o.HubName), "TEST_HUB");\r
2587         o.Port = 443;\r
2588         StrCpy(o.Hostname, sizeof(o.Hostname), "ts.softether.co.jp");\r
2589 \r
2590         Zero(&a, sizeof(a));\r
2591         a.AuthType = CLIENT_AUTHTYPE_ANONYMOUS;\r
2592         StrCpy(a.Username, sizeof(a.Username), "anonymous_test");\r
2593 \r
2594         k = NewLink(s->Cedar, h, &o, &a, GetDefaultPolicy());\r
2595         StartLink(k);\r
2596 \r
2597         ReleaseLink(k);\r
2598 \r
2599         // 証明書を追加する\r
2600         x = FileToX("root.cer");\r
2601         AddRootCert(h, x);\r
2602         FreeX(x);\r
2603 \r
2604         // アクセスリストを追加する\r
2605         ac = ZeroMalloc(sizeof(ACCESS));\r
2606         ac->Id = 1;\r
2607         UniStrCpy(ac->Note, sizeof(ac->Note), L"アクセスリストのテスト");\r
2608         ac->Active = true;\r
2609         ac->Priority = 3;\r
2610         ac->Discard = true;\r
2611         ac->SrcIpAddress = 0x12345678;\r
2612         ac->SrcSubnetMask = 0xffffffff;\r
2613         ac->DestIpAddress = 0x36547894;\r
2614         ac->DestSubnetMask = 0xffffffff;\r
2615         ac->Protocol = IP_PROTO_TCP;\r
2616         StrCpy(ac->SrcUsername, 0, "yagi");\r
2617         StrCpy(ac->DestUsername, 0, "neko");\r
2618         AddAccessList(h, ac);\r
2619         Free(ac);\r
2620 \r
2621         ReleaseHub(h);\r
2622 #endif\r
2623 }\r
2624 \r
2625 // 初期コンフィグレーションを設定する\r
2626 void SiLoadInitialConfiguration(SERVER *s)\r
2627 {\r
2628         RPC_KEEP k;\r
2629         // 引数チェック\r
2630         if (s == NULL)\r
2631         {\r
2632                 return;\r
2633         }\r
2634 \r
2635         // 自動保存間隔関係\r
2636         s->AutoSaveConfigSpan = SERVER_FILE_SAVE_INTERVAL_DEFAULT;\r
2637 \r
2638         s->Weight = FARM_DEFAULT_WEIGHT;\r
2639 \r
2640         // KEEP 関係\r
2641         Zero(&k, sizeof(k));\r
2642         k.UseKeepConnect = true;\r
2643         k.KeepConnectPort = 80;\r
2644         StrCpy(k.KeepConnectHost, sizeof(k.KeepConnectHost), CLIENT_DEFAULT_KEEPALIVE_HOST);\r
2645         k.KeepConnectInterval = KEEP_INTERVAL_DEFAULT * 1000;\r
2646         k.KeepConnectProtocol = CONNECTION_UDP;\r
2647 \r
2648         Lock(s->Keep->lock);\r
2649         {\r
2650                 KEEP *keep = s->Keep;\r
2651                 keep->Enable = k.UseKeepConnect;\r
2652                 keep->Server = true;\r
2653                 StrCpy(keep->ServerName, sizeof(keep->ServerName), k.KeepConnectHost);\r
2654                 keep->ServerPort = k.KeepConnectPort;\r
2655                 keep->UdpMode = k.KeepConnectProtocol;\r
2656                 keep->Interval = k.KeepConnectInterval;\r
2657         }\r
2658         Unlock(s->Keep->lock);\r
2659 \r
2660         // パスワードを初期化する\r
2661         Hash(s->HashedPassword, "", 0, true);\r
2662 \r
2663         // 暗号化アルゴリズム名をデフォルトにする\r
2664         SiInitCipherName(s);\r
2665 \r
2666         // サーバー証明書をデフォルトにする\r
2667         SiInitDefaultServerCert(s);\r
2668 \r
2669         // リスナーリストをデフォルト設定する\r
2670         SiInitListenerList(s);\r
2671 \r
2672         // デフォルト HUB の作成\r
2673         SiInitDefaultHubList(s);\r
2674 \r
2675         s->Eraser = NewEraser(s->Logger, 0);\r
2676 }\r
2677 \r
2678 // コンフィグレーションファイルを読み込む (メイン)\r
2679 bool SiLoadConfigurationFileMain(SERVER *s, FOLDER *root)\r
2680 {\r
2681         // 引数チェック\r
2682         if (s == NULL || root == NULL)\r
2683         {\r
2684                 return false;\r
2685         }\r
2686 \r
2687         return SiLoadConfigurationCfg(s, root);\r
2688 }\r
2689 \r
2690 // コンフィグレーションファイルを読み込む\r
2691 bool SiLoadConfigurationFile(SERVER *s)\r
2692 {\r
2693         // 引数チェック\r
2694         bool ret = false;\r
2695         FOLDER *root;\r
2696         if (s == NULL)\r
2697         {\r
2698                 return false;\r
2699         }\r
2700 \r
2701         s->CfgRw = NewCfgRw(&root,\r
2702                 s->Cedar->Bridge == false ? SERVER_CONFIG_FILE_NAME : BRIDGE_CONFIG_FILE_NAME);\r
2703 \r
2704         if (server_reset_setting)\r
2705         {\r
2706                 CfgDeleteFolder(root);\r
2707                 root = NULL;\r
2708                 server_reset_setting = false;\r
2709         }\r
2710 \r
2711         if (root == NULL)\r
2712         {\r
2713                 return false;\r
2714         }\r
2715 \r
2716         ret = SiLoadConfigurationFileMain(s, root);\r
2717 \r
2718         CfgDeleteFolder(root);\r
2719 \r
2720         return ret;\r
2721 }\r
2722 \r
2723 // コンフィグレーション初期化\r
2724 void SiInitConfiguration(SERVER *s)\r
2725 {\r
2726         // 引数チェック\r
2727         if (s == NULL)\r
2728         {\r
2729                 return;\r
2730         }\r
2731 \r
2732         // Ethernet 初期化\r
2733         InitEth();\r
2734 \r
2735         s->AutoSaveConfigSpan = SERVER_FILE_SAVE_INTERVAL_DEFAULT;\r
2736 \r
2737         SLog(s->Cedar, "LS_LOAD_CONFIG_1");\r
2738         if (SiLoadConfigurationFile(s) == false)\r
2739         {\r
2740                 SLog(s->Cedar, "LS_LOAD_CONFIG_3");\r
2741                 SiLoadInitialConfiguration(s);\r
2742 \r
2743                 server_reset_setting = false;\r
2744         }\r
2745         else\r
2746         {\r
2747                 SLog(s->Cedar, "LS_LOAD_CONFIG_2");\r
2748         }\r
2749 \r
2750         // Linux における arp_filter\r
2751         if (GetOsInfo()->OsType == OSTYPE_LINUX)\r
2752         {\r
2753                 if (s->NoLinuxArpFilter == false)\r
2754                 {\r
2755                         SetLinuxArpFilter();\r
2756                 }\r
2757         }\r
2758 \r
2759         // 保存スレッド作成\r
2760         SLog(s->Cedar, "LS_INIT_SAVE_THREAD", s->AutoSaveConfigSpan / 1000);\r
2761         s->SaveHaltEvent = NewEvent();\r
2762         s->SaveThread = NewThread(SiSaverThread, s);\r
2763 }\r
2764 \r
2765 // サーバー設定を CFG から読み込む\r
2766 bool SiLoadConfigurationCfg(SERVER *s, FOLDER *root)\r
2767 {\r
2768         FOLDER *f1, *f2, *f3, *f4, *f5, *f6;\r
2769         // 引数チェック\r
2770         if (s == NULL || root == NULL)\r
2771         {\r
2772                 return false;\r
2773         }\r
2774 \r
2775         f1 = CfgGetFolder(root, "ServerConfiguration");\r
2776         f2 = CfgGetFolder(root, "VirtualHUB");\r
2777         f3 = CfgGetFolder(root, "ListenerList");\r
2778         f4 = CfgGetFolder(root, "LocalBridgeList");\r
2779         f5 = CfgGetFolder(root, "VirtualLayer3SwitchList");\r
2780         f6 = CfgGetFolder(root, "LicenseManager");\r
2781 \r
2782         if (f1 == NULL)\r
2783         {\r
2784                 SLog(s->Cedar, "LS_BAD_CONFIG");\r
2785                 return false;\r
2786         }\r
2787 \r
2788         s->ConfigRevision = CfgGetInt(root, "ConfigRevision");\r
2789 \r
2790         if (s->Cedar->Bridge == false && f6 != NULL)\r
2791         {\r
2792                 if (GetServerCapsBool(s, "b_support_license"))\r
2793                 {\r
2794                         SiLoadLicenseManager(s, f6);\r
2795                 }\r
2796         }\r
2797 \r
2798         DestroyServerCapsCache(s);\r
2799 \r
2800         SiLoadServerCfg(s, f1);\r
2801 \r
2802         if (s->ServerType != SERVER_TYPE_FARM_MEMBER)\r
2803         {\r
2804                 SiLoadHubs(s, f2);\r
2805         }\r
2806 \r
2807         SiLoadListeners(s, f3);\r
2808 \r
2809         if (f4 != NULL)\r
2810         {\r
2811                 SiLoadLocalBridges(s, f4);\r
2812         }\r
2813 \r
2814         if (s->Cedar->Bridge == false && f5 != NULL)\r
2815         {\r
2816                 SiLoadL3Switchs(s, f5);\r
2817         }\r
2818 \r
2819         return true;\r
2820 }\r
2821 \r
2822 // リスナー設定を書き出す\r
2823 void SiWriteListenerCfg(FOLDER *f, SERVER_LISTENER *r)\r
2824 {\r
2825         // 引数チェック\r
2826         if (f == NULL || r == NULL)\r
2827         {\r
2828                 return;\r
2829         }\r
2830 \r
2831         CfgAddBool(f, "Enabled", r->Enabled);\r
2832         CfgAddInt(f, "Port", r->Port);\r
2833 }\r
2834 \r
2835 // リスナー設定を読み込む\r
2836 void SiLoadListenerCfg(SERVER *s, FOLDER *f)\r
2837 {\r
2838         bool enable;\r
2839         UINT port;\r
2840         // 引数チェック\r
2841         if (s == NULL || f == NULL)\r
2842         {\r
2843                 return;\r
2844         }\r
2845 \r
2846         enable = CfgGetBool(f, "Enabled");\r
2847         port = CfgGetInt(f, "Port");\r
2848 \r
2849         if (port == 0)\r
2850         {\r
2851                 return;\r
2852         }\r
2853 \r
2854         SiAddListener(s, port, enable);\r
2855 }\r
2856 \r
2857 // リスナー一覧を読み込む\r
2858 void SiLoadListeners(SERVER *s, FOLDER *f)\r
2859 {\r
2860         TOKEN_LIST *t;\r
2861         UINT i;\r
2862         // 引数チェック\r
2863         if (s == NULL || f == NULL)\r
2864         {\r
2865                 return;\r
2866         }\r
2867 \r
2868         t = CfgEnumFolderToTokenList(f);\r
2869         for (i = 0;i < t->NumTokens;i++)\r
2870         {\r
2871                 FOLDER *ff = CfgGetFolder(f, t->Token[i]);\r
2872                 if (ff != NULL)\r
2873                 {\r
2874                         SiLoadListenerCfg(s, ff);\r
2875                 }\r
2876         }\r
2877         FreeToken(t);\r
2878 }\r
2879 \r
2880 // リスナー一覧を書き出す\r
2881 void SiWriteListeners(FOLDER *f, SERVER *s)\r
2882 {\r
2883         // 引数チェック\r
2884         if (f == NULL || s == NULL)\r
2885         {\r
2886                 return;\r
2887         }\r
2888 \r
2889         LockList(s->ServerListenerList);\r
2890         {\r
2891                 UINT i;\r
2892                 for (i = 0;i < LIST_NUM(s->ServerListenerList);i++)\r
2893                 {\r
2894                         SERVER_LISTENER *r = LIST_DATA(s->ServerListenerList, i);\r
2895                         char name[MAX_SIZE];\r
2896                         Format(name, sizeof(name), "Listener%u", i);\r
2897                         SiWriteListenerCfg(CfgCreateFolder(f, name), r);\r
2898                 }\r
2899         }\r
2900         UnlockList(s->ServerListenerList);\r
2901 }\r
2902 \r
2903 // ブリッジを書き出す\r
2904 void SiWriteLocalBridgeCfg(FOLDER *f, LOCALBRIDGE *br)\r
2905 {\r
2906         // 引数チェック\r
2907         if (f == NULL || br == NULL)\r
2908         {\r
2909                 return;\r
2910         }\r
2911 \r
2912         CfgAddStr(f, "DeviceName", br->DeviceName);\r
2913         CfgAddStr(f, "HubName", br->HubName);\r
2914         CfgAddBool(f, "NoPromiscuousMode", br->Local);\r
2915         CfgAddBool(f, "MonitorMode", br->Monitor);\r
2916         CfgAddBool(f, "FullBroadcastMode", br->FullBroadcast);\r
2917 \r
2918         if (OS_IS_UNIX(GetOsInfo()->OsType))\r
2919         {\r
2920                 CfgAddBool(f, "TapMode", br->TapMode);\r
2921 \r
2922                 if (br->TapMode)\r
2923                 {\r
2924                         char tmp[MAX_SIZE];\r
2925                         MacToStr(tmp, sizeof(tmp), br->TapMacAddress);\r
2926                         CfgAddStr(f, "TapMacAddress", tmp);\r
2927                 }\r
2928         }\r
2929 }\r
2930 \r
2931 // ブリッジ一覧を書き出す\r
2932 void SiWriteLocalBridges(FOLDER *f, SERVER *s)\r
2933 {\r
2934         // 引数チェック\r
2935         if (s == NULL || f == NULL)\r
2936         {\r
2937                 return;\r
2938         }\r
2939 \r
2940         LockList(s->Cedar->LocalBridgeList);\r
2941         {\r
2942                 UINT i;\r
2943                 for (i = 0;i < LIST_NUM(s->Cedar->LocalBridgeList);i++)\r
2944                 {\r
2945                         LOCALBRIDGE *br = LIST_DATA(s->Cedar->LocalBridgeList, i);\r
2946                         char name[MAX_SIZE];\r
2947 \r
2948                         Format(name, sizeof(name), "LocalBridge%u", i);\r
2949                         SiWriteLocalBridgeCfg(CfgCreateFolder(f, name), br);\r
2950                 }\r
2951         }\r
2952         UnlockList(s->Cedar->LocalBridgeList);\r
2953 }\r
2954 \r
2955 // ブリッジを読み込む\r
2956 void SiLoadLocalBridgeCfg(SERVER *s, FOLDER *f)\r
2957 {\r
2958         char hub[MAX_SIZE];\r
2959         char nic[MAX_SIZE];\r
2960         bool tapmode = false;\r
2961         UCHAR tapaddr[6];\r
2962         // 引数チェック\r
2963         if (s == NULL || f == NULL)\r
2964         {\r
2965                 return;\r
2966         }\r
2967 \r
2968         Zero(hub, sizeof(hub));\r
2969         Zero(nic, sizeof(nic));\r
2970 \r
2971         CfgGetStr(f, "HubName", hub, sizeof(hub));\r
2972         CfgGetStr(f, "DeviceName", nic, sizeof(nic));\r
2973 \r
2974         if (IsEmptyStr(hub) || IsEmptyStr(nic))\r
2975         {\r
2976                 return;\r
2977         }\r
2978 \r
2979         if (OS_IS_UNIX(GetOsInfo()->OsType))\r
2980         {\r
2981                 if (CfgGetBool(f, "TapMode"))\r
2982                 {\r
2983                         char tmp[MAX_SIZE];\r
2984                         tapmode = true;\r
2985                         Zero(tapaddr, sizeof(tapaddr));\r
2986                         if (CfgGetStr(f, "TapMacAddress", tmp, sizeof(tmp)))\r
2987                         {\r
2988                                 BUF *b;\r
2989                                 b = StrToBin(tmp);\r
2990                                 if (b != NULL && b->Size == 6)\r
2991                                 {\r
2992                                         Copy(tapaddr, b->Buf, sizeof(tapaddr));\r
2993                                 }\r
2994                                 FreeBuf(b);\r
2995                         }\r
2996                 }\r
2997         }\r
2998 \r
2999         AddLocalBridge(s->Cedar, hub, nic, CfgGetBool(f, "NoPromiscuousMode"), CfgGetBool(f, "MonitorMode"),\r
3000                 tapmode, tapaddr, CfgGetBool(f, "FullBroadcastMode"));\r
3001 }\r
3002 \r
3003 // ブリッジ一覧を読み込む\r
3004 void SiLoadLocalBridges(SERVER *s, FOLDER *f)\r
3005 {\r
3006         TOKEN_LIST *t;\r
3007         UINT i;\r
3008         // 引数チェック\r
3009         if (s == NULL || f == NULL)\r
3010         {\r
3011                 return;\r
3012         }\r
3013 \r
3014         t = CfgEnumFolderToTokenList(f);\r
3015 \r
3016         for (i = 0;i < t->NumTokens;i++)\r
3017         {\r
3018                 char *name = t->Token[i];\r
3019 \r
3020                 SiLoadLocalBridgeCfg(s, CfgGetFolder(f, name));\r
3021         }\r
3022 \r
3023         FreeToken(t);\r
3024 }\r
3025 \r
3026 // サーバーの設定リビジョンをインクリメントする\r
3027 void IncrementServerConfigRevision(SERVER *s)\r
3028 {\r
3029         // 引数チェック\r
3030         if (s == NULL)\r
3031         {\r
3032                 return;\r
3033         }\r
3034 \r
3035         s->ConfigRevision++;\r
3036 }\r
3037 \r
3038 // サーバー設定を CFG に書き出す\r
3039 FOLDER *SiWriteConfigurationToCfg(SERVER *s)\r
3040 {\r
3041         FOLDER *root;\r
3042         // 引数チェック\r
3043         if (s == NULL)\r
3044         {\r
3045                 return NULL;\r
3046         }\r
3047 \r
3048         root = CfgCreateFolder(NULL, TAG_ROOT);\r
3049 \r
3050         CfgAddInt(root, "ConfigRevision", s->ConfigRevision);\r
3051 \r
3052         SiWriteListeners(CfgCreateFolder(root, "ListenerList"), s);\r
3053 \r
3054         SiWriteLocalBridges(CfgCreateFolder(root, "LocalBridgeList"), s);\r
3055 \r
3056         SiWriteServerCfg(CfgCreateFolder(root, "ServerConfiguration"), s);\r
3057 \r
3058         if (s->UpdatedServerType != SERVER_TYPE_FARM_MEMBER)\r
3059         {\r
3060                 SiWriteHubs(CfgCreateFolder(root, "VirtualHUB"), s);\r
3061         }\r
3062 \r
3063         if (s->Cedar->Bridge == false)\r
3064         {\r
3065                 SiWriteL3Switchs(CfgCreateFolder(root, "VirtualLayer3SwitchList"), s);\r
3066 \r
3067                 if (GetServerCapsBool(s, "b_support_license"))\r
3068                 {\r
3069                         SiWriteLicenseManager(CfgCreateFolder(root, "LicenseManager"), s);\r
3070                 }\r
3071         }\r
3072 \r
3073         return root;\r
3074 }\r
3075 \r
3076 // ポリシーの読み込み\r
3077 void SiLoadPolicyCfg(POLICY *p, FOLDER *f)\r
3078 {\r
3079         // 引数チェック\r
3080         if (f == NULL || p == NULL)\r
3081         {\r
3082                 return;\r
3083         }\r
3084 \r
3085         Zero(p, sizeof(POLICY));\r
3086 \r
3087         // Ver 2\r
3088         p->Access = CfgGetBool(f, "Access");\r
3089         p->DHCPFilter = CfgGetBool(f, "DHCPFilter");\r
3090         p->DHCPNoServer = CfgGetBool(f, "DHCPNoServer");\r
3091         p->DHCPForce = CfgGetBool(f, "DHCPForce");\r
3092         p->NoBridge = CfgGetBool(f, "NoBridge");\r
3093         p->NoRouting = CfgGetBool(f, "NoRouting");\r
3094         p->CheckMac = CfgGetBool(f, "CheckMac");\r
3095         p->CheckIP = CfgGetBool(f, "CheckIP");\r
3096         p->ArpDhcpOnly = CfgGetBool(f, "ArpDhcpOnly");\r
3097         p->PrivacyFilter = CfgGetBool(f, "PrivacyFilter");\r
3098         p->NoServer = CfgGetBool(f, "NoServer");\r
3099         p->NoBroadcastLimiter = CfgGetBool(f, "NoBroadcastLimiter");\r
3100         p->MonitorPort = CfgGetBool(f, "MonitorPort");\r
3101         p->MaxConnection = CfgGetInt(f, "MaxConnection");\r
3102         p->TimeOut = CfgGetInt(f, "TimeOut");\r
3103         p->MaxMac = CfgGetInt(f, "MaxMac");\r
3104         p->MaxIP = CfgGetInt(f, "MaxIP");\r
3105         p->MaxUpload = CfgGetInt(f, "MaxUpload");\r
3106         p->MaxDownload = CfgGetInt(f, "MaxDownload");\r
3107         p->FixPassword = CfgGetBool(f, "FixPassword");\r
3108         p->MultiLogins = CfgGetInt(f, "MultiLogins");\r
3109         p->NoQoS = CfgGetBool(f, "NoQoS");\r
3110 \r
3111         // Ver 3\r
3112         p->RSandRAFilter = CfgGetBool(f, "RSandRAFilter");\r
3113         p->RAFilter = CfgGetBool(f, "RAFilter");\r
3114         p->DHCPv6Filter = CfgGetBool(f, "DHCPv6Filter");\r
3115         p->DHCPv6NoServer = CfgGetBool(f, "DHCPv6NoServer");\r
3116         p->NoRoutingV6 = CfgGetBool(f, "NoRoutingV6");\r
3117         p->CheckIPv6 = CfgGetBool(f, "CheckIPv6");\r
3118         p->NoServerV6 = CfgGetBool(f, "NoServerV6");\r
3119         p->MaxIPv6 = CfgGetInt(f, "MaxIPv6");\r
3120         p->NoSavePassword = CfgGetBool(f, "NoSavePassword");\r
3121         p->AutoDisconnect = CfgGetInt(f, "AutoDisconnect");\r
3122         p->FilterIPv4 = CfgGetBool(f, "FilterIPv4");\r
3123         p->FilterIPv6 = CfgGetBool(f, "FilterIPv6");\r
3124         p->FilterNonIP = CfgGetBool(f, "FilterNonIP");\r
3125         p->NoIPv6DefaultRouterInRA = CfgGetBool(f, "NoIPv6DefaultRouterInRA");\r
3126         p->NoIPv6DefaultRouterInRAWhenIPv6 = CfgGetBool(f, "NoIPv6DefaultRouterInRAWhenIPv6");\r
3127         p->VLanId = CfgGetInt(f, "VLanId");\r
3128 }\r
3129 \r
3130 // ポリシーの書き込み\r
3131 void SiWritePolicyCfg(FOLDER *f, POLICY *p, bool cascade_mode)\r
3132 {\r
3133         // 引数チェック\r
3134         if (f == NULL || p == NULL)\r
3135         {\r
3136                 return;\r
3137         }\r
3138 \r
3139         // Ver 2.0\r
3140         if (cascade_mode == false)\r
3141         {\r
3142                 CfgAddBool(f, "Access", p->Access);\r
3143         }\r
3144 \r
3145         CfgAddBool(f, "DHCPFilter", p->DHCPFilter);\r
3146         CfgAddBool(f, "DHCPNoServer", p->DHCPNoServer);\r
3147         CfgAddBool(f, "DHCPForce", p->DHCPForce);\r
3148 \r
3149         if (cascade_mode == false)\r
3150         {\r
3151                 CfgAddBool(f, "NoBridge", p->NoBridge);\r
3152                 CfgAddBool(f, "NoRouting", p->NoRouting);\r
3153         }\r
3154 \r
3155         CfgAddBool(f, "CheckMac", p->CheckMac);\r
3156         CfgAddBool(f, "CheckIP", p->CheckIP);\r
3157         CfgAddBool(f, "ArpDhcpOnly", p->ArpDhcpOnly);\r
3158 \r
3159         if (cascade_mode == false)\r
3160         {\r
3161                 CfgAddBool(f, "PrivacyFilter", p->PrivacyFilter);\r
3162         }\r
3163 \r
3164         CfgAddBool(f, "NoServer", p->NoServer);\r
3165         CfgAddBool(f, "NoBroadcastLimiter", p->NoBroadcastLimiter);\r
3166 \r
3167         if (cascade_mode == false)\r
3168         {\r
3169                 CfgAddBool(f, "MonitorPort", p->MonitorPort);\r
3170                 CfgAddInt(f, "MaxConnection", p->MaxConnection);\r
3171                 CfgAddInt(f, "TimeOut", p->TimeOut);\r
3172         }\r
3173 \r
3174         CfgAddInt(f, "MaxMac", p->MaxMac);\r
3175         CfgAddInt(f, "MaxIP", p->MaxIP);\r
3176         CfgAddInt(f, "MaxUpload", p->MaxUpload);\r
3177         CfgAddInt(f, "MaxDownload", p->MaxDownload);\r
3178 \r
3179         if (cascade_mode == false)\r
3180         {\r
3181                 CfgAddBool(f, "FixPassword", p->FixPassword);\r
3182                 CfgAddInt(f, "MultiLogins", p->MultiLogins);\r
3183                 CfgAddBool(f, "NoQoS", p->NoQoS);\r
3184         }\r
3185 \r
3186         // Ver 3.0\r
3187         CfgAddBool(f, "RSandRAFilter", p->RSandRAFilter);\r
3188         CfgAddBool(f, "RAFilter", p->RAFilter);\r
3189         CfgAddBool(f, "DHCPv6Filter", p->DHCPv6Filter);\r
3190         CfgAddBool(f, "DHCPv6NoServer", p->DHCPv6NoServer);\r
3191 \r
3192         if (cascade_mode == false)\r
3193         {\r
3194                 CfgAddBool(f, "NoRoutingV6", p->NoRoutingV6);\r
3195         }\r
3196 \r
3197         CfgAddBool(f, "CheckIPv6", p->CheckIPv6);\r
3198         CfgAddBool(f, "NoServerV6", p->NoServerV6);\r
3199         CfgAddInt(f, "MaxIPv6", p->MaxIPv6);\r
3200 \r
3201         if (cascade_mode == false)\r
3202         {\r
3203                 CfgAddBool(f, "NoSavePassword", p->NoSavePassword);\r
3204                 CfgAddInt(f, "AutoDisconnect", p->AutoDisconnect);\r
3205         }\r
3206 \r
3207         CfgAddBool(f, "FilterIPv4", p->FilterIPv4);\r
3208         CfgAddBool(f, "FilterIPv6", p->FilterIPv6);\r
3209         CfgAddBool(f, "FilterNonIP", p->FilterNonIP);\r
3210         CfgAddBool(f, "NoIPv6DefaultRouterInRA", p->NoIPv6DefaultRouterInRA);\r
3211         CfgAddBool(f, "NoIPv6DefaultRouterInRAWhenIPv6", p->NoIPv6DefaultRouterInRAWhenIPv6);\r
3212         CfgAddInt(f, "VLanId", p->VLanId);\r
3213 }\r
3214 \r
3215 // 仮想 HUB のリンク情報の書き込み\r
3216 void SiWriteHubLinkCfg(FOLDER *f, LINK *k)\r
3217 {\r
3218         // 引数チェック\r
3219         if (f == NULL || k == NULL)\r
3220         {\r
3221                 return;\r
3222         }\r
3223 \r
3224         Lock(k->lock);\r
3225         {\r
3226                 // オンライン\r
3227                 CfgAddBool(f, "Online", k->Offline ? false : true);\r
3228 \r
3229                 // クライアントオプション\r
3230                 CiWriteClientOption(CfgCreateFolder(f, "ClientOption"), k->Option);\r
3231 \r
3232                 // クライアント認証データ\r
3233                 CiWriteClientAuth(CfgCreateFolder(f, "ClientAuth"), k->Auth);\r
3234 \r
3235                 // ポリシー\r
3236                 if (k->Policy != NULL)\r
3237                 {\r
3238                         SiWritePolicyCfg(CfgCreateFolder(f, "Policy"), k->Policy, true);\r
3239                 }\r
3240 \r
3241                 CfgAddBool(f, "CheckServerCert", k->CheckServerCert);\r
3242 \r
3243                 if (k->ServerCert != NULL)\r
3244                 {\r
3245                         BUF *b = XToBuf(k->ServerCert, false);\r
3246                         CfgAddBuf(f, "ServerCert", b);\r
3247                         FreeBuf(b);\r
3248                 }\r
3249         }\r
3250         Unlock(k->lock);\r
3251 }\r
3252 \r
3253 // リンク情報の読み込み\r
3254 void SiLoadHubLinkCfg(FOLDER *f, HUB *h)\r
3255 {\r
3256         bool online;\r
3257         CLIENT_OPTION *o;\r
3258         CLIENT_AUTH *a;\r
3259         FOLDER *pf;\r
3260         POLICY p;\r
3261         LINK *k;\r
3262         // 引数チェック\r
3263         if (f == NULL || h == NULL)\r
3264         {\r
3265                 return;\r
3266         }\r
3267 \r
3268         pf = CfgGetFolder(f, "Policy");\r
3269         if (pf == NULL)\r
3270         {\r
3271                 return;\r
3272         }\r
3273 \r
3274         SiLoadPolicyCfg(&p, pf);\r
3275 \r
3276         online = CfgGetBool(f, "Online");\r
3277 \r
3278         o = CiLoadClientOption(CfgGetFolder(f, "ClientOption"));\r
3279         a = CiLoadClientAuth(CfgGetFolder(f, "ClientAuth"));\r
3280         if (o == NULL || a == NULL)\r
3281         {\r
3282                 Free(o);\r
3283                 CiFreeClientAuth(a);\r
3284                 return;\r
3285         }\r
3286 \r
3287         k = NewLink(h->Cedar, h, o, a, &p);\r
3288         if (k != NULL)\r
3289         {\r
3290                 BUF *b;\r
3291                 k->CheckServerCert = CfgGetBool(f, "CheckServerCert");\r
3292                 b = CfgGetBuf(f, "ServerCert");\r
3293                 if (b != NULL)\r
3294                 {\r
3295                         k->ServerCert = BufToX(b, false);\r
3296                         FreeBuf(b);\r
3297                 }\r
3298 \r
3299                 if (online)\r
3300                 {\r
3301                         k->Offline = true;\r
3302                         SetLinkOnline(k);\r
3303                 }\r
3304                 else\r
3305                 {\r
3306                         k->Offline = false;\r
3307                         SetLinkOffline(k);\r
3308                 }\r
3309                 ReleaseLink(k);\r
3310         }\r
3311 \r
3312         Free(o);\r
3313         CiFreeClientAuth(a);\r
3314 }\r
3315 \r
3316 // 仮想 HUB の SecureNAT の書き込み\r
3317 void SiWriteSecureNAT(HUB *h, FOLDER *f)\r
3318 {\r
3319         // 引数チェック\r
3320         if (h == NULL || f == NULL)\r
3321         {\r
3322                 return;\r
3323         }\r
3324 \r
3325         CfgAddBool(f, "Disabled", h->EnableSecureNAT ? false : true);\r
3326 \r
3327         NiWriteVhOptionEx(h->SecureNATOption, f);\r
3328 }\r
3329 \r
3330 // 仮想 HUB の管理オプションの読み込み\r
3331 void SiLoadHubAdminOptions(HUB *h, FOLDER *f)\r
3332 {\r
3333         TOKEN_LIST *t;\r
3334         // 引数チェック\r
3335         if (h == NULL || f == NULL)\r
3336         {\r
3337                 return;\r
3338         }\r
3339 \r
3340         t = CfgEnumItemToTokenList(f);\r
3341         if (t != NULL)\r
3342         {\r
3343                 UINT i;\r
3344 \r
3345                 LockList(h->AdminOptionList);\r
3346                 {\r
3347                         DeleteAllHubAdminOption(h, false);\r
3348 \r
3349                         for (i = 0;i < t->NumTokens;i++)\r
3350                         {\r
3351                                 char *name = t->Token[i];\r
3352                                 ADMIN_OPTION *a;\r
3353                                 UINT value = CfgGetInt(f, name);;\r
3354 \r
3355                                 Trim(name);\r
3356 \r
3357                                 a = ZeroMalloc(sizeof(ADMIN_OPTION));\r
3358                                 StrCpy(a->Name, sizeof(a->Name), name);\r
3359                                 a->Value = value;\r
3360 \r
3361                                 Insert(h->AdminOptionList, a);\r
3362                         }\r
3363 \r
3364                         AddHubAdminOptionsDefaults(h, false);\r
3365                 }\r
3366                 UnlockList(h->AdminOptionList);\r
3367 \r
3368                 FreeToken(t);\r
3369         }\r
3370 }\r
3371 \r
3372 // 仮想 HUB の管理オプションの書き込み\r
3373 void SiWriteHubAdminOptions(FOLDER *f, HUB *h)\r
3374 {\r
3375         // 引数チェック\r
3376         if (f == NULL || h == NULL)\r
3377         {\r
3378                 return;\r
3379         }\r
3380 \r
3381         LockList(h->AdminOptionList);\r
3382         {\r
3383                 UINT i;\r
3384                 for (i = 0;i < LIST_NUM(h->AdminOptionList);i++)\r
3385                 {\r
3386                         ADMIN_OPTION *a = LIST_DATA(h->AdminOptionList, i);\r
3387 \r
3388                         CfgAddInt(f, a->Name, a->Value);\r
3389                 }\r
3390         }\r
3391         UnlockList(h->AdminOptionList);\r
3392 }\r
3393 \r
3394 // 仮想 HUB のリンクリストの書き込み\r
3395 void SiWriteHubLinks(FOLDER *f, HUB *h)\r
3396 {\r
3397         // 引数チェック\r
3398         if (f == NULL || h == NULL)\r
3399         {\r
3400                 return;\r
3401         }\r
3402 \r
3403         LockList(h->LinkList);\r
3404         {\r
3405                 UINT i;\r
3406                 for (i = 0;i < LIST_NUM(h->LinkList);i++)\r
3407                 {\r
3408                         LINK *k = LIST_DATA(h->LinkList, i);\r
3409                         char name[MAX_SIZE];\r
3410                         Format(name, sizeof(name), "Cascade%u", i);\r
3411                         SiWriteHubLinkCfg(CfgCreateFolder(f, name), k);\r
3412                 }\r
3413         }\r
3414         UnlockList(h->LinkList);\r
3415 }\r
3416 \r
3417 // リンクリストの読み込み\r
3418 void SiLoadHubLinks(HUB *h, FOLDER *f)\r
3419 {\r
3420         TOKEN_LIST *t;\r
3421         UINT i;\r
3422         // 引数チェック\r
3423         if (h == NULL || f == NULL)\r
3424         {\r
3425                 return;\r
3426         }\r
3427 \r
3428         t = CfgEnumFolderToTokenList(f);\r
3429 \r
3430         for (i = 0;i < t->NumTokens;i++)\r
3431         {\r
3432                 char *name = t->Token[i];\r
3433                 SiLoadHubLinkCfg(CfgGetFolder(f, name), h);\r
3434         }\r
3435 \r
3436         FreeToken(t);\r
3437 }\r
3438 \r
3439 // アクセスリスト項目の書き込み\r
3440 void SiWriteHubAccessCfg(FOLDER *f, ACCESS *a)\r
3441 {\r
3442         // 引数チェック\r
3443         if (f == NULL || a == NULL)\r
3444         {\r
3445                 return;\r
3446         }\r
3447 \r
3448         CfgAddUniStr(f, "Note", a->Note);\r
3449         CfgAddBool(f, "Active", a->Active);\r
3450         CfgAddInt(f, "Priority", a->Priority);\r
3451         CfgAddBool(f, "Discard", a->Discard);\r
3452         CfgAddBool(f, "IsIPv6", a->IsIPv6);\r
3453 \r
3454         if (a->IsIPv6 == false)\r
3455         {\r
3456                 CfgAddIp32(f, "SrcIpAddress", a->SrcIpAddress);\r
3457                 CfgAddIp32(f, "SrcSubnetMask", a->SrcSubnetMask);\r
3458                 CfgAddIp32(f, "DestIpAddress", a->DestIpAddress);\r
3459                 CfgAddIp32(f, "DestSubnetMask", a->DestSubnetMask);\r
3460         }\r
3461         else\r
3462         {\r
3463                 CfgAddIp6Addr(f, "SrcIpAddress6", &a->SrcIpAddress6);\r
3464                 CfgAddIp6Addr(f, "SrcSubnetMask6", &a->SrcSubnetMask6);\r
3465                 CfgAddIp6Addr(f, "DestIpAddress6", &a->DestIpAddress6);\r
3466                 CfgAddIp6Addr(f, "DestSubnetMask6", &a->DestSubnetMask6);\r
3467         }\r
3468 \r
3469         CfgAddInt(f, "Protocol", a->Protocol);\r
3470         CfgAddInt(f, "SrcPortStart", a->SrcPortStart);\r
3471         CfgAddInt(f, "SrcPortEnd", a->SrcPortEnd);\r
3472         CfgAddInt(f, "DestPortStart", a->DestPortStart);\r
3473         CfgAddInt(f, "DestPortEnd", a->DestPortEnd);\r
3474         CfgAddStr(f, "SrcUsername", a->SrcUsername);\r
3475         CfgAddStr(f, "DestUsername", a->DestUsername);\r
3476         CfgAddBool(f, "CheckSrcMac", a->CheckSrcMac);\r
3477 \r
3478         if (a->CheckSrcMac)\r
3479         {\r
3480                 char tmp[MAX_PATH];\r
3481 \r
3482                 MacToStr(tmp, sizeof(tmp), a->SrcMacAddress);\r
3483                 CfgAddStr(f, "SrcMacAddress", tmp);\r
3484 \r
3485                 MacToStr(tmp, sizeof(tmp), a->SrcMacMask);\r
3486                 CfgAddStr(f, "SrcMacMask", tmp);\r
3487         }\r
3488 \r
3489         CfgAddBool(f, "CheckDstMac", a->CheckDstMac);\r
3490 \r
3491         if (a->CheckDstMac)\r
3492         {\r
3493                 char tmp[MAX_PATH];\r
3494 \r
3495                 MacToStr(tmp, sizeof(tmp), a->DstMacAddress);\r
3496                 CfgAddStr(f, "DstMacAddress", tmp);\r
3497 \r
3498                 MacToStr(tmp, sizeof(tmp), a->DstMacMask);\r
3499                 CfgAddStr(f, "DstMacMask", tmp);\r
3500         }\r
3501 \r
3502         CfgAddBool(f, "CheckTcpState", a->CheckTcpState);\r
3503         CfgAddBool(f, "Established", a->Established);\r
3504 \r
3505         CfgAddInt(f, "Delay", a->Delay);\r
3506         CfgAddInt(f, "Jitter", a->Jitter);\r
3507         CfgAddInt(f, "Loss", a->Loss);\r
3508 }\r
3509 \r
3510 // アクセスリスト項目の読み込み\r
3511 void SiLoadHubAccessCfg(HUB *h, FOLDER *f)\r
3512 {\r
3513         ACCESS a;\r
3514         char tmp[MAX_PATH];\r
3515         // 引数チェック\r
3516         if (h == NULL || f == NULL)\r
3517         {\r
3518                 return;\r
3519         }\r
3520 \r
3521         Zero(&a, sizeof(a));\r
3522 \r
3523         CfgGetUniStr(f, "Note", a.Note, sizeof(a.Note));\r
3524         a.Active = CfgGetBool(f, "Active");\r
3525         a.Priority = CfgGetInt(f, "Priority");\r
3526         a.Discard = CfgGetBool(f, "Discard");\r
3527         a.IsIPv6 = CfgGetBool(f, "IsIPv6");\r
3528 \r
3529         if (a.IsIPv6 == false)\r
3530         {\r
3531                 a.SrcIpAddress = CfgGetIp32(f, "SrcIpAddress");\r
3532                 a.SrcSubnetMask = CfgGetIp32(f, "SrcSubnetMask");\r
3533                 a.DestIpAddress = CfgGetIp32(f, "DestIpAddress");\r
3534                 a.DestSubnetMask = CfgGetIp32(f, "DestSubnetMask");\r
3535         }\r
3536         else\r
3537         {\r
3538                 CfgGetIp6Addr(f, "SrcIpAddress6", &a.SrcIpAddress6);\r
3539                 CfgGetIp6Addr(f, "SrcSubnetMask6", &a.SrcSubnetMask6);\r
3540                 CfgGetIp6Addr(f, "DestIpAddress6", &a.DestIpAddress6);\r
3541                 CfgGetIp6Addr(f, "DestSubnetMask6", &a.DestSubnetMask6);\r
3542         }\r
3543 \r
3544         a.Protocol = CfgGetInt(f, "Protocol");\r
3545         a.SrcPortStart = CfgGetInt(f, "SrcPortStart");\r
3546         a.SrcPortEnd = CfgGetInt(f, "SrcPortEnd");\r
3547         a.DestPortStart = CfgGetInt(f, "DestPortStart");\r
3548         a.DestPortEnd = CfgGetInt(f, "DestPortEnd");\r
3549         CfgGetStr(f, "SrcUsername", a.SrcUsername, sizeof(a.SrcUsername));\r
3550         CfgGetStr(f, "DestUsername", a.DestUsername, sizeof(a.DestUsername));\r
3551         a.CheckSrcMac = CfgGetBool(f, "CheckSrcMac");\r
3552 \r
3553         if (CfgGetByte(f, "SrcMacAddress", a.SrcMacAddress, sizeof(a.SrcMacAddress)) == 0)\r
3554         {\r
3555                 CfgGetStr(f, "SrcMacAddress", tmp, sizeof(tmp));\r
3556                 if (StrToMac(a.SrcMacAddress, tmp) == false)\r
3557                 {\r
3558                         a.CheckSrcMac = false;\r
3559                 }\r
3560         }\r
3561 \r
3562         if (CfgGetByte(f, "SrcMacMask", a.SrcMacMask, sizeof(a.SrcMacMask)) == 0)\r
3563         {\r
3564                 CfgGetStr(f, "SrcMacMask", tmp, sizeof(tmp));\r
3565                 if (StrToMac(a.SrcMacMask, tmp) == false)\r
3566                 {\r
3567                         a.CheckSrcMac = false;\r
3568                 }\r
3569         }\r
3570 \r
3571         a.CheckDstMac = CfgGetBool(f, "CheckDstMac");\r
3572 \r
3573         if (CfgGetByte(f, "DstMacAddress", a.DstMacAddress, sizeof(a.DstMacAddress)) == 0)\r
3574         {\r
3575                 CfgGetStr(f, "DstMacAddress", tmp, sizeof(tmp));\r
3576                 if (StrToMac(a.DstMacAddress, tmp) == false)\r
3577                 {\r
3578                         a.CheckDstMac = false;\r
3579                 }\r
3580         }\r
3581 \r
3582         if (CfgGetByte(f, "DstMacMask", a.DstMacMask, sizeof(a.DstMacMask)) == 0)\r
3583         {\r
3584                 CfgGetStr(f, "DstMacMask", tmp, sizeof(tmp));\r
3585                 if (StrToMac(a.DstMacMask, tmp) == false)\r
3586                 {\r
3587                         a.CheckDstMac = false;\r
3588                 }\r
3589         }\r
3590 \r
3591         a.CheckTcpState = CfgGetBool(f, "CheckTcpState");\r
3592         a.Established = CfgGetBool(f, "Established");\r
3593         a.Delay = MAKESURE(CfgGetInt(f, "Delay"), 0, HUB_ACCESSLIST_DELAY_MAX);\r
3594         a.Jitter = MAKESURE(CfgGetInt(f, "Jitter"), 0, HUB_ACCESSLIST_JITTER_MAX);\r
3595         a.Loss = MAKESURE(CfgGetInt(f, "Loss"), 0, HUB_ACCESSLIST_LOSS_MAX);\r
3596 \r
3597         AddAccessList(h, &a);\r
3598 }\r
3599 \r
3600 // アクセスリストの書き込み\r
3601 void SiWriteHubAccessLists(FOLDER *f, HUB *h)\r
3602 {\r
3603         // 引数チェック\r
3604         if (f == NULL || h == NULL)\r
3605         {\r
3606                 return;\r
3607         }\r
3608 \r
3609         LockList(h->AccessList);\r
3610         {\r
3611                 UINT i;\r
3612                 for (i = 0;i < LIST_NUM(h->AccessList);i++)\r
3613                 {\r
3614                         ACCESS *a = LIST_DATA(h->AccessList, i);\r
3615                         char name[MAX_SIZE];\r
3616                         ToStr(name, a->Id);\r
3617                         SiWriteHubAccessCfg(CfgCreateFolder(f, name), a);\r
3618                 }\r
3619         }\r
3620         UnlockList(h->AccessList);\r
3621 }\r
3622 \r
3623 // アクセスリストの読み込み\r
3624 void SiLoadHubAccessLists(HUB *h, FOLDER *f)\r
3625 {\r
3626         TOKEN_LIST *t;\r
3627         UINT i;\r
3628         // 引数チェック\r
3629         if (f == NULL || h == NULL)\r
3630         {\r
3631                 return;\r
3632         }\r
3633 \r
3634         t = CfgEnumFolderToTokenList(f);\r
3635 \r
3636         for (i = 0;i < t->NumTokens;i++)\r
3637         {\r
3638                 char *name = t->Token[i];\r
3639                 UINT id = ToInt(name);\r
3640                 SiLoadHubAccessCfg(h, CfgGetFolder(f, name));\r
3641         }\r
3642 \r
3643         FreeToken(t);\r
3644 }\r
3645 \r
3646 // HUB_OPTION の読み込み\r
3647 void SiLoadHubOptionCfg(FOLDER *f, HUB_OPTION *o)\r
3648 {\r
3649         char tmp[MAX_SIZE];\r
3650         // 引数チェック\r
3651         if (f == NULL || o == NULL)\r
3652         {\r
3653                 return;\r
3654         }\r
3655 \r
3656         o->MaxSession = CfgGetInt(f, "MaxSession");\r
3657         o->NoArpPolling = CfgGetBool(f, "NoArpPolling");\r
3658         o->NoIPv6AddrPolling = CfgGetBool(f, "NoIPv6AddrPolling");\r
3659         o->NoIpTable = CfgGetBool(f, "NoIpTable");\r
3660         o->NoEnum = CfgGetBool(f, "NoEnum");\r
3661         o->FilterPPPoE = CfgGetBool(f, "FilterPPPoE");\r
3662         o->FilterOSPF = CfgGetBool(f, "FilterOSPF");\r
3663         o->FilterIPv4 = CfgGetBool(f, "FilterIPv4");\r
3664         o->FilterIPv6 = CfgGetBool(f, "FilterIPv6");\r
3665         o->FilterNonIP = CfgGetBool(f, "FilterNonIP");\r
3666         o->FilterBPDU = CfgGetBool(f, "FilterBPDU");\r
3667         o->NoIPv4PacketLog = CfgGetBool(f, "NoIPv4PacketLog");\r
3668         o->NoIPv6PacketLog = CfgGetBool(f, "NoIPv6PacketLog");\r
3669         o->NoIPv6DefaultRouterInRAWhenIPv6 = CfgGetBool(f, "NoIPv6DefaultRouterInRAWhenIPv6");\r
3670         o->DisableIPParsing = CfgGetBool(f, "DisableIPParsing");\r
3671         o->YieldAfterStorePacket = CfgGetBool(f, "YieldAfterStorePacket");\r
3672         o->NoSpinLockForPacketDelay = CfgGetBool(f, "NoSpinLockForPacketDelay");\r
3673         o->BroadcastStormDetectionThreshold = CfgGetInt(f, "BroadcastStormDetectionThreshold");\r
3674         o->ClientMinimumRequiredBuild = CfgGetInt(f, "ClientMinimumRequiredBuild");\r
3675         o->RequiredClientId = CfgGetInt(f, "RequiredClientId");\r
3676         o->NoManageVlanId = CfgGetBool(f, "NoManageVlanId");\r
3677         o->VlanTypeId = 0;\r
3678         if (CfgGetStr(f, "VlanTypeId", tmp, sizeof(tmp)))\r
3679         {\r
3680                 o->VlanTypeId = HexToInt(tmp);\r
3681         }\r
3682         if (o->VlanTypeId == 0)\r
3683         {\r
3684                 o->VlanTypeId = MAC_PROTO_TAGVLAN;\r
3685         }\r
3686         o->FixForDLinkBPDU = CfgGetBool(f, "FixForDLinkBPDU");\r
3687         o->NoLookBPDUBridgeId = CfgGetBool(f, "NoLookBPDUBridgeId");\r
3688 \r
3689         // デフォルトで有効\r
3690         if (CfgIsItem(f, "ManageOnlyPrivateIP"))\r
3691         {\r
3692                 o->ManageOnlyPrivateIP = CfgGetBool(f, "ManageOnlyPrivateIP");\r
3693         }\r
3694         else\r
3695         {\r
3696                 o->ManageOnlyPrivateIP = true;\r
3697         }\r
3698         if (CfgIsItem(f, "ManageOnlyLocalUnicastIPv6"))\r
3699         {\r
3700                 o->ManageOnlyLocalUnicastIPv6 = CfgGetBool(f, "ManageOnlyLocalUnicastIPv6");\r
3701         }\r
3702         else\r
3703         {\r
3704                 o->ManageOnlyLocalUnicastIPv6 = true;\r
3705         }\r
3706         if (CfgIsItem(f, "NoMacAddressLog"))\r
3707         {\r
3708                 o->NoMacAddressLog = CfgGetBool(f, "NoMacAddressLog");\r
3709         }\r
3710         else\r
3711         {\r
3712                 o->NoMacAddressLog = true;\r
3713         }\r
3714 }\r
3715 \r
3716 // HUB_OPTION の書き込み\r
3717 void SiWriteHubOptionCfg(FOLDER *f, HUB_OPTION *o)\r
3718 {\r
3719         char tmp[MAX_SIZE];\r
3720         // 引数チェック\r
3721         if (f == NULL || o == NULL)\r
3722         {\r
3723                 return;\r
3724         }\r
3725 \r
3726         CfgAddInt(f, "MaxSession", o->MaxSession);\r
3727         CfgAddBool(f, "NoArpPolling", o->NoArpPolling);\r
3728         CfgAddBool(f, "NoIPv6AddrPolling", o->NoIPv6AddrPolling);\r
3729         CfgAddBool(f, "NoIpTable", o->NoIpTable);\r
3730         CfgAddBool(f, "NoEnum", o->NoEnum);\r
3731         CfgAddBool(f, "FilterPPPoE", o->FilterPPPoE);\r
3732         CfgAddBool(f, "FilterOSPF", o->FilterOSPF);\r
3733         CfgAddBool(f, "FilterIPv4", o->FilterIPv4);\r
3734         CfgAddBool(f, "FilterIPv6", o->FilterIPv6);\r
3735         CfgAddBool(f, "FilterNonIP", o->FilterNonIP);\r
3736         CfgAddBool(f, "NoIPv4PacketLog", o->NoIPv4PacketLog);\r
3737         CfgAddBool(f, "NoIPv6PacketLog", o->NoIPv6PacketLog);\r
3738         CfgAddBool(f, "FilterBPDU", o->FilterBPDU);\r
3739         CfgAddBool(f, "NoIPv6DefaultRouterInRAWhenIPv6", o->NoIPv6DefaultRouterInRAWhenIPv6);\r
3740         CfgAddBool(f, "NoMacAddressLog", o->NoMacAddressLog);\r
3741         CfgAddBool(f, "ManageOnlyPrivateIP", o->ManageOnlyPrivateIP);\r
3742         CfgAddBool(f, "ManageOnlyLocalUnicastIPv6", o->ManageOnlyLocalUnicastIPv6);\r
3743         CfgAddBool(f, "DisableIPParsing", o->DisableIPParsing);\r
3744         CfgAddBool(f, "YieldAfterStorePacket", o->YieldAfterStorePacket);\r
3745         CfgAddBool(f, "NoSpinLockForPacketDelay", o->NoSpinLockForPacketDelay);\r
3746         CfgAddInt(f, "BroadcastStormDetectionThreshold", o->BroadcastStormDetectionThreshold);\r
3747         CfgAddInt(f, "ClientMinimumRequiredBuild", o->ClientMinimumRequiredBuild);\r
3748         CfgAddInt(f, "RequiredClientId", o->RequiredClientId);\r
3749         CfgAddBool(f, "NoManageVlanId", o->NoManageVlanId);\r
3750         Format(tmp, sizeof(tmp), "0x%x", o->VlanTypeId);\r
3751         CfgAddStr(f, "VlanTypeId", tmp);\r
3752         if (o->FixForDLinkBPDU)\r
3753         {\r
3754                 CfgAddBool(f, "FixForDLinkBPDU", o->FixForDLinkBPDU);\r
3755         }\r
3756         CfgAddBool(f, "NoLookBPDUBridgeId", o->NoLookBPDUBridgeId);\r
3757 }\r
3758 \r
3759 // ユーザーの書き込み\r
3760 void SiWriteUserCfg(FOLDER *f, USER *u)\r
3761 {\r
3762         AUTHPASSWORD *password;\r
3763         // 引数チェック\r
3764         if (f == NULL || u == NULL)\r
3765         {\r
3766                 return;\r
3767         }\r
3768 \r
3769         Lock(u->lock);\r
3770         {\r
3771                 CfgAddUniStr(f, "RealName", u->RealName);\r
3772                 CfgAddUniStr(f, "Note", u->Note);\r
3773                 if (u->Group != NULL)\r
3774                 {\r
3775                         CfgAddStr(f, "GroupName", u->GroupName);\r
3776                 }\r
3777                 CfgAddInt64(f, "CreatedTime", u->CreatedTime);\r
3778                 CfgAddInt64(f, "UpdatedTime", u->UpdatedTime);\r
3779                 CfgAddInt64(f, "ExpireTime", u->ExpireTime);\r
3780                 CfgAddInt64(f, "LastLoginTime", u->LastLoginTime);\r
3781                 CfgAddInt(f, "NumLogin", u->NumLogin);\r
3782                 if (u->Policy != NULL)\r
3783                 {\r
3784                         SiWritePolicyCfg(CfgCreateFolder(f, "Policy"), u->Policy, false);\r
3785                 }\r
3786                 SiWriteTraffic(f, "Traffic", u->Traffic);\r
3787 \r
3788                 CfgAddInt(f, "AuthType", u->AuthType);\r
3789                 if (u->AuthData != NULL)\r
3790                 {\r
3791                         switch (u->AuthType)\r
3792                         {\r
3793                         case AUTHTYPE_ANONYMOUS:\r
3794                                 break;\r
3795 \r
3796                         case AUTHTYPE_PASSWORD:\r
3797                                 password = (AUTHPASSWORD *)u->AuthData;\r
3798                                 CfgAddByte(f, "AuthPassword", password->HashedKey, sizeof(password->HashedKey));\r
3799                                 break;\r
3800                         }\r
3801                 }\r
3802         }\r
3803         Unlock(u->lock);\r
3804 }\r
3805 \r
3806 // ユーザーの読み込み\r
3807 void SiLoadUserCfg(HUB *h, FOLDER *f)\r
3808 {\r
3809         char *username;\r
3810         wchar_t realname[MAX_SIZE];\r
3811         wchar_t note[MAX_SIZE];\r
3812         char groupname[MAX_SIZE];\r
3813         FOLDER *pf;\r
3814         UINT64 created_time;\r
3815         UINT64 updated_time;\r
3816         UINT64 expire_time;\r
3817         UINT64 last_login_time;\r
3818         UINT num_login;\r
3819         POLICY p;\r
3820         TRAFFIC t;\r
3821         UINT authtype;\r
3822         void *authdata;\r
3823         X_SERIAL *serial = NULL;\r
3824         UCHAR hashed_password[SHA1_SIZE];\r
3825         USER *u;\r
3826         USERGROUP *g;\r
3827         // 引数チェック\r
3828         if (h == NULL || f == NULL)\r
3829         {\r
3830                 return;\r
3831         }\r
3832 \r
3833         username = f->Name;\r
3834         CfgGetUniStr(f, "RealName", realname, sizeof(realname));\r
3835         CfgGetUniStr(f, "Note", note, sizeof(note));\r
3836         CfgGetStr(f, "GroupName", groupname, sizeof(groupname));\r
3837 \r
3838         created_time = CfgGetInt64(f, "CreatedTime");\r
3839         updated_time = CfgGetInt64(f, "UpdatedTime");\r
3840         expire_time = CfgGetInt64(f, "ExpireTime");\r
3841         last_login_time = CfgGetInt64(f, "LastLoginTime");\r
3842         num_login = CfgGetInt(f, "NumLogin");\r
3843         pf = CfgGetFolder(f, "Policy");\r
3844         if (pf != NULL)\r
3845         {\r
3846                 SiLoadPolicyCfg(&p, pf);\r
3847         }\r
3848         SiLoadTraffic(f, "Traffic", &t);\r
3849 \r
3850         authtype = CfgGetInt(f, "AuthType");\r
3851         authdata = NULL;\r
3852 \r
3853         switch (authtype)\r
3854         {\r
3855         case AUTHTYPE_PASSWORD:\r
3856                 // 通常のパスワード認証\r
3857                 CfgGetByte(f, "AuthPassword", hashed_password, sizeof(hashed_password));\r
3858                 authdata = NewPasswordAuthDataRaw(hashed_password);\r
3859                 break;\r
3860 \r
3861         default:\r
3862                 // それ以外の認証方法が指定された\r
3863                 authtype = AUTHTYPE_ANONYMOUS;\r
3864                 authdata = NULL;\r
3865                 break;\r
3866         }\r
3867 \r
3868         // ユーザーの追加\r
3869         AcLock(h);\r
3870         {\r
3871                 if (StrLen(groupname) > 0)\r
3872                 {\r
3873                         g = AcGetGroup(h, groupname);\r
3874                 }\r
3875                 else\r
3876                 {\r
3877                         g = NULL;\r
3878                 }\r
3879 \r
3880                 u = NewUser(username, realname, note, authtype, authdata);\r
3881                 if (u != NULL)\r
3882                 {\r
3883                         if (g != NULL)\r
3884                         {\r
3885                                 JoinUserToGroup(u, g);\r
3886                         }\r
3887 \r
3888                         SetUserTraffic(u, &t);\r
3889 \r
3890                         if (pf != NULL)\r
3891                         {\r
3892                                 SetUserPolicy(u, &p);\r
3893                         }\r
3894 \r
3895                         Lock(u->lock);\r
3896                         {\r
3897                                 u->CreatedTime = created_time;\r
3898                                 u->UpdatedTime = updated_time;\r
3899                                 u->ExpireTime = expire_time;\r
3900                                 u->LastLoginTime = last_login_time;\r
3901                                 u->NumLogin = num_login;\r
3902                         }\r
3903                         Unlock(u->lock);\r
3904 \r
3905                         AcAddUser(h, u);\r
3906 \r
3907                         ReleaseUser(u);\r
3908                 }\r
3909 \r
3910                 if (g != NULL)\r
3911                 {\r
3912                         ReleaseGroup(g);\r
3913                 }\r
3914         }\r
3915         AcUnlock(h);\r
3916 \r
3917         if (serial != NULL)\r
3918         {\r
3919                 FreeXSerial(serial);\r
3920         }\r
3921 }\r
3922 \r
3923 // ユーザーリストの書き込み\r
3924 void SiWriteUserList(FOLDER *f, LIST *o)\r
3925 {\r
3926         // 引数チェック\r
3927         if (f == NULL || o == NULL)\r
3928         {\r
3929                 return;\r
3930         }\r
3931 \r
3932         LockList(o);\r
3933         {\r
3934                 UINT i;\r
3935                 for (i = 0;i < LIST_NUM(o);i++)\r
3936                 {\r
3937                         USER *u = LIST_DATA(o, i);\r
3938                         SiWriteUserCfg(CfgCreateFolder(f, u->Name), u);\r
3939                 }\r
3940         }\r
3941         UnlockList(o);\r
3942 }\r
3943 \r
3944 // ユーザーリストの読み込み\r
3945 void SiLoadUserList(HUB *h, FOLDER *f)\r
3946 {\r
3947         TOKEN_LIST *t;\r
3948         UINT i;\r
3949         char *name;\r
3950         // 引数チェック\r
3951         if (f == NULL || h == NULL)\r
3952         {\r
3953                 return;\r
3954         }\r
3955 \r
3956         t = CfgEnumFolderToTokenList(f);\r
3957 \r
3958         for (i = 0;i < t->NumTokens;i++)\r
3959         {\r
3960                 FOLDER *ff;\r
3961                 name = t->Token[i];\r
3962                 ff = CfgGetFolder(f, name);\r
3963                 SiLoadUserCfg(h, ff);\r
3964         }\r
3965 \r
3966         FreeToken(t);\r
3967 }\r
3968 \r
3969 // グループ情報の書き込み\r
3970 void SiWriteGroupCfg(FOLDER *f, USERGROUP *g)\r
3971 {\r
3972         // 引数チェック\r
3973         if (f == NULL || g == NULL)\r
3974         {\r
3975                 return;\r
3976         }\r
3977 \r
3978         Lock(g->lock);\r
3979         {\r
3980                 CfgAddUniStr(f, "RealName", g->RealName);\r
3981                 CfgAddUniStr(f, "Note", g->Note);\r
3982                 if (g->Policy != NULL)\r
3983                 {\r
3984                         SiWritePolicyCfg(CfgCreateFolder(f, "Policy"), g->Policy, false);\r
3985                 }\r
3986                 SiWriteTraffic(f, "Traffic", g->Traffic);\r
3987         }\r
3988         Unlock(g->lock);\r
3989 }\r
3990 \r
3991 // グループ情報の読み込み\r
3992 void SiLoadGroupCfg(HUB *h, FOLDER *f)\r
3993 {\r
3994         wchar_t realname[MAX_SIZE];\r
3995         wchar_t note[MAX_SIZE];\r
3996         char *name;\r
3997         FOLDER *pf;\r
3998         POLICY p;\r
3999         TRAFFIC t;\r
4000         USERGROUP *g;\r
4001         // 引数チェック\r
4002         if (h == NULL || f == NULL)\r
4003         {\r
4004                 return;\r
4005         }\r
4006 \r
4007         name = f->Name;\r
4008 \r
4009         CfgGetUniStr(f, "RealName", realname, sizeof(realname));\r
4010         CfgGetUniStr(f, "Note", note, sizeof(note));\r
4011 \r
4012         pf = CfgGetFolder(f, "Policy");\r
4013         if (pf != NULL)\r
4014         {\r
4015                 SiLoadPolicyCfg(&p, pf);\r
4016         }\r
4017 \r
4018         SiLoadTraffic(f, "Traffic", &t);\r
4019 \r
4020         g = NewGroup(name, realname, note);\r
4021         if (g == NULL)\r
4022         {\r
4023                 return;\r
4024         }\r
4025 \r
4026         if (pf != NULL)\r
4027         {\r
4028                 SetGroupPolicy(g, &p);\r
4029         }\r
4030 \r
4031         SetGroupTraffic(g, &t);\r
4032 \r
4033         AcLock(h);\r
4034         {\r
4035                 AcAddGroup(h, g);\r
4036         }\r
4037         AcUnlock(h);\r
4038 \r
4039         ReleaseGroup(g);\r
4040 }\r
4041 \r
4042 // グループリストの書き込み\r
4043 void SiWriteGroupList(FOLDER *f, LIST *o)\r
4044 {\r
4045         // 引数チェック\r
4046         if (f == NULL || o == NULL)\r
4047         {\r
4048                 return;\r
4049         }\r
4050 \r
4051         LockList(o);\r
4052         {\r
4053                 UINT i;\r
4054                 for (i = 0;i < LIST_NUM(o);i++)\r
4055                 {\r
4056                         USERGROUP *g = LIST_DATA(o, i);\r
4057                         SiWriteGroupCfg(CfgCreateFolder(f, g->Name), g);\r
4058                 }\r
4059         }\r
4060         UnlockList(o);\r
4061 }\r
4062 \r
4063 // グループリストの読み込み\r
4064 void SiLoadGroupList(HUB *h, FOLDER *f)\r
4065 {\r
4066         TOKEN_LIST *t;\r
4067         UINT i;\r
4068         char *name;\r
4069         // 引数チェック\r
4070         if (f == NULL || h == NULL)\r
4071         {\r
4072                 return;\r
4073         }\r
4074 \r
4075         t = CfgEnumFolderToTokenList(f);\r
4076 \r
4077         for (i = 0;i < t->NumTokens;i++)\r
4078         {\r
4079                 name = t->Token[i];\r
4080                 SiLoadGroupCfg(h, CfgGetFolder(f, name));\r
4081         }\r
4082 \r
4083         FreeToken(t);\r
4084 }\r
4085 \r
4086 // 無効な証明書リストの書き込み\r
4087 void SiWriteCrlList(FOLDER *f, LIST *o)\r
4088 {\r
4089         // 引数チェック\r
4090         if (f == NULL || o == NULL)\r
4091         {\r
4092                 return;\r
4093         }\r
4094 \r
4095         LockList(o);\r
4096         {\r
4097                 UINT i;\r
4098                 for (i = 0;i < LIST_NUM(o);i++)\r
4099                 {\r
4100                         char name[MAX_SIZE];\r
4101                         CRL *crl = LIST_DATA(o, i);\r
4102                         FOLDER *ff;\r
4103                         NAME *n;\r
4104 \r
4105                         Format(name, sizeof(name), "Crl%u", i);\r
4106 \r
4107                         ff = CfgCreateFolder(f, name);\r
4108                         n = crl->Name;\r
4109 \r
4110                         if (UniIsEmptyStr(n->CommonName) == false)\r
4111                         {\r
4112                                 CfgAddUniStr(ff, "CommonName", n->CommonName);\r
4113                         }\r
4114 \r
4115                         if (UniIsEmptyStr(n->Organization) == false)\r
4116                         {\r
4117                                 CfgAddUniStr(ff, "Organization", n->Organization);\r
4118                         }\r
4119 \r
4120                         if (UniIsEmptyStr(n->Unit) == false)\r
4121                         {\r
4122                                 CfgAddUniStr(ff, "Unit", n->Unit);\r
4123                         }\r
4124 \r
4125                         if (UniIsEmptyStr(n->Country) == false)\r
4126                         {\r
4127                                 CfgAddUniStr(ff, "Country", n->Country);\r
4128                         }\r
4129 \r
4130                         if (UniIsEmptyStr(n->State) == false)\r
4131                         {\r
4132                                 CfgAddUniStr(ff, "State", n->State);\r
4133                         }\r
4134 \r
4135                         if (UniIsEmptyStr(n->Local) == false)\r
4136                         {\r
4137                                 CfgAddUniStr(ff, "Local", n->Local);\r
4138                         }\r
4139 \r
4140                         if (IsZero(crl->DigestMD5, MD5_SIZE) == false)\r
4141                         {\r
4142                                 char tmp[MAX_SIZE];\r
4143 \r
4144                                 BinToStr(tmp, sizeof(tmp), crl->DigestMD5, MD5_SIZE);\r
4145                                 CfgAddStr(ff, "DigestMD5", tmp);\r
4146                         }\r
4147 \r
4148                         if (IsZero(crl->DigestSHA1, SHA1_SIZE) == false)\r
4149                         {\r
4150                                 char tmp[MAX_SIZE];\r
4151 \r
4152                                 BinToStr(tmp, sizeof(tmp), crl->DigestSHA1, SHA1_SIZE);\r
4153                                 CfgAddStr(ff, "DigestSHA1", tmp);\r
4154                         }\r
4155 \r
4156                         if (crl->Serial != NULL)\r
4157                         {\r
4158                                 char tmp[MAX_SIZE];\r
4159 \r
4160                                 BinToStr(tmp, sizeof(tmp), crl->Serial->data, crl->Serial->size);\r
4161                                 CfgAddStr(ff, "Serial", tmp);\r
4162                         }\r
4163                 }\r
4164         }\r
4165         UnlockList(o);\r
4166 }\r
4167 \r
4168 // 無効な証明書リストの読み込み\r
4169 void SiLoadCrlList(LIST *o, FOLDER *f)\r
4170 {\r
4171         // 引数チェック\r
4172         if (o == NULL || f == NULL)\r
4173         {\r
4174                 return;\r
4175         }\r
4176 \r
4177         LockList(o);\r
4178         {\r
4179                 UINT i;\r
4180                 TOKEN_LIST *t;\r
4181 \r
4182                 t = CfgEnumFolderToTokenList(f);\r
4183 \r
4184                 for (i = 0;i < t->NumTokens;i++)\r
4185                 {\r
4186                         CRL *crl;\r
4187                         FOLDER *ff = CfgGetFolder(f, t->Token[i]);\r
4188                         wchar_t cn[MAX_SIZE], org[MAX_SIZE], u[MAX_SIZE], c[MAX_SIZE],\r
4189                                 st[MAX_SIZE], l[MAX_SIZE];\r
4190                         char tmp[MAX_SIZE];\r
4191 \r
4192                         if (ff != NULL)\r
4193                         {\r
4194                                 BUF *b;\r
4195 \r
4196                                 crl = ZeroMalloc(sizeof(CRL));\r
4197 \r
4198                                 CfgGetUniStr(ff, "CommonName", cn, sizeof(cn));\r
4199                                 CfgGetUniStr(ff, "Organization", org, sizeof(org));\r
4200                                 CfgGetUniStr(ff, "Unit", u, sizeof(u));\r
4201                                 CfgGetUniStr(ff, "Country", c, sizeof(c));\r
4202                                 CfgGetUniStr(ff, "State", st, sizeof(st));\r
4203                                 CfgGetUniStr(ff, "Local", l, sizeof(l));\r
4204 \r
4205                                 crl->Name = NewName(cn, org, u, c, st, l);\r
4206 \r
4207                                 if (CfgGetStr(ff, "Serial", tmp, sizeof(tmp)))\r
4208                                 {\r
4209                                         b = StrToBin(tmp);\r
4210 \r
4211                                         if (b != NULL)\r
4212                                         {\r
4213                                                 if (b->Size >= 1)\r
4214                                                 {\r
4215                                                         crl->Serial = NewXSerial(b->Buf, b->Size);\r
4216                                                 }\r
4217 \r
4218                                                 FreeBuf(b);\r
4219                                         }\r
4220                                 }\r
4221 \r
4222                                 if (CfgGetStr(ff, "DigestMD5", tmp, sizeof(tmp)))\r
4223                                 {\r
4224                                         b = StrToBin(tmp);\r
4225 \r
4226                                         if (b != NULL)\r
4227                                         {\r
4228                                                 if (b->Size == MD5_SIZE)\r
4229                                                 {\r
4230                                                         Copy(crl->DigestMD5, b->Buf, MD5_SIZE);\r
4231                                                 }\r
4232 \r
4233                                                 FreeBuf(b);\r
4234                                         }\r
4235                                 }\r
4236 \r
4237                                 if (CfgGetStr(ff, "DigestSHA1", tmp, sizeof(tmp)))\r
4238                                 {\r
4239                                         b = StrToBin(tmp);\r
4240 \r
4241                                         if (b != NULL)\r
4242                                         {\r
4243                                                 if (b->Size == SHA1_SIZE)\r
4244                                                 {\r
4245                                                         Copy(crl->DigestSHA1, b->Buf, SHA1_SIZE);\r
4246                                                 }\r
4247 \r
4248                                                 FreeBuf(b);\r
4249                                         }\r
4250                                 }\r
4251 \r
4252                                 Insert(o, crl);\r
4253                         }\r
4254                 }\r
4255 \r
4256                 FreeToken(t);\r
4257         }\r
4258         UnlockList(o);\r
4259 }\r
4260 \r
4261 // 証明書リストの書き込み\r
4262 void SiWriteCertList(FOLDER *f, LIST *o)\r
4263 {\r
4264         // 引数チェック\r
4265         if (f == NULL || o == NULL)\r
4266         {\r
4267                 return;\r
4268         }\r
4269 \r
4270         LockList(o);\r
4271         {\r
4272                 UINT i;\r
4273                 X *x;\r
4274                 for (i = 0;i < LIST_NUM(o);i++)\r
4275                 {\r
4276                         char name[MAX_SIZE];\r
4277                         BUF *b;\r
4278                         x = LIST_DATA(o, i);\r
4279                         Format(name, sizeof(name), "Cert%u", i);\r
4280                         b = XToBuf(x, false);\r
4281                         if (b != NULL)\r
4282                         {\r
4283                                 CfgAddBuf(CfgCreateFolder(f, name), "X509", b);\r
4284                                 FreeBuf(b);\r
4285                         }\r
4286                 }\r
4287         }\r
4288         UnlockList(o);\r
4289 }\r
4290 \r
4291 // 証明書リストの読み込み\r
4292 void SiLoadCertList(LIST *o, FOLDER *f)\r
4293 {\r
4294         // 引数チェック\r
4295         if (o == NULL || f == NULL)\r
4296         {\r
4297                 return;\r
4298         }\r
4299 \r
4300         LockList(o);\r
4301         {\r
4302                 UINT i;\r
4303                 TOKEN_LIST *t;\r
4304 \r
4305                 t = CfgEnumFolderToTokenList(f);\r
4306 \r
4307                 for (i = 0;i < t->NumTokens;i++)\r
4308                 {\r
4309                         FOLDER *ff = CfgGetFolder(f, t->Token[i]);\r
4310                         BUF *b;\r
4311 \r
4312                         b = CfgGetBuf(ff, "X509");\r
4313                         if (b != NULL)\r
4314                         {\r
4315                                 X *x = BufToX(b, false);\r
4316                                 if (x != NULL)\r
4317                                 {\r
4318                                         Insert(o, x);\r
4319                                 }\r
4320                                 FreeBuf(b);\r
4321                         }\r
4322                 }\r
4323 \r
4324                 FreeToken(t);\r
4325         }\r
4326         UnlockList(o);\r
4327 }\r
4328 \r
4329 // データベースの書き込み\r
4330 void SiWriteHubDb(FOLDER *f, HUBDB *db)\r
4331 {\r
4332         // 引数チェック\r
4333         if (f == NULL || db == NULL)\r
4334         {\r
4335                 return;\r
4336         }\r
4337 \r
4338         SiWriteUserList(CfgCreateFolder(f, "UserList"), db->UserList);\r
4339         SiWriteGroupList(CfgCreateFolder(f, "GroupList"), db->GroupList);\r
4340         SiWriteCertList(CfgCreateFolder(f, "CertList"), db->RootCertList);\r
4341         SiWriteCrlList(CfgCreateFolder(f, "CrlList"), db->CrlList);\r
4342 }\r
4343 \r
4344 // データベースの読み込み\r
4345 void SiLoadHubDb(HUB *h, FOLDER *f)\r
4346 {\r
4347         // 引数チェック\r
4348         if (f == NULL || h == NULL)\r
4349         {\r
4350                 return;\r
4351         }\r
4352 \r
4353         SiLoadGroupList(h, CfgGetFolder(f, "GroupList"));\r
4354         SiLoadUserList(h, CfgGetFolder(f, "UserList"));\r
4355 \r
4356         if (h->HubDb != NULL)\r
4357         {\r
4358                 SiLoadCertList(h->HubDb->RootCertList, CfgGetFolder(f, "CertList"));\r
4359                 SiLoadCrlList(h->HubDb->CrlList, CfgGetFolder(f, "CrlList"));\r
4360         }\r
4361 }\r
4362 \r
4363 // 仮想 HUB 設定の書き込み\r
4364 void SiWriteHubCfg(FOLDER *f, HUB *h)\r
4365 {\r
4366         // 引数チェック\r
4367         if (f == NULL || h == NULL)\r
4368         {\r
4369                 return;\r
4370         }\r
4371 \r
4372         // パスワード\r
4373         CfgAddByte(f, "HashedPassword", h->HashedPassword, sizeof(h->HashedPassword));\r
4374         CfgAddByte(f, "SecurePassword", h->SecurePassword, sizeof(h->SecurePassword));\r
4375 \r
4376         // Online / Offline フラグ\r
4377         if (h->Cedar->Bridge == false)\r
4378         {\r
4379                 CfgAddBool(f, "Online", (h->Offline && (h->HubIsOnlineButHalting == false)) ? false : true);\r
4380         }\r
4381 \r
4382         // トラフィック情報\r
4383         SiWriteTraffic(f, "Traffic", h->Traffic);\r
4384 \r
4385         // HUB オプション\r
4386         SiWriteHubOptionCfg(CfgCreateFolder(f, "Option"), h->Option);\r
4387 \r
4388         // メッセージ\r
4389         {\r
4390                 FOLDER *folder = CfgCreateFolder(f, "Message");\r
4391 \r
4392                 if (IsEmptyUniStr(h->Msg) == false)\r
4393                 {\r
4394                         CfgAddUniStr(folder, "MessageText", h->Msg);\r
4395                 }\r
4396         }\r
4397 \r
4398         // HUB_LOG\r
4399         SiWriteHubLogCfg(CfgCreateFolder(f, "LogSetting"), &h->LogSetting);\r
4400 \r
4401         if (h->Type == HUB_TYPE_STANDALONE)\r
4402         {\r
4403                 // リンクリスト\r
4404                 SiWriteHubLinks(CfgCreateFolder(f, "CascadeList"), h);\r
4405         }\r
4406 \r
4407         if (h->Type != HUB_TYPE_FARM_STATIC)\r
4408         {\r
4409                 if (GetServerCapsBool(h->Cedar->Server, "b_support_securenat"))\r
4410                 {\r
4411                         // SecureNAT\r
4412                         SiWriteSecureNAT(h, CfgCreateFolder(f, "SecureNAT"));\r
4413                 }\r
4414         }\r
4415 \r
4416         // アクセスリスト\r
4417         SiWriteHubAccessLists(CfgCreateFolder(f, "AccessList"), h);\r
4418 \r
4419         // 管理オプション\r
4420         SiWriteHubAdminOptions(CfgCreateFolder(f, "AdminOption"), h);\r
4421 \r
4422         // HUB の種類\r
4423         CfgAddInt(f, "Type", h->Type);\r
4424 \r
4425         // データベース\r
4426         if (h->Cedar->Bridge == false)\r
4427         {\r
4428                 SiWriteHubDb(CfgCreateFolder(f, "SecurityAccountDatabase"), h->HubDb);\r
4429         }\r
4430 \r
4431         // 利用状況\r
4432         CfgAddInt64(f, "LastCommTime", h->LastCommTime);\r
4433         CfgAddInt64(f, "LastLoginTime", h->LastLoginTime);\r
4434         CfgAddInt64(f, "CreatedTime", h->CreatedTime);\r
4435         CfgAddInt(f, "NumLogin", h->NumLogin);\r
4436 }\r
4437 \r
4438 // ログオプションの読み込み\r
4439 void SiLoadHubLogCfg(HUB_LOG *g, FOLDER *f)\r
4440 {\r
4441         // 引数チェック\r
4442         if (f == NULL || g == NULL)\r
4443         {\r
4444                 return;\r
4445         }\r
4446 \r
4447         Zero(g, sizeof(HUB_LOG));\r
4448         g->SaveSecurityLog = CfgGetBool(f, "SaveSecurityLog");\r
4449         g->SecurityLogSwitchType = CfgGetInt(f, "SecurityLogSwitchType");\r
4450         g->SavePacketLog = CfgGetBool(f, "SavePacketLog");\r
4451         g->PacketLogSwitchType = CfgGetInt(f, "PacketLogSwitchType");\r
4452 \r
4453         g->PacketLogConfig[PACKET_LOG_TCP_CONN] = CfgGetInt(f, "PACKET_LOG_TCP_CONN");\r
4454         g->PacketLogConfig[PACKET_LOG_TCP] = CfgGetInt(f, "PACKET_LOG_TCP");\r
4455         g->PacketLogConfig[PACKET_LOG_DHCP] = CfgGetInt(f, "PACKET_LOG_DHCP");\r
4456         g->PacketLogConfig[PACKET_LOG_UDP] = CfgGetInt(f, "PACKET_LOG_UDP");\r
4457         g->PacketLogConfig[PACKET_LOG_ICMP] = CfgGetInt(f, "PACKET_LOG_ICMP");\r
4458         g->PacketLogConfig[PACKET_LOG_IP] = CfgGetInt(f, "PACKET_LOG_IP");\r
4459         g->PacketLogConfig[PACKET_LOG_ARP] = CfgGetInt(f, "PACKET_LOG_ARP");\r
4460         g->PacketLogConfig[PACKET_LOG_ETHERNET] = CfgGetInt(f, "PACKET_LOG_ETHERNET");\r
4461 }\r
4462 \r
4463 // ログオプションの書き込み\r
4464 void SiWriteHubLogCfg(FOLDER *f, HUB_LOG *g)\r
4465 {\r
4466         SiWriteHubLogCfgEx(f, g, false);\r
4467 }\r
4468 void SiWriteHubLogCfgEx(FOLDER *f, HUB_LOG *g, bool el_mode)\r
4469 {\r
4470         // 引数チェック\r
4471         if (f == NULL || g == NULL)\r
4472         {\r
4473                 return;\r
4474         }\r
4475 \r
4476         if (el_mode == false)\r
4477         {\r
4478                 CfgAddBool(f, "SaveSecurityLog", g->SaveSecurityLog);\r
4479                 CfgAddInt(f, "SecurityLogSwitchType", g->SecurityLogSwitchType);\r
4480                 CfgAddBool(f, "SavePacketLog", g->SavePacketLog);\r
4481         }\r
4482 \r
4483         CfgAddInt(f, "PacketLogSwitchType", g->PacketLogSwitchType);\r
4484 \r
4485         CfgAddInt(f, "PACKET_LOG_TCP_CONN", g->PacketLogConfig[PACKET_LOG_TCP_CONN]);\r
4486         CfgAddInt(f, "PACKET_LOG_TCP", g->PacketLogConfig[PACKET_LOG_TCP]);\r
4487         CfgAddInt(f, "PACKET_LOG_DHCP", g->PacketLogConfig[PACKET_LOG_DHCP]);\r
4488         CfgAddInt(f, "PACKET_LOG_UDP", g->PacketLogConfig[PACKET_LOG_UDP]);\r
4489         CfgAddInt(f, "PACKET_LOG_ICMP", g->PacketLogConfig[PACKET_LOG_ICMP]);\r
4490         CfgAddInt(f, "PACKET_LOG_IP", g->PacketLogConfig[PACKET_LOG_IP]);\r
4491         CfgAddInt(f, "PACKET_LOG_ARP", g->PacketLogConfig[PACKET_LOG_ARP]);\r
4492         CfgAddInt(f, "PACKET_LOG_ETHERNET", g->PacketLogConfig[PACKET_LOG_ETHERNET]);\r
4493 }\r
4494 \r
4495 // 仮想 HUB 設定の読み込み\r
4496 void SiLoadHubCfg(SERVER *s, FOLDER *f, char *name)\r
4497 {\r
4498         HUB *h;\r
4499         CEDAR *c;\r
4500         HUB_OPTION o;\r
4501         bool online;\r
4502         UINT hub_old_type = 0;\r
4503         // 引数チェック\r
4504         if (s == NULL || f == NULL || name == NULL)\r
4505         {\r
4506                 return;\r
4507         }\r
4508 \r
4509         c = s->Cedar;\r
4510 \r
4511         // オプションの取得\r
4512         Zero(&o, sizeof(o));\r
4513         SiLoadHubOptionCfg(CfgGetFolder(f, "Option"), &o);\r
4514 \r
4515         // HUB の作成\r
4516         h = NewHub(c, name, &o);\r
4517         if (h != NULL)\r
4518         {\r
4519                 HUB_LOG g;\r
4520 \r
4521                 // パスワード\r
4522                 if (CfgGetByte(f, "HashedPassword", h->HashedPassword, sizeof(h->HashedPassword)) != sizeof(h->HashedPassword))\r
4523                 {\r
4524                         Hash(h->HashedPassword, "", 0, true);\r
4525                 }\r
4526                 if (CfgGetByte(f, "SecurePassword", h->SecurePassword, sizeof(h->SecurePassword)) != sizeof(h->SecurePassword))\r
4527                 {\r
4528                         HashPassword(h->SecurePassword, ADMINISTRATOR_USERNAME, "");\r
4529                 }\r
4530 \r
4531                 // ログ設定\r
4532                 Zero(&g, sizeof(g));\r
4533                 SiLoadHubLogCfg(&g, CfgGetFolder(f, "LogSetting"));\r
4534                 SetHubLogSetting(h, &g);\r
4535 \r
4536                 // Online / Offline フラグ\r
4537                 if (h->Cedar->Bridge == false)\r
4538                 {\r
4539                         online = CfgGetBool(f, "Online");\r
4540                 }\r
4541                 else\r
4542                 {\r
4543                         online = true;\r
4544                 }\r
4545 \r
4546                 // トラフィック情報\r
4547                 SiLoadTraffic(f, "Traffic", h->Traffic);\r
4548 \r
4549                 // アクセスリスト\r
4550                 SiLoadHubAccessLists(h, CfgGetFolder(f, "AccessList"));\r
4551 \r
4552                 // HUB の種類\r
4553                 hub_old_type = h->Type = CfgGetInt(f, "Type");\r
4554                 if (s->ServerType == SERVER_TYPE_STANDALONE)\r
4555                 {\r
4556                         if (h->Type != HUB_TYPE_STANDALONE)\r
4557                         {\r
4558                                 // サーバーがスタンドアロンの場合は HUB の種類をスタンドアロンに変換する\r
4559                                 h->Type = HUB_TYPE_STANDALONE;\r
4560                         }\r
4561                 }\r
4562                 else\r
4563                 {\r
4564                         if (h->Type == HUB_TYPE_STANDALONE)\r
4565                         {\r
4566                                 // サーバーがファームコントローラの場合は HUB の種類をファーム対応にする\r
4567                                 h->Type = HUB_TYPE_FARM_DYNAMIC;\r
4568                         }\r
4569                 }\r
4570 \r
4571                 // メッセージ\r
4572                 {\r
4573                         FOLDER *folder = CfgGetFolder(f, "Message");\r
4574                         if (folder != NULL)\r
4575                         {\r
4576                                 wchar_t *tmp = Malloc(sizeof(wchar_t) * (HUB_MAXMSG_LEN + 1));\r
4577                                 if (CfgGetUniStr(folder, "MessageText", tmp, sizeof(wchar_t) * (HUB_MAXMSG_LEN + 1)))\r
4578                                 {\r
4579                                         SetHubMsg(h, tmp);\r
4580                                 }\r
4581                                 Free(tmp);\r
4582                         }\r
4583                 }\r
4584 \r
4585                 // リンクリスト\r
4586                 if (h->Type == HUB_TYPE_STANDALONE)\r
4587                 {\r
4588                         // リンクリストはスタンドアロン HUB の場合しか使用しない\r
4589                         SiLoadHubLinks(h, CfgGetFolder(f, "CascadeList"));\r
4590                 }\r
4591 \r
4592                 // SecureNAT\r
4593                 if (GetServerCapsBool(h->Cedar->Server, "b_support_securenat"))\r
4594                 {\r
4595                         if (h->Type == HUB_TYPE_STANDALONE || h->Type == HUB_TYPE_FARM_DYNAMIC)\r
4596                         {\r
4597                                 // SecureNAT はスタンドアロン HUB かダイナミック HUB の場合しか使用しない\r
4598                                 SiLoadSecureNAT(h, CfgGetFolder(f, "SecureNAT"));\r
4599 \r
4600                                 if (h->Type != HUB_TYPE_STANDALONE && h->Cedar != NULL && h->Cedar->Server != NULL &&\r
4601                                         h->Cedar->Server->ServerType == SERVER_TYPE_FARM_CONTROLLER)\r
4602                                 {\r
4603                                         NiClearUnsupportedVhOptionForDynamicHub(h->SecureNATOption,\r
4604                                                 hub_old_type == HUB_TYPE_STANDALONE);\r
4605                                 }\r
4606 \r
4607                         }\r
4608                 }\r
4609 \r
4610                 // 管理オプション\r
4611                 SiLoadHubAdminOptions(h, CfgGetFolder(f, "AdminOption"));\r
4612 \r
4613                 // データベース\r
4614                 if (h->Cedar->Bridge == false)\r
4615                 {\r
4616                         SiLoadHubDb(h, CfgGetFolder(f, "SecurityAccountDatabase"));\r
4617                 }\r
4618 \r
4619                 // 利用状況\r
4620                 h->LastCommTime = CfgGetInt64(f, "LastCommTime");\r
4621                 if (h->LastCommTime == 0)\r
4622                 {\r
4623                         h->LastCommTime = SystemTime64();\r
4624                 }\r
4625                 h->LastLoginTime = CfgGetInt64(f, "LastLoginTime");\r
4626                 if (h->LastLoginTime == 0)\r
4627                 {\r
4628                         h->LastLoginTime = SystemTime64();\r
4629                 }\r
4630                 h->CreatedTime = CfgGetInt64(f, "CreatedTime");\r
4631                 h->NumLogin = CfgGetInt(f, "NumLogin");\r
4632 \r
4633                 // HUB の動作開始\r
4634                 AddHub(c, h);\r
4635 \r
4636                 if (online)\r
4637                 {\r
4638                         h->Offline = true;\r
4639                         SetHubOnline(h);\r
4640                 }\r
4641                 else\r
4642                 {\r
4643                         h->Offline = false;\r
4644                         SetHubOffline(h);\r
4645                 }\r
4646 \r
4647                 WaitLogFlush(h->SecurityLogger);\r
4648                 WaitLogFlush(h->PacketLogger);\r
4649 \r
4650                 ReleaseHub(h);\r
4651         }\r
4652 }\r
4653 \r
4654 // SecureNAT 設定の読み込み\r
4655 void SiLoadSecureNAT(HUB *h, FOLDER *f)\r
4656 {\r
4657         VH_OPTION o;\r
4658         // 引数チェック\r
4659         if (h == NULL || f == NULL)\r
4660         {\r
4661                 return;\r
4662         }\r
4663 \r
4664         // VH_OPTION を読み込む\r
4665         NiLoadVhOptionEx(&o, f);\r
4666 \r
4667         // VH_OPTION をセット\r
4668         Copy(h->SecureNATOption, &o, sizeof(VH_OPTION));\r
4669 \r
4670         EnableSecureNAT(h, CfgGetBool(f, "Disabled") ? false : true);\r
4671 }\r
4672 \r
4673 // 仮想レイヤ 3 スイッチ設定の読み込み\r
4674 void SiLoadL3SwitchCfg(L3SW *sw, FOLDER *f)\r
4675 {\r
4676         UINT i;\r
4677         FOLDER *if_folder, *table_folder;\r
4678         TOKEN_LIST *t;\r
4679         bool active = false;\r
4680         // 引数チェック\r
4681         if (sw == NULL || f == NULL)\r
4682         {\r
4683                 return;\r
4684         }\r
4685 \r
4686         active = CfgGetBool(f, "Active");\r
4687 \r
4688         // インターフェイスリスト\r
4689         if_folder = CfgGetFolder(f, "InterfaceList");\r
4690         if (if_folder != NULL)\r
4691         {\r
4692                 t = CfgEnumFolderToTokenList(if_folder);\r
4693                 if (t != NULL)\r
4694                 {\r
4695                         for (i = 0;i < t->NumTokens;i++)\r
4696                         {\r
4697                                 FOLDER *ff = CfgGetFolder(if_folder, t->Token[i]);\r
4698                                 char name[MAX_HUBNAME_LEN + 1];\r
4699                                 UINT ip, subnet;\r
4700 \r
4701                                 CfgGetStr(ff, "HubName", name, sizeof(name));\r
4702                                 ip = CfgGetIp32(ff, "IpAddress");\r
4703                                 subnet = CfgGetIp32(ff, "SubnetMask");\r
4704 \r
4705                                 L3AddIf(sw, name, ip, subnet);\r
4706                         }\r
4707                         FreeToken(t);\r
4708                 }\r
4709         }\r
4710 \r
4711         // ルーティングテーブル\r
4712         table_folder = CfgGetFolder(f, "RoutingTable");\r
4713         if (table_folder != NULL)\r
4714         {\r
4715                 t = CfgEnumFolderToTokenList(table_folder);\r
4716                 if (t != NULL)\r
4717                 {\r
4718                         for (i = 0;i < t->NumTokens;i++)\r
4719                         {\r
4720                                 FOLDER *ff = CfgGetFolder(table_folder, t->Token[i]);\r
4721                                 L3TABLE tbl;\r
4722 \r
4723                                 Zero(&tbl, sizeof(tbl));\r
4724                                 tbl.NetworkAddress = CfgGetIp32(ff, "NetworkAddress");\r
4725                                 tbl.SubnetMask = CfgGetIp32(ff, "SubnetMask");\r
4726                                 tbl.GatewayAddress = CfgGetIp32(ff, "GatewayAddress");\r
4727                                 tbl.Metric = CfgGetInt(ff, "Metric");\r
4728 \r
4729                                 L3AddTable(sw, &tbl);\r
4730                         }\r
4731                         FreeToken(t);\r
4732                 }\r
4733         }\r
4734 \r
4735         if (active)\r
4736         {\r
4737                 L3SwStart(sw);\r
4738         }\r
4739 }\r
4740 \r
4741 // 仮想レイヤ 3 スイッチ設定の書き込み\r
4742 void SiWriteL3SwitchCfg(FOLDER *f, L3SW *sw)\r
4743 {\r
4744         UINT i;\r
4745         FOLDER *if_folder, *table_folder;\r
4746         char tmp[MAX_SIZE];\r
4747         // 引数チェック\r
4748         if (f == NULL || sw == NULL)\r
4749         {\r
4750                 return;\r
4751         }\r
4752 \r
4753         // 動作フラグ\r
4754         CfgAddBool(f, "Active", sw->Active);\r
4755 \r
4756         // インターフェイスリスト\r
4757         if_folder = CfgCreateFolder(f, "InterfaceList");\r
4758         for (i = 0;i < LIST_NUM(sw->IfList);i++)\r
4759         {\r
4760                 L3IF *e = LIST_DATA(sw->IfList, i);\r
4761                 FOLDER *ff;\r
4762 \r
4763                 Format(tmp, sizeof(tmp), "Interface%u", i);\r
4764                 ff = CfgCreateFolder(if_folder, tmp);\r
4765 \r
4766                 CfgAddStr(ff, "HubName", e->HubName);\r
4767                 CfgAddIp32(ff, "IpAddress", e->IpAddress);\r
4768                 CfgAddIp32(ff, "SubnetMask", e->SubnetMask);\r
4769         }\r
4770 \r
4771         // ルーティングテーブル\r
4772         table_folder = CfgCreateFolder(f, "RoutingTable");\r
4773         for (i = 0;i < LIST_NUM(sw->TableList);i++)\r
4774         {\r
4775                 L3TABLE *e = LIST_DATA(sw->TableList, i);\r
4776                 FOLDER *ff;\r
4777 \r
4778                 Format(tmp, sizeof(tmp), "Entry%u", i);\r
4779                 ff = CfgCreateFolder(table_folder, tmp);\r
4780 \r
4781                 CfgAddIp32(ff, "NetworkAddress", e->NetworkAddress);\r
4782                 CfgAddIp32(ff, "SubnetMask", e->SubnetMask);\r
4783                 CfgAddIp32(ff, "GatewayAddress", e->GatewayAddress);\r
4784                 CfgAddInt(ff, "Metric", e->Metric);\r
4785         }\r
4786 }\r
4787 \r
4788 // 仮想レイヤ 3 スイッチ一覧の読み込み\r
4789 void SiLoadL3Switchs(SERVER *s, FOLDER *f)\r
4790 {\r
4791         UINT i;\r
4792         TOKEN_LIST *t;\r
4793         CEDAR *c;\r
4794         // 引数チェック\r
4795         if (s == NULL || f == NULL)\r
4796         {\r
4797                 return;\r
4798         }\r
4799         c = s->Cedar;\r
4800 \r
4801         t = CfgEnumFolderToTokenList(f);\r
4802         if (t != NULL)\r
4803         {\r
4804                 for (i = 0;i < t->NumTokens;i++)\r
4805                 {\r
4806                         char *name = t->Token[i];\r
4807                         L3SW *sw = L3AddSw(c, name);\r
4808 \r
4809                         SiLoadL3SwitchCfg(sw, CfgGetFolder(f, name));\r
4810 \r
4811                         ReleaseL3Sw(sw);\r
4812                 }\r
4813         }\r
4814         FreeToken(t);\r
4815 }\r
4816 \r
4817 // 仮想レイヤ 3 スイッチ一覧の書き込み\r
4818 void SiWriteL3Switchs(FOLDER *f, SERVER *s)\r
4819 {\r
4820         UINT i;\r
4821         FOLDER *folder;\r
4822         CEDAR *c;\r
4823         // 引数チェック\r
4824         if (f == NULL || s == NULL)\r
4825         {\r
4826                 return;\r
4827         }\r
4828         c = s->Cedar;\r
4829 \r
4830         LockList(c->L3SwList);\r
4831         {\r
4832                 for (i = 0;i < LIST_NUM(c->L3SwList);i++)\r
4833                 {\r
4834                         L3SW *sw = LIST_DATA(c->L3SwList, i);\r
4835 \r
4836                         Lock(sw->lock);\r
4837                         {\r
4838                                 folder = CfgCreateFolder(f, sw->Name);\r
4839 \r
4840                                 SiWriteL3SwitchCfg(folder, sw);\r
4841                         }\r
4842                         Unlock(sw->lock);\r
4843                 }\r
4844         }\r
4845         UnlockList(c->L3SwList);\r
4846 }\r
4847 \r
4848 // ライセンス一覧の書き込み\r
4849 void SiWriteLicenseManager(FOLDER *f, SERVER *s)\r
4850 {\r
4851         LICENSE_SYSTEM *ss;\r
4852         // 引数チェック\r
4853         if (f == NULL || s == NULL)\r
4854         {\r
4855                 return;\r
4856         }\r
4857 \r
4858         ss = s->LicenseSystem;\r
4859         if (s == NULL)\r
4860         {\r
4861                 return;\r
4862         }\r
4863 \r
4864         LockList(ss->LicenseList);\r
4865         {\r
4866                 UINT i;\r
4867                 for (i = 0;i < LIST_NUM(ss->LicenseList);i++)\r
4868                 {\r
4869                         LICENSE *e = LIST_DATA(ss->LicenseList, i);\r
4870                         char name[MAX_SIZE];\r
4871                         FOLDER *ff;\r
4872 \r
4873                         Format(name, sizeof(name), "License%u", i);\r
4874                         ff = CfgCreateFolder(f, name);\r
4875                         CfgAddStr(ff, "LicenseKey", e->LicenseKeyStr);\r
4876                         CfgAddInt(ff, "LicenseType", e->ProductId);\r
4877                 }\r
4878         }\r
4879         UnlockList(ss->LicenseList);\r
4880 }\r
4881 \r
4882 // ライセンス一覧の読み込み\r
4883 void SiLoadLicenseManager(SERVER *s, FOLDER *f)\r
4884 {\r
4885         UINT i;\r
4886         TOKEN_LIST *t;\r
4887         CEDAR *c;\r
4888         // 引数チェック\r
4889         if (s == NULL || f == NULL)\r
4890         {\r
4891                 return;\r
4892         }\r
4893         c = s->Cedar;\r
4894 \r
4895         t = CfgEnumFolderToTokenList(f);\r
4896         if (t != NULL)\r
4897         {\r
4898                 for (i = 0;i < t->NumTokens;i++)\r
4899                 {\r
4900                         char *str = t->Token[i];\r
4901                         FOLDER *ff = CfgGetFolder(f, str);\r
4902 \r
4903                         if (ff != NULL)\r
4904                         {\r
4905                                 UINT product_id = CfgGetInt(ff, "LicenseType");\r
4906                                 char key[MAX_SIZE];\r
4907 \r
4908                                 if (CfgGetStr(ff, "LicenseKey", key, sizeof(key)))\r
4909                                 {\r
4910                                         // ライセンス登録\r
4911                                         //LiInputLicenseKeyEx(c, s->LicenseSystem, key, product_id, NULL);\r
4912                                 }\r
4913                         }\r
4914                 }\r
4915         }\r
4916         FreeToken(t);\r
4917 \r
4918         DestroyServerCapsCache(s);\r
4919 }\r
4920 \r
4921 // 仮想 HUB 一覧の書き込み\r
4922 void SiWriteHubs(FOLDER *f, SERVER *s)\r
4923 {\r
4924         UINT i;\r
4925         FOLDER *hub_folder;\r
4926         CEDAR *c;\r
4927         UINT num;\r
4928         HUB **hubs;\r
4929         // 引数チェック\r
4930         if (f == NULL || s == NULL)\r
4931         {\r
4932                 return;\r
4933         }\r
4934         c = s->Cedar;\r
4935 \r
4936         LockList(c->HubList);\r
4937         {\r
4938                 hubs = ToArray(c->HubList);\r
4939                 num = LIST_NUM(c->HubList);\r
4940 \r
4941                 for (i = 0;i < num;i++)\r
4942                 {\r
4943                         AddRef(hubs[i]->ref);\r
4944                 }\r
4945         }\r
4946         UnlockList(c->HubList);\r
4947 \r
4948         for (i = 0;i < num;i++)\r
4949         {\r
4950                 HUB *h = hubs[i];\r
4951 \r
4952                 Lock(h->lock);\r
4953                 {\r
4954                         hub_folder = CfgCreateFolder(f, h->Name);\r
4955                         SiWriteHubCfg(hub_folder, h);\r
4956                 }\r
4957                 Unlock(h->lock);\r
4958 \r
4959                 ReleaseHub(h);\r
4960 \r
4961                 if ((i % 30) == 1)\r
4962                 {\r
4963                         YieldCpu();\r
4964                 }\r
4965         }\r
4966 \r
4967         Free(hubs);\r
4968 }\r
4969 \r
4970 // 仮想 HUB 一覧の読み込み\r
4971 void SiLoadHubs(SERVER *s, FOLDER *f)\r
4972 {\r
4973         UINT i;\r
4974         FOLDER *hub_folder;\r
4975         CEDAR *c;\r
4976         TOKEN_LIST *t;\r
4977         bool b = false;\r
4978         // 引数チェック\r
4979         if (f == NULL || s == NULL)\r
4980         {\r
4981                 return;\r
4982         }\r
4983         c = s->Cedar;\r
4984 \r
4985         t = CfgEnumFolderToTokenList(f);\r
4986         for (i = 0;i < t->NumTokens;i++)\r
4987         {\r
4988                 char *name = t->Token[i];\r
4989                 if (s->Cedar->Bridge)\r
4990                 {\r
4991                         if (StrCmpi(name, SERVER_DEFAULT_BRIDGE_NAME) == 0)\r
4992                         {\r
4993                                 // Bridge の場合は "BRIDGE" という名前の仮想 HUB の設定\r
4994                                 // しか読み込まない\r
4995                                 b = true;\r
4996                         }\r
4997                         else\r
4998                         {\r
4999                                 continue;\r
5000                         }\r
5001                 }\r
5002                 hub_folder = CfgGetFolder(f, name);\r
5003                 if (hub_folder != NULL)\r
5004                 {\r
5005                         SiLoadHubCfg(s, hub_folder, name);\r
5006                 }\r
5007         }\r
5008         FreeToken(t);\r
5009 \r
5010         if (s->Cedar->Bridge && b == false)\r
5011         {\r
5012                 // "BRIDGE" という名前の仮想 HUB の設定が存在しない場合は新たに作成する\r
5013                 SiInitDefaultHubList(s);\r
5014         }\r
5015 }\r
5016 \r
5017 // サーバー固有の設定の読み込み\r
5018 void SiLoadServerCfg(SERVER *s, FOLDER *f)\r
5019 {\r
5020         BUF *b;\r
5021         CEDAR *c;\r
5022         char tmp[MAX_SIZE];\r
5023         X *x = NULL;\r
5024         K *k = NULL;\r
5025         bool cluster_allowed = false;\r
5026         UINT num_connections_per_ip = 0;\r
5027         // 引数チェック\r
5028         if (s == NULL || f == NULL)\r
5029         {\r
5030                 return;\r
5031         }\r
5032 \r
5033         // 保存間隔関係\r
5034         s->AutoSaveConfigSpan = CfgGetInt(f, "AutoSaveConfigSpan") * 1000;\r
5035         if (s->AutoSaveConfigSpan == 0)\r
5036         {\r
5037                 s->AutoSaveConfigSpan = SERVER_FILE_SAVE_INTERVAL_DEFAULT;\r
5038         }\r
5039         else\r
5040         {\r
5041                 s->AutoSaveConfigSpan = MAKESURE(s->AutoSaveConfigSpan, SERVER_FILE_SAVE_INTERVAL_MIN, SERVER_FILE_SAVE_INTERVAL_MAX);\r
5042         }\r
5043 \r
5044         c = s->Cedar;\r
5045         Lock(c->lock);\r
5046         {\r
5047                 {\r
5048                         RPC_KEEP k;\r
5049 \r
5050                         // キープアライブ関係\r
5051                         Zero(&k, sizeof(k));\r
5052                         k.UseKeepConnect = CfgGetBool(f, "UseKeepConnect");\r
5053                         CfgGetStr(f, "KeepConnectHost", k.KeepConnectHost, sizeof(k.KeepConnectHost));\r
5054                         k.KeepConnectPort = CfgGetInt(f, "KeepConnectPort");\r
5055                         k.KeepConnectProtocol = CfgGetInt(f, "KeepConnectProtocol");\r
5056                         k.KeepConnectInterval = CfgGetInt(f, "KeepConnectInterval") * 1000;\r
5057                         if (k.KeepConnectPort == 0)\r
5058                         {\r
5059                                 k.KeepConnectPort = 80;\r
5060                         }\r
5061                         if (StrLen(k.KeepConnectHost) == 0)\r
5062                         {\r
5063                                 StrCpy(k.KeepConnectHost, sizeof(k.KeepConnectHost), CLIENT_DEFAULT_KEEPALIVE_HOST);\r
5064                         }\r
5065                         if (k.KeepConnectInterval == 0)\r
5066                         {\r
5067                                 k.KeepConnectInterval = KEEP_INTERVAL_DEFAULT * 1000;\r
5068                         }\r
5069                         if (k.KeepConnectInterval < 5000)\r
5070                         {\r
5071                                 k.KeepConnectInterval = 5000;\r
5072                         }\r
5073                         if (k.KeepConnectInterval > 600000)\r
5074                         {\r
5075                                 k.KeepConnectInterval = 600000;\r
5076                         }\r
5077 \r
5078                         Lock(s->Keep->lock);\r
5079                         {\r
5080                                 KEEP *keep = s->Keep;\r
5081                                 keep->Enable = k.UseKeepConnect;\r
5082                                 keep->Server = true;\r
5083                                 StrCpy(keep->ServerName, sizeof(keep->ServerName), k.KeepConnectHost);\r
5084                                 keep->ServerPort = k.KeepConnectPort;\r
5085                                 keep->UdpMode = k.KeepConnectProtocol;\r
5086                                 keep->Interval = k.KeepConnectInterval;\r
5087                         }\r
5088                         Unlock(s->Keep->lock);\r
5089                 }\r
5090 \r
5091                 // IPv6 リスナーを無効にするかどうか\r
5092                 s->Cedar->DisableIPv6Listener = CfgGetBool(f, "DisableIPv6Listener");\r
5093 \r
5094                 // DeadLock\r
5095                 s->DisableDeadLockCheck = CfgGetBool(f, "DisableDeadLockCheck");\r
5096 \r
5097                 // 自動ファイル削除器\r
5098                 s->Eraser = NewEraser(s->Logger, CfgGetInt64(f, "AutoDeleteCheckDiskFreeSpaceMin"));\r
5099 \r
5100                 // NoLinuxArpFilter\r
5101                 s->NoLinuxArpFilter = CfgGetBool(f, "NoLinuxArpFilter");\r
5102 \r
5103                 // NoHighPriorityProcess\r
5104                 s->NoHighPriorityProcess = CfgGetBool(f, "NoHighPriorityProcess");\r
5105 \r
5106                 // NoDebugDump\r
5107                 s->NoDebugDump = CfgGetBool(f, "NoDebugDump");\r
5108                 if (s->NoDebugDump)\r
5109                 {\r
5110 #ifdef  OS_WIN32\r
5111                         MsSetEnableMinidump(false);\r
5112 #endif  // OS_WIN32\r
5113                 }\r
5114 \r
5115                 // クライアントにシグネチャを送信させない\r
5116                 s->NoSendSignature = CfgGetBool(f, "NoSendSignature");\r
5117 \r
5118                 // デバッグログ\r
5119                 s->SaveDebugLog = CfgGetBool(f, "SaveDebugLog");\r
5120                 if (s->SaveDebugLog)\r
5121                 {\r
5122                         s->DebugLog = NewTinyLog();\r
5123                 }\r
5124 \r
5125                 // サーバー証明書\r
5126                 b = CfgGetBuf(f, "ServerCert");\r
5127                 if (b != NULL)\r
5128                 {\r
5129                         x = BufToX(b, false);\r
5130                         FreeBuf(b);\r
5131                 }\r
5132 \r
5133                 // サーバー秘密鍵\r
5134                 b = CfgGetBuf(f, "ServerKey");\r
5135                 if (b != NULL)\r
5136                 {\r
5137                         k = BufToK(b, true, false, NULL);\r
5138                         FreeBuf(b);\r
5139                 }\r
5140 \r
5141                 if (x == NULL || k == NULL || CheckXandK(x, k) == false)\r
5142                 {\r
5143                         FreeX(x);\r
5144                         FreeK(k);\r
5145                         SiGenerateDefualtCert(&x, &k);\r
5146 \r
5147                         SetCedarCert(c, x, k);\r
5148 \r
5149                         FreeX(x);\r
5150                         FreeK(k);\r
5151                 }\r
5152                 else\r
5153                 {\r
5154                         SetCedarCert(c, x, k);\r
5155 \r
5156                         FreeX(x);\r
5157                         FreeK(k);\r
5158                 }\r
5159 \r
5160                 // 暗号化名\r
5161                 if (CfgGetStr(f, "CipherName", tmp, sizeof(tmp)))\r
5162                 {\r
5163                         StrUpper(tmp);\r
5164                         if (CheckCipherListName(tmp))\r
5165                         {\r
5166                                 SetCedarCipherList(c, tmp);\r
5167                         }\r
5168                 }\r
5169 \r
5170                 // トラフィック情報\r
5171                 Lock(c->TrafficLock);\r
5172                 {\r
5173                         SiLoadTraffic(f, "ServerTraffic", c->Traffic);\r
5174                 }\r
5175                 Unlock(c->TrafficLock);\r
5176 \r
5177                 // 現在のライセンスでクラスタモードが許可されているかどうかを取得する\r
5178                 cluster_allowed = false;\r
5179                 if (s->Cedar->Bridge == false)\r
5180                 {\r
5181                         LICENSE_STATUS status;\r
5182 \r
5183                         LiParseCurrentLicenseStatus(s->LicenseSystem, &status);\r
5184 \r
5185                         if (status.AllowEnterpriseFunction)\r
5186                         {\r
5187                                 cluster_allowed = true;\r
5188                         }\r
5189                 }\r
5190 \r
5191                 // サーバーの種類\r
5192                 s->UpdatedServerType = s->ServerType = \r
5193                         cluster_allowed ? CfgGetInt(f, "ServerType") : SERVER_TYPE_STANDALONE;\r
5194 \r
5195                 // パスワード\r
5196                 if (CfgGetByte(f, "HashedPassword", s->HashedPassword, sizeof(s->HashedPassword)) != sizeof(s->HashedPassword))\r
5197                 {\r
5198                         Hash(s->HashedPassword, "", 0, true);\r
5199                 }\r
5200 \r
5201                 if (s->ServerType != SERVER_TYPE_STANDALONE)\r
5202                 {\r
5203                         // サーバーの性能基準比\r
5204                         s->Weight = CfgGetInt(f, "ClusterMemberWeight");\r
5205                         if (s->Weight == 0)\r
5206                         {\r
5207                                 s->Weight = FARM_DEFAULT_WEIGHT;\r
5208                         }\r
5209                 }\r
5210                 else\r
5211                 {\r
5212                         s->Weight = FARM_DEFAULT_WEIGHT;\r
5213                 }\r
5214 \r
5215                 if (s->ServerType == SERVER_TYPE_FARM_CONTROLLER)\r
5216                 {\r
5217                         s->ControllerOnly = CfgGetBool(f, "ControllerOnly");\r
5218                 }\r
5219 \r
5220                 if (s->ServerType == SERVER_TYPE_FARM_MEMBER)\r
5221                 {\r
5222                         char tmp[6 * MAX_PUBLIC_PORT_NUM + 1];\r
5223                         // ファームメンバの場合の設定項目の読み込み\r
5224                         CfgGetStr(f, "ControllerName", s->ControllerName, sizeof(s->ControllerName));\r
5225                         s->ControllerPort = CfgGetInt(f, "ControllerPort");\r
5226                         CfgGetByte(f, "MemberPassword", s->MemberPassword, SHA1_SIZE);\r
5227                         s->PublicIp = CfgGetIp32(f, "PublicIp");\r
5228                         if (CfgGetStr(f, "PublicPorts", tmp, sizeof(tmp)))\r
5229                         {\r
5230                                 TOKEN_LIST *t = ParseToken(tmp, ", ");\r
5231                                 UINT i;\r
5232                                 s->NumPublicPort = t->NumTokens;\r
5233                                 s->PublicPorts = ZeroMalloc(s->NumPublicPort * sizeof(UINT));\r
5234                                 for (i = 0;i < s->NumPublicPort;i++)\r
5235                                 {\r
5236                                         s->PublicPorts[i] = ToInt(t->Token[i]);\r
5237                                 }\r
5238                                 FreeToken(t);\r
5239                         }\r
5240                 }\r
5241         }\r
5242         Unlock(c->lock);\r
5243 }\r
5244 \r
5245 // サーバー固有の設定の書き込み\r
5246 void SiWriteServerCfg(FOLDER *f, SERVER *s)\r
5247 {\r
5248         BUF *b;\r
5249         CEDAR *c;\r
5250         // 引数チェック\r
5251         if (f == NULL || s == NULL)\r
5252         {\r
5253                 return;\r
5254         }\r
5255 \r
5256         CfgAddInt(f, "AutoSaveConfigSpan", s->AutoSaveConfigSpan / 1000);\r
5257 \r
5258         c = s->Cedar;\r
5259 \r
5260         Lock(c->lock);\r
5261         {\r
5262                 Lock(s->Keep->lock);\r
5263                 {\r
5264                         KEEP *k = s->Keep;\r
5265                         CfgAddBool(f, "UseKeepConnect", k->Enable);\r
5266                         CfgAddStr(f, "KeepConnectHost", k->ServerName);\r
5267                         CfgAddInt(f, "KeepConnectPort", k->ServerPort);\r
5268                         CfgAddInt(f, "KeepConnectProtocol", k->UdpMode);\r
5269                         CfgAddInt(f, "KeepConnectInterval", k->Interval / 1000);\r
5270                 }\r
5271                 Unlock(s->Keep->lock);\r
5272 \r
5273                 // IPv6 リスナー無効化設定\r
5274                 CfgAddBool(f, "DisableIPv6Listener", s->Cedar->DisableIPv6Listener);\r
5275 \r
5276                 // DeadLock\r
5277                 CfgAddBool(f, "DisableDeadLockCheck", s->DisableDeadLockCheck);\r
5278 \r
5279                 // 自動ファイル削除器関係\r
5280                 CfgAddInt64(f, "AutoDeleteCheckDiskFreeSpaceMin", s->Eraser->MinFreeSpace);\r
5281 \r
5282                 // NoLinuxArpFilter\r
5283                 if (GetOsInfo()->OsType == OSTYPE_LINUX)\r
5284                 {\r
5285                         CfgAddBool(f, "NoLinuxArpFilter", s->NoLinuxArpFilter);\r
5286                 }\r
5287 \r
5288                 // NoHighPriorityProcess\r
5289                 CfgAddBool(f, "NoHighPriorityProcess", s->NoHighPriorityProcess);\r
5290 \r
5291 #ifdef  OS_WIN32\r
5292                 CfgAddBool(f, "NoDebugDump", s->NoDebugDump);\r
5293 #endif  // OS_WIN32\r
5294 \r
5295                 // デバッグログ\r
5296                 CfgAddBool(f, "SaveDebugLog", s->SaveDebugLog);\r
5297 \r
5298                 // クライアントにシグネチャを送信させない\r
5299                 CfgAddBool(f, "NoSendSignature", s->NoSendSignature);\r
5300 \r
5301                 // サーバー証明書\r
5302                 b = XToBuf(c->ServerX, false);\r
5303                 CfgAddBuf(f, "ServerCert", b);\r
5304                 FreeBuf(b);\r
5305 \r
5306                 // サーバー秘密鍵\r
5307                 b = KToBuf(c->ServerK, false, NULL);\r
5308                 CfgAddBuf(f, "ServerKey", b);\r
5309                 FreeBuf(b);\r
5310 \r
5311                 // トラフィック情報\r
5312                 Lock(c->TrafficLock);\r
5313                 {\r
5314                         SiWriteTraffic(f, "ServerTraffic", c->Traffic);\r
5315                 }\r
5316                 Unlock(c->TrafficLock);\r
5317 \r
5318                 // サーバーの種類\r
5319                 if (s->Cedar->Bridge == false)\r
5320                 {\r
5321                         CfgAddInt(f, "ServerType", s->UpdatedServerType);\r
5322                 }\r
5323 \r
5324                 // 暗号化\r
5325                 CfgAddStr(f, "CipherName", s->Cedar->CipherList);\r
5326 \r
5327                 // パスワード\r
5328                 CfgAddByte(f, "HashedPassword", s->HashedPassword, sizeof(s->HashedPassword));\r
5329 \r
5330                 if (s->UpdatedServerType == SERVER_TYPE_FARM_MEMBER)\r
5331                 {\r
5332                         char tmp[6 * MAX_PUBLIC_PORT_NUM + 1];\r
5333                         UINT i;\r
5334                         // ファームメンバの場合の設定項目\r
5335                         CfgAddStr(f, "ControllerName", s->ControllerName);\r
5336                         CfgAddInt(f, "ControllerPort", s->ControllerPort);\r
5337                         CfgAddByte(f, "MemberPassword", s->MemberPassword, SHA1_SIZE);\r
5338                         CfgAddIp32(f, "PublicIp", s->PublicIp);\r
5339                         tmp[0] = 0;\r
5340                         for (i = 0;i < s->NumPublicPort;i++)\r
5341                         {\r
5342                                 char tmp2[MAX_SIZE];\r
5343                                 ToStr(tmp2, s->PublicPorts[i]);\r
5344                                 StrCat(tmp, sizeof(tmp), tmp2);\r
5345                                 StrCat(tmp, sizeof(tmp), ",");\r
5346                         }\r
5347                         if (StrLen(tmp) >= 1)\r
5348                         {\r
5349                                 if (tmp[StrLen(tmp) - 1] == ',')\r
5350                                 {\r
5351                                         tmp[StrLen(tmp) - 1] = 0;\r
5352                                 }\r
5353                         }\r
5354                         CfgAddStr(f, "PublicPorts", tmp);\r
5355                 }\r
5356 \r
5357                 if (s->UpdatedServerType != SERVER_TYPE_STANDALONE)\r
5358                 {\r
5359                         CfgAddInt(f, "ClusterMemberWeight", s->Weight);\r
5360                 }\r
5361 \r
5362                 if (s->UpdatedServerType == SERVER_TYPE_FARM_CONTROLLER)\r
5363                 {\r
5364                         CfgAddBool(f, "ControllerOnly", s->ControllerOnly);\r
5365                 }\r
5366         }\r
5367         Unlock(c->lock);\r
5368 }\r
5369 \r
5370 // トラフィック情報の読み込み\r
5371 void SiLoadTraffic(FOLDER *parent, char *name, TRAFFIC *t)\r
5372 {\r
5373         FOLDER *f;\r
5374         // 引数チェック\r
5375         if (t != NULL)\r
5376         {\r
5377                 Zero(t, sizeof(TRAFFIC));\r
5378         }\r
5379         if (parent == NULL || name == NULL || t == NULL)\r
5380         {\r
5381                 return;\r
5382         }\r
5383 \r
5384         f = CfgGetFolder(parent, name);\r
5385 \r
5386         if (f == NULL)\r
5387         {\r
5388                 return;\r
5389         }\r
5390 \r
5391         SiLoadTrafficInner(f, "SendTraffic", &t->Send);\r
5392         SiLoadTrafficInner(f, "RecvTraffic", &t->Recv);\r
5393 }\r
5394 void SiLoadTrafficInner(FOLDER *parent, char *name, TRAFFIC_ENTRY *e)\r
5395 {\r
5396         FOLDER *f;\r
5397         // 引数チェック\r
5398         if (e != NULL)\r
5399         {\r
5400                 Zero(e, sizeof(TRAFFIC_ENTRY));\r
5401         }\r
5402         if (parent == NULL || name == NULL || e == NULL)\r
5403         {\r
5404                 return;\r
5405         }\r
5406 \r
5407         f = CfgGetFolder(parent, name);\r
5408         if (f == NULL)\r
5409         {\r
5410                 return;\r
5411         }\r
5412 \r
5413         e->BroadcastCount = CfgGetInt64(f, "BroadcastCount");\r
5414         e->BroadcastBytes = CfgGetInt64(f, "BroadcastBytes");\r
5415         e->UnicastCount = CfgGetInt64(f, "UnicastCount");\r
5416         e->UnicastBytes = CfgGetInt64(f, "UnicastBytes");\r
5417 }\r
5418 \r
5419 // トラフィック情報の書き込み\r
5420 void SiWriteTraffic(FOLDER *parent, char *name, TRAFFIC *t)\r
5421 {\r
5422         FOLDER *f;\r
5423         // 引数チェック\r
5424         if (parent == NULL || name == NULL || t == NULL)\r
5425         {\r
5426                 return;\r
5427         }\r
5428 \r
5429         f = CfgCreateFolder(parent, name);\r
5430 \r
5431         SiWriteTrafficInner(f, "SendTraffic", &t->Send);\r
5432         SiWriteTrafficInner(f, "RecvTraffic", &t->Recv);\r
5433 }\r
5434 void SiWriteTrafficInner(FOLDER *parent, char *name, TRAFFIC_ENTRY *e)\r
5435 {\r
5436         FOLDER *f;\r
5437         // 引数チェック\r
5438         if (parent == NULL || name == NULL || e == NULL)\r
5439         {\r
5440                 return;\r
5441         }\r
5442 \r
5443         f = CfgCreateFolder(parent, name);\r
5444         CfgAddInt64(f, "BroadcastCount", e->BroadcastCount);\r
5445         CfgAddInt64(f, "BroadcastBytes", e->BroadcastBytes);\r
5446         CfgAddInt64(f, "UnicastCount", e->UnicastCount);\r
5447         CfgAddInt64(f, "UnicastBytes", e->UnicastBytes);\r
5448 }\r
5449 \r
5450 // 設定ファイル書き込み用スレッド\r
5451 void SiSaverThread(THREAD *thread, void *param)\r
5452 {\r
5453         SERVER *s = (SERVER *)param;\r
5454         // 引数チェック\r
5455         if (thread == NULL || param == NULL)\r
5456         {\r
5457                 return;\r
5458         }\r
5459 \r
5460         while (s->Halt == false)\r
5461         {\r
5462                 // 設定ファイル保存\r
5463                 SiWriteConfigurationFile(s);\r
5464 \r
5465                 Wait(s->SaveHaltEvent, s->AutoSaveConfigSpan);\r
5466         }\r
5467 }\r
5468 \r
5469 // 設定ファイルに書き込む\r
5470 UINT SiWriteConfigurationFile(SERVER *s)\r
5471 {\r
5472         UINT ret;\r
5473         // 引数チェック\r
5474         if (s == NULL)\r
5475         {\r
5476                 return 0;\r
5477         }\r
5478 \r
5479         if (s->CfgRw == NULL)\r
5480         {\r
5481                 return 0;\r
5482         }\r
5483 \r
5484         Lock(s->SaveCfgLock);\r
5485         {\r
5486                 FOLDER *f;\r
5487 \r
5488                 Debug("save: SiWriteConfigurationToCfg() start.\n");\r
5489                 f = SiWriteConfigurationToCfg(s);\r
5490                 Debug("save: SiWriteConfigurationToCfg() finished.\n");\r
5491 \r
5492                 Debug("save: SaveCfgRw() start.\n");\r
5493                 ret = SaveCfgRw(s->CfgRw, f);\r
5494                 Debug("save: SaveCfgRw() finished.\n");\r
5495 \r
5496                 Debug("save: CfgDeleteFolder() start.\n");\r
5497                 CfgDeleteFolder(f);\r
5498                 Debug("save: CfgDeleteFolder() finished.\n");\r
5499         }\r
5500         Unlock(s->SaveCfgLock);\r
5501 \r
5502         return ret;\r
5503 }\r
5504 \r
5505 // コンフィグレーション解放\r
5506 void SiFreeConfiguration(SERVER *s)\r
5507 {\r
5508         // 引数チェック\r
5509         if (s == NULL)\r
5510         {\r
5511                 return;\r
5512         }\r
5513 \r
5514         // 設定ファイルに書き込む\r
5515         SiWriteConfigurationFile(s);\r
5516 \r
5517         // 設定ファイル保存スレッドの終了\r
5518         s->Halt = true;\r
5519         Set(s->SaveHaltEvent);\r
5520         WaitThread(s->SaveThread, INFINITE);\r
5521 \r
5522         ReleaseEvent(s->SaveHaltEvent);\r
5523         ReleaseThread(s->SaveThread);\r
5524 \r
5525         FreeCfgRw(s->CfgRw);\r
5526         s->CfgRw = NULL;\r
5527 \r
5528         // Ethernet 解放\r
5529         FreeEth();\r
5530 }\r
5531 \r
5532 // StXxx 関係関数の初期化\r
5533 void StInit()\r
5534 {\r
5535         if (server_lock != NULL)\r
5536         {\r
5537                 return;\r
5538         }\r
5539 \r
5540         server_lock = NewLock();\r
5541 }\r
5542 \r
5543 // StXxx 関係関数の解放\r
5544 void StFree()\r
5545 {\r
5546         DeleteLock(server_lock);\r
5547         server_lock = NULL;\r
5548 }\r
5549 \r
5550 // サーバーの開始\r
5551 void StStartServer(bool bridge)\r
5552 {\r
5553         Lock(server_lock);\r
5554         {\r
5555                 if (server != NULL)\r
5556                 {\r
5557                         // すでに開始されている\r
5558                         Unlock(server_lock);\r
5559                         return;\r
5560                 }\r
5561 \r
5562                 // サーバーの作成\r
5563                 server = SiNewServer(bridge);\r
5564         }\r
5565         Unlock(server_lock);\r
5566 \r
5567 //      StartCedarLog();\r
5568 }\r
5569 \r
5570 // サーバーの取得\r
5571 SERVER *StGetServer()\r
5572 {\r
5573         if (server == NULL)\r
5574         {\r
5575                 return NULL;\r
5576         }\r
5577         return server;\r
5578 }\r
5579 \r
5580 // サーバーの停止\r
5581 void StStopServer()\r
5582 {\r
5583         Lock(server_lock);\r
5584         {\r
5585                 if (server == NULL)\r
5586                 {\r
5587                         // 開始されていない\r
5588                         Unlock(server_lock);\r
5589                         return;\r
5590                 }\r
5591 \r
5592                 // サーバーの解放\r
5593                 SiReleaseServer(server);\r
5594                 server = NULL;\r
5595         }\r
5596         Unlock(server_lock);\r
5597 \r
5598         StopCedarLog();\r
5599 }\r
5600 \r
5601 // サーバーの種類の設定\r
5602 void SiSetServerType(SERVER *s, UINT type,\r
5603                                          UINT ip, UINT num_port, UINT *ports,\r
5604                                          char *controller_name, UINT controller_port, UCHAR *password, UINT weight, bool controller_only)\r
5605 {\r
5606         bool bridge;\r
5607         // 引数チェック\r
5608         if (s == NULL)\r
5609         {\r
5610                 return;\r
5611         }\r
5612         if (type == SERVER_TYPE_FARM_MEMBER &&\r
5613                 (num_port == 0 || ports == NULL || controller_name == NULL ||\r
5614                 controller_port == 0 || password == NULL || num_port > MAX_PUBLIC_PORT_NUM))\r
5615         {\r
5616                 return;\r
5617         }\r
5618         if (weight == 0)\r
5619         {\r
5620                 weight = FARM_DEFAULT_WEIGHT;\r
5621         }\r
5622 \r
5623         bridge = s->Cedar->Bridge;\r
5624 \r
5625         Lock(s->lock);\r
5626         {\r
5627                 // 種類の更新\r
5628                 s->UpdatedServerType = type;\r
5629 \r
5630                 s->Weight = weight;\r
5631 \r
5632                 // 値の設定\r
5633                 if (type == SERVER_TYPE_FARM_MEMBER)\r
5634                 {\r
5635                         StrCpy(s->ControllerName, sizeof(s->ControllerName), controller_name);\r
5636                         s->ControllerPort = controller_port;\r
5637                         if (IsZero(password, SHA1_SIZE) == false)\r
5638                         {\r
5639                                 Copy(s->MemberPassword, password, SHA1_SIZE);\r
5640                         }\r
5641                         s->PublicIp = ip;\r
5642                         s->NumPublicPort = num_port;\r
5643                         if (s->PublicPorts != NULL)\r
5644                         {\r
5645                                 Free(s->PublicPorts);\r
5646                         }\r
5647                         s->PublicPorts = ZeroMalloc(num_port * sizeof(UINT));\r
5648                         Copy(s->PublicPorts, ports, num_port * sizeof(UINT));\r
5649                 }\r
5650 \r
5651                 if (type == SERVER_TYPE_FARM_CONTROLLER)\r
5652                 {\r
5653                         s->ControllerOnly = controller_only;\r
5654                 }\r
5655         }\r
5656         Unlock(s->lock);\r
5657 \r
5658         // サーバーの再起動\r
5659         SiRebootServer(bridge);\r
5660 }\r
5661 \r
5662 // サーバーの再起動スレッド\r
5663 void SiRebootServerThread(THREAD *thread, void *param)\r
5664 {\r
5665         // 引数チェック\r
5666         if (thread == NULL)\r
5667         {\r
5668                 return;\r
5669         }\r
5670 \r
5671         if (server == NULL)\r
5672         {\r
5673                 return;\r
5674         }\r
5675 \r
5676         // サーバーの停止\r
5677         StStopServer();\r
5678 \r
5679         // サーバーの開始\r
5680         StStartServer((bool)param);\r
5681 }\r
5682 \r
5683 // サーバーの再起動\r
5684 void SiRebootServer(bool bridge)\r
5685 {\r
5686         SiRebootServerEx(bridge, false);\r
5687 }\r
5688 void SiRebootServerEx(bool bridge, bool reset_setting)\r
5689 {\r
5690         THREAD *t;\r
5691 \r
5692         server_reset_setting = reset_setting;\r
5693 \r
5694         t = NewThread(SiRebootServerThread, (void *)bridge);\r
5695         ReleaseThread(t);\r
5696 }\r
5697 \r
5698 // すべてのリスナーの停止\r
5699 void SiStopAllListener(SERVER *s)\r
5700 {\r
5701         // 引数チェック\r
5702         if (s == NULL)\r
5703         {\r
5704                 return;\r
5705         }\r
5706 \r
5707         SiLockListenerList(s);\r
5708         {\r
5709                 UINT i;\r
5710                 LIST *o = NewListFast(NULL);\r
5711                 for (i = 0;i < LIST_NUM(s->ServerListenerList);i++)\r
5712                 {\r
5713                         SERVER_LISTENER *e = LIST_DATA(s->ServerListenerList, i);\r
5714                         Add(o, e);\r
5715                 }\r
5716 \r
5717                 for (i = 0;i < LIST_NUM(o);i++)\r
5718                 {\r
5719                         SERVER_LISTENER *e = LIST_DATA(o, i);\r
5720                         SiDeleteListener(s, e->Port);\r
5721                 }\r
5722 \r
5723                 ReleaseList(o);\r
5724         }\r
5725         SiUnlockListenerList(s);\r
5726 \r
5727         ReleaseList(s->ServerListenerList);\r
5728 }\r
5729 \r
5730 // サーバーのクリーンアップ\r
5731 void SiCleanupServer(SERVER *s)\r
5732 {\r
5733         UINT i;\r
5734         CEDAR *c;\r
5735         LISTENER **listener_list;\r
5736         UINT num_listener;\r
5737         HUB **hub_list;\r
5738         UINT num_hub;\r
5739         // 引数チェック\r
5740         if (s == NULL)\r
5741         {\r
5742                 return;\r
5743         }\r
5744 \r
5745         SiFreeDeadLockCheck(s);\r
5746 \r
5747         FreeServerSnapshot(s);\r
5748 \r
5749         c = s->Cedar;\r
5750 \r
5751         if (s->ServerType == SERVER_TYPE_FARM_MEMBER)\r
5752         {\r
5753                 // ファームメンバの場合、ファームコントローラへの接続を停止\r
5754                 SLog(c, "LS_STOP_FARM_MEMBER");\r
5755                 SiStopConnectToController(s->FarmController);\r
5756                 s->FarmController = NULL;\r
5757                 SLog(c, "LS_STOP_FARM_MEMBER_2");\r
5758         }\r
5759 \r
5760         IncrementServerConfigRevision(s);\r
5761 \r
5762         SLog(c, "LS_END_2");\r
5763 \r
5764         SLog(c, "LS_STOP_ALL_LISTENER");\r
5765         // すべてのリスナーを停止\r
5766         LockList(c->ListenerList);\r
5767         {\r
5768                 listener_list = ToArray(c->ListenerList);\r
5769                 num_listener = LIST_NUM(c->ListenerList);\r
5770                 for (i = 0;i < num_listener;i++)\r
5771                 {\r
5772                         AddRef(listener_list[i]->ref);\r
5773                 }\r
5774         }\r
5775         UnlockList(c->ListenerList);\r
5776 \r
5777         for (i = 0;i < num_listener;i++)\r
5778         {\r
5779                 StopListener(listener_list[i]);\r
5780                 ReleaseListener(listener_list[i]);\r
5781         }\r
5782         Free(listener_list);\r
5783         SLog(c, "LS_STOP_ALL_LISTENER_2");\r
5784 \r
5785         SLog(c, "LS_STOP_ALL_HUB");\r
5786         // すべての HUB を停止\r
5787         LockList(c->HubList);\r
5788         {\r
5789                 hub_list = ToArray(c->HubList);\r
5790                 num_hub = LIST_NUM(c->HubList);\r
5791                 for (i = 0;i < num_hub;i++)\r
5792                 {\r
5793                         AddRef(hub_list[i]->ref);\r
5794                 }\r
5795         }\r
5796         UnlockList(c->HubList);\r
5797 \r
5798         for (i = 0;i < num_hub;i++)\r
5799         {\r
5800                 StopHub(hub_list[i]);\r
5801                 ReleaseHub(hub_list[i]);\r
5802         }\r
5803         Free(hub_list);\r
5804         SLog(c, "LS_STOP_ALL_HUB_2");\r
5805 \r
5806         // コンフィグレーション解放\r
5807         SiFreeConfiguration(s);\r
5808 \r
5809         // Cedar の停止\r
5810         SLog(c, "LS_STOP_CEDAR");\r
5811         StopCedar(s->Cedar);\r
5812         SLog(c, "LS_STOP_CEDAR_2");\r
5813 \r
5814         // すべてのリスナーの停止\r
5815         SiStopAllListener(s);\r
5816 \r
5817         if (s->ServerType == SERVER_TYPE_FARM_CONTROLLER)\r
5818         {\r
5819                 // ファームコントローラの場合\r
5820                 UINT i;\r
5821 \r
5822                 SLog(c, "LS_STOP_FARM_CONTROL");\r
5823 \r
5824                 // ファームコントロールを停止\r
5825                 SiStopFarmControl(s);\r
5826 \r
5827                 // ファームメンバ情報を解放\r
5828                 ReleaseList(s->FarmMemberList);\r
5829                 s->FarmMemberList = NULL;\r
5830 \r
5831                 for (i = 0;i < LIST_NUM(s->Me->HubList);i++)\r
5832                 {\r
5833                         Free(LIST_DATA(s->Me->HubList, i));\r
5834                 }\r
5835                 ReleaseList(s->Me->HubList);\r
5836 \r
5837                 Free(s->Me);\r
5838 \r
5839                 SLog(c, "LS_STOP_FARM_CONTROL_2");\r
5840         }\r
5841 \r
5842         if (s->PublicPorts != NULL)\r
5843         {\r
5844                 Free(s->PublicPorts);\r
5845         }\r
5846 \r
5847         SLog(s->Cedar, "LS_END_1");\r
5848         SLog(s->Cedar, "L_LINE");\r
5849 \r
5850         ReleaseCedar(s->Cedar);\r
5851         DeleteLock(s->lock);\r
5852         DeleteLock(s->SaveCfgLock);\r
5853 \r
5854         StopKeep(s->Keep);\r
5855 \r
5856         FreeEraser(s->Eraser);\r
5857 \r
5858         // ライセンスシステム解放\r
5859         if (s->LicenseSystem != NULL)\r
5860         {\r
5861                 LiFreeLicenseSystem(s->LicenseSystem);\r
5862         }\r
5863 \r
5864         FreeLog(s->Logger);\r
5865 \r
5866         FreeServerCapsCache(s);\r
5867 \r
5868         SiFreeHubCreateHistory(s);\r
5869 \r
5870         // デバッグログの停止\r
5871         FreeTinyLog(s->DebugLog);\r
5872 \r
5873         DeleteLock(s->TasksFromFarmControllerLock);\r
5874 \r
5875         Free(s);\r
5876 }\r
5877 \r
5878 // サーバーの解放\r
5879 void SiReleaseServer(SERVER *s)\r
5880 {\r
5881         // 引数チェック\r
5882         if (s == NULL)\r
5883         {\r
5884                 return;\r
5885         }\r
5886 \r
5887         if (Release(s->ref) == 0)\r
5888         {\r
5889                 SiCleanupServer(s);\r
5890         }\r
5891 }\r
5892 \r
5893 // 次に処理をさせるファームメンバーを指定する\r
5894 FARM_MEMBER *SiGetNextFarmMember(SERVER *s)\r
5895 {\r
5896         UINT i, num;\r
5897         UINT min_point = 0;\r
5898         FARM_MEMBER *ret = NULL;\r
5899         // 引数チェック\r
5900         if (s == NULL || s->ServerType != SERVER_TYPE_FARM_CONTROLLER)\r
5901         {\r
5902                 return NULL;\r
5903         }\r
5904 \r
5905         num = LIST_NUM(s->FarmMemberList);\r
5906         if (num == 0)\r
5907         {\r
5908                 return NULL;\r
5909         }\r
5910 \r
5911         for (i = 0;i < num;i++)\r
5912         {\r
5913                 UINT num_sessions;\r
5914                 UINT max_sessions;\r
5915                 FARM_MEMBER *f = LIST_DATA(s->FarmMemberList, i);\r
5916                 if (s->ControllerOnly)\r
5917                 {\r
5918                         if (f->Me)\r
5919                         {\r
5920                                 // ControllerOnly のとき自分自身は選定しない\r
5921                                 continue;\r
5922                         }\r
5923                 }\r
5924 \r
5925                 if (f->Me == false)\r
5926                 {\r
5927                         num_sessions = f->NumSessions;\r
5928                         max_sessions = f->MaxSessions;\r
5929                 }\r
5930                 else\r
5931                 {\r
5932                         num_sessions = Count(s->Cedar->CurrentSessions);\r
5933                         max_sessions = GetServerCapsInt(s, "i_max_sessions");\r
5934                 }\r
5935 \r
5936                 if (max_sessions == 0)\r
5937                 {\r
5938                         max_sessions = GetServerCapsInt(s, "i_max_sessions");\r
5939                 }\r
5940 \r
5941                 if (num_sessions < max_sessions)\r
5942                 {\r
5943                         if (f->Point >= min_point)\r
5944                         {\r
5945                                 min_point = f->Point;\r
5946                                 ret = f;\r
5947                         }\r
5948                 }\r
5949         }\r
5950 \r
5951         return ret;\r
5952 }\r
5953 \r
5954 // HUB 列挙指令受信\r
5955 void SiCalledEnumHub(SERVER *s, PACK *p, PACK *req)\r
5956 {\r
5957         UINT i;\r
5958         CEDAR *c;\r
5959         LICENSE_STATUS st;\r
5960         UINT num = 0;\r
5961         // 引数チェック\r
5962         if (s == NULL || p == NULL || req == NULL)\r
5963         {\r
5964                 return;\r
5965         }\r
5966 \r
5967         LiParseCurrentLicenseStatus(s->LicenseSystem, &st);\r
5968 \r
5969         c = s->Cedar;\r
5970 \r
5971         LockList(c->HubList);\r
5972         {\r
5973                 UINT num = LIST_NUM(c->HubList);\r
5974                 for (i = 0;i < num;i++)\r
5975                 {\r
5976                         HUB *h = LIST_DATA(c->HubList, i);\r
5977                         Lock(h->lock);\r
5978                         {\r
5979                                 PackAddStrEx(p, "HubName", h->Name, i, num);\r
5980                                 PackAddIntEx(p, "HubType", h->Type, i, num);\r
5981                                 PackAddIntEx(p, "NumSession", Count(h->NumSessions), i, num);\r
5982 \r
5983                                 PackAddIntEx(p, "NumSessions", LIST_NUM(h->SessionList), i, num);\r
5984                                 PackAddIntEx(p, "NumSessionsClient", Count(h->NumSessionsClient), i, num);\r
5985                                 PackAddIntEx(p, "NumSessionsBridge", Count(h->NumSessionsBridge), i, num);\r
5986 \r
5987                                 PackAddIntEx(p, "NumMacTables", LIST_NUM(h->MacTable), i, num);\r
5988 \r
5989                                 PackAddIntEx(p, "NumIpTables", LIST_NUM(h->IpTable), i, num);\r
5990 \r
5991                                 PackAddInt64Ex(p, "LastCommTime", h->LastCommTime, i, num);\r
5992                                 PackAddInt64Ex(p, "CreatedTime", h->CreatedTime, i, num);\r
5993                         }\r
5994                         Unlock(h->lock);\r
5995                 }\r
5996         }\r
5997         UnlockList(c->HubList);\r
5998 \r
5999         PackAddInt(p, "Point", SiGetPoint(s));\r
6000         PackAddInt(p, "NumTcpConnections", Count(s->Cedar->CurrentTcpConnections));\r
6001         PackAddInt(p, "NumTotalSessions", Count(s->Cedar->CurrentSessions));\r
6002         PackAddInt(p, "MaxSessions", GetServerCapsInt(s, "i_max_sessions"));\r
6003 \r
6004         PackAddInt(p, "AssignedClientLicense", Count(s->Cedar->AssignedClientLicense));\r
6005         PackAddInt(p, "AssignedBridgeLicense", Count(s->Cedar->AssignedBridgeLicense));\r
6006 \r
6007         PackAddData(p, "RandomKey", s->MyRandomKey, SHA1_SIZE);\r
6008         PackAddInt64(p, "SystemId", st.SystemId);\r
6009 \r
6010         Lock(c->TrafficLock);\r
6011         {\r
6012                 OutRpcTraffic(p, c->Traffic);\r
6013         }\r
6014         Unlock(c->TrafficLock);\r
6015 \r
6016         LockList(c->TrafficDiffList);\r
6017         {\r
6018                 UINT num = LIST_NUM(c->TrafficDiffList);\r
6019                 UINT i;\r
6020 \r
6021                 for (i = 0;i < num;i++)\r
6022                 {\r
6023                         TRAFFIC_DIFF *d = LIST_DATA(c->TrafficDiffList, i);\r
6024 \r
6025                         PackAddIntEx(p, "TdType", d->Type, i, num);\r
6026                         PackAddStrEx(p, "TdHubName", d->HubName, i, num);\r
6027                         PackAddStrEx(p, "TdName", d->Name, i, num);\r
6028 \r
6029                         OutRpcTrafficEx(&d->Traffic, p, i, num);\r
6030 \r
6031                         Free(d->HubName);\r
6032                         Free(d->Name);\r
6033                         Free(d);\r
6034                 }\r
6035 \r
6036                 DeleteAll(c->TrafficDiffList);\r
6037         }\r
6038         UnlockList(c->TrafficDiffList);\r
6039 }\r
6040 \r
6041 // HUB 削除指令受信\r
6042 void SiCalledDeleteHub(SERVER *s, PACK *p)\r
6043 {\r
6044         char name[MAX_SIZE];\r
6045         HUB *h;\r
6046         // 引数チェック\r
6047         if (s == NULL || p == NULL)\r
6048         {\r
6049                 return;\r
6050         }\r
6051 \r
6052         if (PackGetStr(p, "HubName", name, sizeof(name)) == false)\r
6053         {\r
6054                 return;\r
6055         }\r
6056 \r
6057         LockHubList(s->Cedar);\r
6058 \r
6059         h = GetHub(s->Cedar, name);\r
6060         if (h == NULL)\r
6061         {\r
6062                 UnlockHubList(s->Cedar);\r
6063                 return;\r
6064         }\r
6065         UnlockHubList(s->Cedar);\r
6066 \r
6067         SetHubOffline(h);\r
6068 \r
6069         LockHubList(s->Cedar);\r
6070 \r
6071         DelHubEx(s->Cedar, h, true);\r
6072 \r
6073         UnlockHubList(s->Cedar);\r
6074 \r
6075         ReleaseHub(h);\r
6076 }\r
6077 \r
6078 // HUB 更新指令受信\r
6079 void SiCalledUpdateHub(SERVER *s, PACK *p)\r
6080 {\r
6081         char name[MAX_SIZE];\r
6082         UINT type;\r
6083         HUB_OPTION o;\r
6084         HUB_LOG log;\r
6085         bool save_packet_log;\r
6086         UINT packet_log_switch_type;\r
6087         UINT packet_log_config[NUM_PACKET_LOG];\r
6088         bool save_security_log;\r
6089         bool type_changed = false;\r
6090         UINT security_log_switch_type;\r
6091         UINT i;\r
6092         HUB *h;\r
6093         // 引数チェック\r
6094         if (s == NULL || p == NULL)\r
6095         {\r
6096                 return;\r
6097         }\r
6098 \r
6099         PackGetStr(p, "HubName", name, sizeof(name));\r
6100         type = PackGetInt(p, "HubType");\r
6101         Zero(&o, sizeof(o));\r
6102         o.MaxSession = PackGetInt(p, "MaxSession");\r
6103         o.NoArpPolling = PackGetBool(p, "NoArpPolling");\r
6104         o.NoIPv6AddrPolling = PackGetBool(p, "NoIPv6AddrPolling");\r
6105         o.FilterPPPoE = PackGetBool(p, "FilterPPPoE");\r
6106         o.YieldAfterStorePacket = PackGetBool(p, "YieldAfterStorePacket");\r
6107         o.NoSpinLockForPacketDelay = PackGetBool(p, "NoSpinLockForPacketDelay");\r
6108         o.BroadcastStormDetectionThreshold = PackGetInt(p, "BroadcastStormDetectionThreshold");\r
6109         o.ClientMinimumRequiredBuild = PackGetInt(p, "ClientMinimumRequiredBuild");\r
6110         o.FixForDLinkBPDU = PackGetBool(p, "FixForDLinkBPDU");\r
6111         o.NoLookBPDUBridgeId = PackGetBool(p, "NoLookBPDUBridgeId");\r
6112         o.NoManageVlanId = PackGetBool(p, "NoManageVlanId");\r
6113         o.VlanTypeId = PackGetInt(p, "VlanTypeId");\r
6114         if (o.VlanTypeId == 0)\r
6115         {\r
6116                 o.VlanTypeId = MAC_PROTO_TAGVLAN;\r
6117         }\r
6118         o.FilterOSPF = PackGetBool(p, "FilterOSPF");\r
6119         o.FilterIPv4 = PackGetBool(p, "FilterIPv4");\r
6120         o.FilterIPv6 = PackGetBool(p, "FilterIPv6");\r
6121         o.FilterNonIP = PackGetBool(p, "FilterNonIP");\r
6122         o.NoIPv4PacketLog = PackGetBool(p, "NoIPv4PacketLog");\r
6123         o.NoIPv6PacketLog = PackGetBool(p, "NoIPv6PacketLog");\r
6124         o.FilterBPDU = PackGetBool(p, "FilterBPDU");\r
6125         o.NoIPv6DefaultRouterInRAWhenIPv6 = PackGetBool(p, "NoIPv6DefaultRouterInRAWhenIPv6");\r
6126         o.NoMacAddressLog = PackGetBool(p, "NoMacAddressLog");\r
6127         o.ManageOnlyPrivateIP = PackGetBool(p, "ManageOnlyPrivateIP");\r
6128         o.ManageOnlyLocalUnicastIPv6 = PackGetBool(p, "ManageOnlyLocalUnicastIPv6");\r
6129         o.DisableIPParsing = PackGetBool(p, "DisableIPParsing");\r
6130         o.NoIpTable = PackGetBool(p, "NoIpTable");\r
6131         o.NoEnum = PackGetBool(p, "NoEnum");\r
6132         save_packet_log = PackGetInt(p, "SavePacketLog");\r
6133         packet_log_switch_type = PackGetInt(p, "PacketLogSwitchType");\r
6134         for (i = 0;i < NUM_PACKET_LOG;i++)\r
6135         {\r
6136                 packet_log_config[i] = PackGetIntEx(p, "PacketLogConfig", i);\r
6137         }\r
6138         save_security_log = PackGetInt(p, "SaveSecurityLog");\r
6139         security_log_switch_type = PackGetInt(p, "SecurityLogSwitchType");\r
6140 \r
6141         Zero(&log, sizeof(log));\r
6142         log.SavePacketLog = save_packet_log;\r
6143         log.PacketLogSwitchType = packet_log_switch_type;\r
6144         Copy(log.PacketLogConfig, packet_log_config, sizeof(log.PacketLogConfig));\r
6145         log.SaveSecurityLog = save_security_log;\r
6146         log.SecurityLogSwitchType = security_log_switch_type;\r
6147 \r
6148         h = GetHub(s->Cedar, name);\r
6149         if (h == NULL)\r
6150         {\r
6151                 return;\r
6152         }\r
6153 \r
6154         h->FarmMember_MaxSessionClient = PackGetInt(p, "MaxSessionClient");\r
6155         h->FarmMember_MaxSessionBridge = PackGetInt(p, "MaxSessionBridge");\r
6156         h->FarmMember_MaxSessionClientBridgeApply = PackGetBool(p, "MaxSessionClientBridgeApply");\r
6157 \r
6158         if (h->FarmMember_MaxSessionClientBridgeApply == false)\r
6159         {\r
6160                 h->FarmMember_MaxSessionClient = INFINITE;\r
6161                 h->FarmMember_MaxSessionBridge = INFINITE;\r
6162         }\r
6163 \r
6164         Lock(h->lock);\r
6165         {\r
6166                 Copy(h->Option, &o, sizeof(HUB_OPTION));\r
6167                 PackGetData2(p, "SecurePassword", h->SecurePassword, SHA1_SIZE);\r
6168                 PackGetData2(p, "HashedPassword", h->HashedPassword, SHA1_SIZE);\r
6169         }\r
6170         Unlock(h->lock);\r
6171 \r
6172         SetHubLogSetting(h, &log);\r
6173 \r
6174         if (h->Type != type)\r
6175         {\r
6176                 h->Type = type;\r
6177                 type_changed = true;\r
6178         }\r
6179 \r
6180         LockList(h->AccessList);\r
6181         {\r
6182                 UINT i;\r
6183                 for (i = 0;i < LIST_NUM(h->AccessList);i++)\r
6184                 {\r
6185                         ACCESS *a = LIST_DATA(h->AccessList, i);\r
6186                         Free(a);\r
6187                 }\r
6188                 DeleteAll(h->AccessList);\r
6189         }\r
6190         UnlockList(h->AccessList);\r
6191 \r
6192         for (i = 0;i < SiNumAccessFromPack(p);i++)\r
6193         {\r
6194                 ACCESS *a = SiPackToAccess(p, i);\r
6195                 AddAccessList(h, a);\r
6196                 Free(a);\r
6197         }\r
6198 \r
6199         if (PackGetBool(p, "EnableSecureNAT"))\r
6200         {\r
6201                 VH_OPTION t;\r
6202                 bool changed;\r
6203 \r
6204                 InVhOption(&t, p);\r
6205 \r
6206                 changed = Cmp(h->SecureNATOption, &t, sizeof(VH_OPTION)) == 0 ? false : true;\r
6207                 Copy(h->SecureNATOption, &t, sizeof(VH_OPTION));\r
6208 \r
6209                 EnableSecureNAT(h, true);\r
6210 \r
6211                 if (changed)\r
6212                 {\r
6213                         Lock(h->lock_online);\r
6214                         {\r
6215                                 if (h->SecureNAT != NULL)\r
6216                                 {\r
6217                                         SetVirtualHostOption(h->SecureNAT->Nat->Virtual, &t);\r
6218                                         Debug("SiCalledUpdateHub: SecureNAT Updated.\n");\r
6219                                 }\r
6220                         }\r
6221                         Unlock(h->lock_online);\r
6222                 }\r
6223         }\r
6224         else\r
6225         {\r
6226                 EnableSecureNAT(h, false);\r
6227                 Debug("SiCalledUpdateHub: SecureNAT Disabled.\n");\r
6228         }\r
6229 \r
6230         if (type_changed)\r
6231         {\r
6232                 // HUB の種類が変更されたのですべてのセッションを削除する\r
6233                 if (h->Offline == false)\r
6234                 {\r
6235                         SetHubOffline(h);\r
6236                         SetHubOnline(h);\r
6237                 }\r
6238         }\r
6239 \r
6240         ReleaseHub(h);\r
6241 }\r
6242 \r
6243 // チケットの検査\r
6244 bool SiCheckTicket(HUB *h, UCHAR *ticket, char *username, UINT username_size, char *usernamereal, UINT usernamereal_size, POLICY *policy, char *sessionname, UINT sessionname_size, char *groupname, UINT groupname_size)\r
6245 {\r
6246         bool ret = false;\r
6247         // 引数チェック\r
6248         if (h == NULL || ticket == NULL || username == NULL || usernamereal == NULL || policy == NULL || sessionname == NULL)\r
6249         {\r
6250                 return false;\r
6251         }\r
6252 \r
6253         LockList(h->TicketList);\r
6254         {\r
6255                 UINT i;\r
6256                 for (i = 0;i < LIST_NUM(h->TicketList);i++)\r
6257                 {\r
6258                         TICKET *t = LIST_DATA(h->TicketList, i);\r
6259                         if (Cmp(t->Ticket, ticket, SHA1_SIZE) == 0)\r
6260                         {\r
6261                                 ret = true;\r
6262                                 StrCpy(username, username_size, t->Username);\r
6263                                 StrCpy(usernamereal, usernamereal_size, t->UsernameReal);\r
6264                                 StrCpy(sessionname, sessionname_size, t->SessionName);\r
6265                                 StrCpy(groupname, groupname_size, t->GroupName);\r
6266                                 Copy(policy, &t->Policy, sizeof(POLICY));\r
6267                                 Delete(h->TicketList, t);\r
6268                                 Free(t);\r
6269                                 break;\r
6270                         }\r
6271                 }\r
6272         }\r
6273         UnlockList(h->TicketList);\r
6274 \r
6275         return ret;\r
6276 }\r
6277 \r
6278 // MAC アドレス削除指令受信\r
6279 void SiCalledDeleteMacTable(SERVER *s, PACK *p)\r
6280 {\r
6281         UINT key;\r
6282         char hubname[MAX_HUBNAME_LEN + 1];\r
6283         HUB *h;\r
6284         // 引数チェック\r
6285         if (s == NULL || p == NULL)\r
6286         {\r
6287                 return;\r
6288         }\r
6289 \r
6290         if (PackGetStr(p, "HubName", hubname, sizeof(hubname)) == false)\r
6291         {\r
6292                 return;\r
6293         }\r
6294         key = PackGetInt(p, "Key");\r
6295 \r
6296         LockHubList(s->Cedar);\r
6297         {\r
6298                 h = GetHub(s->Cedar, hubname);\r
6299         }\r
6300         UnlockHubList(s->Cedar);\r
6301 \r
6302         if (h == NULL)\r
6303         {\r
6304                 return;\r
6305         }\r
6306 \r
6307         LockList(h->MacTable);\r
6308         {\r
6309                 if (IsInList(h->MacTable, (void *)key))\r
6310                 {\r
6311                         MAC_TABLE_ENTRY *e = (MAC_TABLE_ENTRY *)key;\r
6312                         Delete(h->MacTable, e);\r
6313                         Free(e);\r
6314                 }\r
6315         }\r
6316         UnlockList(h->MacTable);\r
6317 \r
6318         ReleaseHub(h);\r
6319 }\r
6320 \r
6321 // IP アドレス削除指令受信\r
6322 void SiCalledDeleteIpTable(SERVER *s, PACK *p)\r
6323 {\r
6324         UINT key;\r
6325         char hubname[MAX_HUBNAME_LEN + 1];\r
6326         HUB *h;\r
6327         // 引数チェック\r
6328         if (s == NULL || p == NULL)\r
6329         {\r
6330                 return;\r
6331         }\r
6332 \r
6333         if (PackGetStr(p, "HubName", hubname, sizeof(hubname)) == false)\r
6334         {\r
6335                 return;\r
6336         }\r
6337         key = PackGetInt(p, "Key");\r
6338 \r
6339         LockHubList(s->Cedar);\r
6340         {\r
6341                 h = GetHub(s->Cedar, hubname);\r
6342         }\r
6343         UnlockHubList(s->Cedar);\r
6344 \r
6345         if (h == NULL)\r
6346         {\r
6347                 return;\r
6348         }\r
6349 \r
6350         LockList(h->IpTable);\r
6351         {\r
6352                 if (IsInList(h->IpTable, (void *)key))\r
6353                 {\r
6354                         IP_TABLE_ENTRY *e = (IP_TABLE_ENTRY *)key;\r
6355                         Delete(h->IpTable, e);\r
6356                         Free(e);\r
6357                 }\r
6358         }\r
6359         UnlockList(h->IpTable);\r
6360 \r
6361         ReleaseHub(h);\r
6362 }\r
6363 \r
6364 // セッション削除指令受信\r
6365 void SiCalledDeleteSession(SERVER *s, PACK *p)\r
6366 {\r
6367         char name[MAX_SESSION_NAME_LEN + 1];\r
6368         char hubname[MAX_HUBNAME_LEN + 1];\r
6369         HUB *h;\r
6370         SESSION *sess;\r
6371         // 引数チェック\r
6372         if (s == NULL || p == NULL)\r
6373         {\r
6374                 return;\r
6375         }\r
6376 \r
6377         if (PackGetStr(p, "HubName", hubname, sizeof(hubname)) == false)\r
6378         {\r
6379                 return;\r
6380         }\r
6381         if (PackGetStr(p, "SessionName", name, sizeof(name)) == false)\r
6382         {\r
6383                 return;\r
6384         }\r
6385 \r
6386         LockHubList(s->Cedar);\r
6387         {\r
6388                 h = GetHub(s->Cedar, hubname);\r
6389         }\r
6390         UnlockHubList(s->Cedar);\r
6391 \r
6392         if (h == NULL)\r
6393         {\r
6394                 return;\r
6395         }\r
6396 \r
6397         sess = GetSessionByName(h, name);\r
6398 \r
6399         if (sess != NULL)\r
6400         {\r
6401                 if (sess->BridgeMode == false && sess->LinkModeServer == false && sess->SecureNATMode == false)\r
6402                 {\r
6403                         StopSession(sess);\r
6404                 }\r
6405                 ReleaseSession(sess);\r
6406         }\r
6407 \r
6408         ReleaseHub(h);\r
6409 }\r
6410 \r
6411 // ログファイル読み込み指令受信\r
6412 PACK *SiCalledReadLogFile(SERVER *s, PACK *p)\r
6413 {\r
6414         RPC_READ_LOG_FILE t;\r
6415         PACK *ret;\r
6416         char filepath[MAX_PATH];\r
6417         UINT offset;\r
6418         // 引数チェック\r
6419         if (s == NULL || p == NULL)\r
6420         {\r
6421                 return NULL;\r
6422         }\r
6423 \r
6424         PackGetStr(p, "FilePath", filepath, sizeof(filepath));\r
6425         offset = PackGetInt(p, "Offset");\r
6426 \r
6427         Zero(&t, sizeof(t));\r
6428 \r
6429         SiReadLocalLogFile(s, filepath, offset, &t);\r
6430 \r
6431         ret = NewPack();\r
6432 \r
6433         OutRpcReadLogFile(ret, &t);\r
6434         FreeRpcReadLogFile(&t);\r
6435 \r
6436         return ret;\r
6437 }\r
6438 \r
6439 // ログファイル列挙指令受信\r
6440 PACK *SiCalledEnumLogFileList(SERVER *s, PACK *p)\r
6441 {\r
6442         RPC_ENUM_LOG_FILE t;\r
6443         PACK *ret;\r
6444         char hubname[MAX_HUBNAME_LEN + 1];\r
6445         // 引数チェック\r
6446         if (s == NULL || p == NULL)\r
6447         {\r
6448                 return NULL;\r
6449         }\r
6450 \r
6451         PackGetStr(p, "HubName", hubname, sizeof(hubname));\r
6452 \r
6453         Zero(&t, sizeof(t));\r
6454 \r
6455         SiEnumLocalLogFileList(s, hubname, &t);\r
6456 \r
6457         ret = NewPack();\r
6458 \r
6459         OutRpcEnumLogFile(ret, &t);\r
6460         FreeRpcEnumLogFile(&t);\r
6461 \r
6462         return ret;\r
6463 }\r
6464 \r
6465 // セッション情報指令受信\r
6466 PACK *SiCalledGetSessionStatus(SERVER *s, PACK *p)\r
6467 {\r
6468         RPC_SESSION_STATUS t;\r
6469         ADMIN a;\r
6470         PACK *ret;\r
6471         // 引数チェック\r
6472         if (s == NULL || p == NULL)\r
6473         {\r
6474                 return NULL;\r
6475         }\r
6476 \r
6477         Zero(&t, sizeof(t));\r
6478         InRpcSessionStatus(&t, p);\r
6479 \r
6480         Zero(&a, sizeof(a));\r
6481         a.Server = s;\r
6482         a.ServerAdmin = true;\r
6483 \r
6484         if (StGetSessionStatus(&a, &t) != ERR_NO_ERROR)\r
6485         {\r
6486                 FreeRpcSessionStatus(&t);\r
6487                 return NULL;\r
6488         }\r
6489 \r
6490         ret = NewPack();\r
6491 \r
6492         OutRpcSessionStatus(ret, &t);\r
6493 \r
6494         FreeRpcSessionStatus(&t);\r
6495 \r
6496         return ret;\r
6497 }\r
6498 \r
6499 // IP テーブル列挙指令\r
6500 PACK *SiCalledEnumIpTable(SERVER *s, PACK *p)\r
6501 {\r
6502         char hubname[MAX_HUBNAME_LEN + 1];\r
6503         RPC_ENUM_IP_TABLE t;\r
6504         PACK *ret;\r
6505         // 引数チェック\r
6506         if (s == NULL || p == NULL)\r
6507         {\r
6508                 return NewPack();\r
6509         }\r
6510         if (PackGetStr(p, "HubName", hubname, sizeof(hubname)) == false)\r
6511         {\r
6512                 return NewPack();\r
6513         }\r
6514         Zero(&t, sizeof(t));\r
6515 \r
6516         SiEnumIpTable(s, hubname, &t);\r
6517 \r
6518         ret = NewPack();\r
6519         OutRpcEnumIpTable(ret, &t);\r
6520         FreeRpcEnumIpTable(&t);\r
6521 \r
6522         return ret;\r
6523 }\r
6524 \r
6525 // MAC テーブル列挙指令\r
6526 PACK *SiCalledEnumMacTable(SERVER *s, PACK *p)\r
6527 {\r
6528         char hubname[MAX_HUBNAME_LEN + 1];\r
6529         RPC_ENUM_MAC_TABLE t;\r
6530         PACK *ret;\r
6531         // 引数チェック\r
6532         if (s == NULL || p == NULL)\r
6533         {\r
6534                 return NewPack();\r
6535         }\r
6536         if (PackGetStr(p, "HubName", hubname, sizeof(hubname)) == false)\r
6537         {\r
6538                 return NewPack();\r
6539         }\r
6540         Zero(&t, sizeof(t));\r
6541 \r
6542         SiEnumMacTable(s, hubname, &t);\r
6543 \r
6544         ret = NewPack();\r
6545         OutRpcEnumMacTable(ret, &t);\r
6546         FreeRpcEnumMacTable(&t);\r
6547 \r
6548         return ret;\r
6549 }\r
6550 \r
6551 // NAT の状況取得指令\r
6552 PACK *SiCalledGetNatStatus(SERVER *s, PACK *p)\r
6553 {\r
6554         char hubname[MAX_HUBNAME_LEN + 1];\r
6555         RPC_NAT_STATUS t;\r
6556         PACK *ret;\r
6557         HUB *h;\r
6558         // 引数チェック\r
6559         if (s == NULL || p == NULL)\r
6560         {\r
6561                 return NewPack();\r
6562         }\r
6563         if (PackGetStr(p, "HubName", hubname, sizeof(hubname)) == false)\r
6564         {\r
6565                 return NewPack();\r
6566         }\r
6567         Zero(&t, sizeof(t));\r
6568 \r
6569         LockHubList(s->Cedar);\r
6570         {\r
6571                 h = GetHub(s->Cedar, hubname);\r
6572         }\r
6573         UnlockHubList(s->Cedar);\r
6574 \r
6575         if (h != NULL)\r
6576         {\r
6577                 Lock(h->lock_online);\r
6578                 {\r
6579                         if (h->SecureNAT != NULL)\r
6580                         {\r
6581                                 NtGetStatus(h->SecureNAT->Nat, &t);\r
6582                         }\r
6583                 }\r
6584                 Unlock(h->lock_online);\r
6585         }\r
6586 \r
6587         ReleaseHub(h);\r
6588 \r
6589         ret = NewPack();\r
6590         OutRpcNatStatus(ret, &t);\r
6591         FreeRpcNatStatus(&t);\r
6592 \r
6593         return ret;\r
6594 }\r
6595 \r
6596 // DHCP テーブル列挙指令\r
6597 PACK *SiCalledEnumDhcp(SERVER *s, PACK *p)\r
6598 {\r
6599         char hubname[MAX_HUBNAME_LEN + 1];\r
6600         RPC_ENUM_DHCP t;\r
6601         PACK *ret;\r
6602         HUB *h;\r
6603         // 引数チェック\r
6604         if (s == NULL || p == NULL)\r
6605         {\r
6606                 return NewPack();\r
6607         }\r
6608         if (PackGetStr(p, "HubName", hubname, sizeof(hubname)) == false)\r
6609         {\r
6610                 return NewPack();\r
6611         }\r
6612         Zero(&t, sizeof(t));\r
6613 \r
6614         LockHubList(s->Cedar);\r
6615         {\r
6616                 h = GetHub(s->Cedar, hubname);\r
6617         }\r
6618         UnlockHubList(s->Cedar);\r
6619 \r
6620         if (h != NULL)\r
6621         {\r
6622                 Lock(h->lock_online);\r
6623                 {\r
6624                         if (h->SecureNAT != NULL)\r
6625                         {\r
6626                                 NtEnumDhcpList(h->SecureNAT->Nat, &t);\r
6627                         }\r
6628                 }\r
6629                 Unlock(h->lock_online);\r
6630         }\r
6631 \r
6632         ReleaseHub(h);\r
6633 \r
6634         ret = NewPack();\r
6635         OutRpcEnumDhcp(ret, &t);\r
6636         FreeRpcEnumDhcp(&t);\r
6637 \r
6638         return ret;\r
6639 }\r
6640 \r
6641 // NAT テーブル列挙指令\r
6642 PACK *SiCalledEnumNat(SERVER *s, PACK *p)\r
6643 {\r
6644         char hubname[MAX_HUBNAME_LEN + 1];\r
6645         RPC_ENUM_NAT t;\r
6646         PACK *ret;\r
6647         HUB *h;\r
6648         // 引数チェック\r
6649         if (s == NULL || p == NULL)\r
6650         {\r
6651                 return NewPack();\r
6652         }\r
6653         if (PackGetStr(p, "HubName", hubname, sizeof(hubname)) == false)\r
6654         {\r
6655                 return NewPack();\r
6656         }\r
6657         Zero(&t, sizeof(t));\r
6658 \r
6659         LockHubList(s->Cedar);\r
6660         {\r
6661                 h = GetHub(s->Cedar, hubname);\r
6662         }\r
6663         UnlockHubList(s->Cedar);\r
6664 \r
6665         if (h != NULL)\r
6666         {\r
6667                 Lock(h->lock_online);\r
6668                 {\r
6669                         if (h->SecureNAT != NULL)\r
6670                         {\r
6671                                 NtEnumNatList(h->SecureNAT->Nat, &t);\r
6672                         }\r
6673                 }\r
6674                 Unlock(h->lock_online);\r
6675         }\r
6676 \r
6677         ReleaseHub(h);\r
6678 \r
6679         ret = NewPack();\r
6680         OutRpcEnumNat(ret, &t);\r
6681         FreeRpcEnumNat(&t);\r
6682 \r
6683         return ret;\r
6684 }\r
6685 \r
6686 // セッション列挙指令受信\r
6687 PACK *SiCalledEnumSession(SERVER *s, PACK *p)\r
6688 {\r
6689         char hubname[MAX_HUBNAME_LEN + 1];\r
6690         RPC_ENUM_SESSION t;\r
6691         PACK *ret;\r
6692         // 引数チェック\r
6693         if (s == NULL || p == NULL)\r
6694         {\r
6695                 return NewPack();\r
6696         }\r
6697         if (PackGetStr(p, "HubName", hubname, sizeof(hubname)) == false)\r
6698         {\r
6699                 return NewPack();\r
6700         }\r
6701         Zero(&t, sizeof(t));\r
6702 \r
6703         SiEnumLocalSession(s, hubname, &t);\r
6704 \r
6705         ret = NewPack();\r
6706         OutRpcEnumSession(ret, &t);\r
6707         FreeRpcEnumSession(&t);\r
6708 \r
6709         return ret;\r
6710 }\r
6711 \r
6712 // チケット作成指令受信\r
6713 PACK *SiCalledCreateTicket(SERVER *s, PACK *p)\r
6714 {\r
6715         char username[MAX_SIZE];\r
6716         char hubname[MAX_SIZE];\r
6717         char groupname[MAX_SIZE];\r
6718         char realusername[MAX_SIZE];\r
6719         char sessionname[MAX_SESSION_NAME_LEN + 1];\r
6720         POLICY policy;\r
6721         UCHAR ticket[SHA1_SIZE];\r
6722         char ticket_str[MAX_SIZE];\r
6723         HUB *h;\r
6724         UINT i;\r
6725         PACK *ret;\r
6726         TICKET *t;\r
6727         // 引数チェック\r
6728         if (s == NULL || p == NULL)\r
6729         {\r
6730                 return NewPack();\r
6731         }\r
6732 \r
6733         PackGetStr(p, "UserName", username, sizeof(username));\r
6734         PackGetStr(p, "GroupName", groupname, sizeof(groupname));\r
6735         PackGetStr(p, "HubName", hubname, sizeof(hubname));\r
6736         PackGetStr(p, "RealUserName", realusername, sizeof(realusername));\r
6737         PackGetStr(p, "SessionName", sessionname, sizeof(sessionname));\r
6738 \r
6739         InRpcPolicy(&policy, p);\r
6740         if (PackGetDataSize(p, "Ticket") == SHA1_SIZE)\r
6741         {\r
6742                 PackGetData(p, "Ticket", ticket);\r
6743         }\r
6744 \r
6745         BinToStr(ticket_str, sizeof(ticket_str), ticket, SHA1_SIZE);\r
6746 \r
6747         SLog(s->Cedar, "LS_TICKET_2", hubname, username, realusername, sessionname,\r
6748                 ticket_str, TICKET_EXPIRES / 1000);\r
6749 \r
6750         // HUB を取得\r
6751         h = GetHub(s->Cedar, hubname);\r
6752         if (h == NULL)\r
6753         {\r
6754                 return NewPack();\r
6755         }\r
6756 \r
6757         LockList(h->TicketList);\r
6758         {\r
6759                 LIST *o = NewListFast(NULL);\r
6760                 // 古いチケットを破棄\r
6761                 for (i = 0;i < LIST_NUM(h->TicketList);i++)\r
6762                 {\r
6763                         TICKET *t = LIST_DATA(h->TicketList, i);\r
6764                         if ((t->CreatedTick + TICKET_EXPIRES) < Tick64())\r
6765                         {\r
6766                                 Add(o, t);\r
6767                         }\r
6768                 }\r
6769                 for (i = 0;i < LIST_NUM(o);i++)\r
6770                 {\r
6771                         TICKET *t = LIST_DATA(o, i);\r
6772                         Delete(h->TicketList, t);\r
6773                         Free(t);\r
6774                 }\r
6775                 ReleaseList(o);\r
6776 \r
6777                 // チケットを作成\r
6778                 t = ZeroMalloc(sizeof(TICKET));\r
6779                 t->CreatedTick = Tick64();\r
6780                 Copy(&t->Policy, &policy, sizeof(POLICY));\r
6781                 Copy(t->Ticket, ticket, SHA1_SIZE);\r
6782                 StrCpy(t->Username, sizeof(t->Username), username);\r
6783                 StrCpy(t->UsernameReal, sizeof(t->UsernameReal), realusername);\r
6784                 StrCpy(t->GroupName, sizeof(t->GroupName), groupname);\r
6785                 StrCpy(t->SessionName, sizeof(t->SessionName), sessionname);\r
6786 \r
6787                 Add(h->TicketList, t);\r
6788         }\r
6789         UnlockList(h->TicketList);\r
6790 \r
6791         ReleaseHub(h);\r
6792 \r
6793         ret = NewPack();\r
6794 \r
6795         PackAddInt(ret, "Point", SiGetPoint(s));\r
6796 \r
6797         return ret;\r
6798 }\r
6799 \r
6800 // HUB 作成指令受信\r
6801 void SiCalledCreateHub(SERVER *s, PACK *p)\r
6802 {\r
6803         char name[MAX_SIZE];\r
6804         UINT type;\r
6805         HUB_OPTION o;\r
6806         HUB_LOG log;\r
6807         bool save_packet_log;\r
6808         UINT packet_log_switch_type;\r
6809         UINT packet_log_config[NUM_PACKET_LOG];\r
6810         bool save_security_log;\r
6811         UINT security_log_switch_type;\r
6812         UINT i;\r
6813         HUB *h;\r
6814         // 引数チェック\r
6815         if (s == NULL || p == NULL)\r
6816         {\r
6817                 return;\r
6818         }\r
6819 \r
6820         PackGetStr(p, "HubName", name, sizeof(name));\r
6821         type = PackGetInt(p, "HubType");\r
6822         Zero(&o, sizeof(o));\r
6823         o.MaxSession = PackGetInt(p, "MaxSession");\r
6824         save_packet_log = PackGetInt(p, "SavePacketLog");\r
6825         packet_log_switch_type = PackGetInt(p, "PacketLogSwitchType");\r
6826         for (i = 0;i < NUM_PACKET_LOG;i++)\r
6827         {\r
6828                 packet_log_config[i] = PackGetIntEx(p, "PacketLogConfig", i);\r
6829         }\r
6830         save_security_log = PackGetInt(p, "SaveSecurityLog");\r
6831         security_log_switch_type = PackGetInt(p, "SecurityLogSwitchType");\r
6832 \r
6833         Zero(&log, sizeof(log));\r
6834         log.SavePacketLog = save_packet_log;\r
6835         log.PacketLogSwitchType = packet_log_switch_type;\r
6836         Copy(log.PacketLogConfig, packet_log_config, sizeof(log.PacketLogConfig));\r
6837         log.SaveSecurityLog = save_security_log;\r
6838         log.SecurityLogSwitchType = security_log_switch_type;\r
6839 \r
6840         h = NewHub(s->Cedar, name, &o);\r
6841         h->LastCommTime = h->LastLoginTime = h->CreatedTime = 0;\r
6842         SetHubLogSetting(h, &log);\r
6843         h->Type = type;\r
6844         h->FarmMember_MaxSessionClient = PackGetInt(p, "MaxSessionClient");\r
6845         h->FarmMember_MaxSessionBridge = PackGetInt(p, "MaxSessionBridge");\r
6846         h->FarmMember_MaxSessionClientBridgeApply = PackGetBool(p, "MaxSessionClientBridgeApply");\r
6847 \r
6848         if (h->FarmMember_MaxSessionClientBridgeApply == false)\r
6849         {\r
6850                 h->FarmMember_MaxSessionClient = INFINITE;\r
6851                 h->FarmMember_MaxSessionBridge = INFINITE;\r
6852         }\r
6853 \r
6854         PackGetData2(p, "SecurePassword", h->SecurePassword, SHA1_SIZE);\r
6855         PackGetData2(p, "HashedPassword", h->HashedPassword, SHA1_SIZE);\r
6856 \r
6857         for (i = 0;i < SiNumAccessFromPack(p);i++)\r
6858         {\r
6859                 ACCESS *a = SiPackToAccess(p, i);\r
6860                 AddAccessList(h, a);\r
6861                 Free(a);\r
6862         }\r
6863 \r
6864         if (PackGetBool(p, "EnableSecureNAT"))\r
6865         {\r
6866                 VH_OPTION t;\r
6867 \r
6868                 InVhOption(&t, p);\r
6869 \r
6870                 Copy(h->SecureNATOption, &t, sizeof(VH_OPTION));\r
6871                 EnableSecureNAT(h, true);\r
6872 \r
6873                 Debug("SiCalledCreateHub: SecureNAT Created.\n");\r
6874         }\r
6875 \r
6876         AddHub(s->Cedar, h);\r
6877         h->Offline = true;\r
6878         SetHubOnline(h);\r
6879 \r
6880         ReleaseHub(h);\r
6881 }\r
6882 \r
6883 // ファームコントロールスレッド\r
6884 void SiFarmControlThread(THREAD *thread, void *param)\r
6885 {\r
6886         SERVER *s;\r
6887         CEDAR *c;\r
6888         EVENT *e;\r
6889         LIST *o;\r
6890         UINT i;\r
6891         char tmp[MAX_PATH];\r
6892         // 引数チェック\r
6893         if (thread == NULL || param == NULL)\r
6894         {\r
6895                 return;\r
6896         }\r
6897 \r
6898         s = (SERVER *)param;\r
6899         c = s->Cedar;\r
6900         e = s->FarmControlThreadHaltEvent;\r
6901 \r
6902         while (true)\r
6903         {\r
6904                 Lock(c->CedarSuperLock);\r
6905 \r
6906                 // 各ファームメンバーがホストしている HUB 一覧を列挙する\r
6907                 Format(tmp, sizeof(tmp), "CONTROLLER: %s %u", __FILE__, __LINE__);\r
6908                 SiDebugLog(s, tmp);\r
6909 \r
6910                 LockList(s->FarmMemberList);\r
6911                 {\r
6912                         UINT i;\r
6913                         UINT num;\r
6914                         UINT assigned_client_license = 0;\r
6915                         UINT assigned_bridge_license = 0;\r
6916 \r
6917                         Format(tmp, sizeof(tmp), "CONTROLLER: %s %u", __FILE__, __LINE__);\r
6918                         SiDebugLog(s, tmp);\r
6919 \r
6920                         num = 0;\r
6921 \r
6922                         for (i = 0;i < LIST_NUM(s->FarmMemberList);i++)\r
6923                         {\r
6924                                 FARM_MEMBER *f = LIST_DATA(s->FarmMemberList, i);\r
6925                                 SiCallEnumHub(s, f);\r
6926                                 // サーバーファーム全体での合計セッション数を取得する\r
6927                                 num += f->NumSessions;\r
6928 \r
6929                                 assigned_client_license += f->AssignedClientLicense;\r
6930                                 assigned_bridge_license += f->AssignedBridgeLicense;\r
6931                         }\r
6932 \r
6933                         s->CurrentTotalNumSessionsOnFarm = num;\r
6934 \r
6935                         // 割り当て済みライセンス数を更新する\r
6936                         s->CurrentAssignedBridgeLicense = assigned_bridge_license;\r
6937                         s->CurrentAssignedClientLicense = assigned_client_license;\r
6938 \r
6939                         Format(tmp, sizeof(tmp), "CONTROLLER: %s %u", __FILE__, __LINE__);\r
6940                         SiDebugLog(s, tmp);\r
6941                 }\r
6942                 UnlockList(s->FarmMemberList);\r
6943 \r
6944                 Format(tmp, sizeof(tmp), "CONTROLLER: %s %u", __FILE__, __LINE__);\r
6945                 SiDebugLog(s, tmp);\r
6946 \r
6947                 o = NewListFast(NULL);\r
6948 \r
6949                 Format(tmp, sizeof(tmp), "CONTROLLER: %s %u", __FILE__, __LINE__);\r
6950                 SiDebugLog(s, tmp);\r
6951 \r
6952                 // 各 HUB に対して更新通知を発する\r
6953                 LockList(c->HubList);\r
6954                 {\r
6955                         UINT i;\r
6956                         for (i = 0;i < LIST_NUM(c->HubList);i++)\r
6957                         {\r
6958                                 HUB *h = LIST_DATA(c->HubList, i);\r
6959                                 AddRef(h->ref);\r
6960                                 Add(o, h);\r
6961                         }\r
6962                 }\r
6963                 UnlockList(c->HubList);\r
6964 \r
6965                 Format(tmp, sizeof(tmp), "CONTROLLER: %s %u", __FILE__, __LINE__);\r
6966                 SiDebugLog(s, tmp);\r
6967 \r
6968                 for (i = 0;i < LIST_NUM(o);i++)\r
6969                 {\r
6970                         HUB *h = LIST_DATA(o, i);\r
6971                         SiHubUpdateProc(h);\r
6972                         ReleaseHub(h);\r
6973                 }\r
6974 \r
6975                 Format(tmp, sizeof(tmp), "CONTROLLER: %s %u", __FILE__, __LINE__);\r
6976                 SiDebugLog(s, tmp);\r
6977 \r
6978                 ReleaseList(o);\r
6979 \r
6980                 Unlock(c->CedarSuperLock);\r
6981 \r
6982                 Wait(e, SERVER_FARM_CONTROL_INTERVAL);\r
6983                 if (s->Halt)\r
6984                 {\r
6985                         break;\r
6986                 }\r
6987         }\r
6988 }\r
6989 \r
6990 // ファームコントロールの開始\r
6991 void SiStartFarmControl(SERVER *s)\r
6992 {\r
6993         // 引数チェック\r
6994         if (s == NULL || s->ServerType != SERVER_TYPE_FARM_CONTROLLER)\r
6995         {\r
6996                 return;\r
6997         }\r
6998 \r
6999         s->FarmControlThreadHaltEvent = NewEvent();\r
7000         s->FarmControlThread = NewThread(SiFarmControlThread, s);\r
7001 }\r
7002 \r
7003 // ファームコントロールの終了\r
7004 void SiStopFarmControl(SERVER *s)\r
7005 {\r
7006         // 引数チェック\r
7007         if (s == NULL || s->ServerType != SERVER_TYPE_FARM_CONTROLLER)\r
7008         {\r
7009                 return;\r
7010         }\r
7011 \r
7012         Set(s->FarmControlThreadHaltEvent);\r
7013         WaitThread(s->FarmControlThread, INFINITE);\r
7014         ReleaseEvent(s->FarmControlThreadHaltEvent);\r
7015         ReleaseThread(s->FarmControlThread);\r
7016 }\r
7017 \r
7018 // HUB 列挙指令\r
7019 void SiCallEnumHub(SERVER *s, FARM_MEMBER *f)\r
7020 {\r
7021         CEDAR *c;\r
7022         // 引数チェック\r
7023         if (s == NULL || f == NULL)\r
7024         {\r
7025                 return;\r
7026         }\r
7027 \r
7028         c = s->Cedar;\r
7029 \r
7030         if (f->Me)\r
7031         {\r
7032                 LICENSE_STATUS st;\r
7033 \r
7034                 LiParseCurrentLicenseStatus(s->LicenseSystem, &st);\r
7035 \r
7036                 // ローカルの HUB を列挙する\r
7037                 LockList(f->HubList);\r
7038                 {\r
7039                         // ローカル HUB の場合、まず STATIC HUB リストを一旦\r
7040                         // すべて消去して再列挙を行うようにする\r
7041                         UINT i;\r
7042                         LIST *o = NewListFast(NULL);\r
7043                         for (i = 0;i < LIST_NUM(f->HubList);i++)\r
7044                         {\r
7045                                 HUB_LIST *h = LIST_DATA(f->HubList, i);\r
7046                                 if (h->DynamicHub == false)\r
7047                                 {\r
7048                                         Add(o, h);\r
7049                                 }\r
7050                         }\r
7051 \r
7052                         // STATIC HUB をすべて消去\r
7053                         for (i = 0;i < LIST_NUM(o);i++)\r
7054                         {\r
7055                                 HUB_LIST *h = LIST_DATA(o, i);\r
7056                                 Free(h);\r
7057                                 Delete(f->HubList, h);\r
7058                         }\r
7059                         ReleaseList(o);\r
7060 \r
7061                         // 次に DYNAMIC HUB でユーザーが 1 人もいないものを停止する\r
7062                         o = NewListFast(NULL);\r
7063                         for (i = 0;i < LIST_NUM(f->HubList);i++)\r
7064                         {\r
7065                                 HUB_LIST *h = LIST_DATA(f->HubList, i);\r
7066                                 if (h->DynamicHub == true)\r
7067                                 {\r
7068                                         LockList(c->HubList);\r
7069                                         {\r
7070                                                 HUB *hub = GetHub(s->Cedar, h->Name);\r
7071                                                 if (hub != NULL)\r
7072                                                 {\r
7073                                                         if (Count(hub->NumSessions) == 0 || hub->Type != HUB_TYPE_FARM_DYNAMIC)\r
7074                                                         {\r
7075                                                                 Add(o, h);\r
7076                                                         }\r
7077                                                         ReleaseHub(hub);\r
7078                                                 }\r
7079                                         }\r
7080                                         UnlockList(c->HubList);\r
7081                                 }\r
7082                         }\r
7083 \r
7084                         for (i = 0;i < LIST_NUM(o);i++)\r
7085                         {\r
7086                                 HUB_LIST *h = LIST_DATA(o, i);\r
7087                                 Debug("Delete HUB: %s\n", h->Name);\r
7088                                 Free(h);\r
7089                                 Delete(f->HubList, h);\r
7090                         }\r
7091 \r
7092                         ReleaseList(o);\r
7093 \r
7094                         // 列挙結果を設定\r
7095                         LockList(c->HubList);\r
7096                         {\r
7097                                 for (i = 0;i < LIST_NUM(c->HubList);i++)\r
7098                                 {\r
7099                                         HUB *h = LIST_DATA(c->HubList, i);\r
7100                                         if (h->Offline == false)\r
7101                                         {\r
7102                                                 if (h->Type == HUB_TYPE_FARM_STATIC)\r
7103                                                 {\r
7104                                                         HUB_LIST *hh = ZeroMalloc(sizeof(HUB_LIST));\r
7105                                                         hh->FarmMember = f;\r
7106                                                         hh->DynamicHub = false;\r
7107                                                         StrCpy(hh->Name, sizeof(hh->Name), h->Name);\r
7108                                                         Add(f->HubList, hh);\r
7109 \r
7110                                                         LockList(h->SessionList);\r
7111                                                         {\r
7112                                                                 hh->NumSessions = LIST_NUM(h->SessionList);\r
7113                                                                 hh->NumSessionsBridge = Count(h->NumSessionsBridge);\r
7114                                                                 hh->NumSessionsClient = Count(h->NumSessionsClient);\r
7115                                                         }\r
7116                                                         UnlockList(h->SessionList);\r
7117 \r
7118                                                         LockList(h->MacTable);\r
7119                                                         {\r
7120                                                                 hh->NumMacTables = LIST_NUM(h->MacTable);\r
7121                                                         }\r
7122                                                         UnlockList(h->MacTable);\r
7123 \r
7124                                                         LockList(h->IpTable);\r
7125                                                         {\r
7126                                                                 hh->NumIpTables = LIST_NUM(h->IpTable);\r
7127                                                         }\r
7128                                                         UnlockList(h->IpTable);\r
7129                                                 }\r
7130                                         }\r
7131                                 }\r
7132                         }\r
7133                         UnlockList(c->HubList);\r
7134                 }\r
7135                 UnlockList(f->HubList);\r
7136 \r
7137                 // ポイント\r
7138                 f->Point = SiGetPoint(s);\r
7139                 f->NumSessions = Count(s->Cedar->CurrentSessions);\r
7140                 f->MaxSessions = GetServerCapsInt(s, "i_max_sessions");\r
7141                 f->NumTcpConnections = Count(s->Cedar->CurrentTcpConnections);\r
7142 \r
7143                 Lock(s->Cedar->TrafficLock);\r
7144                 {\r
7145                         Copy(&f->Traffic, s->Cedar->Traffic, sizeof(TRAFFIC));\r
7146                 }\r
7147                 Unlock(s->Cedar->TrafficLock);\r
7148 \r
7149                 f->AssignedBridgeLicense = Count(s->Cedar->AssignedBridgeLicense);\r
7150                 f->AssignedClientLicense = Count(s->Cedar->AssignedClientLicense);\r
7151 \r
7152                 Copy(f->RandomKey, s->MyRandomKey, SHA1_SIZE);\r
7153                 f->SystemId = st.SystemId;\r
7154 \r
7155                 Debug("Server %s: Point %u\n", f->hostname, f->Point);\r
7156         }\r
7157         else\r
7158         {\r
7159                 // リモートのメンバの HUB を列挙する\r
7160                 PACK *p = NewPack();\r
7161                 UINT i, num, j;\r
7162                 LIST *o = NewListFast(NULL);\r
7163 \r
7164                 num = 0;\r
7165 \r
7166                 for (i = 0;i < LIST_NUM(s->FarmMemberList);i++)\r
7167                 {\r
7168                         FARM_MEMBER *f = LIST_DATA(s->FarmMemberList, i);\r
7169 \r
7170                         if (IsZero(f->RandomKey, SHA1_SIZE) == false && f->SystemId != 0)\r
7171                         {\r
7172                                 num++;\r
7173                         }\r
7174                 }\r
7175 \r
7176                 j = 0;\r
7177 \r
7178                 for (i = 0;i < LIST_NUM(s->FarmMemberList);i++)\r
7179                 {\r
7180                         FARM_MEMBER *f = LIST_DATA(s->FarmMemberList, i);\r
7181 \r
7182                         if (IsZero(f->RandomKey, SHA1_SIZE) == false && f->SystemId != 0)\r
7183                         {\r
7184                                 PackAddDataEx(p, "MemberRandomKey", f->RandomKey, SHA1_SIZE, j, num);\r
7185                                 PackAddInt64Ex(p, "MemberSystemId", f->SystemId, j, num);\r
7186                                 j++;\r
7187                         }\r
7188                 }\r
7189                 PackAddInt(p, "MemberSystemIdNum", num);\r
7190 \r
7191                 p = SiCallTask(f, p, "enumhub");\r
7192                 if (p != NULL)\r
7193                 {\r
7194                         LockList(f->HubList);\r
7195                         {\r
7196                                 UINT i;\r
7197                                 // リスト消去\r
7198                                 for (i = 0;i < LIST_NUM(f->HubList);i++)\r
7199                                 {\r
7200                                         HUB_LIST *hh = LIST_DATA(f->HubList, i);\r
7201                                         Free(hh);\r
7202                                 }\r
7203                                 DeleteAll(f->HubList);\r
7204 \r
7205                                 for (i = 0;i < PackGetIndexCount(p, "HubName");i++)\r
7206                                 {\r
7207                                         HUB_LIST *hh = ZeroMalloc(sizeof(HUB_LIST));\r
7208                                         UINT num;\r
7209                                         UINT64 LastCommTime;\r
7210 \r
7211                                         PackGetStrEx(p, "HubName", hh->Name, sizeof(hh->Name), i);\r
7212                                         num = PackGetIntEx(p, "NumSession", i);\r
7213                                         hh->DynamicHub = ((PackGetIntEx(p, "HubType", i) == HUB_TYPE_FARM_DYNAMIC) ? true : false);\r
7214                                         hh->FarmMember = f;\r
7215                                         hh->NumSessions = PackGetIntEx(p, "NumSessions", i);\r
7216                                         hh->NumSessionsClient = PackGetIntEx(p, "NumSessionsClient", i);\r
7217                                         hh->NumSessionsBridge = PackGetIntEx(p, "NumSessionsBridge", i);\r
7218                                         hh->NumIpTables = PackGetIntEx(p, "NumIpTables", i);\r
7219                                         hh->NumMacTables = PackGetIntEx(p, "NumMacTables", i);\r
7220                                         LastCommTime = PackGetInt64Ex(p, "LastCommTime", i);\r
7221                                         Add(f->HubList, hh);\r
7222                                         Debug("%s\n", hh->Name);\r
7223 \r
7224                                         LockList(c->HubList);\r
7225                                         {\r
7226                                                 HUB *h = GetHub(c, hh->Name);\r
7227 \r
7228                                                 if (h != NULL)\r
7229                                                 {\r
7230                                                         // 仮想 HUB の LastCommTime を更新する\r
7231                                                         Lock(h->lock);\r
7232                                                         {\r
7233                                                                 if (h->LastCommTime < LastCommTime)\r
7234                                                                 {\r
7235                                                                         h->LastCommTime = LastCommTime;\r
7236                                                                 }\r
7237                                                         }\r
7238                                                         Unlock(h->lock);\r
7239 \r
7240                                                         ReleaseHub(h);\r
7241                                                 }\r
7242                                         }\r
7243                                         UnlockList(c->HubList);\r
7244 \r
7245                                         if (hh->DynamicHub && num >= 1)\r
7246                                         {\r
7247                                                 // すでにユーザーセッションが 1 以上接続されているので\r
7248                                                 // 仮想 HUB 作成履歴リストに登録しておく必要はない\r
7249                                                 // 仮想 HUB 作成履歴リストから削除する\r
7250                                                 SiDelHubCreateHistory(s, hh->Name);\r
7251                                         }\r
7252 \r
7253                                         if (hh->DynamicHub && num == 0)\r
7254                                         {\r
7255                                                 // 仮想 HUB 作成履歴リストを確認する\r
7256                                                 // 直近 60 秒以内に作成され、まだ 1 人目のユーザーが接続\r
7257                                                 // していない仮想 HUB の場合は、ユーザーが 1 人もいないという\r
7258                                                 // 理由で削除しない\r
7259                                                 if (SiIsHubRegistedOnCreateHistory(s, hh->Name) == false)\r
7260                                                 {\r
7261                                                         // ダイナミック HUB でユーザーが 1 人もいないので停止する\r
7262                                                         HUB *h;\r
7263                                                         LockList(c->HubList);\r
7264                                                         {\r
7265                                                                 h = GetHub(c, hh->Name);\r
7266                                                         }\r
7267                                                         UnlockList(c->HubList);\r
7268 \r
7269                                                         if (h != NULL)\r
7270                                                         {\r
7271                                                                 Add(o, h);\r
7272                                                         }\r
7273                                                 }\r
7274                                         }\r
7275                                 }\r
7276                         }\r
7277                         UnlockList(f->HubList);\r
7278                         f->Point = PackGetInt(p, "Point");\r
7279                         Debug("Server %s: Point %u\n", f->hostname, f->Point);\r
7280                         f->NumSessions = PackGetInt(p, "NumTotalSessions");\r
7281                         if (f->NumSessions == 0)\r
7282                         {\r
7283                                 f->NumSessions = PackGetInt(p, "NumSessions");\r
7284                         }\r
7285                         f->MaxSessions = PackGetInt(p, "MaxSessions");\r
7286                         f->NumTcpConnections = PackGetInt(p, "NumTcpConnections");\r
7287                         InRpcTraffic(&f->Traffic, p);\r
7288 \r
7289                         f->AssignedBridgeLicense = PackGetInt(p, "AssignedBridgeLicense");\r
7290                         f->AssignedClientLicense = PackGetInt(p, "AssignedClientLicense");\r
7291 \r
7292                         if (PackGetDataSize(p, "RandomKey") == SHA1_SIZE)\r
7293                         {\r
7294                                 PackGetData(p, "RandomKey", f->RandomKey);\r
7295                         }\r
7296 \r
7297                         f->SystemId = PackGetInt64(p, "SystemId");\r
7298 \r
7299                         // トラフィック差分情報を適用する\r
7300                         num = PackGetIndexCount(p, "TdType");\r
7301                         for (i = 0;i < num;i++)\r
7302                         {\r
7303                                 TRAFFIC traffic;\r
7304                                 UINT type;\r
7305                                 HUB *h;\r
7306                                 char name[MAX_SIZE];\r
7307                                 char hubname[MAX_SIZE];\r
7308 \r
7309                                 type = PackGetIntEx(p, "TdType", i);\r
7310                                 PackGetStrEx(p, "TdName", name, sizeof(name), i);\r
7311                                 PackGetStrEx(p, "TdHubName", hubname, sizeof(hubname), i);\r
7312                                 InRpcTrafficEx(&traffic, p, i);\r
7313 \r
7314                                 LockList(c->HubList);\r
7315                                 {\r
7316                                         h = GetHub(c, hubname);\r
7317                                         if (h != NULL)\r
7318                                         {\r
7319                                                 if (type == TRAFFIC_DIFF_HUB)\r
7320                                                 {\r
7321                                                         Lock(h->TrafficLock);\r
7322                                                         {\r
7323                                                                 AddTraffic(h->Traffic, &traffic);\r
7324                                                         }\r
7325                                                         Unlock(h->TrafficLock);\r
7326                                                 }\r
7327                                                 else\r
7328                                                 {\r
7329                                                         AcLock(h);\r
7330                                                         {\r
7331                                                                 USER *u = AcGetUser(h, name);\r
7332                                                                 if (u != NULL)\r
7333                                                                 {\r
7334                                                                         Lock(u->lock);\r
7335                                                                         {\r
7336                                                                                 AddTraffic(u->Traffic, &traffic);\r
7337                                                                         }\r
7338                                                                         Unlock(u->lock);\r
7339                                                                         if (u->Group != NULL)\r
7340                                                                         {\r
7341                                                                                 Lock(u->Group->lock);\r
7342                                                                                 {\r
7343                                                                                         AddTraffic(u->Group->Traffic, &traffic);\r
7344                                                                                 }\r
7345                                                                                 Unlock(u->Group->lock);\r
7346                                                                         }\r
7347                                                                         ReleaseUser(u);\r
7348                                                                 }\r
7349                                                         }\r
7350                                                         AcUnlock(h);\r
7351                                                 }\r
7352                                                 ReleaseHub(h);\r
7353                                         }\r
7354                                         UnlockList(c->HubList);\r
7355                                 }\r
7356                         }\r
7357 \r
7358                         FreePack(p);\r
7359                 }\r
7360 \r
7361                 for (i = 0;i < LIST_NUM(o);i++)\r
7362                 {\r
7363                         HUB *h = LIST_DATA(o, i);\r
7364                         SiCallDeleteHub(s, f, h);\r
7365                         Debug("Delete HUB: %s\n", h->Name);\r
7366                         ReleaseHub(h);\r
7367                 }\r
7368 \r
7369                 ReleaseList(o);\r
7370         }\r
7371 }\r
7372 \r
7373 // セッション情報取得指令\r
7374 bool SiCallGetSessionStatus(SERVER *s, FARM_MEMBER *f, RPC_SESSION_STATUS *t)\r
7375 {\r
7376         PACK *p;\r
7377         // 引数チェック\r
7378         if (s == NULL || f == NULL)\r
7379         {\r
7380                 return false;\r
7381         }\r
7382 \r
7383         p = NewPack();\r
7384         OutRpcSessionStatus(p, t);\r
7385         FreeRpcSessionStatus(t);\r
7386         Zero(t, sizeof(RPC_SESSION_STATUS));\r
7387 \r
7388         p = SiCallTask(f, p, "getsessionstatus");\r
7389 \r
7390         if (p == NULL)\r
7391         {\r
7392                 return false;\r
7393         }\r
7394 \r
7395         InRpcSessionStatus(t, p);\r
7396         FreePack(p);\r
7397 \r
7398         return true;\r
7399 }\r
7400 \r
7401 // ログファイル読み込み指令\r
7402 bool SiCallReadLogFile(SERVER *s, FARM_MEMBER *f, RPC_READ_LOG_FILE *t)\r
7403 {\r
7404         PACK *p;\r
7405         // 引数チェック\r
7406         if (s == NULL || f == NULL)\r
7407         {\r
7408                 return false;\r
7409         }\r
7410 \r
7411         p = NewPack();\r
7412         OutRpcReadLogFile(p, t);\r
7413         FreeRpcReadLogFile(t);\r
7414         Zero(t, sizeof(RPC_READ_LOG_FILE));\r
7415 \r
7416         p = SiCallTask(f, p, "readlogfile");\r
7417 \r
7418         if (p == NULL)\r
7419         {\r
7420                 return false;\r
7421         }\r
7422 \r
7423         InRpcReadLogFile(t, p);\r
7424         FreePack(p);\r
7425 \r
7426         return true;\r
7427 }\r
7428 \r
7429 // ログファイルリスト列挙指令\r
7430 bool SiCallEnumLogFileList(SERVER *s, FARM_MEMBER *f, RPC_ENUM_LOG_FILE *t, char *hubname)\r
7431 {\r
7432         PACK *p;\r
7433         // 引数チェック\r
7434         if (s == NULL || f == NULL)\r
7435         {\r
7436                 return false;\r
7437         }\r
7438 \r
7439         p = NewPack();\r
7440         OutRpcEnumLogFile(p, t);\r
7441         FreeRpcEnumLogFile(t);\r
7442         Zero(t, sizeof(RPC_ENUM_LOG_FILE));\r
7443 \r
7444         PackAddStr(p, "HubName", hubname);\r
7445 \r
7446         p = SiCallTask(f, p, "enumlogfilelist");\r
7447 \r
7448         if (p == NULL)\r
7449         {\r
7450                 return false;\r
7451         }\r
7452 \r
7453         InRpcEnumLogFile(t, p);\r
7454         FreePack(p);\r
7455 \r
7456         return true;\r
7457 }\r
7458 \r
7459 // HUB 削除指令\r
7460 void SiCallDeleteHub(SERVER *s, FARM_MEMBER *f, HUB *h)\r
7461 {\r
7462         PACK *p;\r
7463         UINT i;\r
7464         // 引数チェック\r
7465         if (s == NULL || f == NULL)\r
7466         {\r
7467                 return;\r
7468         }\r
7469 \r
7470         if (f->Me == false)\r
7471         {\r
7472                 p = NewPack();\r
7473 \r
7474                 PackAddStr(p, "HubName", h->Name);\r
7475 \r
7476                 p = SiCallTask(f, p, "deletehub");\r
7477                 FreePack(p);\r
7478         }\r
7479 \r
7480         LockList(f->HubList);\r
7481         {\r
7482                 for (i = 0;i < LIST_NUM(f->HubList);i++)\r
7483                 {\r
7484                         HUB_LIST *hh = LIST_DATA(f->HubList, i);\r
7485                         if (StrCmpi(hh->Name, h->Name) == 0)\r
7486                         {\r
7487                                 Free(hh);\r
7488                                 Delete(f->HubList, hh);\r
7489                         }\r
7490                 }\r
7491         }\r
7492         UnlockList(f->HubList);\r
7493 }\r
7494 \r
7495 // HUB 更新指令送信\r
7496 void SiCallUpdateHub(SERVER *s, FARM_MEMBER *f, HUB *h)\r
7497 {\r
7498         PACK *p;\r
7499         // 引数チェック\r
7500         if (s == NULL || f == NULL)\r
7501         {\r
7502                 return;\r
7503         }\r
7504 \r
7505         if (f->Me == false)\r
7506         {\r
7507                 p = NewPack();\r
7508 \r
7509                 SiPackAddCreateHub(p, h);\r
7510 \r
7511                 p = SiCallTask(f, p, "updatehub");\r
7512                 FreePack(p);\r
7513         }\r
7514 }\r
7515 \r
7516 // チケット作成指令送信\r
7517 void SiCallCreateTicket(SERVER *s, FARM_MEMBER *f, char *hubname, char *username, char *realusername, POLICY *policy, UCHAR *ticket, UINT counter, char *groupname)\r
7518 {\r
7519         PACK *p;\r
7520         char name[MAX_SESSION_NAME_LEN + 1];\r
7521         char hub_name_upper[MAX_SIZE];\r
7522         char user_name_upper[MAX_USERNAME_LEN + 1];\r
7523         char ticket_str[MAX_SIZE];\r
7524         UINT point;\r
7525         // 引数チェック\r
7526         if (s == NULL || f == NULL || realusername == NULL || hubname == NULL || username == NULL || policy == NULL || ticket == NULL)\r
7527         {\r
7528                 return;\r
7529         }\r
7530         if (groupname == NULL)\r
7531         {\r
7532                 groupname = "";\r
7533         }\r
7534 \r
7535         p = NewPack();\r
7536         PackAddStr(p, "HubName", hubname);\r
7537         PackAddStr(p, "UserName", username);\r
7538         PackAddStr(p, "groupname", groupname);\r
7539         PackAddStr(p, "RealUserName", realusername);\r
7540         OutRpcPolicy(p, policy);\r
7541         PackAddData(p, "Ticket", ticket, SHA1_SIZE);\r
7542 \r
7543         BinToStr(ticket_str, sizeof(ticket_str), ticket, SHA1_SIZE);\r
7544 \r
7545         StrCpy(hub_name_upper, sizeof(hub_name_upper), hubname);\r
7546         StrUpper(hub_name_upper);\r
7547         StrCpy(user_name_upper, sizeof(user_name_upper), username);\r
7548         StrUpper(user_name_upper);\r
7549         Format(name, sizeof(name), "SID-%s-%u", user_name_upper,\r
7550                 counter);\r
7551         PackAddStr(p, "SessionName", name);\r
7552 \r
7553         p = SiCallTask(f, p, "createticket");\r
7554 \r
7555         SLog(s->Cedar, "LS_TICKET_1", f->hostname, hubname, username, realusername, name, ticket_str);\r
7556 \r
7557         point = PackGetInt(p, "Point");\r
7558         if (point != 0)\r
7559         {\r
7560                 f->Point = point;\r
7561                 f->NumSessions++;\r
7562         }\r
7563 \r
7564         FreePack(p);\r
7565 }\r
7566 \r
7567 // MAC アドレス削除指令送信\r
7568 void SiCallDeleteMacTable(SERVER *s, FARM_MEMBER *f, char *hubname, UINT key)\r
7569 {\r
7570         PACK *p;\r
7571         // 引数チェック\r
7572         if (s == NULL || f == NULL || hubname == NULL)\r
7573         {\r
7574                 return;\r
7575         }\r
7576 \r
7577         p = NewPack();\r
7578         PackAddStr(p, "HubName", hubname);\r
7579         PackAddInt(p, "Key", key);\r
7580 \r
7581         p = SiCallTask(f, p, "deletemactable");\r
7582 \r
7583         FreePack(p);\r
7584 }\r
7585 \r
7586 // IP アドレス削除指令送信\r
7587 void SiCallDeleteIpTable(SERVER *s, FARM_MEMBER *f, char *hubname, UINT key)\r
7588 {\r
7589         PACK *p;\r
7590         // 引数チェック\r
7591         if (s == NULL || f == NULL || hubname == NULL)\r
7592         {\r
7593                 return;\r
7594         }\r
7595 \r
7596         p = NewPack();\r
7597         PackAddStr(p, "HubName", hubname);\r
7598         PackAddInt(p, "Key", key);\r
7599 \r
7600         p = SiCallTask(f, p, "deleteiptable");\r
7601 \r
7602         FreePack(p);\r
7603 }\r
7604 \r
7605 // セッション削除指令送信\r
7606 void SiCallDeleteSession(SERVER *s, FARM_MEMBER *f, char *hubname, char *session_name)\r
7607 {\r
7608         PACK *p;\r
7609         // 引数チェック\r
7610         if (s == NULL || f == NULL || hubname == NULL || session_name == NULL)\r
7611         {\r
7612                 return;\r
7613         }\r
7614 \r
7615         p = NewPack();\r
7616         PackAddStr(p, "HubName", hubname);\r
7617         PackAddStr(p, "SessionName", session_name);\r
7618 \r
7619         p = SiCallTask(f, p, "deletesession");\r
7620 \r
7621         FreePack(p);\r
7622 }\r
7623 \r
7624 // IP テーブル列挙指令送信\r
7625 void SiCallEnumIpTable(SERVER *s, FARM_MEMBER *f, char *hubname, RPC_ENUM_IP_TABLE *t)\r
7626 {\r
7627         PACK *p;\r
7628         UINT i;\r
7629         // 引数チェック\r
7630         if (s == NULL || f == NULL || hubname == NULL || t == NULL)\r
7631         {\r
7632                 return;\r
7633         }\r
7634 \r
7635         p = NewPack();\r
7636         PackAddStr(p, "HubName", hubname);\r
7637 \r
7638         p = SiCallTask(f, p, "enumiptable");\r
7639 \r
7640         Zero(t, sizeof(RPC_ENUM_IP_TABLE));\r
7641         InRpcEnumIpTable(t, p);\r
7642 \r
7643         for (i = 0;i < t->NumIpTable;i++)\r
7644         {\r
7645                 t->IpTables[i].RemoteItem = true;\r
7646                 StrCpy(t->IpTables[i].RemoteHostname, sizeof(t->IpTables[i].RemoteHostname),\r
7647                         f->hostname);\r
7648         }\r
7649 \r
7650         FreePack(p);\r
7651 }\r
7652 \r
7653 // MAC テーブル列挙指令送信\r
7654 void SiCallEnumMacTable(SERVER *s, FARM_MEMBER *f, char *hubname, RPC_ENUM_MAC_TABLE *t)\r
7655 {\r
7656         PACK *p;\r
7657         UINT i;\r
7658         // 引数チェック\r
7659         if (s == NULL || f == NULL || hubname == NULL || t == NULL)\r
7660         {\r
7661                 return;\r
7662         }\r
7663 \r
7664         p = NewPack();\r
7665         PackAddStr(p, "HubName", hubname);\r
7666 \r
7667         p = SiCallTask(f, p, "enummactable");\r
7668 \r
7669         Zero(t, sizeof(RPC_ENUM_MAC_TABLE));\r
7670         InRpcEnumMacTable(t, p);\r
7671 \r
7672         for (i = 0;i < t->NumMacTable;i++)\r
7673         {\r
7674                 t->MacTables[i].RemoteItem = true;\r
7675                 StrCpy(t->MacTables[i].RemoteHostname, sizeof(t->MacTables[i].RemoteHostname),\r
7676                         f->hostname);\r
7677         }\r
7678 \r
7679         FreePack(p);\r
7680 }\r
7681 \r
7682 // SecureNAT 状況の取得指令送信\r
7683 void SiCallGetNatStatus(SERVER *s, FARM_MEMBER *f, char *hubname, RPC_NAT_STATUS *t)\r
7684 {\r
7685         PACK *p;\r
7686         // 引数チェック\r
7687         if (s == NULL || f == NULL || hubname == NULL || t == NULL)\r
7688         {\r
7689                 return;\r
7690         }\r
7691 \r
7692         p = NewPack();\r
7693         PackAddStr(p, "HubName", hubname);\r
7694 \r
7695         p = SiCallTask(f, p, "getnatstatus");\r
7696 \r
7697         Zero(t, sizeof(RPC_NAT_STATUS));\r
7698         InRpcNatStatus(t, p);\r
7699 \r
7700         FreePack(p);\r
7701 }\r
7702 \r
7703 // DHCP エントリ列挙指令送信\r
7704 void SiCallEnumDhcp(SERVER *s, FARM_MEMBER *f, char *hubname, RPC_ENUM_DHCP *t)\r
7705 {\r
7706         PACK *p;\r
7707         // 引数チェック\r
7708         if (s == NULL || f == NULL || hubname == NULL || t == NULL)\r
7709         {\r
7710                 return;\r
7711         }\r
7712 \r
7713         p = NewPack();\r
7714         PackAddStr(p, "HubName", hubname);\r
7715 \r
7716         p = SiCallTask(f, p, "enumdhcp");\r
7717 \r
7718         Zero(t, sizeof(RPC_ENUM_DHCP));\r
7719         InRpcEnumDhcp(t, p);\r
7720 \r
7721         FreePack(p);\r
7722 }\r
7723 \r
7724 // NAT エントリ列挙指令送信\r
7725 void SiCallEnumNat(SERVER *s, FARM_MEMBER *f, char *hubname, RPC_ENUM_NAT *t)\r
7726 {\r
7727         PACK *p;\r
7728         // 引数チェック\r
7729         if (s == NULL || f == NULL || hubname == NULL || t == NULL)\r
7730         {\r
7731                 return;\r
7732         }\r
7733 \r
7734         p = NewPack();\r
7735         PackAddStr(p, "HubName", hubname);\r
7736 \r
7737         p = SiCallTask(f, p, "enumnat");\r
7738 \r
7739         Zero(t, sizeof(RPC_ENUM_NAT));\r
7740         InRpcEnumNat(t, p);\r
7741 \r
7742         FreePack(p);\r
7743 }\r
7744 \r
7745 // セッション列挙指令送信\r
7746 void SiCallEnumSession(SERVER *s, FARM_MEMBER *f, char *hubname, RPC_ENUM_SESSION *t)\r
7747 {\r
7748         PACK *p;\r
7749         UINT i;\r
7750         // 引数チェック\r
7751         if (s == NULL || f == NULL || hubname == NULL || t == NULL)\r
7752         {\r
7753                 return;\r
7754         }\r
7755 \r
7756         p = NewPack();\r
7757         PackAddStr(p, "HubName", hubname);\r
7758 \r
7759         p = SiCallTask(f, p, "enumsession");\r
7760 \r
7761         Zero(t, sizeof(RPC_ENUM_SESSION));\r
7762         InRpcEnumSession(t, p);\r
7763 \r
7764         for (i = 0;i < t->NumSession;i++)\r
7765         {\r
7766                 t->Sessions[i].RemoteSession = true;\r
7767                 StrCpy(t->Sessions[i].RemoteHostname, sizeof(t->Sessions[i].RemoteHostname),\r
7768                         f->hostname);\r
7769         }\r
7770 \r
7771         FreePack(p);\r
7772 }\r
7773 \r
7774 // HUB 作成指令送信\r
7775 void SiCallCreateHub(SERVER *s, FARM_MEMBER *f, HUB *h)\r
7776 {\r
7777         PACK *p;\r
7778         HUB_LIST *hh;\r
7779         // 引数チェック\r
7780         if (s == NULL || f == NULL)\r
7781         {\r
7782                 return;\r
7783         }\r
7784 \r
7785         if (f->Me == false)\r
7786         {\r
7787                 p = NewPack();\r
7788 \r
7789                 SiPackAddCreateHub(p, h);\r
7790 \r
7791                 p = SiCallTask(f, p, "createhub");\r
7792                 FreePack(p);\r
7793         }\r
7794 \r
7795         hh = ZeroMalloc(sizeof(HUB_LIST));\r
7796         hh->DynamicHub = (h->Type == HUB_TYPE_FARM_DYNAMIC ? true : false);\r
7797         StrCpy(hh->Name, sizeof(hh->Name), h->Name);\r
7798         hh->FarmMember = f;\r
7799 \r
7800         LockList(f->HubList);\r
7801         {\r
7802                 bool exists = false;\r
7803                 UINT i;\r
7804                 for (i = 0;i < LIST_NUM(f->HubList);i++)\r
7805                 {\r
7806                         HUB_LIST *t = LIST_DATA(f->HubList, i);\r
7807                         if (StrCmpi(t->Name, hh->Name) == 0)\r
7808                         {\r
7809                                 exists = true;\r
7810                         }\r
7811                 }\r
7812                 if (exists == false)\r
7813                 {\r
7814                         Add(f->HubList, hh);\r
7815                 }\r
7816                 else\r
7817                 {\r
7818                         Free(hh);\r
7819                 }\r
7820         }\r
7821         UnlockList(f->HubList);\r
7822 }\r
7823 \r
7824 // HUB 作成用 PACK の書き込み\r
7825 void SiPackAddCreateHub(PACK *p, HUB *h)\r
7826 {\r
7827         UINT i;\r
7828         UINT max_session;\r
7829         SERVER *s;\r
7830         LICENSE_STATUS license;\r
7831         // 引数チェック\r
7832         if (p == NULL || h == NULL)\r
7833         {\r
7834                 return;\r
7835         }\r
7836 \r
7837         Zero(&license, sizeof(license));\r
7838         s = h->Cedar->Server;\r
7839         if (s != NULL)\r
7840         {\r
7841                 LiParseCurrentLicenseStatus(s->LicenseSystem, &license);\r
7842         }\r
7843 \r
7844         PackAddStr(p, "HubName", h->Name);\r
7845         PackAddInt(p, "HubType", h->Type);\r
7846 \r
7847         max_session = h->Option->MaxSession;\r
7848 \r
7849         if (GetHubAdminOption(h, "max_sessions") != 0)\r
7850         {\r
7851                 if (max_session == 0)\r
7852                 {\r
7853                         max_session = GetHubAdminOption(h, "max_sessions");\r
7854                 }\r
7855                 else\r
7856                 {\r
7857                         max_session = MIN(max_session, GetHubAdminOption(h, "max_sessions"));\r
7858                 }\r
7859         }\r
7860 \r
7861         PackAddInt(p, "MaxSession", max_session);\r
7862 \r
7863         if (GetHubAdminOption(h, "max_sessions_client_bridge_apply") != 0 || license.CarrierEdition)\r
7864         {\r
7865                 PackAddInt(p, "MaxSessionClient", GetHubAdminOption(h, "max_sessions_client"));\r
7866                 PackAddInt(p, "MaxSessionBridge", GetHubAdminOption(h, "max_sessions_bridge"));\r
7867                 PackAddBool(p, "MaxSessionClientBridgeApply", true);\r
7868         }\r
7869         else\r
7870         {\r
7871                 PackAddInt(p, "MaxSessionClient", INFINITE);\r
7872                 PackAddInt(p, "MaxSessionBridge", INFINITE);\r
7873         }\r
7874 \r
7875         PackAddBool(p, "NoArpPolling", h->Option->NoArpPolling);\r
7876         PackAddBool(p, "NoIPv6AddrPolling", h->Option->NoIPv6AddrPolling);\r
7877         PackAddBool(p, "NoIpTable", h->Option->NoIpTable);\r
7878         PackAddBool(p, "NoEnum", h->Option->NoEnum);\r
7879         PackAddBool(p, "FilterPPPoE", h->Option->FilterPPPoE);\r
7880         PackAddBool(p, "YieldAfterStorePacket", h->Option->YieldAfterStorePacket);\r
7881         PackAddBool(p, "NoSpinLockForPacketDelay", h->Option->NoSpinLockForPacketDelay);\r
7882         PackAddInt(p, "BroadcastStormDetectionThreshold", h->Option->BroadcastStormDetectionThreshold);\r
7883         PackAddInt(p, "ClientMinimumRequiredBuild", h->Option->ClientMinimumRequiredBuild);\r
7884         PackAddBool(p, "FixForDLinkBPDU", h->Option->FixForDLinkBPDU);\r
7885         PackAddBool(p, "NoLookBPDUBridgeId", h->Option->NoLookBPDUBridgeId);\r
7886         PackAddBool(p, "NoManageVlanId", h->Option->NoManageVlanId);\r
7887         PackAddInt(p, "VlanTypeId", h->Option->VlanTypeId);\r
7888         PackAddBool(p, "FilterOSPF", h->Option->FilterOSPF);\r
7889         PackAddBool(p, "FilterIPv4", h->Option->FilterIPv4);\r
7890         PackAddBool(p, "FilterIPv6", h->Option->FilterIPv6);\r
7891         PackAddBool(p, "FilterNonIP", h->Option->FilterNonIP);\r
7892         PackAddBool(p, "NoIPv4PacketLog", h->Option->NoIPv4PacketLog);\r
7893         PackAddBool(p, "NoIPv6PacketLog", h->Option->NoIPv6PacketLog);\r
7894         PackAddBool(p, "FilterBPDU", h->Option->FilterBPDU);\r
7895         PackAddBool(p, "NoIPv6DefaultRouterInRAWhenIPv6", h->Option->NoIPv6DefaultRouterInRAWhenIPv6);\r
7896         PackAddBool(p, "NoMacAddressLog", h->Option->NoMacAddressLog);\r
7897         PackAddBool(p, "ManageOnlyPrivateIP", h->Option->ManageOnlyPrivateIP);\r
7898         PackAddBool(p, "ManageOnlyLocalUnicastIPv6", h->Option->ManageOnlyLocalUnicastIPv6);\r
7899         PackAddBool(p, "DisableIPParsing", h->Option->DisableIPParsing);\r
7900 \r
7901         PackAddInt(p, "SavePacketLog", h->LogSetting.SavePacketLog);\r
7902         PackAddInt(p, "PacketLogSwitchType", h->LogSetting.PacketLogSwitchType);\r
7903         for (i = 0;i < NUM_PACKET_LOG;i++)\r
7904         {\r
7905                 PackAddIntEx(p, "PacketLogConfig", h->LogSetting.PacketLogConfig[i], i, NUM_PACKET_LOG);\r
7906         }\r
7907         PackAddInt(p, "SaveSecurityLog", h->LogSetting.SaveSecurityLog);\r
7908         PackAddInt(p, "SecurityLogSwitchType", h->LogSetting.SecurityLogSwitchType);\r
7909         PackAddData(p, "HashedPassword", h->HashedPassword, SHA1_SIZE);\r
7910         PackAddData(p, "SecurePassword", h->SecurePassword, SHA1_SIZE);\r
7911 \r
7912         SiAccessListToPack(p, h->AccessList);\r
7913 \r
7914         if (h->EnableSecureNAT)\r
7915         {\r
7916                 PackAddBool(p, "EnableSecureNAT", h->EnableSecureNAT);\r
7917                 OutVhOption(p, h->SecureNATOption);\r
7918         }\r
7919 }\r
7920 \r
7921 // HUB の設定が更新された\r
7922 void SiHubUpdateProc(HUB *h)\r
7923 {\r
7924         SERVER *s;\r
7925         UINT i;\r
7926         // 引数チェック\r
7927         if (h == NULL || h->Cedar->Server == NULL || h->Cedar->Server->ServerType != SERVER_TYPE_FARM_CONTROLLER)\r
7928         {\r
7929                 return;\r
7930         }\r
7931 \r
7932         s = h->Cedar->Server;\r
7933 \r
7934         if (s->FarmMemberList == NULL)\r
7935         {\r
7936                 return;\r
7937         }\r
7938 \r
7939         if (h->LastVersion != h->CurrentVersion || h->CurrentVersion == 0)\r
7940         {\r
7941                 if (h->CurrentVersion == 0)\r
7942                 {\r
7943                         h->CurrentVersion = 1;\r
7944                 }\r
7945                 h->LastVersion = h->CurrentVersion;\r
7946 \r
7947                 LockList(s->FarmMemberList);\r
7948                 {\r
7949                         // すべてのメンバで HUB を更新する\r
7950                         for (i = 0;i < LIST_NUM(s->FarmMemberList);i++)\r
7951                         {\r
7952                                 FARM_MEMBER *f = LIST_DATA(s->FarmMemberList, i);\r
7953                                 if (f->Me == false)\r
7954                                 {\r
7955                                         SiCallUpdateHub(s, f, h);\r
7956                                 }\r
7957                         }\r
7958                 }\r
7959                 UnlockList(s->FarmMemberList);\r
7960         }\r
7961 \r
7962         if (h->Offline == false)\r
7963         {\r
7964                 SiHubOnlineProc(h);\r
7965         }\r
7966 }\r
7967 \r
7968 // HUB がオンラインになった\r
7969 void SiHubOnlineProc(HUB *h)\r
7970 {\r
7971         SERVER *s;\r
7972         UINT i;\r
7973         // 引数チェック\r
7974         if (h == NULL || h->Cedar->Server == NULL || h->Cedar->Server->ServerType != SERVER_TYPE_FARM_CONTROLLER)\r
7975         {\r
7976                 // ファームコントローラ以外では処理しない\r
7977                 return;\r
7978         }\r
7979 \r
7980         s = h->Cedar->Server;\r
7981 \r
7982         if (s->FarmMemberList == NULL)\r
7983         {\r
7984                 return;\r
7985         }\r
7986 \r
7987         LockList(s->FarmMemberList);\r
7988         {\r
7989                 if (h->Type == HUB_TYPE_FARM_STATIC)\r
7990                 {\r
7991                         // スタティック HUB\r
7992                         // すべてのメンバで HUB を作成する\r
7993                         for (i = 0;i < LIST_NUM(s->FarmMemberList);i++)\r
7994                         {\r
7995                                 UINT j;\r
7996                                 bool exists = false;\r
7997                                 FARM_MEMBER *f = LIST_DATA(s->FarmMemberList, i);\r
7998 \r
7999                                 LockList(f->HubList);\r
8000                                 {\r
8001                                         for (j = 0;j < LIST_NUM(f->HubList);j++)\r
8002                                         {\r
8003                                                 HUB_LIST *hh = LIST_DATA(f->HubList, j);\r
8004                                                 if (StrCmpi(hh->Name, h->Name) == 0)\r
8005                                                 {\r
8006                                                         exists = true;\r
8007                                                 }\r
8008                                         }\r
8009                                 }\r
8010                                 UnlockList(f->HubList);\r
8011 \r
8012                                 if (exists == false)\r
8013                                 {\r
8014                                         SiCallCreateHub(s, f, h);\r
8015                                 }\r
8016                         }\r
8017                 }\r
8018         }\r
8019         UnlockList(s->FarmMemberList);\r
8020 }\r
8021 \r
8022 // HUB がオフラインになった\r
8023 void SiHubOfflineProc(HUB *h)\r
8024 {\r
8025         SERVER *s;\r
8026         char hubname[MAX_HUBNAME_LEN + 1];\r
8027         UINT i;\r
8028         // 引数チェック\r
8029         if (h == NULL || h->Cedar->Server == NULL || h->Cedar->Server->ServerType != SERVER_TYPE_FARM_CONTROLLER)\r
8030         {\r
8031                 // ファームコントローラ以外では処理しない\r
8032                 return;\r
8033         }\r
8034 \r
8035         s = h->Cedar->Server;\r
8036 \r
8037         if (s->FarmMemberList == NULL)\r
8038         {\r
8039                 return;\r
8040         }\r
8041 \r
8042         StrCpy(hubname, sizeof(hubname), h->Name);\r
8043 \r
8044         LockList(s->FarmMemberList);\r
8045         {\r
8046                 // すべてのメンバで HUB を停止する\r
8047                 for (i = 0;i < LIST_NUM(s->FarmMemberList);i++)\r
8048                 {\r
8049                         FARM_MEMBER *f = LIST_DATA(s->FarmMemberList, i);\r
8050                         SiCallDeleteHub(s, f, h);\r
8051                 }\r
8052         }\r
8053         UnlockList(s->FarmMemberList);\r
8054 }\r
8055 \r
8056 // アクセスを PACK に変換する\r
8057 void SiAccessToPack(PACK *p, ACCESS *a, UINT i, UINT total)\r
8058 {\r
8059         // 引数チェック\r
8060         if (p == NULL || a == NULL)\r
8061         {\r
8062                 return;\r
8063         }\r
8064 \r
8065         PackAddUniStrEx(p, "Note", a->Note, i, total);\r
8066         PackAddIntEx(p, "Active", a->Active, i, total);\r
8067         PackAddIntEx(p, "Priority", a->Priority, i, total);\r
8068         PackAddIntEx(p, "Discard", a->Discard, i, total);\r
8069         if (a->IsIPv6)\r
8070         {\r
8071                 PackAddIp32Ex(p, "SrcIpAddress", 0xFDFFFFDF, i, total);\r
8072                 PackAddIp32Ex(p, "SrcSubnetMask", 0xFFFFFFFF, i, total);\r
8073                 PackAddIp32Ex(p, "DestIpAddress", 0xFDFFFFDF, i, total);\r
8074                 PackAddIp32Ex(p, "DestSubnetMask", 0xFFFFFFFF, i, total);\r
8075         }\r
8076         else\r
8077         {\r
8078                 PackAddIp32Ex(p, "SrcIpAddress", a->SrcIpAddress, i, total);\r
8079                 PackAddIp32Ex(p, "SrcSubnetMask", a->SrcSubnetMask, i, total);\r
8080                 PackAddIp32Ex(p, "DestIpAddress", a->DestIpAddress, i, total);\r
8081                 PackAddIp32Ex(p, "DestSubnetMask", a->DestSubnetMask, i, total);\r
8082         }\r
8083         PackAddIntEx(p, "Protocol", a->Protocol, i, total);\r
8084         PackAddIntEx(p, "SrcPortStart", a->SrcPortStart, i, total);\r
8085         PackAddIntEx(p, "SrcPortEnd", a->SrcPortEnd, i, total);\r
8086         PackAddIntEx(p, "DestPortStart", a->DestPortStart, i, total);\r
8087         PackAddIntEx(p, "DestPortEnd", a->DestPortEnd, i, total);\r
8088         PackAddStrEx(p, "SrcUsername", a->SrcUsername, i, total);\r
8089         PackAddStrEx(p, "DestUsername", a->DestUsername, i, total);\r
8090         PackAddBoolEx(p, "CheckSrcMac", a->CheckSrcMac, i, total);\r
8091         PackAddDataEx(p, "SrcMacAddress", a->SrcMacAddress, sizeof(a->SrcMacAddress), i, total);\r
8092         PackAddDataEx(p, "SrcMacMask", a->SrcMacMask, sizeof(a->SrcMacMask), i, total);\r
8093         PackAddBoolEx(p, "CheckDstMac", a->CheckDstMac, i, total);\r
8094         PackAddDataEx(p, "DstMacAddress", a->DstMacAddress, sizeof(a->DstMacAddress), i, total);\r
8095         PackAddDataEx(p, "DstMacMask", a->DstMacMask, sizeof(a->DstMacMask), i, total);\r
8096         PackAddBoolEx(p, "CheckTcpState", a->CheckTcpState, i, total);\r
8097         PackAddBoolEx(p, "Established", a->Established, i, total);\r
8098         PackAddIntEx(p, "Delay", a->Delay, i, total);\r
8099         PackAddIntEx(p, "Jitter", a->Jitter, i, total);\r
8100         PackAddIntEx(p, "Loss", a->Loss, i, total);\r
8101         PackAddBoolEx(p, "IsIPv6", a->IsIPv6, i, total);\r
8102         if (a->IsIPv6)\r
8103         {\r
8104                 PackAddIp6AddrEx(p, "SrcIpAddress6", &a->SrcIpAddress6, i, total);\r
8105                 PackAddIp6AddrEx(p, "SrcSubnetMask6", &a->SrcSubnetMask6, i, total);\r
8106                 PackAddIp6AddrEx(p, "DestIpAddress6", &a->DestIpAddress6, i, total);\r
8107                 PackAddIp6AddrEx(p, "DestSubnetMask6", &a->DestSubnetMask6, i, total);\r
8108         }\r
8109         else\r
8110         {\r
8111                 IPV6_ADDR zero;\r
8112 \r
8113                 Zero(&zero, sizeof(zero));\r
8114 \r
8115                 PackAddIp6AddrEx(p, "SrcIpAddress6", &zero, i, total);\r
8116                 PackAddIp6AddrEx(p, "SrcSubnetMask6", &zero, i, total);\r
8117                 PackAddIp6AddrEx(p, "DestIpAddress6", &zero, i, total);\r
8118                 PackAddIp6AddrEx(p, "DestSubnetMask6", &zero, i, total);\r
8119         }\r
8120 }\r
8121 \r
8122 // PACK に入っているアクセス個数を取得\r
8123 UINT SiNumAccessFromPack(PACK *p)\r
8124 {\r
8125         // 引数チェック\r
8126         if (p == NULL)\r
8127         {\r
8128                 return 0;\r
8129         }\r
8130 \r
8131         return PackGetIndexCount(p, "Active");\r
8132 }\r
8133 \r
8134 // PACK をアクセスに変換する\r
8135 ACCESS *SiPackToAccess(PACK *p, UINT i)\r
8136 {\r
8137         ACCESS *a;\r
8138         // 引数チェック\r
8139         if (p == NULL)\r
8140         {\r
8141                 return NULL;\r
8142         }\r
8143 \r
8144         a = ZeroMalloc(sizeof(ACCESS));\r
8145 \r
8146         PackGetUniStrEx(p, "Note", a->Note, sizeof(a->Note), i);\r
8147         a->Active = PackGetIntEx(p, "Active", i);\r
8148         a->Priority = PackGetIntEx(p, "Priority", i);\r
8149         a->Discard = PackGetIntEx(p, "Discard", i);\r
8150         a->SrcIpAddress = PackGetIp32Ex(p, "SrcIpAddress", i);\r
8151         a->SrcSubnetMask = PackGetIp32Ex(p, "SrcSubnetMask", i);\r
8152         a->DestIpAddress = PackGetIp32Ex(p, "DestIpAddress", i);\r
8153         a->DestSubnetMask = PackGetIp32Ex(p, "DestSubnetMask", i);\r
8154         a->Protocol = PackGetIntEx(p, "Protocol", i);\r
8155         a->SrcPortStart = PackGetIntEx(p, "SrcPortStart", i);\r
8156         a->SrcPortEnd = PackGetIntEx(p, "SrcPortEnd", i);\r
8157         a->DestPortStart = PackGetIntEx(p, "DestPortStart", i);\r
8158         a->DestPortEnd = PackGetIntEx(p, "DestPortEnd", i);\r
8159         PackGetStrEx(p, "SrcUsername", a->SrcUsername, sizeof(a->SrcUsername), i);\r
8160         PackGetStrEx(p, "DestUsername", a->DestUsername, sizeof(a->DestUsername), i);\r
8161         a->CheckSrcMac = PackGetBoolEx(p, "CheckSrcMac", i);\r
8162         PackGetDataEx2(p, "SrcMacAddress", a->SrcMacAddress, sizeof(a->SrcMacAddress), i);\r
8163         PackGetDataEx2(p, "SrcMacMask", a->SrcMacMask, sizeof(a->SrcMacMask), i);\r
8164         a->CheckDstMac = PackGetBoolEx(p, "CheckDstMac", i);\r
8165         PackGetDataEx2(p, "DstMacAddress", a->DstMacAddress, sizeof(a->DstMacAddress), i);\r
8166         PackGetDataEx2(p, "DstMacMask", a->DstMacMask, sizeof(a->DstMacMask), i);\r
8167         a->CheckTcpState = PackGetBoolEx(p, "CheckTcpState", i);\r
8168         a->Established = PackGetBoolEx(p, "Established", i);\r
8169         a->Delay = PackGetIntEx(p, "Delay", i);\r
8170         a->Jitter = PackGetIntEx(p, "Jitter", i);\r
8171         a->Loss = PackGetIntEx(p, "Loss", i);\r
8172         a->IsIPv6 = PackGetBoolEx(p, "IsIPv6", i);\r
8173         if (a->IsIPv6)\r
8174         {\r
8175                 PackGetIp6AddrEx(p, "SrcIpAddress6", &a->SrcIpAddress6, i);\r
8176                 PackGetIp6AddrEx(p, "SrcSubnetMask6", &a->SrcSubnetMask6, i);\r
8177                 PackGetIp6AddrEx(p, "DestIpAddress6", &a->DestIpAddress6, i);\r
8178                 PackGetIp6AddrEx(p, "DestSubnetMask6", &a->DestSubnetMask6, i);\r
8179         }\r
8180 \r
8181         return a;\r
8182 }\r
8183 \r
8184 // アクセスリストを PACK に変換する\r
8185 void SiAccessListToPack(PACK *p, LIST *o)\r
8186 {\r
8187         // 引数チェック\r
8188         if (p == NULL || o == NULL)\r
8189         {\r
8190                 return;\r
8191         }\r
8192 \r
8193         LockList(o);\r
8194         {\r
8195                 UINT i;\r
8196                 for (i = 0;i < LIST_NUM(o);i++)\r
8197                 {\r
8198                         ACCESS *a = LIST_DATA(o, i);\r
8199                         SiAccessToPack(p, a, i, LIST_NUM(o));\r
8200                 }\r
8201         }\r
8202         UnlockList(o);\r
8203 }\r
8204 \r
8205 // 指定した HUB をホストしているメンバを取得する\r
8206 FARM_MEMBER *SiGetHubHostingMember(SERVER *s, HUB *h, bool admin_mode)\r
8207 {\r
8208         FARM_MEMBER *ret = NULL;\r
8209         char name[MAX_SIZE];\r
8210         // 引数チェック\r
8211         if (s == NULL || h == NULL)\r
8212         {\r
8213                 return NULL;\r
8214         }\r
8215 \r
8216         StrCpy(name, sizeof(name), h->Name);\r
8217 \r
8218         if (h->Type == HUB_TYPE_FARM_STATIC)\r
8219         {\r
8220                 // スタティック HUB の場合 任意のメンバを選択すれば良い\r
8221                 if (admin_mode == false)\r
8222                 {\r
8223                         ret = SiGetNextFarmMember(s);\r
8224                 }\r
8225                 else\r
8226                 {\r
8227                         UINT i;\r
8228                         ret = NULL;\r
8229 \r
8230                         for (i = 0;i < LIST_NUM(s->FarmMemberList);i++)\r
8231                         {\r
8232                                 FARM_MEMBER *f = LIST_DATA(s->FarmMemberList, i);\r
8233                                 if (f->Me)\r
8234                                 {\r
8235                                         ret = f;\r
8236                                         break;\r
8237                                 }\r
8238                         }\r
8239                 }\r
8240         }\r
8241         else\r
8242         {\r
8243                 // ダイナミック HUB の場合\r
8244                 // すでに HUB をホストしているメンバがあるかどうか調べる\r
8245                 UINT i;\r
8246 \r
8247                 for (i = 0;i < LIST_NUM(s->FarmMemberList);i++)\r
8248                 {\r
8249                         FARM_MEMBER *f = LIST_DATA(s->FarmMemberList, i);\r
8250                         HUB_LIST *hh, t;\r
8251                         StrCpy(t.Name, sizeof(t.Name), name);\r
8252                         LockList(f->HubList);\r
8253                         {\r
8254                                 hh = Search(f->HubList, &t);\r
8255                                 if (hh != NULL)\r
8256                                 {\r
8257                                         // 発見した\r
8258                                         ret = f;\r
8259                                 }\r
8260                         }\r
8261                         UnlockList(f->HubList);\r
8262                 }\r
8263 \r
8264                 if (ret == NULL)\r
8265                 {\r
8266                         // 新しく HUB をホストさせる\r
8267                         FARM_MEMBER *f;\r
8268 \r
8269                         // ホストさせるメンバの選択\r
8270                         ret = SiGetNextFarmMember(s);\r
8271 \r
8272                         f = ret;\r
8273                         if (f != NULL)\r
8274                         {\r
8275                                 // HUB 作成指令\r
8276                                 SiAddHubCreateHistory(s, name);\r
8277                                 SiCallCreateHub(s, f, h);\r
8278                                 SiCallUpdateHub(s, f, h);\r
8279                         }\r
8280                 }\r
8281         }\r
8282 \r
8283         return ret;\r
8284 }\r
8285 \r
8286 // タスクが呼び出された\r
8287 PACK *SiCalledTask(FARM_CONTROLLER *f, PACK *p, char *taskname)\r
8288 {\r
8289         PACK *ret;\r
8290         SERVER *s;\r
8291         // 引数チェック\r
8292         if (f == NULL || p == NULL || taskname == NULL)\r
8293         {\r
8294                 return NULL;\r
8295         }\r
8296 \r
8297         ret = NULL;\r
8298         s = f->Server;\r
8299 \r
8300         if (StrCmpi(taskname, "noop") == 0)\r
8301         {\r
8302                 // NO OPERATION\r
8303                 ret = NewPack();\r
8304         }\r
8305         else\r
8306         {\r
8307                 Debug("Task Called: [%s].\n", taskname);\r
8308                 if (StrCmpi(taskname, "createhub") == 0)\r
8309                 {\r
8310                         SiCalledCreateHub(s, p);\r
8311                         ret = NewPack();\r
8312                 }\r
8313                 else if (StrCmpi(taskname, "deletehub") == 0)\r
8314                 {\r
8315                         SiCalledDeleteHub(s, p);\r
8316                         ret = NewPack();\r
8317                 }\r
8318                 else if (StrCmpi(taskname, "enumhub") == 0)\r
8319                 {\r
8320                         ret = NewPack();\r
8321                         SiCalledEnumHub(s, ret, p);\r
8322                 }\r
8323                 else if (StrCmpi(taskname, "updatehub") == 0)\r
8324                 {\r
8325                         SiCalledUpdateHub(s, p);\r
8326                         ret = NewPack();\r
8327                 }\r
8328                 else if (StrCmpi(taskname, "createticket") == 0)\r
8329                 {\r
8330                         ret = SiCalledCreateTicket(s, p);\r
8331                 }\r
8332                 else if (StrCmpi(taskname, "enumnat") == 0)\r
8333                 {\r
8334                         ret = SiCalledEnumNat(s, p);\r
8335                 }\r
8336                 else if (StrCmpi(taskname, "enumdhcp") == 0)\r
8337                 {\r
8338                         ret = SiCalledEnumDhcp(s, p);\r
8339                 }\r
8340                 else if (StrCmpi(taskname, "getnatstatus") == 0)\r
8341                 {\r
8342                         ret = SiCalledGetNatStatus(s, p);\r
8343                 }\r
8344                 else if (StrCmpi(taskname, "enumsession") == 0)\r
8345                 {\r
8346                         ret = SiCalledEnumSession(s, p);\r
8347                 }\r
8348                 else if (StrCmpi(taskname, "deletesession") == 0)\r
8349                 {\r
8350                         SiCalledDeleteSession(s, p);\r
8351                         ret = NewPack();\r
8352                 }\r
8353                 else if (StrCmpi(taskname, "deletemactable") == 0)\r
8354                 {\r
8355                         SiCalledDeleteMacTable(s, p);\r
8356                         ret = NewPack();\r
8357                 }\r
8358                 else if (StrCmpi(taskname, "deleteiptable") == 0)\r
8359                 {\r
8360                         SiCalledDeleteIpTable(s, p);\r
8361                         ret = NewPack();\r
8362                 }\r
8363                 else if (StrCmpi(taskname, "enummactable") == 0)\r
8364                 {\r
8365                         ret = SiCalledEnumMacTable(s, p);\r
8366                 }\r
8367                 else if (StrCmpi(taskname, "enumiptable") == 0)\r
8368                 {\r
8369                         ret = SiCalledEnumIpTable(s, p);\r
8370                 }\r
8371                 else if (StrCmpi(taskname, "getsessionstatus") == 0)\r
8372                 {\r
8373                         ret = SiCalledGetSessionStatus(s, p);\r
8374                 }\r
8375                 else if (StrCmpi(taskname, "enumlogfilelist") == 0)\r
8376                 {\r
8377                         ret = SiCalledEnumLogFileList(s, p);\r
8378                 }\r
8379                 else if (StrCmpi(taskname, "readlogfile") == 0)\r
8380                 {\r
8381                         ret = SiCalledReadLogFile(s, p);\r
8382                 }\r
8383         }\r
8384 \r
8385         return ret;\r
8386 }\r
8387 \r
8388 // タスクを呼び出す\r
8389 PACK *SiCallTask(FARM_MEMBER *f, PACK *p, char *taskname)\r
8390 {\r
8391         PACK *ret;\r
8392         char tmp[MAX_PATH];\r
8393         // 引数チェック\r
8394         if (f == NULL || p == NULL || taskname == NULL)\r
8395         {\r
8396                 return NULL;\r
8397         }\r
8398 \r
8399         PackAddStr(p, "taskname", taskname);\r
8400 \r
8401         Debug("Call Task [%s] (%s)\n", taskname, f->hostname);\r
8402 \r
8403         Format(tmp, sizeof(tmp), "CLUSTER_CALL: Entering Call [%s] to %s", taskname, f->hostname);\r
8404         SiDebugLog(f->Cedar->Server, tmp);\r
8405 \r
8406         ret = SiExecTask(f, p);\r
8407 \r
8408         Format(tmp, sizeof(tmp), "CLUSTER_CALL: Leaving Call [%s] to %s", taskname, f->hostname);\r
8409         SiDebugLog(f->Cedar->Server, tmp);\r
8410 \r
8411         return ret;\r
8412 }\r
8413 \r
8414 // タスク待ちうけプロシージャ (メイン処理)\r
8415 void SiAcceptTasksFromControllerMain(FARM_CONTROLLER *f, SOCK *sock)\r
8416 {\r
8417         PACK *request;\r
8418         PACK *response;\r
8419         char taskname[MAX_SIZE];\r
8420         // 引数チェック\r
8421         if (f == NULL || sock == NULL)\r
8422         {\r
8423                 return;\r
8424         }\r
8425 \r
8426         while (true)\r
8427         {\r
8428                 bool ret;\r
8429                 // PACK を受信する\r
8430                 request = HttpClientRecv(sock);\r
8431                 if (request == NULL)\r
8432                 {\r
8433                         // 切断\r
8434                         return;\r
8435                 }\r
8436 \r
8437                 response = NULL;\r
8438 \r
8439                 // 名前の取得\r
8440                 if (PackGetStr(request, "taskname", taskname, sizeof(taskname)))\r
8441                 {\r
8442                         Lock(f->Server->TasksFromFarmControllerLock);\r
8443                         {\r
8444                                 response = SiCalledTask(f, request, taskname);\r
8445                         }\r
8446                         Unlock(f->Server->TasksFromFarmControllerLock);\r
8447                 }\r
8448 \r
8449                 FreePack(request);\r
8450 \r
8451                 // 応答を返す\r
8452                 if (response == NULL)\r
8453                 {\r
8454                         response = NewPack();\r
8455                 }\r
8456                 else\r
8457                 {\r
8458                         PackAddInt(response, "succeed", 1);\r
8459                 }\r
8460 \r
8461                 ret = HttpClientSend(sock, response);\r
8462                 FreePack(response);\r
8463 \r
8464                 if (ret == false)\r
8465                 {\r
8466                         // 切断\r
8467                         return;\r
8468                 }\r
8469         }\r
8470 }\r
8471 \r
8472 // タスク待ちうけプロシージャ\r
8473 void SiAcceptTasksFromController(FARM_CONTROLLER *f, SOCK *sock)\r
8474 {\r
8475         UINT i;\r
8476         HUB **hubs;\r
8477         UINT num_hubs;\r
8478         CEDAR *c;\r
8479         SERVER *s;\r
8480         // 引数チェック\r
8481         if (f == NULL || sock == NULL)\r
8482         {\r
8483                 return;\r
8484         }\r
8485 \r
8486         s = f->Server;\r
8487         c = s->Cedar;\r
8488 \r
8489         // メイン処理\r
8490         SiAcceptTasksFromControllerMain(f, sock);\r
8491 \r
8492         // コントローラとの接続が切断されたためすべての仮想 HUB を停止する\r
8493         LockList(c->HubList);\r
8494         {\r
8495                 hubs = ToArray(c->HubList);\r
8496                 num_hubs = LIST_NUM(c->HubList);\r
8497                 for (i = 0;i < num_hubs;i++)\r
8498                 {\r
8499                         AddRef(hubs[i]->ref);\r
8500                 }\r
8501         }\r
8502         UnlockList(c->HubList);\r
8503 \r
8504         for (i = 0;i < num_hubs;i++)\r
8505         {\r
8506                 SetHubOffline(hubs[i]);\r
8507                 DelHub(c, hubs[i]);\r
8508                 ReleaseHub(hubs[i]);\r
8509         }\r
8510 \r
8511         Free(hubs);\r
8512 }\r
8513 \r
8514 // タスクを実行する\r
8515 PACK *SiExecTask(FARM_MEMBER *f, PACK *p)\r
8516 {\r
8517         FARM_TASK *t;\r
8518         // 引数チェック\r
8519         if (f == NULL || p == NULL)\r
8520         {\r
8521                 return NULL;\r
8522         }\r
8523 \r
8524         t = SiFarmServPostTask(f, p);\r
8525         if (t == NULL)\r
8526         {\r
8527                 return NULL;\r
8528         }\r
8529 \r
8530         return SiFarmServWaitTask(t);\r
8531 }\r
8532 \r
8533 // タスク投入\r
8534 FARM_TASK *SiFarmServPostTask(FARM_MEMBER *f, PACK *request)\r
8535 {\r
8536         FARM_TASK *t;\r
8537         // 引数チェック\r
8538         if (f == NULL || request == NULL)\r
8539         {\r
8540                 return NULL;\r
8541         }\r
8542 \r
8543         t = ZeroMalloc(sizeof(FARM_TASK));\r
8544         t->CompleteEvent = NewEvent();\r
8545         t->Request = request;\r
8546 \r
8547         LockQueue(f->TaskQueue);\r
8548         {\r
8549                 if (f->Halting)\r
8550                 {\r
8551                         // 停止中 (失敗)\r
8552                         UnlockQueue(f->TaskQueue);\r
8553                         ReleaseEvent(t->CompleteEvent);\r
8554                         Free(t);\r
8555                         return NULL;\r
8556                 }\r
8557 \r
8558                 InsertQueue(f->TaskQueue, t);\r
8559         }\r
8560         UnlockQueue(f->TaskQueue);\r
8561 \r
8562         Set(f->TaskPostEvent);\r
8563 \r
8564         return t;\r
8565 }\r
8566 \r
8567 // タスク結果待ち\r
8568 PACK *SiFarmServWaitTask(FARM_TASK *t)\r
8569 {\r
8570         PACK *response;\r
8571         // 引数チェック\r
8572         if (t == NULL)\r
8573         {\r
8574                 return NULL;\r
8575         }\r
8576 \r
8577         Wait(t->CompleteEvent, INFINITE);\r
8578         ReleaseEvent(t->CompleteEvent);\r
8579         FreePack(t->Request);\r
8580 \r
8581         response = t->Response;\r
8582         Free(t);\r
8583 \r
8584         if (PackGetInt(response, "succeed") == 0)\r
8585         {\r
8586                 // 何らかの原因でタスク呼び出しが失敗した\r
8587                 FreePack(response);\r
8588                 return NULL;\r
8589         }\r
8590 \r
8591         return response;\r
8592 }\r
8593 \r
8594 // ファームサーバー処理メイン\r
8595 void SiFarmServMain(SERVER *server, SOCK *sock, FARM_MEMBER *f)\r
8596 {\r
8597         UINT wait_time = SERVER_CONTROL_TCP_TIMEOUT / 2;\r
8598         bool send_noop = false;\r
8599         UINT i;\r
8600         CEDAR *c;\r
8601         // 引数チェック\r
8602         if (server == NULL || sock == NULL || f == NULL)\r
8603         {\r
8604                 Debug("SiFarmServMain Failed.\n");\r
8605                 return;\r
8606         }\r
8607 \r
8608         Debug("SiFarmServMain Started.\n");\r
8609 \r
8610         c = server->Cedar;\r
8611 \r
8612         // メンバがコントローラに接続してきた段階で\r
8613         // すべてのスタティック HUB の作成指令を送信する\r
8614         LockList(c->HubList);\r
8615         {\r
8616                 for (i = 0;i < LIST_NUM(c->HubList);i++)\r
8617                 {\r
8618                         HUB *h = LIST_DATA(c->HubList, i);\r
8619                         if (h->Offline == false)\r
8620                         {\r
8621                                 if (h->Type == HUB_TYPE_FARM_STATIC)\r
8622                                 {\r
8623                                         PACK *p;\r
8624                                         HUB_LIST *hh;\r
8625                                         p = NewPack();\r
8626                                         SiPackAddCreateHub(p, h);\r
8627                                         PackAddStr(p, "taskname", "createhub");\r
8628                                         HttpServerSend(sock, p);\r
8629                                         FreePack(p);\r
8630                                         p = HttpServerRecv(sock);\r
8631                                         FreePack(p);\r
8632 \r
8633                                         p = NewPack();\r
8634                                         SiPackAddCreateHub(p, h);\r
8635                                         PackAddStr(p, "taskname", "updatehub");\r
8636                                         HttpServerSend(sock, p);\r
8637                                         FreePack(p);\r
8638                                         p = HttpServerRecv(sock);\r
8639                                         FreePack(p);\r
8640 \r
8641                                         hh = ZeroMalloc(sizeof(HUB_LIST));\r
8642                                         hh->DynamicHub = false;\r
8643                                         hh->FarmMember = f;\r
8644                                         StrCpy(hh->Name, sizeof(hh->Name), h->Name);\r
8645                                         LockList(f->HubList);\r
8646                                         {\r
8647                                                 Add(f->HubList, hh);\r
8648                                         }\r
8649                                         UnlockList(f->HubList);\r
8650                                 }\r
8651                         }\r
8652                 }\r
8653         }\r
8654         UnlockList(c->HubList);\r
8655 \r
8656         Debug("SiFarmServMain: while (true)\n");\r
8657 \r
8658         while (true)\r
8659         {\r
8660                 FARM_TASK *t;\r
8661                 UINT64 tick;\r
8662 \r
8663                 do\r
8664                 {\r
8665                         // 新しいタスクが到着していないかどうか調べる\r
8666                         LockQueue(f->TaskQueue);\r
8667                         {\r
8668                                 t = GetNext(f->TaskQueue);\r
8669                         }\r
8670                         UnlockQueue(f->TaskQueue);\r
8671 \r
8672                         if (t != NULL)\r
8673                         {\r
8674                                 // このタスクを処理する\r
8675                                 PACK *p = t->Request;\r
8676                                 bool ret;\r
8677 \r
8678                                 // 送信\r
8679                                 ret = HttpServerSend(sock, p);\r
8680                                 send_noop = false;\r
8681 \r
8682                                 if (ret == false)\r
8683                                 {\r
8684                                         // 接続が切れた\r
8685                                         // このタスクをキャンセルする\r
8686                                         Set(t->CompleteEvent);\r
8687                                         goto DISCONNECTED;\r
8688                                 }\r
8689 \r
8690                                 // 受信\r
8691                                 p = HttpServerRecv(sock);\r
8692 \r
8693                                 t->Response = p;\r
8694                                 Set(t->CompleteEvent);\r
8695 \r
8696                                 send_noop = false;\r
8697                         }\r
8698                 }\r
8699                 while (t != NULL);\r
8700 \r
8701                 if (send_noop)\r
8702                 {\r
8703                         // NOOP を送信する\r
8704                         PACK *p;\r
8705                         bool ret;\r
8706                         p = NewPack();\r
8707                         PackAddStr(p, "taskname", "noop");\r
8708 \r
8709                         ret = HttpServerSend(sock, p);\r
8710                         FreePack(p);\r
8711 \r
8712                         if (ret == false)\r
8713                         {\r
8714                                 goto DISCONNECTED;\r
8715                         }\r
8716 \r
8717                         p = HttpServerRecv(sock);\r
8718                         if (p == NULL)\r
8719                         {\r
8720                                 goto DISCONNECTED;\r
8721                         }\r
8722 \r
8723                         FreePack(p);\r
8724                 }\r
8725 \r
8726                 tick = Tick64();\r
8727 \r
8728                 while (true)\r
8729                 {\r
8730                         bool break_flag;\r
8731                         if ((tick + wait_time) <= Tick64())\r
8732                         {\r
8733                                 break;\r
8734                         }\r
8735 \r
8736                         Wait(f->TaskPostEvent, 250);\r
8737 \r
8738                         break_flag = false;\r
8739                         LockQueue(f->TaskQueue);\r
8740                         {\r
8741                                 if (f->TaskQueue->num_item != 0)\r
8742                                 {\r
8743                                         break_flag = true;\r
8744                                 }\r
8745                         }\r
8746                         UnlockQueue(f->TaskQueue);\r
8747 \r
8748                         if (break_flag || f->Halting || server->Halt)\r
8749                         {\r
8750                                 break;\r
8751                         }\r
8752                 }\r
8753                 send_noop = true;\r
8754         }\r
8755 \r
8756 DISCONNECTED:\r
8757 \r
8758         Debug("SiFarmServMain: DISCONNECTED\n");\r
8759 \r
8760         f->Halting = true;\r
8761         // すべての未処理のタスクをキャンセルする\r
8762         LockQueue(f->TaskQueue);\r
8763         {\r
8764                 FARM_TASK *t;\r
8765 \r
8766                 while (t = GetNext(f->TaskQueue))\r
8767                 {\r
8768                         Set(t->CompleteEvent);\r
8769                 }\r
8770         }\r
8771         UnlockQueue(f->TaskQueue);\r
8772 }\r
8773 \r
8774 // ファームメンバからの接続を処理するファームサーバー関数\r
8775 void SiFarmServ(SERVER *server, SOCK *sock, X *cert, UINT ip, UINT num_port, UINT *ports, char *hostname, UINT point, UINT weight, UINT max_sessions)\r
8776 {\r
8777         PACK *p;\r
8778         FARM_MEMBER *f;\r
8779         UINT i;\r
8780         char tmp[MAX_SIZE];\r
8781         // 引数チェック\r
8782         if (server == NULL || sock == NULL || cert == NULL || num_port == 0 || ports == NULL || hostname == NULL)\r
8783         {\r
8784                 return;\r
8785         }\r
8786 \r
8787         if (weight == 0)\r
8788         {\r
8789                 weight = FARM_DEFAULT_WEIGHT;\r
8790         }\r
8791 \r
8792         if (max_sessions == 0)\r
8793         {\r
8794                 max_sessions = SERVER_MAX_SESSIONS;\r
8795         }\r
8796 \r
8797         if (ip == 0)\r
8798         {\r
8799                 // 公開 IP アドレスが指定されていない場合はこのファームメンバサーバーの\r
8800                 // 接続元 IP アドレスを指定する\r
8801                 ip = IPToUINT(&sock->RemoteIP);\r
8802         }\r
8803 \r
8804         IPToStr32(tmp, sizeof(tmp), ip);\r
8805         SLog(server->Cedar, "LS_FARM_SERV_START", tmp, hostname);\r
8806 \r
8807         // 成功を知らせる\r
8808         p = NewPack();\r
8809         HttpServerSend(sock, p);\r
8810         FreePack(p);\r
8811 \r
8812         IPToStr32(tmp, sizeof(tmp), ip);\r
8813         Debug("Farm Member %s Connected. IP: %s\n", hostname, tmp);\r
8814 \r
8815         SetTimeout(sock, SERVER_CONTROL_TCP_TIMEOUT);\r
8816 \r
8817         f = ZeroMalloc(sizeof(FARM_MEMBER));\r
8818         f->Cedar = server->Cedar;\r
8819         f->Ip = ip;\r
8820         f->NumPort = num_port;\r
8821         f->Ports = ports;\r
8822         StrCpy(f->hostname, sizeof(f->hostname), hostname);\r
8823         f->ServerCert = cert;\r
8824         f->ConnectedTime = SystemTime64();\r
8825         f->Weight = weight;\r
8826         f->MaxSessions = max_sessions;\r
8827 \r
8828         f->HubList = NewList(CompareHubList);\r
8829         f->Point = point;\r
8830 \r
8831         f->TaskQueue = NewQueue();\r
8832         f->TaskPostEvent = NewEvent();\r
8833 \r
8834         // リストに追加する\r
8835         LockList(server->FarmMemberList);\r
8836         {\r
8837                 Add(server->FarmMemberList, f);\r
8838         }\r
8839         UnlockList(server->FarmMemberList);\r
8840 \r
8841         // メイン処理\r
8842         SiFarmServMain(server, sock, f);\r
8843 \r
8844         // リストから削除する\r
8845         LockList(server->FarmMemberList);\r
8846         {\r
8847                 Delete(server->FarmMemberList, f);\r
8848         }\r
8849         UnlockList(server->FarmMemberList);\r
8850 \r
8851         ReleaseQueue(f->TaskQueue);\r
8852         ReleaseEvent(f->TaskPostEvent);\r
8853 \r
8854         for (i = 0;i < LIST_NUM(f->HubList);i++)\r
8855         {\r
8856                 HUB_LIST *hh = LIST_DATA(f->HubList, i);\r
8857                 Free(hh);\r
8858         }\r
8859 \r
8860         ReleaseList(f->HubList);\r
8861 \r
8862         Free(f);\r
8863 \r
8864         SLog(server->Cedar, "LS_FARM_SERV_END", hostname);\r
8865 }\r
8866 \r
8867 // HUB リストの検索\r
8868 int CompareHubList(void *p1, void *p2)\r
8869 {\r
8870         HUB_LIST *h1, *h2;\r
8871         if (p1 == NULL || p2 == NULL)\r
8872         {\r
8873                 return 0;\r
8874         }\r
8875         h1 = *(HUB_LIST **)p1;\r
8876         h2 = *(HUB_LIST **)p2;\r
8877         if (h1 == NULL || h2 == NULL)\r
8878         {\r
8879                 return 0;\r
8880         }\r
8881         return StrCmpi(h1->Name, h2->Name);\r
8882 }\r
8883 \r
8884 // コントローラへの接続スレッド\r
8885 void SiConnectToControllerThread(THREAD *thread, void *param)\r
8886 {\r
8887         FARM_CONTROLLER *f;\r
8888         SESSION *s;\r
8889         CONNECTION *c;\r
8890         SERVER *server;\r
8891         bool first_failed;\r
8892         // 引数チェック\r
8893         if (thread == NULL || param == NULL)\r
8894         {\r
8895                 return;\r
8896         }\r
8897 \r
8898 #ifdef  OS_WIN32\r
8899         MsSetThreadPriorityRealtime();\r
8900 #endif  // OS_WIN32\r
8901 \r
8902         f = (FARM_CONTROLLER *)param;\r
8903         f->Thread = thread;\r
8904         AddRef(f->Thread->ref);\r
8905         NoticeThreadInit(thread);\r
8906 \r
8907         f->StartedTime = SystemTime64();\r
8908 \r
8909         server = f->Server;\r
8910 \r
8911         f->StartedTime = SystemTime64();\r
8912 \r
8913         SLog(server->Cedar, "LS_FARM_CONNECT_1", server->ControllerName);\r
8914 \r
8915         first_failed = true;\r
8916 \r
8917         while (true)\r
8918         {\r
8919                 // 接続を試行\r
8920                 CLIENT_OPTION o;\r
8921 \r
8922                 f->LastError = ERR_TRYING_TO_CONNECT;\r
8923 \r
8924                 Zero(&o, sizeof(CLIENT_OPTION));\r
8925                 StrCpy(o.Hostname, sizeof(o.Hostname), server->ControllerName);\r
8926                 o.Port = server->ControllerPort;\r
8927                 f->NumTry++;\r
8928 \r
8929                 Debug("Try to Connect %s (Controller).\n", server->ControllerName);\r
8930 \r
8931                 s = NewRpcSessionEx(server->Cedar, &o, NULL, CEDAR_SERVER_FARM_STR);\r
8932 \r
8933                 if (s != NULL)\r
8934                 {\r
8935                         // 接続成功: 認証データを送信\r
8936                         PACK *p = NewPack();\r
8937                         UCHAR secure_password[SHA1_SIZE];\r
8938                         BUF *b;\r
8939 \r
8940                         c = s->Connection;\r
8941 \r
8942                         Lock(f->lock);\r
8943                         {\r
8944                                 f->Sock = c->FirstSock;\r
8945                                 AddRef(f->Sock->ref);\r
8946                                 SetTimeout(f->Sock, SERVER_CONTROL_TCP_TIMEOUT);\r
8947                         }\r
8948                         Unlock(f->lock);\r
8949 \r
8950                         // メソッド\r
8951                         PackAddStr(p, "method", "farm_connect");\r
8952                         PackAddClientVersion(p, s->Connection);\r
8953 \r
8954                         // パスワード\r
8955                         SecurePassword(secure_password, server->MemberPassword, s->Connection->Random);\r
8956                         PackAddData(p, "SecurePassword", secure_password, sizeof(secure_password));\r
8957 \r
8958                         Lock(server->Cedar->lock);\r
8959                         {\r
8960                                 b = XToBuf(server->Cedar->ServerX, false);\r
8961                         }\r
8962                         Unlock(server->Cedar->lock);\r
8963 \r
8964                         if (b != NULL)\r
8965                         {\r
8966                                 char tmp[MAX_SIZE];\r
8967                                 bool ret;\r
8968                                 UINT i;\r
8969                                 // サーバー証明書\r
8970                                 PackAddBuf(p, "ServerCert", b);\r
8971                                 FreeBuf(b);\r
8972 \r
8973                                 // 最大セッション数\r
8974                                 PackAddInt(p, "MaxSessions", GetServerCapsInt(server, "i_max_sessions"));\r
8975 \r
8976                                 // ポイント\r
8977                                 PackAddInt(p, "Point", SiGetPoint(server));\r
8978                                 PackAddInt(p, "Weight", server->Weight);\r
8979 \r
8980                                 // ホスト名\r
8981                                 GetMachineName(tmp, sizeof(tmp));\r
8982                                 PackAddStr(p, "HostName", tmp);\r
8983 \r
8984                                 // 公開 IP\r
8985                                 PackAddIp32(p, "PublicIp", server->PublicIp);\r
8986 \r
8987                                 // 公開ポート\r
8988                                 for (i = 0;i < server->NumPublicPort;i++)\r
8989                                 {\r
8990                                         PackAddIntEx(p, "PublicPort", server->PublicPorts[i], i, server->NumPublicPort);\r
8991                                 }\r
8992 \r
8993                                 ret = HttpClientSend(c->FirstSock, p);\r
8994 \r
8995                                 if (ret)\r
8996                                 {\r
8997                                         PACK *p;\r
8998                                         UINT err = ERR_PROTOCOL_ERROR;\r
8999 \r
9000                                         first_failed = true;\r
9001                                         p = HttpClientRecv(c->FirstSock);\r
9002                                         if (p != NULL && (err = GetErrorFromPack(p)) == 0)\r
9003                                         {\r
9004                                                 // 接続成功\r
9005                                                 SLog(server->Cedar, "LS_FARM_START");\r
9006                                                 f->CurrentConnectedTime = SystemTime64();\r
9007                                                 if (f->FirstConnectedTime == 0)\r
9008                                                 {\r
9009                                                         f->FirstConnectedTime = SystemTime64();\r
9010                                                 }\r
9011                                                 f->NumConnected++;\r
9012                                                 Debug("Connect Succeed.\n");\r
9013                                                 f->Online = true;\r
9014 \r
9015                                                 // メイン処理\r
9016                                                 SiAcceptTasksFromController(f, c->FirstSock);\r
9017 \r
9018                                                 f->Online = false;\r
9019                                         }\r
9020                                         else\r
9021                                         {\r
9022                                                 // エラー\r
9023                                                 f->LastError = err;\r
9024                                                 SLog(server->Cedar, "LS_FARM_CONNECT_2", server->ControllerName,\r
9025                                                         GetUniErrorStr(err), err);\r
9026                                         }\r
9027                                         FreePack(p);\r
9028                                 }\r
9029                                 else\r
9030                                 {\r
9031                                         f->LastError = ERR_DISCONNECTED;\r
9032 \r
9033                                         if (first_failed)\r
9034                                         {\r
9035                                                 SLog(server->Cedar, "LS_FARM_CONNECT_3", server->ControllerName, RETRY_CONNECT_TO_CONTROLLER_INTERVAL / 1000);\r
9036                                                 first_failed = false;\r
9037                                         }\r
9038                                 }\r
9039                         }\r
9040 \r
9041                         FreePack(p);\r
9042 \r
9043                         // 接続切断\r
9044                         Lock(f->lock);\r
9045                         {\r
9046                                 if (f->Sock != NULL)\r
9047                                 {\r
9048                                         ReleaseSock(f->Sock);\r
9049                                         f->Sock = NULL;\r
9050                                 }\r
9051                         }\r
9052                         Unlock(f->lock);\r
9053 \r
9054                         ReleaseSession(s);\r
9055                         s = NULL;\r
9056 \r
9057                         if (f->LastError == ERR_TRYING_TO_CONNECT)\r
9058                         {\r
9059                                 f->LastError = ERR_DISCONNECTED;\r
9060                         }\r
9061                 }\r
9062                 else\r
9063                 {\r
9064                         // 接続失敗\r
9065                         f->LastError = ERR_CONNECT_TO_FARM_CONTROLLER;\r
9066 \r
9067                         if (first_failed)\r
9068                         {\r
9069                                 SLog(server->Cedar, "LS_FARM_CONNECT_3", server->ControllerName, RETRY_CONNECT_TO_CONTROLLER_INTERVAL / 1000);\r
9070                                 first_failed = false;\r
9071                         }\r
9072                 }\r
9073 \r
9074                 Debug("Controller Disconnected. ERROR = %S\n", _E(f->LastError));\r
9075 \r
9076                 f->NumFailed = f->NumTry - f->NumConnected;\r
9077 \r
9078                 // イベント待機\r
9079                 Wait(f->HaltEvent, RETRY_CONNECT_TO_CONTROLLER_INTERVAL);\r
9080 \r
9081                 if (f->Halt)\r
9082                 {\r
9083                         // 停止フラグ\r
9084                         break;\r
9085                 }\r
9086         }\r
9087 \r
9088         SLog(server->Cedar, "LS_FARM_DISCONNECT");\r
9089 }\r
9090 \r
9091 // コントローラへの接続を切断\r
9092 void SiStopConnectToController(FARM_CONTROLLER *f)\r
9093 {\r
9094         // 引数チェック\r
9095         if (f == NULL)\r
9096         {\r
9097                 return;\r
9098         }\r
9099 \r
9100         f->Halt = true;\r
9101 \r
9102         // 接続を停止\r
9103         Lock(f->lock);\r
9104         {\r
9105                 Disconnect(f->Sock);\r
9106         }\r
9107         Unlock(f->lock);\r
9108 \r
9109         Set(f->HaltEvent);\r
9110 \r
9111         // スレッド停止を待機\r
9112         WaitThread(f->Thread, INFINITE);\r
9113         ReleaseThread(f->Thread);\r
9114 \r
9115         DeleteLock(f->lock);\r
9116         ReleaseEvent(f->HaltEvent);\r
9117 \r
9118         Free(f);\r
9119 }\r
9120 \r
9121 // コントローラへの接続の開始\r
9122 FARM_CONTROLLER *SiStartConnectToController(SERVER *s)\r
9123 {\r
9124         FARM_CONTROLLER *f;\r
9125         THREAD *t;\r
9126         // 引数チェック\r
9127         if (s == NULL)\r
9128         {\r
9129                 return NULL;\r
9130         }\r
9131 \r
9132         f = ZeroMalloc(sizeof(FARM_CONTROLLER));\r
9133         f->Server = s;\r
9134         f->LastError = ERR_TRYING_TO_CONNECT;\r
9135         f->HaltEvent = NewEvent();\r
9136         f->lock = NewLock();\r
9137 \r
9138         t = NewThread(SiConnectToControllerThread, f);\r
9139         WaitThreadInit(t);\r
9140         ReleaseThread(t);\r
9141 \r
9142         return f;\r
9143 }\r
9144 \r
9145 // サーバーの作成\r
9146 SERVER *SiNewServer(bool bridge)\r
9147 {\r
9148         SERVER *s;\r
9149 \r
9150         s = ZeroMalloc(sizeof(SERVER));\r
9151 \r
9152         SiInitHubCreateHistory(s);\r
9153 \r
9154         InitServerCapsCache(s);\r
9155 \r
9156         Rand(s->MyRandomKey, sizeof(s->MyRandomKey));\r
9157 \r
9158         s->lock = NewLock();\r
9159         s->SaveCfgLock = NewLock();\r
9160         s->ref = NewRef();\r
9161         s->Cedar = NewCedar(NULL, NULL);\r
9162         s->Cedar->Server = s;\r
9163         s->Cedar->CheckExpires = true;\r
9164         s->ServerListenerList = NewList(CompareServerListener);\r
9165         s->StartTime = SystemTime64();\r
9166         s->TasksFromFarmControllerLock = NewLock();\r
9167 \r
9168         if (bridge)\r
9169         {\r
9170                 SetCedarVpnBridge(s->Cedar);\r
9171         }\r
9172 \r
9173 #ifdef OS_WIN32\r
9174         if (IsHamMode() == false)\r
9175         {\r
9176                 RegistWindowsFirewallAll();\r
9177         }\r
9178 #endif\r
9179 \r
9180         s->Keep = StartKeep();\r
9181 \r
9182         // ログ関係\r
9183         MakeDir(bridge == false ? SERVER_LOG_DIR_NAME : BRIDGE_LOG_DIR_NAME);\r
9184         s->Logger = NewLog(bridge == false ? SERVER_LOG_DIR_NAME : BRIDGE_LOG_DIR_NAME, SERVER_LOG_PERFIX, LOG_SWITCH_DAY);\r
9185 \r
9186         SLog(s->Cedar, "L_LINE");\r
9187         SLog(s->Cedar, "LS_START_2", s->Cedar->ServerStr, s->Cedar->VerString);\r
9188         SLog(s->Cedar, "LS_START_3", s->Cedar->BuildInfo);\r
9189         SLog(s->Cedar, "LS_START_UTF8");\r
9190         SLog(s->Cedar, "LS_START_1");\r
9191 \r
9192         if (s->Cedar->Bridge == false)\r
9193         {\r
9194                 s->LicenseSystem = LiNewLicenseSystem();\r
9195         }\r
9196 \r
9197         // コンフィグレーション初期化\r
9198         SiInitConfiguration(s);\r
9199 \r
9200         // 優先順位を上げる\r
9201         if (s->NoHighPriorityProcess == false)\r
9202         {\r
9203                 OSSetHighPriority();\r
9204         }\r
9205 \r
9206         if (s->ServerType == SERVER_TYPE_FARM_MEMBER)\r
9207         {\r
9208                 // コントローラへの接続を開始する\r
9209                 s->FarmController = SiStartConnectToController(s);\r
9210         }\r
9211         else if (s->ServerType == SERVER_TYPE_FARM_CONTROLLER)\r
9212         {\r
9213                 FARM_MEMBER *f;\r
9214                 // コントローラとしての動作を開始する\r
9215                 s->FarmMemberList = NewList(NULL);\r
9216 \r
9217                 f = ZeroMalloc(sizeof(FARM_MEMBER));\r
9218                 f->Cedar = s->Cedar;\r
9219                 GetMachineName(f->hostname, sizeof(f->hostname));\r
9220                 f->Me = true;\r
9221                 f->HubList = NewList(CompareHubList);\r
9222                 f->Weight = s->Weight;\r
9223 \r
9224                 s->Me = f;\r
9225 \r
9226                 Add(s->FarmMemberList, f);\r
9227 \r
9228                 SiStartFarmControl(s);\r
9229 \r
9230                 s->FarmControllerInited = true;\r
9231         }\r
9232 \r
9233         InitServerSnapshot(s);\r
9234 \r
9235         SiInitDeadLockCheck(s);\r
9236 \r
9237         return s;\r
9238 }\r
9239 \r