OSDN Git Service

commit client-src-ip ver. for ossc. not completed
[ultramonkey-l7/ultramonkey-l7-v3.git] / l7vsd / src / l7vsadm.cpp
1 /*!
2  * @file  l7vsadm.cpp
3  * @brief l7vsadm command is l7vsd control application
4  *
5  * L7VSD: Linux Virtual Server for Layer7 Load Balancing
6  * Copyright (C) 2009  NTT COMWARE Corporation.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21  * 02110-1301 USA
22  *
23  **********************************************************************/
24
25 #include <iostream>
26 #include <sstream>
27 #include <exception>
28 #include <boost/bind.hpp>
29 #include <boost/archive/text_oarchive.hpp>
30 #include <boost/archive/text_iarchive.hpp>
31 #include <boost/format.hpp>
32 #include <boost/algorithm/string.hpp>
33 #include <sys/file.h>
34 #include "l7vsadm.h"
35 #include "logger.h"
36 #include "parameter.h"
37 #include "protocol_module_control.h"
38 #include "schedule_module_control.h"
39 #include "virtualservice_element.h"
40 #include "logger_access_manager.h"
41
42 #define VS_CONTACT_CLASS_SSL (0x00000001)
43
44 // global function prototype
45 static void sig_exit_handler(int sig);
46 static int  set_sighandler(int sig, void (*handler)(int));
47 static int  set_sighandlers();
48
49 // global variables
50 static bool signal_flag = false;
51 static int  received_sig = 0;
52
53 //
54 // command functions.
55 //
56 //! list command parsing.
57 //! @param[in] request command
58 //! @param[in] argument count
59 //! @param[in] argument value
60 bool l7vs::l7vsadm::parse_list_func(l7vs::l7vsadm_request::COMMAND_CODE_TAG cmd, int argc, char *argv[])
61 {
62         Logger logger(LOG_CAT_L7VSADM_COMMON, 1, "l7vsadm::parse_list_func", __FILE__, __LINE__);
63
64         request.command = cmd; // set command
65         if (argc < 3) {
66                 return true; // option is none. this pattern is true
67         }
68         else if (argc > 3) {
69                 std::stringstream buf;
70                 buf << "Argument argc is illegal for " << argv[1] << " command.";
71                 l7vsadm_err.setter(true, buf.str());
72                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 117, buf.str(), __FILE__, __LINE__);
73                 return false;
74         }
75
76         for (int pos = 2; pos < argc; ++pos) { //search option function from argv strings
77                 parse_opt_map_type::iterator itr = list_option_dic.find(argv[pos]);
78                 if (itr != list_option_dic.end()) { // option string function find.
79                         if (! itr->second(pos, argc, argv)) {
80                                 return false; // option string function error.
81                         }
82                 } else { //option string function not found.
83                         // print option not found message.
84                         std::stringstream buf;
85                         buf << "list option not found: " << argv[pos];
86                         l7vsadm_err.setter(true, buf.str());
87                         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 1, buf.str(), __FILE__, __LINE__);
88                         return false;
89                 }
90         }
91         return true;
92 }
93 //
94 // option list functions.
95 //
96 //! list numeric flag check.
97 //! @param[in] argument position
98 //! @param[in] argument count
99 //! @param[in] argument value
100 bool l7vs::l7vsadm::parse_opt_list_numeric_func(int &pos, int argc, char *argv[])
101 {
102         Logger logger(LOG_CAT_L7VSADM_COMMON, 2, "l7vsadm::parse_opt_list_numeric_func", __FILE__, __LINE__);
103
104         numeric_flag = true; //numeric flag on.
105         return true;
106 }
107
108 //! virtualservice command parsing.
109 //! @param[in] request command
110 //! @param[in] argument count
111 //! @param[in] argument value
112 bool l7vs::l7vsadm::parse_vs_func(l7vs::l7vsadm_request::COMMAND_CODE_TAG cmd, int argc, char *argv[])
113 {
114         Logger logger(LOG_CAT_L7VSADM_COMMON, 3, "l7vsadm::parse_vs_func", __FILE__, __LINE__);
115
116         request.command = cmd; // set command
117         if (l7vsadm_request::CMD_FLUSH_VS == cmd) {
118                 if (argc != 2) {
119                         std::stringstream buf;
120                         buf << "Argument argc is illegal for " << argv[1] << " command.";
121                         l7vsadm_err.setter(true, buf.str());
122                         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 118, buf.str(), __FILE__, __LINE__);
123                         return false;
124                 }
125         } else {
126                 if (argc < 6) {
127                         std::stringstream buf;
128                         buf << "Argument argc is illegal for " << argv[1] << " command.";
129                         l7vsadm_err.setter(true, buf.str());
130                         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 119, buf.str(), __FILE__, __LINE__);
131                         return false;
132                 }
133         }
134
135         std::map<std::string, int> count_map;
136
137         for (parse_opt_map_type::iterator itr = vs_option_dic.begin() ;
138              itr != vs_option_dic.end() ; ++itr) {
139                 count_map[ itr->first ] = 0;
140         }
141
142         if (l7vsadm_request::CMD_EDIT_VS == cmd) {
143                 request.vs_element.access_log_flag = -1;
144         }
145
146         for (int pos = 2; pos < argc; ++pos) { // check options.
147                 parse_opt_map_type::iterator itr = vs_option_dic.find(argv[pos]);
148                 if (itr != vs_option_dic.end()) { // find option
149                         count_map[ itr->first ]++;
150                         if (! itr->second(pos, argc, argv)) {
151                                 return false; // option function execute.
152                         }
153                 } else { // not found option function.
154                         std::stringstream buf;
155                         buf << "virtualservice option not found: " << argv[pos];
156                         l7vsadm_err.setter(true, buf.str());
157                         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 2, buf.str(), __FILE__, __LINE__);
158                         return false;
159                 }
160         }
161         // check virtualservice on response
162         if (l7vsadm_request::CMD_FLUSH_VS == cmd) {
163                 // flush vs required no option
164                 return true;
165         }
166         if ((l7vsadm_request::CMD_ADD_VS == cmd) && (request.vs_element.schedule_module_name.length() == 0)) {
167                 //scheduler module not specified
168                 //scheduler module check.
169                 std::string scheduler_name = L7VSADM_DEFAULT_SCHEDULER; //default scheduler
170                 schedule_module_control &ctrl = schedule_module_control::getInstance();
171                 ctrl.initialize(L7VS_MODULE_PATH);
172                 schedule_module_base *module;
173                 try {
174                         module = ctrl.load_module(scheduler_name);
175                 } catch (...) {
176                         std::stringstream buf;
177                         buf << "scheduler module load error(--scheduler): " << scheduler_name;
178                         l7vsadm_err.setter(true, buf.str());
179                         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 3, buf.str(), __FILE__, __LINE__);
180                         return false;
181                 }
182                 if (!module) {
183                         // schedule module not found
184                         std::stringstream buf;
185                         buf << "scheduler module not found(--scheduler): " << scheduler_name;
186                         l7vsadm_err.setter(true, buf.str());
187                         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 4, buf.str(), __FILE__, __LINE__);
188                         return false;
189                 }
190                 ctrl.unload_module(module);
191                 request.vs_element.schedule_module_name = scheduler_name;
192         }
193         if (request.vs_element.protocol_module_name.length() == 0) {
194                 //protocol module name error
195                 std::string buf("protocol module is not specified.(--proto-module)");
196                 l7vsadm_err.setter(true, buf);
197                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 5, buf, __FILE__, __LINE__);
198                 return false;
199         }
200         if (request.vs_element.udpmode) {
201                 if (request.vs_element.udp_recv_endpoint == boost::asio::ip::udp::endpoint()) {
202                         // udp mode, but no receive endpoint
203                         std::string buf("udp recv endpoint is not specified.(--udp-service)");
204                         l7vsadm_err.setter(true, buf);
205                         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 6, buf, __FILE__, __LINE__);
206                         return false;
207                 }
208         } else {
209                 if (request.vs_element.tcp_accept_endpoint == boost::asio::ip::tcp::endpoint()) {
210                         // tcp mode, but no acceptor endpoint
211                         std::string buf("tcp accpeptor endpoint is not specified.(--tcp-service)");
212                         l7vsadm_err.setter(true, buf);
213                         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 7, buf, __FILE__, __LINE__);
214                         return false;
215                 }
216         }
217         if (0 > request.vs_element.sorry_maxconnection) {
218                 std::string buf("invalid sorry max connection value.(--upper)");
219                 l7vsadm_err.setter(true, buf);
220                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 8, buf, __FILE__, __LINE__);
221                 return false;
222         }
223         if ((l7vsadm_request::CMD_ADD_VS == cmd) &&
224                 (request.vs_element.sorry_fwdmode == virtualservice_element::FWD_NONE)) {
225                 request.vs_element.sorry_fwdmode = virtualservice_element::FWD_MASQ;
226         }
227
228         if ((l7vsadm_request::CMD_ADD_VS == cmd) &&
229             (request.vs_element.access_log_flag == 1) && (request.vs_element.access_log_file_name.length() == 0)) {
230                 std::string buf("access log file is not specified.(--access-log-name)");
231                 l7vsadm_err.setter(true, buf);
232                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 89, buf, __FILE__, __LINE__);
233                 return false;
234         }
235
236         if (l7vsadm_request::CMD_EDIT_VS == cmd) {
237                 // Existence check of the parameter
238                 if (count_map["-s"] == 0 &&
239                     count_map["--scheduler"] == 0 &&
240                     count_map["-u"] == 0 &&
241                     count_map["--upper"] == 0 &&
242                     count_map["-b"] == 0 &&
243                     count_map["--bypass"] == 0 &&
244                     count_map["-f"] == 0 &&
245                     count_map["--flag"] == 0 &&
246                     count_map["-M"] == 0 &&
247                     count_map["--masq"] == 0 &&
248                     count_map["-T"] == 0 &&
249                     count_map["--tproxy"] == 0 &&
250                     count_map["-Q"] == 0 &&
251                     count_map["--qos-up"] == 0 &&
252                     count_map["-q"] == 0 &&
253                     count_map["--qos-down"] == 0 &&
254                     count_map["-L"] == 0 &&
255                     count_map["--access-log"] == 0) {
256
257                         std::string buf("All option omitted for edit vs command.");
258                         l7vsadm_err.setter(true, buf);
259                         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 116, buf, __FILE__, __LINE__);
260                         return false;
261                 }
262         }
263
264         //conflict check
265         std::string conflict_option_name;
266         bool is_conflict = false;
267
268         for (std::map<std::string, int>::iterator itr = count_map.begin() ;
269              itr != count_map.end() ; ++itr) {
270                 if (itr->second > 1) {
271                         conflict_option_name = itr->first;
272                         is_conflict = true;
273                         break;
274                 }
275         }
276
277         if (is_conflict == false &&
278             count_map["-t"] == 1 && count_map["--tcp-service"] == 1) {
279                 //-t(--tcp-service)
280                 conflict_option_name = "--tcp-service";
281                 is_conflict = true;
282         }
283         if (is_conflict == false &&
284             count_map["-m"] == 1 && count_map["--proto-module"] == 1) {
285                 //-m(--proto-module)
286                 conflict_option_name = "--proto-module";
287                 is_conflict = true;
288         }
289         if (is_conflict == false &&
290             count_map["-s"] == 1 && count_map["--scheduler"] == 1) {
291                 //-s(--scheduler)
292                 conflict_option_name = "--scheduler";
293                 is_conflict = true;
294         }
295         if (is_conflict == false &&
296             count_map["-u"] == 1 && count_map["--upper"] == 1) {
297                 //-u(--upper)
298                 conflict_option_name = "--upper";
299                 is_conflict = true;
300         }
301         if (is_conflict == false &&
302             count_map["-b"] == 1 && count_map["--bypass"] == 1) {
303                 //-b(--bypass)
304                 conflict_option_name = "--bypass";
305                 is_conflict = true;
306         }
307         if (is_conflict == false &&
308             count_map["-f"] == 1 && count_map["--flag"] == 1) {
309                 //-f(--flag)
310                 conflict_option_name = "--flag";
311                 is_conflict = true;
312         }
313         if (is_conflict == false &&
314             count_map["-M"] == 1 && count_map["--masq"] == 1) {
315                 //-M(--masq)
316                 conflict_option_name = "--masq";
317                 is_conflict = true;
318         }
319         if (is_conflict == false &&
320             count_map["-T"] == 1 && count_map["--tproxy"] == 1) {
321                 //-T(--tproxy)
322                 conflict_option_name = "--tproxy";
323                 is_conflict = true;
324         }
325         if (is_conflict == false &&
326             count_map["-M"] + count_map["--masq"] +
327             count_map["-T"] + count_map["--tproxy"] > 1) {
328                 conflict_option_name = "--masq/tproxy";
329                 is_conflict = true;
330         }
331         if (is_conflict == false &&
332             count_map["-Q"] == 1 && count_map["--qos-up"] == 1) {
333                 //-Q(--qos-up)
334                 conflict_option_name = "--qos-up";
335                 is_conflict = true;
336         }
337         if (is_conflict == false &&
338             count_map["-q"] == 1 && count_map["--qos-down"] == 1) {
339                 //-q(--qos-down)
340                 conflict_option_name = "--qos-down";
341                 is_conflict = true;
342         }
343         if (is_conflict == false &&
344             count_map["-p"] == 1 && count_map["--udp"] == 1) {
345                 //-p(--udp)
346                 conflict_option_name = "--udp";
347                 is_conflict = true;
348         }
349         if (is_conflict == false &&
350             count_map["-z"] == 1 && count_map["--ssl"] == 1) {
351                 //-z(--ssl)
352                 conflict_option_name = "--ssl";
353                 is_conflict = true;
354         }
355         if (is_conflict == false &&
356             count_map["-O"] == 1 && count_map["--sockopt"] == 1) {
357                 //-O(--sockopt)
358                 conflict_option_name = "--sockopt";
359                 is_conflict = true;
360         }
361         if (is_conflict == false &&
362             count_map["-L"] == 1 && count_map["--access-log"] == 1) {
363                 //-L(--access-log)
364                 conflict_option_name = "--access-log";
365                 is_conflict = true;
366         }
367         if (is_conflict == false &&
368             count_map["-a"] == 1 && count_map["--access-log-name"] == 1) {
369                 //-a(--access-log-name)
370                 conflict_option_name = "--access-log-name";
371                 is_conflict = true;
372         }
373
374         if (is_conflict == true) {
375                 std::stringstream buf;
376                 buf << "Option " << conflict_option_name << " is conflict.";
377                 l7vsadm_err.setter(true, buf.str());
378                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 120, buf.str(), __FILE__, __LINE__);
379                 return false;
380         }
381
382         if (l7vsadm_request::CMD_ADD_VS == cmd &&
383             (count_map["-z"] > 0 || count_map["--ssl"] > 0)) {
384                 protocol_module_control &ctrl
385                 = protocol_module_control::getInstance();
386                 ctrl.initialize(L7VS_MODULE_PATH);
387                 protocol_module_base *module;
388                 try {
389                         module
390                         = ctrl.load_module(request.vs_element.protocol_module_name);
391                 } catch (...) {
392                         std::stringstream buf;
393                         buf << "protocol module load error(--proto-module): "
394                             << request.vs_element.protocol_module_name;
395                         l7vsadm_err.setter(true, buf.str());
396                         Logger::putLogError(
397                                 LOG_CAT_L7VSADM_PARSE,
398                                 108,
399                                 buf.str(),
400                                 __FILE__,
401                                 __LINE__);
402                         return false;
403                 }
404                 if (!module) {
405                         // protocol module not found.
406                         std::stringstream buf;
407                         buf << "protocol module not found(--proto-module): "
408                             << request.vs_element.protocol_module_name;
409                         l7vsadm_err.setter(true, buf.str());
410                         Logger::putLogError(
411                                 LOG_CAT_L7VSADM_PARSE,
412                                 109, buf.str(),
413                                 __FILE__,
414                                 __LINE__);
415                         return false;
416                 }
417
418                 bool module_used_flag = module->is_exec_OK(VS_CONTACT_CLASS_SSL);
419                 if (module_used_flag == false) {
420                         // protocol module not found.
421                         std::stringstream buf;
422                         buf << "You cannot set \"-z\" option with \"sslid\" protocol module.";
423                         l7vsadm_err.setter(true, buf.str());
424                         Logger::putLogError(
425                                 LOG_CAT_L7VSADM_PARSE,
426                                 110,
427                                 buf.str(),
428                                 __FILE__,
429                                 __LINE__);
430                         return false;
431                 }
432         }
433
434         return true;
435 }
436 //
437 // option virtualservice functions.
438 //
439 //! target option check
440 //! @param[in] argument position
441 //! @param[in] argument count
442 //! @param[in] argument value
443 bool l7vs::l7vsadm::parse_opt_vs_target_func(int &pos, int argc, char *argv[])
444 {
445         Logger logger(LOG_CAT_L7VSADM_COMMON, 4, "l7vsadm::parse_opt_vs_target_func", __FILE__, __LINE__);
446
447         if (++pos >= argc) {
448                 // target address and port are not specified
449                 std::string buf("target endpoint is not specified.(--tcp-service)");
450                 l7vsadm_err.setter(true, buf);
451                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 9, buf, __FILE__, __LINE__);
452                 return false;
453         }
454         // get host endpoint from string
455         std::string src_str = argv[pos];
456         if (request.vs_element.udpmode) {
457                 error_code err;
458                 request.vs_element.udp_recv_endpoint = string_to_endpoint<boost::asio::ip::udp>(src_str, err);
459                 if (err) {
460                         std::stringstream buf;
461                         buf << "target endpoint parse error(--tcp-service): " << err.get_message() << src_str;
462                         l7vsadm_err.setter(true, buf.str());
463                         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 10, buf.str(), __FILE__, __LINE__);
464                         return false;
465                 }
466                 check_endpoint<boost::asio::ip::udp>(request.vs_element.udp_recv_endpoint, true, err);
467                 if (err) {
468                         std::stringstream buf;
469                         buf << "target endpoint parse error(--tcp-service): " << err.get_message() << src_str;
470                         l7vsadm_err.setter(true, buf.str());
471                         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 11, buf.str(), __FILE__, __LINE__);
472                         return false;
473                 }
474         } else {
475                 error_code err;
476                 request.vs_element.tcp_accept_endpoint = string_to_endpoint<boost::asio::ip::tcp>(src_str, err);
477                 if (err) {
478                         std::stringstream buf;
479                         buf << "target endpoint parse error(--tcp-service): " << err.get_message() << src_str;
480                         l7vsadm_err.setter(true, buf.str());
481                         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 12, buf.str(), __FILE__, __LINE__);
482                         return false;
483                 }
484                 check_endpoint<boost::asio::ip::tcp>(request.vs_element.tcp_accept_endpoint, true, err);
485                 if (err) {
486                         std::stringstream buf;
487                         buf << "target endpoint parse error(--tcp-service): " << err.get_message() << src_str;
488                         l7vsadm_err.setter(true, buf.str());
489                         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 13, buf.str(), __FILE__, __LINE__);
490                         return false;
491                 }
492         }
493         return true;
494 }
495 //! module option check
496 //! @param[in] argument position
497 //! @param[in] argument count
498 //! @param[in] argument value
499 bool l7vs::l7vsadm::parse_opt_vs_module_func(int &pos, int argc, char *argv[])
500 {
501         Logger logger(LOG_CAT_L7VSADM_COMMON, 5, "l7vsadm::parse_opt_vs_module_func", __FILE__, __LINE__);
502         if (++pos >= argc) {
503                 // target protomod name not specified.
504                 std::string buf("protocol module name is not specified.(--proto-module)");
505                 l7vsadm_err.setter(true, buf);
506                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 14, buf, __FILE__, __LINE__);
507                 return false;
508         }
509         std::string module_name = argv[pos];
510         if (L7VS_MODNAME_LEN < module_name.length()) {
511                 std::string buf("protocol module name is too long.(--proto-module)");
512                 l7vsadm_err.setter(true, buf);
513                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 15, buf, __FILE__, __LINE__);
514                 return false;
515         }
516         protocol_module_control &ctrl = protocol_module_control::getInstance();
517         ctrl.initialize(L7VS_MODULE_PATH);
518         protocol_module_base *module;
519         try {
520                 module = ctrl.load_module(module_name);
521         } catch (...) {
522                 std::stringstream buf;
523                 buf << "protocol module load error(--proto-module): " << module_name;
524                 l7vsadm_err.setter(true, buf.str());
525                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 16, buf.str(), __FILE__, __LINE__);
526                 return false;
527         }
528         if (!module) {
529                 // protocol module not found.
530                 std::stringstream buf;
531                 buf << "protocol module not found(--proto-module): " << module_name;
532                 l7vsadm_err.setter(true, buf.str());
533                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 17, buf.str(), __FILE__, __LINE__);
534                 return false;
535         }
536         module->init_logger_functions(
537                 boost::bind(&l7vs::Logger::getLogLevel, l7vs::LOG_CAT_PROTOCOL),
538                 boost::bind(&l7vs::Logger::putLogFatal, l7vs::LOG_CAT_PROTOCOL, _1, _2, _3, _4),
539                 boost::bind(&l7vs::Logger::putLogError, l7vs::LOG_CAT_PROTOCOL, _1, _2, _3, _4),
540                 boost::bind(&l7vs::Logger::putLogWarn, l7vs::LOG_CAT_PROTOCOL, _1, _2, _3, _4),
541                 boost::bind(&l7vs::Logger::putLogInfo, l7vs::LOG_CAT_PROTOCOL, _1, _2, _3, _4),
542                 boost::bind(&l7vs::Logger::putLogDebug, l7vs::LOG_CAT_PROTOCOL, _1, _2, _3, _4));
543         // create module args.
544         std::vector<std::string> module_args;
545         while (true) {
546                 if (++pos == argc) break; //module option end.
547                 parse_opt_map_type::iterator vsitr = vs_option_dic.find(argv[pos]);
548                 if (vsitr != vs_option_dic.end()) {
549                         --pos; // back for next option
550                         break; // module option end.
551                 }
552                 parse_opt_map_type::iterator rsitr = rs_option_dic.find(argv[pos]);
553                 if (rsitr != rs_option_dic.end()) {
554                         --pos; // back for next option
555                         break; // module option end.
556                 }
557                 module_args.push_back(argv[pos]);
558         }
559         protocol_module_base::check_message_result module_message = module->check_parameter(module_args);
560
561         if (!module_message.flag) {
562                 // args is not supported.
563                 std::stringstream buf;
564                 buf << "protocol module argument error(--proto-module): " << module_message.message;
565                 l7vsadm_err.setter(true, buf.str());
566                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 18, buf.str(), __FILE__, __LINE__);
567                 return false;
568         }
569         request.vs_element.protocol_module_name = module_name;
570         BOOST_FOREACH(std::string str, module_args) {
571                 request.vs_element.protocol_args.push_back(str);
572         }
573         ctrl.unload_module(module);
574
575         return true;
576 }
577
578 //! scheduler option check.
579 //! @param[in] argument position
580 //! @param[in] argument count
581 //! @param[in] argument value
582 bool l7vs::l7vsadm::parse_opt_vs_scheduler_func(int &pos, int argc, char *argv[])
583 {
584         Logger logger(LOG_CAT_L7VSADM_COMMON, 6, "l7vsadm::parse_opt_vs_scheduler_func", __FILE__, __LINE__);
585
586         if (++pos >= argc) {
587                 // target scheduler name not specified.
588                 std::string buf("schedule module name is not specified.(--scheduler)");
589                 l7vsadm_err.setter(true, buf);
590                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 19, buf, __FILE__, __LINE__);
591                 return false;
592         }
593         //schedule module check.
594         std::string scheduler_name = argv[pos];
595         if (L7VS_MODNAME_LEN < scheduler_name.length()) {
596                 std::string buf("schedule module name is too long.(--scheduler)");
597                 l7vsadm_err.setter(true, buf);
598                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 20, buf, __FILE__, __LINE__);
599                 return false;
600         }
601         schedule_module_control &ctrl = schedule_module_control::getInstance();
602         ctrl.initialize(L7VS_MODULE_PATH);
603         schedule_module_base *module;
604         try {
605                 module = ctrl.load_module(scheduler_name);
606         } catch (...) {
607                 std::stringstream buf;
608                 buf << "scheduler module load error(--scheduler): " << scheduler_name;
609                 l7vsadm_err.setter(true, buf.str());
610                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 21, buf.str(), __FILE__, __LINE__);
611                 return false;
612         }
613         if (!module) {
614                 // schedule module not found
615                 std::stringstream buf;
616                 buf << "scheduler module not found(--scheduler): " << scheduler_name;
617                 l7vsadm_err.setter(true, buf.str());
618                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 22, buf.str(), __FILE__, __LINE__);
619                 return false;
620         }
621         ctrl.unload_module(module);
622         request.vs_element.schedule_module_name = scheduler_name;
623         return true;
624 }
625 //! upper flag check
626 //! @param[in] argument position
627 //! @param[in] argument count
628 //! @param[in] argument value
629 bool l7vs::l7vsadm::parse_opt_vs_upper_func(int &pos, int argc, char *argv[])
630 {
631         Logger logger(LOG_CAT_L7VSADM_COMMON, 7, "l7vsadm::parse_opt_vs_upper_func", __FILE__, __LINE__);
632
633         if (++pos >= argc) {
634                 // target max connection number not specified
635                 std::string buf("sorry max connection value is not specified.(--upper)");
636                 l7vsadm_err.setter(true, buf);
637                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 23, buf, __FILE__, __LINE__);
638                 return false;
639         }
640         try {
641                 request.vs_element.sorry_maxconnection = boost::lexical_cast<long long>(argv[pos]);
642                 if ((0LL > request.vs_element.sorry_maxconnection) ||
643                     (100000LL < request.vs_element.sorry_maxconnection)) {
644                         std::string buf("invalid sorry max connection value.(--upper)");
645                         l7vsadm_err.setter(true, buf);
646                         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 24, buf, __FILE__, __LINE__);
647                         return false;
648                 }
649                 if (0LL == request.vs_element.sorry_maxconnection)
650                         request.vs_element.sorry_maxconnection = LLONG_MAX; // clear value
651         } catch (boost::bad_lexical_cast &e) {
652                 std::string buf("invalid sorry max connection value.(--upper)");
653                 l7vsadm_err.setter(true, buf);
654                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 25, buf, __FILE__, __LINE__);
655                 return false;
656         }
657         //check connection limit and zero
658         return true;
659 }
660 //! bypass(SorryServer) option check
661 //! @param[in] argument position
662 //! @param[in] argument count
663 //! @param[in] argument value
664 bool l7vs::l7vsadm::parse_opt_vs_bypass_func(int &pos, int argc, char *argv[])
665 {
666         Logger logger(LOG_CAT_L7VSADM_COMMON, 8, "l7vsadm::parse_opt_vs_bypass_func", __FILE__, __LINE__);
667
668         if (++pos >= argc) {
669                 // sorryserver addr and port not specified
670                 std::string buf("sorryserver endpoint is not specified.(--bypass)");
671                 l7vsadm_err.setter(true, buf);
672                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 26, buf, __FILE__, __LINE__);
673                 return false;
674         }
675         std::string sorry_endpoint = argv[pos];
676         error_code err;
677         request.vs_element.sorry_endpoint = string_to_endpoint<boost::asio::ip::tcp>(sorry_endpoint, err);
678         if (err) {
679                 std::stringstream buf;
680                 buf << "sorryserver endpoint parse error(--bypass): " << err.get_message() << sorry_endpoint;
681                 l7vsadm_err.setter(true, buf.str());
682                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 27, buf.str(), __FILE__, __LINE__);
683                 return false;
684         }
685         // clear endpoint check (0.0.0.0:0)
686         if (request.vs_element.sorry_endpoint == boost::asio::ip::tcp::endpoint()) {
687                 request.vs_element.sorry_endpoint = boost::asio::ip::tcp::endpoint(
688                         boost::asio::ip::address::from_string("255.255.255.255"), 0);
689         } else {
690                 check_endpoint<boost::asio::ip::tcp>(request.vs_element.sorry_endpoint, false, err);
691                 if (err) {
692                         std::stringstream buf;
693                         buf << "sorryserver endpoint parse error(--bypass): " << err.get_message() << sorry_endpoint;
694                         l7vsadm_err.setter(true, buf.str());
695                         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 29, buf.str(), __FILE__, __LINE__);
696                         return false;
697                 }
698         }
699         return true;
700 }
701 //! virtualservice option flag function
702 //! @param[in] argument position
703 //! @param[in] argument count
704 //! @param[in] argument value
705 bool l7vs::l7vsadm::parse_opt_vs_flag_func(int &pos, int argc, char *argv[])
706 {
707         Logger logger(LOG_CAT_L7VSADM_COMMON, 9, "l7vsadm::parse_opt_vs_flag_func", __FILE__, __LINE__);
708
709         if (++pos >= argc) {
710                 // sorry flag is not specified
711                 std::string buf("sorry flag value is not specified.(--flag)");
712                 l7vsadm_err.setter(true, buf);
713                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 30, buf, __FILE__, __LINE__);
714                 return false;
715         }
716         try {
717                 int tmp = boost::lexical_cast<int>(argv[pos]);
718                 if ((0 != tmp) && (1 != tmp)) {
719                         std::string buf("invalid sorry flag value.(--flag)");
720                         l7vsadm_err.setter(true, buf);
721                         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 31, buf, __FILE__, __LINE__);
722                         return false;
723                 }
724                 if (0 == tmp)
725                         request.vs_element.sorry_flag = INT_MAX; // clear value
726                 else
727                         request.vs_element.sorry_flag = 1;
728         } catch (boost::bad_lexical_cast &e) {
729                 std::string buf("invalid sorry flag value.(--flag)");
730                 l7vsadm_err.setter(true, buf);
731                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 32, buf, __FILE__, __LINE__);
732                 return false;
733         }
734         return true;
735 }
736 //! virtualservice option sorry forward mode function
737 //! @param[in] argument position
738 //! @param[in] argument count
739 //! @param[in] argument value
740 bool l7vs::l7vsadm::parse_opt_vs_fwdmode_func(int &pos, int argc, char *argv[])
741 {
742         Logger logger(LOG_CAT_L7VSADM_COMMON, /*XXX*/999, "l7vsadm::parse_opt_vs_fwdmode_func", __FILE__, __LINE__);
743
744         std::string opt(argv[pos]);
745         if (opt == "-M" || opt == "--masq") {
746                 request.vs_element.sorry_fwdmode = virtualservice_element::FWD_MASQ;
747         } else if (opt == "-T" || opt == "--tproxy") {
748                 request.vs_element.sorry_fwdmode = virtualservice_element::FWD_TPROXY;
749         } else {
750                 // should never come here
751                 std::stringstream buf;
752                 buf << boost::format("unknown sorryserver forward mode specified.(%s)") % opt;
753                 l7vsadm_err.setter(true, buf.str());
754                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, /*XXX*/999, buf.str(), __FILE__, __LINE__);
755                 return false;
756         }
757         return true;
758 }
759 //! virtualservice option qosupstream function
760 //! @param[in] argument position
761 //! @param[in] argument count
762 //! @param[in] argument value
763 bool l7vs::l7vsadm::parse_opt_vs_qosup_func(int &pos, int argc, char *argv[])
764 {
765         Logger logger(LOG_CAT_L7VSADM_COMMON, 10, "l7vsadm::parse_opt_vs_qosup_func", __FILE__, __LINE__);
766
767         if (++pos >= argc) {
768                 // QoS upstream value is not specified.
769                 std::string buf("QoS upstream value is not specified.(--qos-up)");
770                 l7vsadm_err.setter(true, buf);
771                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 33, buf, __FILE__, __LINE__);
772                 return false;
773         }
774         try {
775                 virtualservice_element &elem = request.vs_element; // request virtualservice element refalence get.
776                 std::string tmp = argv[pos];
777                 std::string::reverse_iterator ritr = tmp.rbegin();
778                 if (*ritr == 'G' || *ritr == 'g') {
779                         std::string strval = tmp.substr(0, tmp.length() - 1);
780                         unsigned long long ullval = boost::lexical_cast<unsigned long long> (strval);
781                         if (ullval > 999) {
782                                 std::string buf("QoS upstream value is too big.(--qos-up)");
783                                 l7vsadm_err.setter(true, buf);
784                                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 34, buf, __FILE__, __LINE__);
785                                 return false;
786                         }
787                         elem.qos_upstream = ullval * 1000 * 1000 * 1000; // set qos_upstream
788                 } else if (*ritr == 'M' || *ritr == 'm') {
789                         std::string strval = tmp.substr(0, tmp.length() - 1);
790                         unsigned long long ullval = boost::lexical_cast<unsigned long long> (strval);
791                         if (ullval > 999) {
792                                 std::string buf("QoS upstream value is too big.(--qos-up)");
793                                 l7vsadm_err.setter(true, buf);
794                                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 35, buf, __FILE__, __LINE__);
795                                 return false;
796                         }
797                         elem.qos_upstream = ullval * 1000 * 1000; // set qos_upstream
798                 } else if (*ritr == 'K' || *ritr == 'k') {
799                         std::string strval = tmp.substr(0, tmp.length() - 1);
800                         unsigned long long ullval = boost::lexical_cast<unsigned long long> (strval);
801                         if (ullval > 999) {
802                                 std::string buf("QoS upstream value is too big.(--qos-up)");
803                                 l7vsadm_err.setter(true, buf);
804                                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 36, buf, __FILE__, __LINE__);
805                                 return false;
806                         }
807                         elem.qos_upstream = ullval * 1000; // set qos_upstream
808                 } else {
809                         unsigned long long ullval = boost::lexical_cast<unsigned long long> (argv[pos]);
810                         if (ullval > 999) {
811                                 std::string buf("QoS upstream value is too big.(--qos-up)");
812                                 l7vsadm_err.setter(true, buf);
813                                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 111, buf, __FILE__, __LINE__);
814                                 return false;
815                         }
816                         elem.qos_upstream = ullval; // set qos_upstream
817                 }
818                 if (0ULL == elem.qos_upstream) {
819                         elem.qos_upstream = ULLONG_MAX; // clear value
820                 } else {
821                         elem.qos_upstream /= 8; //qos convert to bytes per sec to bit per sec
822                 }
823
824         } catch (boost::bad_lexical_cast &ex) {
825                 std::string buf("invalid QoS upstream value.(--qos-up)");
826                 l7vsadm_err.setter(true, buf);
827                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 37, buf, __FILE__, __LINE__);
828                 return false;
829         }
830         return true;
831 }
832 //! virtualservice option qosdownstream functipn
833 //! @param[in] argument position
834 //! @param[in] argument count
835 //! @param[in] argument value
836 bool l7vs::l7vsadm::parse_opt_vs_qosdown_func(int &pos, int argc, char *argv[])
837 {
838         Logger logger(LOG_CAT_L7VSADM_COMMON, 11, "l7vsadm::parse_opt_vs_qosdown_func", __FILE__, __LINE__);
839
840         if (++pos >= argc) {
841                 // QoS downstream value is not specified
842                 std::string buf("QoS downstream value is not specified.(--qos-down)");
843                 l7vsadm_err.setter(true, buf);
844                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 38, buf, __FILE__, __LINE__);
845                 return false;
846         }
847         try {
848                 virtualservice_element &elem = request.vs_element; // request virtualservice element refalence get.
849                 std::string tmp = argv[pos];
850                 std::string::reverse_iterator ritr = tmp.rbegin();
851                 if (*ritr == 'G' || *ritr == 'g') {
852                         std::string strval = tmp.substr(0, tmp.length() - 1);
853                         unsigned long long ullval = boost::lexical_cast<unsigned long long> (strval);
854                         if (ullval > 999) {
855                                 std::string buf("QoS downstream value is too big.(--qos-down)");
856                                 l7vsadm_err.setter(true, buf);
857                                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 39, buf, __FILE__, __LINE__);
858                                 return false;
859                         }
860                         elem.qos_downstream = ullval * 1000 * 1000 * 1000; // set qos_upstream
861                 } else if (*ritr == 'M' || *ritr == 'm') {
862                         std::string strval = tmp.substr(0, tmp.length() - 1);
863                         unsigned long long ullval = boost::lexical_cast<unsigned long long> (strval);
864                         if (ullval > 999) {
865                                 std::string buf("QoS downstream value is too big.(--qos-down)");
866                                 l7vsadm_err.setter(true, buf);
867                                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 40, buf, __FILE__, __LINE__);
868                                 return false;
869                         }
870                         elem.qos_downstream = ullval * 1000 * 1000; // set qos_upstream
871                 } else if (*ritr == 'K' || *ritr == 'k') {
872                         std::string strval = tmp.substr(0, tmp.length() - 1);
873                         unsigned long long ullval = boost::lexical_cast<unsigned long long> (strval);
874                         if (ullval > 999) {
875                                 std::string buf("QoS downstream value is too big.(--qos-down)");
876                                 l7vsadm_err.setter(true, buf);
877                                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 41, buf, __FILE__, __LINE__);
878                                 return false;
879                         }
880                         elem.qos_downstream = ullval * 1000; // set qos_upstream
881                 } else {
882                         unsigned long long ullval = boost::lexical_cast<unsigned long long> (argv[pos]);
883                         if (ullval > 999) {
884                                 std::string buf("QoS downstream value is too big.(--qos-down)");
885                                 l7vsadm_err.setter(true, buf);
886                                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 115, buf, __FILE__, __LINE__);
887                                 return false;
888                         }
889                         elem.qos_downstream = boost::lexical_cast<unsigned long long> (argv[pos]); // set qos_downstream
890                 }
891                 if (0ULL == elem.qos_downstream) {
892                         elem.qos_downstream = ULLONG_MAX; // clear value
893                 } else {
894                         elem.qos_downstream /= 8; //qos convert to bytes per sec to bit per sec
895                 }
896         } catch (boost::bad_lexical_cast &ex) {
897                 // don' conv qos downstream
898                 std::string buf("invalid QoS downstream value.(--qos-down)");
899                 l7vsadm_err.setter(true, buf);
900                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 42, buf, __FILE__, __LINE__);
901                 return false;
902         }
903         return true;
904 }
905 //! virtualservice option udp func.
906 //! @param[in] argument position
907 //! @param[in] argument count
908 //! @param[in] argument value
909 bool l7vs::l7vsadm::parse_opt_vs_udp_func(int &pos, int argc, char *argv[])
910 {
911         Logger logger(LOG_CAT_L7VSADM_COMMON, 12, "l7vsadm::parse_opt_vs_udp_func", __FILE__, __LINE__);
912
913         virtualservice_element &elem = request.vs_element; // request virtualservie element reference get.
914         elem.udpmode = true; // udpmode on.
915         boost::asio::ip::tcp::endpoint zeropoint;
916         if (zeropoint != elem.tcp_accept_endpoint) { // adddress tcp_acceptor endpoint
917                 std::stringstream sstream;
918                 sstream << elem.tcp_accept_endpoint;
919                 std::string endpoint = sstream.str();
920                 error_code err;
921                 elem.udp_recv_endpoint = string_to_endpoint<boost::asio::ip::udp>(endpoint, err);
922                 if (err) {
923                         std::stringstream buf;
924                         buf << "target endpoint parse error(--udp-service): " << err.get_message() << endpoint;
925                         l7vsadm_err.setter(true, buf.str());
926                         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 43, buf.str(), __FILE__, __LINE__);
927                         return false;
928                 }
929                 elem.tcp_accept_endpoint = zeropoint;
930         }
931         if (elem.realserver_vector.size() != 0 && elem.realserver_vector.front().tcp_endpoint != zeropoint) {
932                 std::stringstream sstream;
933                 sstream << elem.realserver_vector.front().tcp_endpoint;
934                 std::string endpoint = sstream.str();
935                 error_code err;
936                 elem.realserver_vector.front().udp_endpoint = string_to_endpoint<boost::asio::ip::udp> (endpoint, err);
937                 if (err) {
938                         std::stringstream buf;
939                         buf << "realserver endpoint parse error(--udp-service): " << err.get_message() << endpoint;
940                         l7vsadm_err.setter(true, buf.str());
941                         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 44, buf.str(), __FILE__, __LINE__);
942                         return false;
943                 }
944                 elem.realserver_vector.front().tcp_endpoint = zeropoint;
945         }
946         return true;
947 }
948 //! virtualservice option ssl_file function
949 //! @param[in] argument position
950 //! @param[in] argument count
951 //! @param[in] argument value
952 bool l7vs::l7vsadm::parse_opt_vs_ssl_file_func(int &pos, int argc, char *argv[])
953 {
954         Logger logger(LOG_CAT_L7VSADM_COMMON, 38, "l7vsadm::parse_opt_vs_ssl_file_func", __FILE__, __LINE__);
955
956         if (++pos >= argc) {
957                 std::string buf("ssl config file is not specified.(--ssl)");
958                 l7vsadm_err.setter(true, buf);
959                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 90, buf, __FILE__, __LINE__);
960                 return false;
961         }
962         // ssl config file check.
963         std::string conf_file_name = argv[pos];
964         if (L7VS_FILENAME_LEN < conf_file_name.length()) {
965                 std::string buf("ssl config file name is too long.(--ssl)");
966                 l7vsadm_err.setter(true, buf);
967                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 91, buf, __FILE__, __LINE__);
968                 return false;
969         }
970         FILE *fp;
971         if ((fp = fopen(conf_file_name.c_str(), "r")) == NULL) {
972                 std::string buf("ssl config file cannot open.(--ssl)");
973                 l7vsadm_err.setter(true, buf);
974                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 92, buf, __FILE__, __LINE__);
975                 return false;
976         }
977         fclose(fp);
978
979         request.vs_element.ssl_file_name = conf_file_name;
980         return true;
981 }
982
983 //! virtualservice option access log function
984 //! @param[in] argument position
985 //! @param[in] argument count
986 //! @param[in] argument value
987 bool l7vs::l7vsadm::parse_opt_vs_access_log_func(int &pos, int argc, char *argv[])
988 {
989         Logger logger(LOG_CAT_L7VSADM_COMMON, 39, "l7vsadm::parse_opt_vs_access_log_func", __FILE__, __LINE__);
990
991         if (++pos >= argc) {
992                 // access log flag is not specified
993                 std::string buf("access log flag value is not specified.(--access-log)");
994                 l7vsadm_err.setter(true, buf);
995                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 93, buf, __FILE__, __LINE__);
996                 return false;
997         }
998         try {
999                 int tmp = boost::lexical_cast<int>(argv[pos]);
1000                 if ((0 != tmp) && (1 != tmp)) {
1001                         std::string buf("invalid access log flag value.(--access-log)");
1002                         l7vsadm_err.setter(true, buf);
1003                         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 94, buf, __FILE__, __LINE__);
1004                         return false;
1005                 }
1006                 request.vs_element.access_log_flag = tmp;
1007         } catch (boost::bad_lexical_cast &e) {
1008                 std::string buf("invalid access log flag value.(--access-log)");
1009                 l7vsadm_err.setter(true, buf);
1010                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 95, buf, __FILE__, __LINE__);
1011                 return false;
1012         }
1013         return true;
1014 }
1015
1016 //! virtualservice option access_log_logrotate function
1017 //! @param[in] argument position
1018 //! @param[in] argument count
1019 //! @param[in] argument value
1020 bool l7vs::l7vsadm::parse_opt_vs_access_log_logrotate_func(int &pos, int argc, char *argv[])
1021 {
1022         Logger logger(LOG_CAT_L7VSADM_COMMON, 40, "l7vsadm::parse_opt_vs_accesslog_logrotate_func", __FILE__, __LINE__);
1023
1024         if (++pos >= argc) {
1025                 std::string buf("access log file is not specified.(--access-log-name)");
1026                 l7vsadm_err.setter(true, buf);
1027                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 96, buf, __FILE__, __LINE__);
1028                 return false;
1029         }
1030         // access log file check.
1031         std::string access_log_file_name = argv[pos];
1032         if (L7VS_FILENAME_LEN < access_log_file_name.length()) {
1033                 std::string buf("access log file name is too long.(--access-log-name)");
1034                 l7vsadm_err.setter(true, buf);
1035                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 97, buf, __FILE__, __LINE__);
1036                 return false;
1037         }
1038         if ("/" != access_log_file_name.substr(0, 1)) {
1039                 std::string buf("please specify access log filename in fullpath.(--access-log-name)");
1040                 l7vsadm_err.setter(true, buf);
1041                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 98, buf, __FILE__, __LINE__);
1042                 return false;
1043         }
1044
1045         request.vs_element.access_log_rotate_key_info = "";
1046
1047         // create access log args.
1048         std::vector<std::string> arguments_vector;
1049         virtualservice_element::access_log_rotate_arguments_map_type arguments_map;
1050         while (true) {
1051                 if (++pos == argc) break; //access log arguments end.
1052                 parse_opt_map_type::iterator vsitr = vs_option_dic.find(argv[pos]);
1053                 if (vsitr != vs_option_dic.end()) {
1054                         --pos; // back for next option
1055                         break; // module option end.
1056                 }
1057                 arguments_vector.push_back(argv[pos]);
1058
1059                 request.vs_element.access_log_rotate_key_info += argv[pos];
1060                 request.vs_element.access_log_rotate_key_info += " ";
1061
1062         }
1063         boost::algorithm::erase_last(request.vs_element.access_log_rotate_key_info , " ");
1064
1065         if (0 < arguments_vector.size()) {
1066                 if (0 == (arguments_vector.size() % 2)) {
1067                         for (unsigned int i = 0; i < (arguments_vector.size() - 1); ++i) {
1068                                 std::pair<virtualservice_element::access_log_rotate_arguments_map_type::iterator, bool> ret =
1069                                         arguments_map.insert(
1070                                                 virtualservice_element::access_log_rotate_arguments_pair_type(
1071                                                         arguments_vector[i], arguments_vector[i+1]));
1072                                 if (!ret.second) {
1073                                         std::string buf("access log rotation argument is duplicated.(--access-log-name)");
1074                                         l7vsadm_err.setter(true, buf);
1075                                         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 99, buf, __FILE__, __LINE__);
1076                                         return false;
1077                                 }
1078                                 ++i;
1079                         }
1080                 } else {
1081                         std::string buf("access log rotation argument error.(--access-log-name)");
1082                         l7vsadm_err.setter(true, buf);
1083                         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 100, buf, __FILE__, __LINE__);
1084                         return false;
1085                 }
1086                 bool ret = logger_access_manager::getInstance().access_log_logrotate_parameter_check(arguments_map);
1087                 if (!ret) {
1088                         std::string buf("access log rotation argument error.(--access-log-name)");
1089                         l7vsadm_err.setter(true, buf);
1090                         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 101, buf, __FILE__, __LINE__);
1091                         return false;
1092                 }
1093         }
1094
1095         request.vs_element.access_log_file_name = access_log_file_name;
1096         request.vs_element.access_log_rotate_arguments.clear();
1097         BOOST_FOREACH(virtualservice_element::access_log_rotate_arguments_pair_type pair, arguments_map) {
1098                 request.vs_element.access_log_rotate_arguments.insert(pair);
1099         }
1100
1101         return true;
1102 }
1103
1104 //! virtualservice option socket function
1105 //! @param[in] argument position
1106 //! @param[in] argument count
1107 //! @param[in] argument value
1108 bool l7vs::l7vsadm::parse_opt_vs_socket_func(int &pos, int argc, char *argv[])
1109 {
1110         Logger logger(LOG_CAT_L7VSADM_COMMON, 41, "l7vsadm::parse_opt_vs_socket_func", __FILE__, __LINE__);
1111
1112         if (++pos >= argc) {
1113                 std::string buf("socket option is not specified.(--sockopt)");
1114                 l7vsadm_err.setter(true, buf);
1115                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 102, buf, __FILE__, __LINE__);
1116                 return false;
1117         }
1118
1119         bool is_set_defer_accept = false;
1120         bool is_set_nodelay = false;
1121         bool is_set_cork = false;
1122         bool is_set_quickack = false;
1123
1124         request.vs_element.socket_option_tcp_defer_accept = 0;
1125         request.vs_element.socket_option_tcp_nodelay = 0;
1126         request.vs_element.socket_option_tcp_cork = 0;
1127         request.vs_element.socket_option_tcp_quickack = 0;
1128
1129         std::string socket_option_string = argv[pos];
1130         std::vector<std::string> socket_options;
1131         boost::split(socket_options, socket_option_string, boost::algorithm::is_any_of(","));
1132
1133         BOOST_FOREACH(std::string option, socket_options) {
1134                 if (option == "deferaccept") {
1135                         if (!is_set_defer_accept) {
1136                                 is_set_defer_accept = true;
1137                                 request.vs_element.socket_option_tcp_defer_accept = 1;
1138                         } else {
1139                                 // defer_accept is duplicated
1140                                 std::stringstream buf;
1141                                 buf << "socket option deferaccept is duplicated.(--sockopt)";
1142                                 l7vsadm_err.setter(true, buf.str());
1143                                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 103, buf.str(), __FILE__, __LINE__);
1144                                 return false;
1145                         }
1146                 } else if (option == "nodelay") {
1147                         if (!is_set_nodelay) {
1148                                 is_set_nodelay = true;
1149                                 request.vs_element.socket_option_tcp_nodelay = 1;
1150                         } else {
1151                                 // nodelay is duplicated
1152                                 std::stringstream buf;
1153                                 buf << "socket option nodelay is duplicated.(--sockopt)";
1154                                 l7vsadm_err.setter(true, buf.str());
1155                                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 104, buf.str(), __FILE__, __LINE__);
1156                                 return false;
1157                         }
1158                 } else if (option == "cork") {
1159                         if (!is_set_cork) {
1160                                 is_set_cork = true;
1161                                 request.vs_element.socket_option_tcp_cork = 1;
1162                         } else {
1163                                 // cork is duplicated
1164                                 std::stringstream buf;
1165                                 buf << "socket option cork is duplicated.(--sockopt)";
1166                                 l7vsadm_err.setter(true, buf.str());
1167                                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 105, buf.str(), __FILE__, __LINE__);
1168                                 return false;
1169                         }
1170                 } else if (option == "quickackon" || option == "quickackoff") {
1171                         if (!is_set_quickack) {
1172                                 is_set_quickack = true;
1173                                 request.vs_element.socket_option_tcp_quickack = ((option == "quickackon") ? 1 : 2);
1174                         } else {
1175                                 // quickack is duplicated
1176                                 std::stringstream buf;
1177                                 buf << "socket option quickack is duplicated.(--sockopt)";
1178                                 l7vsadm_err.setter(true, buf.str());
1179                                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 106, buf.str(), __FILE__, __LINE__);
1180                                 return false;
1181                         }
1182                 } else {
1183                         // unknown socket option
1184                         std::stringstream buf;
1185                         buf << "unknown socket option.(--sockopt)";
1186                         l7vsadm_err.setter(true, buf.str());
1187                         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 107, buf.str(), __FILE__, __LINE__);
1188                         return false;
1189                 }
1190         }
1191
1192         request.vs_element.socket_option_string = socket_option_string;
1193         return true;
1194
1195 }
1196 //! realserver command parsing.
1197 //! @param[in] request command
1198 //! @param[in] argument count
1199 //! @param[in] argument value
1200 bool l7vs::l7vsadm::parse_rs_func(l7vs::l7vsadm_request::COMMAND_CODE_TAG cmd, int argc, char *argv[])
1201 {
1202         Logger logger(LOG_CAT_L7VSADM_COMMON, 13, "l7vsadm::parse_rs_func", __FILE__, __LINE__);
1203
1204         if (argc < 8) {
1205                 //argument num err
1206                 std::stringstream buf;
1207                 buf << "Argument argc is illegal for ";
1208                 buf << argv[1];
1209                 buf << " command.";
1210
1211                 l7vsadm_err.setter(true, buf.str());
1212                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 121, buf.str(), __FILE__, __LINE__);
1213                 return false;
1214         }
1215
1216         request.command = cmd;
1217
1218         request.vs_element.realserver_vector.push_back(realserver_element());
1219
1220         std::map<std::string, int> count_map;
1221         for (parse_opt_map_type::iterator itr = rs_option_dic.begin() ;
1222              itr != rs_option_dic.end() ; ++itr) {
1223                 count_map[ itr->first ] = 0;
1224         }
1225
1226         for (int pos = 2; pos < argc; ++pos) {
1227                 parse_opt_map_type::iterator itr = rs_option_dic.find(argv[pos]);
1228                 if (itr != rs_option_dic.end()) {
1229                         count_map[ itr->first ]++;
1230                         if (! itr->second(pos, argc, argv)) return false;
1231                 } else {
1232                         std::stringstream buf;
1233                         buf << "realserver option not found(--real-server): " << argv[pos];
1234                         l7vsadm_err.setter(true, buf.str());
1235                         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 45, buf.str(), __FILE__, __LINE__);
1236                         return false;
1237                 }
1238         }
1239
1240         if (request.vs_element.protocol_module_name.length() == 0) {
1241                 //protocol module name error
1242                 std::string buf("protocol module is not specified.(--proto-module)");
1243                 l7vsadm_err.setter(true, buf);
1244                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 46, buf, __FILE__, __LINE__);
1245                 return false;
1246         }
1247         if (request.vs_element.udpmode) {
1248                 if (request.vs_element.udp_recv_endpoint == boost::asio::ip::udp::endpoint()) {
1249                         // udp mode,but not acceptor endpoint
1250                         std::string buf("udp receive endpoint is not specified.(--udp-service)");
1251                         l7vsadm_err.setter(true, buf);
1252                         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 47, buf, __FILE__, __LINE__);
1253                         return false;
1254                 }
1255                 if (request.vs_element.realserver_vector.front().udp_endpoint == boost::asio::ip::udp::endpoint()) {
1256                         // udp mode,but not realserver endpoint
1257                         std::string buf("realserver udp endpoint is not specified.(--real-server)");
1258                         l7vsadm_err.setter(true, buf);
1259                         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 48, buf, __FILE__, __LINE__);
1260                         return false;
1261                 }
1262         } else {
1263                 if (request.vs_element.tcp_accept_endpoint == boost::asio::ip::tcp::endpoint()) {
1264                         // tcp mode, but not acceptor endpoint
1265                         std::string buf("tcp accpeptor endpoint not specified.(--tcp-service)");
1266                         l7vsadm_err.setter(true, buf);
1267                         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 49, buf, __FILE__, __LINE__);
1268                         return false;
1269                 }
1270                 if (request.vs_element.realserver_vector.front().tcp_endpoint == boost::asio::ip::tcp::endpoint()) {
1271                         // tcp mode,but not realserver endpoint
1272                         std::string buf("realserver tcp endpoint not specified.(--real-server)");
1273                         l7vsadm_err.setter(true, buf);
1274                         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 50, buf, __FILE__, __LINE__);
1275                         return false;
1276                 }
1277         }
1278
1279         if (l7vsadm_request::CMD_EDIT_RS != cmd) {
1280                 // realserver weight default value = 1
1281                 if (-1 == request.vs_element.realserver_vector.front().weight) {
1282                         request.vs_element.realserver_vector.front().weight = 1;
1283                 }
1284                 // realserver forward mode default value = FWD_MASQ
1285                 if (realserver_element::FWD_NONE == request.vs_element.realserver_vector.front().fwdmode) {
1286                         request.vs_element.realserver_vector.front().fwdmode = realserver_element::FWD_MASQ;
1287                 }
1288         } else {
1289                 // Existence check of the parameter
1290                 if (count_map["-w"] == 0 &&
1291                     count_map["--weight"] == 0 &&
1292                     count_map["-M"] == 0 &&
1293                     count_map["--masq"] == 0 &&
1294                     count_map["-T"] == 0 &&
1295                     count_map["--tproxy"] == 0) {
1296                         std::string buf("All option omitted for edit rs command.");
1297                         l7vsadm_err.setter(true, buf);
1298                         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 112, buf, __FILE__, __LINE__);
1299                         return false;
1300                 }
1301         }
1302
1303         //conflict check
1304         std::string conflict_option_name;
1305         bool is_conflict = false;
1306
1307         for (std::map<std::string, int>::iterator itr = count_map.begin() ;
1308              itr != count_map.end() ; ++itr) {
1309                 if (itr->second > 1) {
1310                         conflict_option_name = itr->first;
1311                         is_conflict = true;
1312                         break;
1313                 }
1314         }
1315
1316         if (is_conflict == false &&
1317             count_map["-t"] == 1 && count_map["--tcp-service"] == 1) {
1318                 //-t(--tcp-service)
1319                 conflict_option_name = "--tcp-service";
1320                 is_conflict = true;
1321         }
1322         if (is_conflict == false &&
1323             count_map["-m"] == 1 && count_map["--proto-module"] == 1) {
1324                 //-m(--proto-module)
1325                 conflict_option_name = "--proto-module";
1326                 is_conflict = true;
1327         }
1328         if (is_conflict == false &&
1329             count_map["-r"] == 1 && count_map["--real-server"] == 1) {
1330                 //-r(--real-server)
1331                 conflict_option_name = "--real-server";
1332                 is_conflict = true;
1333         }
1334         if ((is_conflict == false) &&
1335             (count_map["-w"] == 1) && (count_map["--weight"] == 1) &&
1336             (l7vsadm_request::CMD_DEL_RS != cmd)) {
1337                 //-w(--weight)
1338                 conflict_option_name = "--weight";
1339                 is_conflict = true;
1340         }
1341         if ((is_conflict == false) &&
1342             (count_map["-M"] == 1) && (count_map["--masq"] == 1) &&
1343             (l7vsadm_request::CMD_DEL_RS != cmd)) {
1344                 //-M(--masq)
1345                 conflict_option_name = "--masq";
1346                 is_conflict = true;
1347         }
1348         if ((is_conflict == false) &&
1349             (count_map["-T"] == 1) && (count_map["--tproxy"] == 1) &&
1350             (l7vsadm_request::CMD_DEL_RS != cmd)) {
1351                 //-T(--tproxy)
1352                 conflict_option_name = "--tproxy";
1353                 is_conflict = true;
1354         }
1355         if ((is_conflict == false) &&
1356             count_map["-M"] + count_map["--masq"] +
1357             count_map["-T"] + count_map["--tproxy"] > 1 &&
1358             (l7vsadm_request::CMD_DEL_RS != cmd)) {
1359                 //-M/T(--masq/tproxy)
1360                 conflict_option_name = "--masq/tproxy";
1361                 is_conflict = true;
1362         }
1363
1364         if (is_conflict == true) {
1365                 std::stringstream buf;
1366                 buf << "Option " << conflict_option_name << " is conflict.";
1367                 l7vsadm_err.setter(true, buf.str());
1368                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 122, buf.str(), __FILE__, __LINE__);
1369                 return false;
1370         }
1371
1372         return true;
1373 }
1374 //
1375 // realserver option functions.
1376 //
1377 //! realserver weight set
1378 //! @param[in] argument position
1379 //! @param[in] argument count
1380 //! @param[in] argument value
1381 bool l7vs::l7vsadm::parse_opt_rs_weight_func(int &pos, int argc, char *argv[])
1382 {
1383         Logger logger(LOG_CAT_L7VSADM_COMMON, 14, "l7vsadm::parse_opt_rs_weight_func", __FILE__, __LINE__);
1384
1385         if (++pos >= argc) {
1386                 // weight value is not specified
1387                 std::string buf("weight value is not specified.(--weight)");
1388                 l7vsadm_err.setter(true, buf);
1389                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 51, buf, __FILE__, __LINE__);
1390                 return false;
1391         }
1392         try {
1393                 request.vs_element.realserver_vector.front().weight = boost::lexical_cast<int>(argv[pos]);
1394                 if ((0 > request.vs_element.realserver_vector.front().weight) ||
1395                     (100 < request.vs_element.realserver_vector.front().weight)) {
1396                         std::string buf("invalid weight value.(--weight)");
1397                         l7vsadm_err.setter(true, buf);
1398                         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 52, buf, __FILE__, __LINE__);
1399                         return false;
1400                 }
1401         } catch (boost::bad_lexical_cast &ex) {
1402                 // lexical cast error
1403                 std::string buf("invalid weight value.(--weight)");
1404                 l7vsadm_err.setter(true, buf);
1405                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 53, buf, __FILE__, __LINE__);
1406                 return false;
1407         }
1408         return true;
1409 }
1410 //! realserver forward mode set
1411 //! @param[in] argument position
1412 //! @param[in] argument count
1413 //! @param[in] argument value
1414 bool l7vs::l7vsadm::parse_opt_rs_fwdmode_func(int &pos, int argc, char *argv[])
1415 {
1416         Logger logger(LOG_CAT_L7VSADM_COMMON, /*XXX*/999, "l7vsadm::parse_opt_rs_fwdmode_func", __FILE__, __LINE__);
1417
1418         std::string opt(argv[pos]);
1419         if (opt == "-M" || opt == "--masq") {
1420                 request.vs_element.realserver_vector.front().fwdmode = realserver_element::FWD_MASQ;
1421         } else if (opt == "-T" || opt == "--tproxy") {
1422                 request.vs_element.realserver_vector.front().fwdmode = realserver_element::FWD_TPROXY;
1423         } else {
1424                 // should never come here
1425                 std::stringstream buf;
1426                 buf << boost::format("unknown realserver forward mode specified.(%s)") % opt;
1427                 l7vsadm_err.setter(true, buf.str());
1428                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, /*XXX*/999, buf.str(), __FILE__, __LINE__);
1429                 return false;
1430         }
1431         return true;
1432
1433 }
1434 //! realserver target set
1435 //! @param[in] argument position
1436 //! @param[in] argument count
1437 //! @param[in] argument value
1438 bool l7vs::l7vsadm::parse_opt_rs_realserver_func(int &pos, int argc, char *argv[])
1439 {
1440         Logger logger(LOG_CAT_L7VSADM_COMMON, 15, "l7vsadm::parse_opt_rs_realserver_func", __FILE__, __LINE__);
1441
1442         if (++pos >= argc) {
1443                 // realserver address is not specified
1444                 std::string buf("realserver address is not specified.(--real-server)");
1445                 l7vsadm_err.setter(true, buf);
1446                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 54, buf, __FILE__, __LINE__);
1447                 return false;
1448         }
1449         std::string src_str = argv[pos];
1450         if (request.vs_element.udpmode) {
1451                 error_code err;
1452                 request.vs_element.realserver_vector.front().udp_endpoint = string_to_endpoint<boost::asio::ip::udp>(src_str, err);
1453                 if (err) {
1454                         // address string error.
1455                         std::stringstream buf;
1456                         buf << "realserver endpoint parse error(--real-server): " << err.get_message() << src_str;
1457                         l7vsadm_err.setter(true, buf.str());
1458                         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 55, buf.str(), __FILE__, __LINE__);
1459                         return false;
1460                 }
1461                 check_endpoint<boost::asio::ip::udp>(request.vs_element.realserver_vector.front().udp_endpoint, false, err);
1462                 if (err) {
1463                         std::stringstream buf;
1464                         buf << "realserver endpoint parse error(--real-server): " << err.get_message() << src_str;
1465                         l7vsadm_err.setter(true, buf.str());
1466                         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 56, buf.str(), __FILE__, __LINE__);
1467                         return false;
1468                 }
1469         } else {
1470                 error_code err;
1471                 request.vs_element.realserver_vector.front().tcp_endpoint = string_to_endpoint<boost::asio::ip::tcp>(src_str, err);
1472                 if (err) {
1473                         // address string error.
1474                         std::stringstream buf;
1475                         buf << "realserver endpoint parse error(--real-server): " << err.get_message() << src_str;
1476                         l7vsadm_err.setter(true, buf.str());
1477                         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 57, buf.str(), __FILE__, __LINE__);
1478                         return false;
1479                 }
1480                 check_endpoint<boost::asio::ip::tcp>(request.vs_element.realserver_vector.front().tcp_endpoint, false, err);
1481                 if (err) {
1482                         std::stringstream buf;
1483                         buf << "realserver endpoint parse error(--real-server): " << err.get_message() << src_str;
1484                         l7vsadm_err.setter(true, buf.str());
1485                         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 58, buf.str(), __FILE__, __LINE__);
1486                         return false;
1487                 }
1488         }
1489         return true;
1490 }
1491
1492 //! replication command parsing.
1493 //! @param[in] request command
1494 //! @param[in] argument count
1495 //! @param[in] argument value
1496 bool l7vs::l7vsadm::parse_replication_func(l7vs::l7vsadm_request::COMMAND_CODE_TAG cmd, int argc, char *argv[])
1497 {
1498         Logger logger(LOG_CAT_L7VSADM_COMMON, 16, "l7vsadm::parse_replication_func", __FILE__, __LINE__);
1499
1500         if (argc < 3 || argc > 4) {
1501                 //argument num err
1502                 std::stringstream buf;
1503                 buf << "Argument argc is illegal for ";
1504                 buf << argv[1];
1505                 buf << " command.";
1506
1507                 l7vsadm_err.setter(true, buf.str());
1508                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 123, buf.str(), __FILE__, __LINE__);
1509                 return false;
1510         }
1511
1512         request.command = cmd;
1513
1514         for (int pos = 2; pos < argc; ++pos) {
1515                 parse_opt_map_type::iterator itr = replication_option_dic.find(argv[pos]);
1516                 if (itr != replication_option_dic.end()) {
1517                         if (! itr->second(pos, argc, argv)) return false;
1518                 } else {
1519                         std::stringstream buf;
1520                         buf << "replication option not found(--replication): " << argv[pos];
1521                         l7vsadm_err.setter(true, buf.str());
1522                         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 59, buf.str(), __FILE__, __LINE__);
1523                         return false;
1524                 }
1525         }
1526         if (l7vsadm_request::REP_NONE == request.replication_command) {
1527                 // not specified replication command
1528                 std::string buf("replication command not specified.(--replication)");
1529                 l7vsadm_err.setter(true, buf);
1530                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 60, buf, __FILE__, __LINE__);
1531                 return false;
1532         }
1533
1534         return true;
1535 }
1536
1537 //
1538 // replication option functions.
1539 //
1540 //! replication switch function
1541 //! @param[in] argument position
1542 //! @param[in] argument count
1543 //! @param[in] argument value
1544 bool l7vs::l7vsadm::parse_opt_replication_switch_func(int &pos, int argc, char *argv[])
1545 {
1546         Logger logger(LOG_CAT_L7VSADM_COMMON, 17, "l7vsadm::parse_opt_replication_switch_func", __FILE__, __LINE__);
1547
1548         if (request.replication_command != l7vsadm_request::REP_NONE) {
1549                 // double command target.
1550                 std::string buf("replication option is double specified.(--switch)");
1551                 l7vsadm_err.setter(true, buf);
1552                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 61, buf, __FILE__, __LINE__);
1553                 return false;
1554         }
1555         if (++pos >= argc) {
1556                 // replication switch value is not specified
1557                 std::string buf("replication switch option is not specified.(--switch)");
1558                 l7vsadm_err.setter(true, buf);
1559                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 62, buf, __FILE__, __LINE__);
1560                 return false;
1561         }
1562         parse_opt_map_type::iterator itr = replication_switch_option_dic.find(argv[pos]);
1563         if (itr != replication_switch_option_dic.end()) { // option string function find.
1564                 if (! itr->second(pos, argc, argv)) return false; // option string function error.
1565         } else { //option string function not found.
1566                 // print option not found message.
1567                 std::stringstream buf;
1568                 buf << "replication switch option not found(--switch): " << argv[pos];
1569                 l7vsadm_err.setter(true, buf.str());
1570                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 63, buf.str(), __FILE__, __LINE__);
1571                 return false;
1572         }
1573         return true;
1574 }
1575 //! replication start function
1576 //! @param[in] argument position
1577 //! @param[in] argument count
1578 //! @param[in] argument value
1579 bool l7vs::l7vsadm::parse_opt_replication_start_func(int &pos, int argc, char *argv[])
1580 {
1581         Logger logger(LOG_CAT_L7VSADM_COMMON, 18, "l7vsadm::parse_opt_replication_start_func", __FILE__, __LINE__);
1582
1583         request.replication_command = l7vsadm_request::REP_START;
1584         return true;
1585 }
1586 //! replication stop function
1587 //! @param[in] argument position
1588 //! @param[in] argument count
1589 //! @param[in] argument value
1590 bool l7vs::l7vsadm::parse_opt_replication_stop_func(int &pos, int argc, char *argv[])
1591 {
1592         Logger logger(LOG_CAT_L7VSADM_COMMON, 19, "l7vsadm::parse_opt_replication_stop_func", __FILE__, __LINE__);
1593
1594         request.replication_command = l7vsadm_request::REP_STOP;
1595         return true;
1596 }
1597 //! replication force function
1598 //! @param[in] argument position
1599 //! @param[in] argument count
1600 //! @param[in] argument value
1601 bool l7vs::l7vsadm::parse_opt_replication_force_func(int &pos, int argc, char *argv[])
1602 {
1603         Logger logger(LOG_CAT_L7VSADM_COMMON, 20, "l7vsadm::parse_opt_replication_force_func", __FILE__, __LINE__);
1604
1605         if (request.replication_command != l7vsadm_request::REP_NONE) {
1606                 // double command target.
1607                 std::string buf("replication option is double specified.(--force)");
1608                 l7vsadm_err.setter(true, buf);
1609                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 64, buf, __FILE__, __LINE__);
1610                 return false;
1611         }
1612         request.replication_command = l7vsadm_request::REP_FORCE;
1613         return true;
1614 }
1615 //! replication dump function
1616 //! @param[in] argument position
1617 //! @param[in] argument count
1618 //! @param[in] argument value
1619 bool l7vs::l7vsadm::parse_opt_replication_dump_func(int &pos, int argc, char *argv[])
1620 {
1621         Logger logger(LOG_CAT_L7VSADM_COMMON, 21, "l7vsadm::parse_opt_replication_dump_func", __FILE__, __LINE__);
1622
1623         if (request.replication_command != l7vsadm_request::REP_NONE) {
1624                 // double command target.
1625                 std::string buf("replication option is double specified.(--dump)");
1626                 l7vsadm_err.setter(true, buf);
1627                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 65, buf, __FILE__, __LINE__);
1628                 return false;
1629         }
1630         request.replication_command = l7vsadm_request::REP_DUMP;
1631         return true;
1632 }
1633
1634 //! log command parsing.
1635 //! @param[in] request command
1636 //! @param[in] argument count
1637 //! @param[in] argument value
1638 bool l7vs::l7vsadm::parse_log_func(l7vs::l7vsadm_request::COMMAND_CODE_TAG cmd, int argc, char *argv[])
1639 {
1640         Logger logger(LOG_CAT_L7VSADM_COMMON, 22, "l7vsadm::parse_log_func", __FILE__, __LINE__);
1641
1642         if (argc != 6) {
1643                 //argument num err
1644                 std::stringstream buf;
1645                 buf << "Argument argc is illegal for ";
1646                 buf << argv[1];
1647                 buf << " command.";
1648
1649                 l7vsadm_err.setter(true, buf.str());
1650                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 124, buf.str(), __FILE__, __LINE__);
1651                 return false;
1652         }
1653
1654         request.command = cmd;
1655
1656         for (int pos = 2; pos < argc; ++pos) {
1657                 parse_opt_map_type::iterator itr = log_option_dic.find(argv[pos]);
1658                 if (itr != log_option_dic.end()) { // option string function find.
1659                         if (! itr->second(pos, argc, argv)) return false; // option string function error.
1660                 } else { //option string function not found.
1661                         // print option not found message.
1662                         std::stringstream buf;
1663                         buf << "log option not found(--log): " << argv[pos];
1664                         l7vsadm_err.setter(true, buf.str());
1665                         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 66, buf.str(), __FILE__, __LINE__);
1666                         return false;
1667                 }
1668         }
1669         if (LOG_CAT_NONE == request.log_category) {
1670                 // not specified logcategory
1671                 std::string buf("log category is not specified(--category).");
1672                 l7vsadm_err.setter(true, buf);
1673                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 67, buf, __FILE__, __LINE__);
1674                 return false;
1675         }
1676         if (LOG_LV_NONE == request.log_level) {
1677                 // not specified loglevel
1678                 std::string buf("log level is not specified.(--level)");
1679                 l7vsadm_err.setter(true, buf);
1680                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 68, buf, __FILE__, __LINE__);
1681                 return false;
1682         }
1683
1684         return true;
1685 }
1686 //
1687 // log option function
1688 //
1689 //! log category set function
1690 //! @param[in] argument position
1691 //! @param[in] argument count
1692 //! @param[in] argument value
1693 bool l7vs::l7vsadm::parse_opt_log_category_func(int &pos, int argc, char *argv[])
1694 {
1695         Logger logger(LOG_CAT_L7VSADM_COMMON, 23, "l7vsadm::parse_opt_log_category_func", __FILE__, __LINE__);
1696
1697         if (request.log_category != LOG_CAT_NONE) {
1698                 // double target commands.
1699                 std::stringstream buf;
1700                 buf << "Option ";
1701                 buf << argv[pos];
1702                 buf << " conflict.";
1703
1704                 l7vsadm_err.setter(true, buf.str());
1705                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 69, buf.str(), __FILE__, __LINE__);
1706                 return false;
1707         }
1708         if (++pos >= argc) {
1709                 // log category is not specified.
1710                 std::string buf("log category is not specified.(--category)");
1711                 l7vsadm_err.setter(true, buf);
1712                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 70, buf, __FILE__, __LINE__);
1713                 return false;
1714         }
1715         string_logcategory_map_type::iterator itr = string_logcategory_dic.find(argv[pos]);
1716         if (itr != string_logcategory_dic.end()) {
1717                 request.log_category = itr->second;
1718                 return true;
1719         }
1720         std::stringstream buf;
1721         buf << "log category not found(--category): " << argv[pos];
1722         l7vsadm_err.setter(true, buf.str());
1723         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 71, buf.str(), __FILE__, __LINE__);
1724         return false;
1725 }
1726 //! log level set function
1727 //! @param[in] argument position
1728 //! @param[in] argument count
1729 //! @param[in] argument value
1730 bool l7vs::l7vsadm::parse_opt_log_level_func(int &pos, int argc, char *argv[])
1731 {
1732         Logger logger(LOG_CAT_L7VSADM_COMMON, 24, "l7vsadm::parse_opt_log_level_func", __FILE__, __LINE__);
1733
1734         if (request.log_level != LOG_LV_NONE) {
1735                 // double target commands.
1736                 std::stringstream buf;
1737                 buf << "Option ";
1738                 buf << argv[pos];
1739                 buf << " conflict.";
1740
1741                 l7vsadm_err.setter(true, buf.str());
1742                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 72, buf.str(), __FILE__, __LINE__);
1743                 return false;
1744         }
1745         if (++pos >= argc) {
1746                 // log level is not specified.
1747                 std::string buf("log level is not specified.(--level)");
1748                 l7vsadm_err.setter(true, buf);
1749                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 73, buf, __FILE__, __LINE__);
1750                 return false;
1751         }
1752         string_loglevel_map_type::iterator itr = string_loglevel_dic.find(argv[pos]);
1753         if (itr != string_loglevel_dic.end()) {
1754                 request.log_level = itr->second;
1755                 return true;
1756         }
1757         std::stringstream buf;
1758         buf << "log level not found(--level): " << argv[pos];
1759         l7vsadm_err.setter(true, buf.str());
1760         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 74, buf.str(), __FILE__, __LINE__);
1761         return false;
1762 }
1763
1764 //! snmp command parsing
1765 //! @param[in] request command
1766 //! @param[in] argument count
1767 //! @param[in] argument value
1768 bool l7vs::l7vsadm::parse_snmp_func(l7vs::l7vsadm_request::COMMAND_CODE_TAG cmd, int argc, char *argv[])
1769 {
1770         Logger logger(LOG_CAT_L7VSADM_COMMON, 25, "l7vsadm::parse_snmp_func", __FILE__, __LINE__);
1771
1772         if (argc != 6) {
1773                 //argument num err
1774                 std::stringstream buf;
1775                 buf << "Argument argc is illegal for ";
1776                 buf << argv[1];
1777                 buf << " command.";
1778
1779                 l7vsadm_err.setter(true, buf.str());
1780                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 125, buf.str(), __FILE__, __LINE__);
1781                 return false;
1782         }
1783
1784         request.command = cmd;
1785
1786         for (int pos = 2; pos < argc; ++pos) {
1787                 parse_opt_map_type::iterator itr = snmp_option_dic.find(argv[pos]);
1788                 if (itr != snmp_option_dic.end()) { // option string function find.
1789                         if (! itr->second(pos, argc, argv)) return false; // option string function error.
1790                 } else { //option string function not found.
1791                         // print option not found message.
1792                         std::stringstream buf;
1793                         buf << "snmp log option not found(--snmp): " << argv[pos];
1794                         l7vsadm_err.setter(true, buf.str());
1795                         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 75, buf.str(), __FILE__, __LINE__);
1796                         return false;
1797                 }
1798         }
1799         if (LOG_CAT_NONE == request.snmp_log_category) {
1800                 // not specified logcategory
1801                 std::string buf("snmp log category not specified.(--category)");
1802                 l7vsadm_err.setter(true, buf);
1803                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 76, buf, __FILE__, __LINE__);
1804                 return false;
1805         }
1806         if (LOG_LV_NONE == request.snmp_log_level) {
1807                 // not specified loglevel
1808                 std::string buf("snmp log level not specified.(--level)");
1809                 l7vsadm_err.setter(true, buf);
1810                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 77, buf, __FILE__, __LINE__);
1811                 return false;
1812         }
1813         return true;
1814 }
1815 //! snmp log category set function
1816 //! @param[in] argument position
1817 //! @param[in] argument count
1818 //! @param[in] argument value
1819 bool l7vs::l7vsadm::parse_opt_snmp_log_category_func(int &pos, int argc, char *argv[])
1820 {
1821         Logger logger(LOG_CAT_L7VSADM_COMMON, 26, "l7vsadm::parse_opt_snmp_log_category_func", __FILE__, __LINE__);
1822
1823         if (request.snmp_log_category != LOG_CAT_NONE) {
1824                 // double target commands.
1825                 std::stringstream buf;
1826                 buf << "Option ";
1827                 buf << argv[pos];
1828                 buf << " conflict.";
1829
1830                 l7vsadm_err.setter(true, buf.str());
1831                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 78, buf.str(), __FILE__, __LINE__);
1832                 return false;
1833         }
1834         if (++pos >= argc) {
1835                 // log category is not specified.
1836                 std::string buf("snmp log category is not specified.(--category)");
1837                 l7vsadm_err.setter(true, buf);
1838                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 79, buf, __FILE__, __LINE__);
1839                 return false;
1840         }
1841         string_logcategory_map_type::iterator itr = string_snmp_logcategory_dic.find(argv[pos]);
1842         if (itr != string_snmp_logcategory_dic.end()) {
1843                 request.snmp_log_category = itr->second;
1844                 return true;
1845         }
1846         std::stringstream buf;
1847         buf << "snmp log category not found(--category): " << argv[pos];
1848         l7vsadm_err.setter(true, buf.str());
1849         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 80, buf.str(), __FILE__, __LINE__);
1850         return false;
1851 }
1852 //! snmp log level set function
1853 //! @param[in] argument position
1854 //! @param[in] argument count
1855 //! @param[in] argument value
1856 bool l7vs::l7vsadm::parse_opt_snmp_log_level_func(int &pos, int argc, char *argv[])
1857 {
1858         Logger logger(LOG_CAT_L7VSADM_COMMON, 27, "l7vsadm::parse_opt_snmp_log_level_func", __FILE__, __LINE__);
1859
1860         if (request.snmp_log_level != LOG_LV_NONE) {
1861                 // double target commands.
1862                 std::stringstream buf;
1863                 buf << "Option ";
1864                 buf << argv[pos];
1865                 buf << " conflict.";
1866
1867                 l7vsadm_err.setter(true, buf.str());
1868                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 81, buf.str(), __FILE__, __LINE__);
1869                 return false;
1870         }
1871         if (++pos >= argc) {
1872                 // log category is not specified.
1873                 std::string buf("snmp log level is not specified.(--level)");
1874                 l7vsadm_err.setter(true, buf);
1875                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 82, buf, __FILE__, __LINE__);
1876                 return false;
1877         }
1878         string_loglevel_map_type::iterator itr = string_loglevel_dic.find(argv[pos]);
1879         if (itr != string_loglevel_dic.end()) {
1880                 request.snmp_log_level = itr->second;
1881                 return true;
1882         }
1883         std::stringstream buf;
1884         buf << "snmp loglevel not found(--level): " << argv[pos];
1885         l7vsadm_err.setter(true, buf.str());
1886         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 83, buf.str(), __FILE__, __LINE__);
1887         return false;
1888 }
1889
1890 //! parameter command parsing
1891 //! @param[in] request command
1892 //! @param[in] argument count
1893 //! @param[in] argument value
1894 bool l7vs::l7vsadm::parse_parameter_func(l7vs::l7vsadm_request::COMMAND_CODE_TAG cmd, int argc, char *argv[])
1895 {
1896         Logger logger(LOG_CAT_L7VSADM_COMMON, 28, "l7vsadm::parse_parameter_func", __FILE__, __LINE__);
1897
1898         if (argc != 4) {
1899                 //argument num err
1900                 std::stringstream buf;
1901                 buf << "Argument argc is illegal for ";
1902                 buf << argv[1];
1903                 buf << " command.";
1904
1905                 l7vsadm_err.setter(true, buf.str());
1906                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 126, buf.str(), __FILE__, __LINE__);
1907                 return false;
1908         }
1909
1910         request.command = cmd;
1911
1912         for (int pos = 2; pos < argc; ++pos) {
1913                 parse_opt_map_type::iterator itr = parameter_option_dic.find(argv[pos]);
1914                 if (itr != parameter_option_dic.end()) { // option string function find.
1915                         if (! itr->second(pos, argc, argv)) return false; // option string function error.
1916                 } else { //option string function not found.
1917                         // print option not found message.
1918                         std::stringstream buf;
1919                         buf << "parameter option not found(--parameter): " << argv[pos];
1920                         l7vsadm_err.setter(true, buf.str());
1921                         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 84, buf.str(), __FILE__, __LINE__);
1922                         return false;
1923                 }
1924         }
1925
1926         if (PARAM_COMP_NOCAT == request.reload_param) {
1927                 // not specified reload_param
1928                 std::string buf("reload component is not specified.(--reload)");
1929                 l7vsadm_err.setter(true, buf);
1930                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 85, buf, __FILE__, __LINE__);
1931                 return false;
1932         }
1933
1934         return true;
1935 }
1936 //
1937 // parameter command
1938 //
1939 //! parameter reload component parsing
1940 //! @param[in] argument position
1941 //! @param[in] argument count
1942 //! @param[in] argument value
1943 bool l7vs::l7vsadm::parse_opt_parameter_reload_func(int &pos, int argc, char *argv[])
1944 {
1945         Logger logger(LOG_CAT_L7VSADM_COMMON, 29, "l7vsadm::parse_opt_parameter_reload_func", __FILE__, __LINE__);
1946
1947         if (++pos >= argc) {
1948                 // reload component is not specified
1949                 std::string buf("reload component is not specified.(--reload)");
1950                 l7vsadm_err.setter(true, buf);
1951                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 86, buf, __FILE__, __LINE__);
1952                 return false;
1953         }
1954         string_parameter_map_type::iterator itr = string_parameter_dic.find(argv[pos]);
1955         if (itr != string_parameter_dic.end()) {
1956                 request.reload_param = itr->second;
1957                 return true;
1958         }
1959         std::stringstream buf;
1960         buf << "reload component not found(--reload): " << argv[pos];
1961         l7vsadm_err.setter(true, buf.str());
1962         Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 87, buf.str(), __FILE__, __LINE__);
1963         return false;
1964 }
1965
1966 //! help command parsing
1967 //! @param[in] request command
1968 //! @param[in] argument count
1969 //! @param[in] argument value
1970 bool l7vs::l7vsadm::parse_help_func(l7vs::l7vsadm_request::COMMAND_CODE_TAG cmd, int argc, char *argv[])
1971 {
1972         Logger logger(LOG_CAT_L7VSADM_COMMON, 30, "l7vsadm::parse_help_func", __FILE__, __LINE__);
1973
1974         request.command = cmd;
1975
1976         std::cout << usage();
1977
1978         std::cout <<
1979                   "Commands:\n"
1980                   "  --add-service      -A        add virtual service with options\n"
1981                   "  --edit-service     -E        edit virtual service with options\n"
1982                   "  --delete-service   -D        delete virtual service with options\n"
1983                   "  --flush            -C        flush virtual service\n"
1984                   "  --add-server       -a        add real server with options\n"
1985                   "  --edit-server      -e        edit real server with options\n"
1986                   "  --delete-server    -d        delete real server with options\n"
1987                   "  --replication      -R        control replication-function\n"
1988                   "  --log              -L        control logger-function\n"
1989                   "  --snmp             -S        control SNMP Agent-function\n"
1990                   "  --parameter        -P        control parameter-function\n"
1991                   "  --list             -l        list the table\n"
1992                   "  --verbose          -V        list the table in verbose format\n"
1993                   "  --key              -K        list the table in key setting format\n"
1994                   "  --help             -h        show usage\n"
1995                   << std::endl;
1996
1997         std::cout <<
1998                   "Options:\n"
1999                   "  --tcp-service      -t service-address     service-address is host:port\n"
2000                   "  --proto-module     -m proto-module        protocol module name and module argment\n"
2001                   "                        [module-args]\n"
2002                   "  --scheduler        -s scheduler           one of rr,lc,wrr\n"
2003                   "  --upper            -u connection-count    maximum number of connections\n"
2004                   "  --bypass           -b sorry-server        sorry server address is host:port\n"
2005                   "  --tproxy           -T                     set sorry server connection to IP transparent mode.\n"
2006                   "  --masq             -M                     set sorry server connection to IP masquarade mode.\n"
2007
2008                   "  --flag             -f sorry-flag          sorry status set to virtual service\n"
2009                   "  --qos-up           -Q QoSval-up           QoS Threshold(bps) set to real server direction\n"
2010                   "  --qos-down         -q QoSval-down         QoS Threshold(bps) set to client direction\n"
2011                   "  --ssl              -z ssl-config-file     SSL configuration file(Use SSL)\n"
2012                   "  --sockopt          -O socket-option       deferaccept,nodelay,cork,quickackon or quickackoff set to socket option\n"
2013                   "  --access-log       -L access-log-flag     access log flag 0(none) or 1(output)\n"
2014                   "  --access-log-name  -a access-log-file     access log file\n"
2015                   "                        [logrotate-args]\n"
2016                   "  --real-server      -r server-address      server-address is host:port\n"
2017                   "  --weight           -w weight              scheduling weight set to real server\n"
2018                   "  --tproxy           -T                     set real server connection to IP transparent mode.\n"
2019                   "  --masq             -M                     set real server connection to IP masquarade mode.\n"
2020                   "  --switch           -s replication-switch  start or stop replication\n"
2021                   "  --force            -f                     force replication start\n"
2022                   "  --dump             -d                     dump replication memory\n"
2023                   "  --category         -c log-category        set log category for l7vsd or SNMP Agent\n"
2024                   "  --level            -l log-level           set log level for l7vsd or SNMP Agent\n"
2025                   "  --reload           -r reload-parameter    reload specified config parameter\n"
2026                   "  --numeric          -n                     list the table in numeric\n"
2027                   << std::endl;
2028
2029         return true;
2030 }
2031
2032 //! usage function.
2033 std::string l7vs::l7vsadm::usage()
2034 {
2035         Logger logger(LOG_CAT_L7VSADM_COMMON, 31, "l7vsadm::usage", __FILE__, __LINE__);
2036
2037         std::stringstream stream;
2038         stream <<
2039                "Usage: \n"
2040                "  l7vsadm -A -t service-address -m proto-module [module-args]\n"
2041                "          [-s scheduler] [-u connection-count] [-b sorry-server] [-T|M]\n"
2042                "          [-f sorry-flag] [-Q QoSval-up] [-q QoSval-down] [-z ssl-config-file]\n"
2043                "          [-O socket-option] [-L access-log-flag] [-a access-log-file [logrotate-args]]\n"
2044                "  l7vsadm -E -t service-address -m proto-module [module-args]\n"
2045                "          [-s scheduler] [-u connection-count] [-b sorry-server] [-T|M]\n"
2046                "          [-f sorry-flag] [-Q QoSval-up] [-q QoSval-down] [-L access-log-flag]\n"
2047                "  l7vsadm -D -t service-address -m proto-module [module-args]\n"
2048                "  l7vsadm -C\n"
2049                "  l7vsadm -a|e -t service-address -m proto-module [module-args]\n"
2050                "          -r server-address [-w weight] [-T|M]\n"
2051                "  l7vsadm -d -t service-address -m proto-module [module-args]\n"
2052                "          -r server-address\n"
2053                "  l7vsadm -R -s replication-switch\n"
2054                "  l7vsadm -R -f\n"
2055                "  l7vsadm -R -d\n"
2056                "  l7vsadm -L -c log-category -l log-level\n"
2057                "  l7vsadm -S -c log-category -l log-level\n"
2058                "  l7vsadm -P -r reload-parameter\n"
2059                "  l7vsadm -l [-n]\n"
2060                "  l7vsadm -V [-n]\n"
2061                "  l7vsadm -K [-n]\n"
2062                "  l7vsadm -h\n"
2063                << std::endl;
2064         return stream.str();
2065 }
2066
2067 //! disp_list function
2068 void l7vs::l7vsadm::disp_list()
2069 {
2070         Logger logger(LOG_CAT_L7VSADM_COMMON, 32, "l7vsadm::disp_list", __FILE__, __LINE__);
2071
2072         std::stringstream buf;
2073         buf << boost::format("Layer-7 Virtual Server version %s\n") % VERSION;
2074         buf << "Prot LocalAddress:Port ProtoMod Scheduler\n";
2075         buf << "  -> RemoteAddress:Port           Forward Weight ActiveConn InactConn\n";
2076         BOOST_FOREACH(virtualservice_element vse, response.virtualservice_status_list) {
2077                 std::string vsepstr;
2078                 if (vse.udpmode) {
2079                         vsepstr = endpoint_to_string<boost::asio::ip::udp>(vse.udp_recv_endpoint, numeric_flag);
2080                 } else {
2081                         vsepstr = endpoint_to_string<boost::asio::ip::tcp>(vse.tcp_accept_endpoint, numeric_flag);
2082                 }
2083                 buf << boost::format("%s %s %s %s\n")
2084                     % (vse.udpmode ? "UDP" : "TCP")
2085                     % vsepstr
2086                     % vse.protocol_module_name
2087                     % vse.schedule_module_name;
2088                 BOOST_FOREACH(realserver_element rse, vse.realserver_vector) {
2089                         std::string rsepstr;
2090                         if (vse.udpmode) {
2091                                 rsepstr = endpoint_to_string<boost::asio::ip::udp>(rse.udp_endpoint, numeric_flag);
2092                         } else {
2093                                 rsepstr = endpoint_to_string<boost::asio::ip::tcp>(rse.tcp_endpoint, numeric_flag);
2094                         }
2095                         buf << boost::format("  -> %-28s %-7s %-6d %-10d %-10d\n")
2096                             % rsepstr
2097                             % rse.get_fwdmode_str()
2098                             % rse.weight
2099                             % rse.get_active()
2100                             % rse.get_inact();
2101                 }
2102         }
2103         std::cout << buf.str();
2104 }
2105
2106 //! disp_list_key function
2107 void l7vs::l7vsadm::disp_list_key()
2108 {
2109         Logger logger(LOG_CAT_L7VSADM_COMMON, 33, "l7vsadm::disp_list_key", __FILE__, __LINE__);
2110
2111         std::stringstream buf;
2112         buf << boost::format("Layer-7 Virtual Server version %s\n") % VERSION;
2113         buf << "Prot LocalAddress:Port ProtoMod Scheduler\n";
2114         buf << "     SSL_config_file\n";
2115         buf << "     Socket option\n";
2116         buf << "     Access_log_flag\n";
2117         buf << "     Access_log_file\n";
2118         buf << "     Access_log_rotate option\n";
2119         buf << "  -> RemoteAddress:Port           Forward Weight ActiveConn InactConn\n";
2120         BOOST_FOREACH(virtualservice_element vse, response.virtualservice_status_list) {
2121                 std::string vsepstr;
2122                 if (vse.udpmode) {
2123                         vsepstr = endpoint_to_string<boost::asio::ip::udp>(vse.udp_recv_endpoint, numeric_flag);
2124                 } else {
2125                         vsepstr = endpoint_to_string<boost::asio::ip::tcp>(vse.tcp_accept_endpoint, numeric_flag);
2126                 }
2127                 buf << boost::format("%s %s %s %s\n")
2128                     % (vse.udpmode ? "UDP" : "TCP")
2129                     % vsepstr
2130                     % vse.protocol_module_name
2131                     % vse.schedule_module_name;
2132                 buf << boost::format("    %s\n")
2133                     % ((0 == vse.ssl_file_name.length()) ? "none" : vse.ssl_file_name);
2134                 buf << boost::format("    %s\n")
2135                     % ((0 == vse.socket_option_string.length()) ? "none" : vse.socket_option_string);
2136                 buf << boost::format("    %d\n") % vse.access_log_flag;
2137                 buf << boost::format("    %s\n")
2138                     % ((0 == vse.access_log_file_name.length()) ? "none" : vse.access_log_file_name);
2139                 buf << boost::format("    %s\n")
2140                     % ((0 == vse.access_log_rotate_key_info.length()) ? "none" :  vse.access_log_rotate_key_info);
2141
2142                 BOOST_FOREACH(realserver_element rse, vse.realserver_vector) {
2143                         std::string    rsepstr;
2144                         if (vse.udpmode)
2145                                 rsepstr = endpoint_to_string<boost::asio::ip::udp>(rse.udp_endpoint, numeric_flag);
2146                         else
2147                                 rsepstr = endpoint_to_string<boost::asio::ip::tcp>(rse.tcp_endpoint, numeric_flag);
2148                         buf << boost::format("  -> %-28s %-7s %-6d %-10d %-10d\n")
2149                             % rsepstr
2150                             % rse.get_fwdmode_str()
2151                             % rse.weight
2152                             % rse.get_active()
2153                             % rse.get_inact();
2154                 }
2155         }
2156         std::cout << buf.str();
2157 }
2158
2159 //! disp_list_verbose function
2160 void l7vs::l7vsadm::disp_list_verbose()
2161 {
2162         Logger logger(LOG_CAT_L7VSADM_COMMON, 34, "l7vsadm::disp_list_verbose", __FILE__, __LINE__);
2163
2164         unsigned long long output_qos_upstream_value;
2165         unsigned long long output_qos_downstream_value;
2166
2167         std::stringstream buf;
2168         buf << boost::format("Layer-7 Virtual Server version %s\n") % VERSION;
2169
2170         //disp loglevel
2171         buf << "L7vsd Log Level:\n";
2172         buf << "Category                       Level\n";
2173         typedef std::pair<LOG_CATEGORY_TAG, LOG_LEVEL_TAG> logstatus_type;
2174         BOOST_FOREACH(logstatus_type logstatus, response.log_status_list) {
2175                 buf << boost::format("%-30s %s\n")
2176                     % logcategory_string_dic[logstatus.first]
2177                     % loglevel_string_dic[logstatus.second];
2178         }
2179         buf << "\n";
2180
2181         //disp replication
2182         buf << "Replication Mode:\n";
2183         buf << boost::format("%s\n") % replication_mode_string_dic[response.replication_mode_status];
2184         buf << "\n";
2185
2186         //disp snmp connection status
2187         buf << "SNMPAgent Connection Status:\n";
2188         if (response.snmp_connection_status)
2189                 buf << "connecting\n";
2190         else
2191                 buf << "non-connecting\n";
2192         buf << "\n";
2193
2194         //disp snmp loglevel
2195         buf << "SNMPAgent Log Level:\n";
2196         buf << "Category                       Level\n";
2197         BOOST_FOREACH(logstatus_type snmplogstatus, response.snmp_log_status_list) {
2198                 buf << boost::format("%-30s %s\n")
2199                     % snmp_logcategory_string_dic[snmplogstatus.first]
2200                     % loglevel_string_dic[snmplogstatus.second];
2201         }
2202         buf << "\n";
2203
2204         // disp vs
2205         buf << "Prot LocalAddress:Port ProtoMod Scheduler Protomod_opt_string\n";
2206         buf << "     SorryAddress:Port Sorry_cc Sorry_flag\n";
2207         buf << "     QoS-up   Throughput-up\n";
2208         buf << "     QoS-down Throughput-down\n";
2209         buf << "     SSL_config_file\n";
2210         buf << "     Socket option\n";
2211         buf << "     Access_log_flag\n";
2212         buf << "     Access_log_file\n";
2213         buf << "     Access_log_rotate option\n";
2214         buf << "  -> RemoteAddress:Port           Forward Weight ActiveConn InactConn\n";
2215         BOOST_FOREACH(virtualservice_element vse, response.virtualservice_status_list) {
2216                 std::string vsepstr;
2217                 if (vse.udpmode) {
2218                         vsepstr = endpoint_to_string<boost::asio::ip::udp>(vse.udp_recv_endpoint, numeric_flag);
2219                 } else {
2220                         vsepstr = endpoint_to_string<boost::asio::ip::tcp>(vse.tcp_accept_endpoint, numeric_flag);
2221                 }
2222
2223                 if (vse.qos_upstream == ULLONG_MAX) {
2224                         output_qos_upstream_value = 0;
2225                 } else {
2226                         output_qos_upstream_value = vse.qos_upstream * 8;
2227                 }
2228
2229                 if (vse.qos_downstream == ULLONG_MAX) {
2230                         output_qos_downstream_value = 0;
2231                 } else {
2232                         output_qos_downstream_value = vse.qos_downstream * 8;
2233                 }
2234
2235                 buf << boost::format("%s %s %s %s %s\n")
2236                     % (vse.udpmode ? "UDP" : "TCP")
2237                     % vsepstr
2238                     % vse.protocol_module_name
2239                     % vse.schedule_module_name
2240                     % vse.protocol_module_for_indication_options;
2241                 if (!vse.udpmode) {
2242                         std::stringstream sorry_ep;
2243                         boost::asio::ip::tcp::endpoint zeropoint;
2244                         if (zeropoint == vse.sorry_endpoint) {
2245                                 sorry_ep << "none";
2246                         } else {
2247                                 sorry_ep << endpoint_to_string<boost::asio::ip::tcp>(
2248                                                 vse.sorry_endpoint, numeric_flag);
2249                                 sorry_ep << boost::format("(%s)") % vse.get_fwdmode_str();
2250                         }
2251                         buf << boost::format("    %s %d %d\n")
2252                             % sorry_ep.str()
2253                             % vse.sorry_maxconnection
2254                             % vse.sorry_flag;
2255                 }
2256                 // QoS value and throughput convert from byte/s to bps.
2257                 buf << boost::format("    %lld %lld\n")
2258                     % (output_qos_upstream_value)
2259                     % (vse.throughput_upstream * 8);
2260                 buf << boost::format("    %lld %lld\n")
2261                     % (output_qos_downstream_value)
2262                     % (vse.throughput_downstream * 8);
2263                 buf << boost::format("    %s\n")
2264                     % ((0 == vse.ssl_file_name.length()) ? "none" : vse.ssl_file_name);
2265                 buf << boost::format("    %s\n")
2266                     % ((0 == vse.socket_option_string.length()) ? "none" : vse.socket_option_string);
2267                 buf << boost::format("    %d\n") % vse.access_log_flag;
2268                 buf << boost::format("    %s\n")
2269                     % ((0 == vse.access_log_file_name.length()) ? "none" : vse.access_log_file_name);
2270                 buf << boost::format("    %s\n")
2271                     % ((0 == vse.access_log_rotate_verbose_info.length()) ? "none" : vse.access_log_rotate_verbose_info);
2272
2273                 BOOST_FOREACH(realserver_element rse, vse.realserver_vector) {
2274                         std::string rsepstr;
2275                         if (vse.udpmode) {
2276                                 rsepstr = endpoint_to_string<boost::asio::ip::udp>(rse.udp_endpoint, numeric_flag);
2277                         } else {
2278                                 rsepstr = endpoint_to_string<boost::asio::ip::tcp>(rse.tcp_endpoint, numeric_flag);
2279                         }
2280                         buf << boost::format("  -> %-28s %-7s %-6d %-10d %-10d\n")
2281                             % rsepstr
2282                             % rse.get_fwdmode_str()
2283                             % rse.weight
2284                             % rse.get_active()
2285                             % rse.get_inact();
2286                 }
2287         }
2288         std::cout << buf.str();
2289 }
2290 //! l7vsadm constractor.
2291 //! create including all dictionary.
2292 l7vs::l7vsadm::l7vsadm()
2293         :
2294         numeric_flag(false),
2295         command_wait_interval(L7VSADM_DEFAULT_WAIT_INTERVAL),
2296         command_wait_count(L7VSADM_DEFAULT_WAIT_COUNT)
2297 {
2298         Logger logger(LOG_CAT_L7VSADM_COMMON, 35, "l7vsadm::l7vsadm(constructor)", __FILE__, __LINE__);
2299
2300         // create command dictionary.
2301         command_dic["-l"]               = boost::bind(&l7vsadm::parse_list_func, this, l7vsadm_request::CMD_LIST, _1, _2);
2302         command_dic["--list"]           = boost::bind(&l7vsadm::parse_list_func, this, l7vsadm_request::CMD_LIST, _1, _2);
2303         command_dic["-V"]               = boost::bind(&l7vsadm::parse_list_func, this, l7vsadm_request::CMD_LIST_VERBOSE, _1, _2);
2304         command_dic["--verbose"]        = boost::bind(&l7vsadm::parse_list_func, this, l7vsadm_request::CMD_LIST_VERBOSE, _1, _2);
2305         command_dic["-K"]               = boost::bind(&l7vsadm::parse_list_func, this, l7vsadm_request::CMD_LIST_KEY, _1, _2);
2306         command_dic["--key"]            = boost::bind(&l7vsadm::parse_list_func, this, l7vsadm_request::CMD_LIST_KEY, _1, _2);
2307         command_dic["-A"]               = boost::bind(&l7vsadm::parse_vs_func, this, l7vsadm_request::CMD_ADD_VS, _1, _2);
2308         command_dic["--add-service"]    = boost::bind(&l7vsadm::parse_vs_func, this, l7vsadm_request::CMD_ADD_VS, _1, _2);
2309         command_dic["-D"]               = boost::bind(&l7vsadm::parse_vs_func, this, l7vsadm_request::CMD_DEL_VS, _1, _2);
2310         command_dic["--delete-service"] = boost::bind(&l7vsadm::parse_vs_func, this, l7vsadm_request::CMD_DEL_VS, _1, _2);
2311         command_dic["-E"]               = boost::bind(&l7vsadm::parse_vs_func, this, l7vsadm_request::CMD_EDIT_VS, _1, _2);
2312         command_dic["--edit-service"]   = boost::bind(&l7vsadm::parse_vs_func, this, l7vsadm_request::CMD_EDIT_VS, _1, _2);
2313         command_dic["-C"]               = boost::bind(&l7vsadm::parse_vs_func, this, l7vsadm_request::CMD_FLUSH_VS, _1, _2);
2314         command_dic["--flush"]          = boost::bind(&l7vsadm::parse_vs_func, this, l7vsadm_request::CMD_FLUSH_VS, _1, _2);
2315         command_dic["-a"]               = boost::bind(&l7vsadm::parse_rs_func, this, l7vsadm_request::CMD_ADD_RS, _1, _2);
2316         command_dic["--add-server"]     = boost::bind(&l7vsadm::parse_rs_func, this, l7vsadm_request::CMD_ADD_RS, _1, _2);
2317         command_dic["-d"]               = boost::bind(&l7vsadm::parse_rs_func, this, l7vsadm_request::CMD_DEL_RS, _1, _2);
2318         command_dic["--delete-server"]  = boost::bind(&l7vsadm::parse_rs_func, this, l7vsadm_request::CMD_DEL_RS, _1, _2);
2319         command_dic["-e"]               = boost::bind(&l7vsadm::parse_rs_func, this, l7vsadm_request::CMD_EDIT_RS, _1, _2);
2320         command_dic["--edit-server"]    = boost::bind(&l7vsadm::parse_rs_func, this, l7vsadm_request::CMD_EDIT_RS, _1, _2);
2321         command_dic["-R"]               = boost::bind(&l7vsadm::parse_replication_func, this, l7vsadm_request::CMD_REPLICATION, _1, _2);
2322         command_dic["--replication"]    = boost::bind(&l7vsadm::parse_replication_func, this, l7vsadm_request::CMD_REPLICATION, _1, _2);
2323         command_dic["-L"]               = boost::bind(&l7vsadm::parse_log_func, this, l7vsadm_request::CMD_LOG, _1, _2);
2324         command_dic["--log"]            = boost::bind(&l7vsadm::parse_log_func, this, l7vsadm_request::CMD_LOG, _1, _2);
2325         command_dic["-S"]               = boost::bind(&l7vsadm::parse_snmp_func, this, l7vsadm_request::CMD_SNMP, _1, _2);
2326         command_dic["--snmp"]           = boost::bind(&l7vsadm::parse_snmp_func, this, l7vsadm_request::CMD_SNMP, _1, _2);
2327         command_dic["-P"]               = boost::bind(&l7vsadm::parse_parameter_func, this, l7vsadm_request::CMD_PARAMETER, _1, _2);
2328         command_dic["--parameter"]      = boost::bind(&l7vsadm::parse_parameter_func, this, l7vsadm_request::CMD_PARAMETER, _1, _2);
2329         command_dic["-h"]               = boost::bind(&l7vsadm::parse_help_func, this, l7vsadm_request::CMD_HELP, _1, _2);
2330         command_dic["--help"]           = boost::bind(&l7vsadm::parse_help_func, this, l7vsadm_request::CMD_HELP, _1, _2);
2331
2332         // create list option dictionary.
2333         list_option_dic["-n"]        = boost::bind(&l7vsadm::parse_opt_list_numeric_func, this, _1, _2, _3);
2334         list_option_dic["--numeric"] = boost::bind(&l7vsadm::parse_opt_list_numeric_func, this, _1, _2, _3);
2335
2336         // create virtualservice option dictionary
2337         vs_option_dic["-t"]                = boost::bind(&l7vsadm::parse_opt_vs_target_func, this, _1, _2, _3);
2338         vs_option_dic["--tcp-service"]     = boost::bind(&l7vsadm::parse_opt_vs_target_func, this, _1, _2, _3);
2339         vs_option_dic["-m"]                = boost::bind(&l7vsadm::parse_opt_vs_module_func, this, _1, _2, _3);
2340         vs_option_dic["--proto-module"]    = boost::bind(&l7vsadm::parse_opt_vs_module_func, this, _1, _2, _3);
2341         vs_option_dic["-s"]                = boost::bind(&l7vsadm::parse_opt_vs_scheduler_func, this, _1, _2, _3);
2342         vs_option_dic["--scheduler"]       = boost::bind(&l7vsadm::parse_opt_vs_scheduler_func, this, _1, _2, _3);
2343         vs_option_dic["-u"]                = boost::bind(&l7vsadm::parse_opt_vs_upper_func, this, _1, _2, _3);
2344         vs_option_dic["--upper"]           = boost::bind(&l7vsadm::parse_opt_vs_upper_func, this, _1, _2, _3);
2345         vs_option_dic["-b"]                = boost::bind(&l7vsadm::parse_opt_vs_bypass_func, this, _1, _2, _3);
2346         vs_option_dic["--bypass"]          = boost::bind(&l7vsadm::parse_opt_vs_bypass_func, this, _1, _2, _3);
2347         vs_option_dic["-T"]                = boost::bind(&l7vsadm::parse_opt_vs_fwdmode_func, this, _1, _2, _3);
2348         vs_option_dic["--tproxy"]          = boost::bind(&l7vsadm::parse_opt_vs_fwdmode_func, this, _1, _2, _3);
2349         vs_option_dic["-M"]                = boost::bind(&l7vsadm::parse_opt_vs_fwdmode_func, this, _1, _2, _3);
2350         vs_option_dic["--masq"]            = boost::bind(&l7vsadm::parse_opt_vs_fwdmode_func, this, _1, _2, _3);
2351         vs_option_dic["-f"]                = boost::bind(&l7vsadm::parse_opt_vs_flag_func, this, _1, _2, _3);
2352         vs_option_dic["--flag"]            = boost::bind(&l7vsadm::parse_opt_vs_flag_func, this, _1, _2, _3);
2353         vs_option_dic["-Q"]                = boost::bind(&l7vsadm::parse_opt_vs_qosup_func, this, _1, _2, _3);
2354         vs_option_dic["--qos-up"]          = boost::bind(&l7vsadm::parse_opt_vs_qosup_func, this, _1, _2, _3);
2355         vs_option_dic["-q"]                = boost::bind(&l7vsadm::parse_opt_vs_qosdown_func, this, _1, _2, _3);
2356         vs_option_dic["--qos-down"]        = boost::bind(&l7vsadm::parse_opt_vs_qosdown_func, this, _1, _2, _3);
2357         vs_option_dic["-p"]                = boost::bind(&l7vsadm::parse_opt_vs_udp_func, this, _1, _2, _3);
2358         vs_option_dic["--udp"]             = boost::bind(&l7vsadm::parse_opt_vs_udp_func, this, _1, _2, _3);
2359         vs_option_dic["-z"]                = boost::bind(&l7vsadm::parse_opt_vs_ssl_file_func, this, _1, _2, _3);
2360         vs_option_dic["--ssl"]             = boost::bind(&l7vsadm::parse_opt_vs_ssl_file_func, this, _1, _2, _3);
2361         vs_option_dic["-O"]                = boost::bind(&l7vsadm::parse_opt_vs_socket_func, this, _1, _2, _3);
2362         vs_option_dic["--sockopt"]         = boost::bind(&l7vsadm::parse_opt_vs_socket_func, this, _1, _2, _3);
2363         vs_option_dic["-L"]                = boost::bind(&l7vsadm::parse_opt_vs_access_log_func, this, _1, _2, _3);
2364         vs_option_dic["--access-log"]      = boost::bind(&l7vsadm::parse_opt_vs_access_log_func, this, _1, _2, _3);
2365         vs_option_dic["-a"]                = boost::bind(&l7vsadm::parse_opt_vs_access_log_logrotate_func, this, _1, _2, _3);
2366         vs_option_dic["--access-log-name"] = boost::bind(&l7vsadm::parse_opt_vs_access_log_logrotate_func, this, _1, _2, _3);
2367
2368         // create realserver option dictionary
2369         rs_option_dic["-t"]             = boost::bind(&l7vsadm::parse_opt_vs_target_func, this, _1, _2, _3);
2370         rs_option_dic["--tcp-service"]  = boost::bind(&l7vsadm::parse_opt_vs_target_func, this, _1, _2, _3);
2371         rs_option_dic["-w"]             = boost::bind(&l7vsadm::parse_opt_rs_weight_func, this, _1, _2, _3);
2372         rs_option_dic["--weight"]       = boost::bind(&l7vsadm::parse_opt_rs_weight_func, this, _1, _2, _3);
2373         rs_option_dic["-T"]             = boost::bind(&l7vsadm::parse_opt_rs_fwdmode_func, this, _1, _2, _3);
2374         rs_option_dic["--tproxy"]       = boost::bind(&l7vsadm::parse_opt_rs_fwdmode_func, this, _1, _2, _3);
2375         rs_option_dic["-M"]             = boost::bind(&l7vsadm::parse_opt_rs_fwdmode_func, this, _1, _2, _3);
2376         rs_option_dic["--masq"]         = boost::bind(&l7vsadm::parse_opt_rs_fwdmode_func, this, _1, _2, _3);
2377         rs_option_dic["-m"]             = boost::bind(&l7vsadm::parse_opt_vs_module_func, this, _1, _2, _3);
2378         rs_option_dic["--proto-module"] = boost::bind(&l7vsadm::parse_opt_vs_module_func, this, _1, _2, _3);
2379         rs_option_dic["-p"]             = boost::bind(&l7vsadm::parse_opt_vs_udp_func, this, _1, _2, _3);
2380         rs_option_dic["--udp"]          = boost::bind(&l7vsadm::parse_opt_vs_udp_func, this, _1, _2, _3);
2381         rs_option_dic["-r"]             = boost::bind(&l7vsadm::parse_opt_rs_realserver_func, this, _1, _2, _3);
2382         rs_option_dic["--real-server"]  = boost::bind(&l7vsadm::parse_opt_rs_realserver_func, this, _1, _2, _3);
2383
2384         // create replication option dictionary
2385         replication_option_dic["-s"]           = boost::bind(&l7vsadm::parse_opt_replication_switch_func, this, _1, _2, _3);
2386         replication_option_dic["--switch"]     = boost::bind(&l7vsadm::parse_opt_replication_switch_func, this, _1, _2, _3);
2387         replication_switch_option_dic["start"] = boost::bind(&l7vsadm::parse_opt_replication_start_func, this, _1, _2, _3);
2388         replication_switch_option_dic["stop"]  = boost::bind(&l7vsadm::parse_opt_replication_stop_func, this, _1, _2, _3);
2389         replication_option_dic["-f"]           = boost::bind(&l7vsadm::parse_opt_replication_force_func, this, _1, _2, _3);
2390         replication_option_dic["--force"]      = boost::bind(&l7vsadm::parse_opt_replication_force_func, this, _1, _2, _3);
2391         replication_option_dic["-d"]           = boost::bind(&l7vsadm::parse_opt_replication_dump_func, this, _1, _2, _3);
2392         replication_option_dic["--dump"]       = boost::bind(&l7vsadm::parse_opt_replication_dump_func, this, _1, _2, _3);
2393
2394         // create log option function dictionary create
2395         log_option_dic["-c"]         = boost::bind(&l7vsadm::parse_opt_log_category_func, this, _1, _2, _3);
2396         log_option_dic["--category"] = boost::bind(&l7vsadm::parse_opt_log_category_func, this, _1, _2, _3);
2397         log_option_dic["-l"]         = boost::bind(&l7vsadm::parse_opt_log_level_func, this, _1, _2, _3);
2398         log_option_dic["--level"]    = boost::bind(&l7vsadm::parse_opt_log_level_func, this, _1, _2, _3);
2399
2400         // snmp agent option function dictionary create
2401         snmp_option_dic["-c"]         = boost::bind(&l7vsadm::parse_opt_snmp_log_category_func, this, _1, _2, _3);
2402         snmp_option_dic["--category"] = boost::bind(&l7vsadm::parse_opt_snmp_log_category_func, this, _1, _2, _3);
2403         snmp_option_dic["-l"]         = boost::bind(&l7vsadm::parse_opt_snmp_log_level_func, this, _1, _2, _3);
2404         snmp_option_dic["--level"]    = boost::bind(&l7vsadm::parse_opt_snmp_log_level_func, this, _1, _2, _3);
2405
2406         // parameter option function dictionary create
2407         parameter_option_dic["-r"]       = boost::bind(&l7vsadm::parse_opt_parameter_reload_func, this, _1, _2, _3);
2408         parameter_option_dic["--reload"] = boost::bind(&l7vsadm::parse_opt_parameter_reload_func, this, _1, _2, _3);
2409
2410         // string logcategory dictionary create
2411         string_logcategory_dic["l7vsd_network"]                      = LOG_CAT_L7VSD_NETWORK;
2412         string_logcategory_dic["nw"]                                 = LOG_CAT_L7VSD_NETWORK;
2413         logcategory_string_dic[LOG_CAT_L7VSD_NETWORK]                = "l7vsd_network";
2414         string_logcategory_dic["l7vsd_network_qos"]                  = LOG_CAT_L7VSD_NETWORK_QOS;
2415         string_logcategory_dic["nw_qos"]                             = LOG_CAT_L7VSD_NETWORK_QOS;
2416         logcategory_string_dic[LOG_CAT_L7VSD_NETWORK_QOS]            = "l7vsd_network_qos";
2417         string_logcategory_dic["l7vsd_network_bandwidth"]            = LOG_CAT_L7VSD_NETWORK_BANDWIDTH;
2418         string_logcategory_dic["nw_bw"]                              = LOG_CAT_L7VSD_NETWORK_BANDWIDTH;
2419         logcategory_string_dic[LOG_CAT_L7VSD_NETWORK_BANDWIDTH]      = "l7vsd_network_bandwidth";
2420         string_logcategory_dic["l7vsd_network_num_connection"]       = LOG_CAT_L7VSD_NETWORK_NUM_CONNECTION;
2421         string_logcategory_dic["nw_conn"]                            = LOG_CAT_L7VSD_NETWORK_NUM_CONNECTION;
2422         logcategory_string_dic[LOG_CAT_L7VSD_NETWORK_NUM_CONNECTION] = "l7vsd_network_num_connection";
2423         string_logcategory_dic["l7vsd_network_access"]               = LOG_CAT_L7VSD_NETWORK_ACCESS;
2424         string_logcategory_dic["nw_acc"]                             = LOG_CAT_L7VSD_NETWORK_ACCESS;
2425         logcategory_string_dic[LOG_CAT_L7VSD_NETWORK_ACCESS]         = "l7vsd_network_access";
2426         string_logcategory_dic["l7vsd_mainthread"]                   = LOG_CAT_L7VSD_MAINTHREAD;
2427         string_logcategory_dic["mth"]                                = LOG_CAT_L7VSD_MAINTHREAD;
2428         logcategory_string_dic[LOG_CAT_L7VSD_MAINTHREAD]             = "l7vsd_mainthread";
2429         string_logcategory_dic["l7vsd_virtualservice"]               = LOG_CAT_L7VSD_VIRTUALSERVICE;
2430         string_logcategory_dic["vs"]                                 = LOG_CAT_L7VSD_VIRTUALSERVICE;
2431         logcategory_string_dic[LOG_CAT_L7VSD_VIRTUALSERVICE]         = "l7vsd_virtualservice";
2432         string_logcategory_dic["l7vsd_virtualservice_thread"]        = LOG_CAT_L7VSD_VIRTUALSERVICE_THREAD;
2433         string_logcategory_dic["vs_th"]                              = LOG_CAT_L7VSD_VIRTUALSERVICE_THREAD;
2434         logcategory_string_dic[LOG_CAT_L7VSD_VIRTUALSERVICE_THREAD]  = "l7vsd_virtualservice_thread";
2435         string_logcategory_dic["l7vsd_session"]                      = LOG_CAT_L7VSD_SESSION;
2436         string_logcategory_dic["ss"]                                 = LOG_CAT_L7VSD_SESSION;
2437         logcategory_string_dic[LOG_CAT_L7VSD_SESSION]                = "l7vsd_session";
2438         string_logcategory_dic["l7vsd_session_thread"]               = LOG_CAT_L7VSD_SESSION_THREAD;
2439         string_logcategory_dic["ss_th"]                              = LOG_CAT_L7VSD_SESSION_THREAD;
2440         logcategory_string_dic[LOG_CAT_L7VSD_SESSION_THREAD]         = "l7vsd_session_thread";
2441         string_logcategory_dic["l7vsd_realserver"]                   = LOG_CAT_L7VSD_REALSERVER;
2442         string_logcategory_dic["rs"]                                 = LOG_CAT_L7VSD_REALSERVER;
2443         logcategory_string_dic[LOG_CAT_L7VSD_REALSERVER]             = "l7vsd_realserver";
2444         string_logcategory_dic["l7vsd_sorryserver"]                  = LOG_CAT_L7VSD_SORRYSERVER;
2445         string_logcategory_dic["sorry"]                              = LOG_CAT_L7VSD_SORRYSERVER;
2446         logcategory_string_dic[LOG_CAT_L7VSD_SORRYSERVER]            = "l7vsd_sorryserver";
2447         string_logcategory_dic["l7vsd_module"]                       = LOG_CAT_L7VSD_MODULE;
2448         string_logcategory_dic["mod"]                                = LOG_CAT_L7VSD_MODULE;
2449         logcategory_string_dic[LOG_CAT_L7VSD_MODULE]                 = "l7vsd_module";
2450         string_logcategory_dic["l7vsd_replication"]                  = LOG_CAT_L7VSD_REPLICATION;
2451         string_logcategory_dic["rep"]                                = LOG_CAT_L7VSD_REPLICATION;
2452         logcategory_string_dic[LOG_CAT_L7VSD_REPLICATION]            = "l7vsd_replication";
2453         string_logcategory_dic["l7vsd_replication_sendthread"]       = LOG_CAT_L7VSD_REPLICATION_SENDTHREAD;
2454         string_logcategory_dic["rep_sth"]                            = LOG_CAT_L7VSD_REPLICATION_SENDTHREAD;
2455         logcategory_string_dic[LOG_CAT_L7VSD_REPLICATION_SENDTHREAD] = "l7vsd_replication_sendthread";
2456         string_logcategory_dic["l7vsd_parameter"]                    = LOG_CAT_L7VSD_PARAMETER;
2457         string_logcategory_dic["para"]                               = LOG_CAT_L7VSD_PARAMETER;
2458         logcategory_string_dic[LOG_CAT_L7VSD_PARAMETER]              = "l7vsd_parameter";
2459         string_logcategory_dic["l7vsd_logger"]                       = LOG_CAT_L7VSD_LOGGER;
2460         string_logcategory_dic["logger"]                             = LOG_CAT_L7VSD_LOGGER;
2461         logcategory_string_dic[LOG_CAT_L7VSD_LOGGER]                 = "l7vsd_logger";
2462         string_logcategory_dic["l7vsd_command"]                      = LOG_CAT_L7VSD_COMMAND;
2463         string_logcategory_dic["cmd"]                                = LOG_CAT_L7VSD_COMMAND;
2464         logcategory_string_dic[LOG_CAT_L7VSD_COMMAND]                = "l7vsd_command";
2465         string_logcategory_dic["l7vsd_start_stop"]                   = LOG_CAT_L7VSD_START_STOP;
2466         string_logcategory_dic["stastp"]                             = LOG_CAT_L7VSD_START_STOP;
2467         logcategory_string_dic[LOG_CAT_L7VSD_START_STOP]             = "l7vsd_start_stop";
2468         string_logcategory_dic["l7vsd_system"]                       = LOG_CAT_L7VSD_SYSTEM;
2469         string_logcategory_dic["sys"]                                = LOG_CAT_L7VSD_SYSTEM;
2470         logcategory_string_dic[LOG_CAT_L7VSD_SYSTEM]                 = "l7vsd_system";
2471         string_logcategory_dic["l7vsd_system_memory"]                = LOG_CAT_L7VSD_SYSTEM_MEMORY;
2472         string_logcategory_dic["sys_mem"]                            = LOG_CAT_L7VSD_SYSTEM_MEMORY;
2473         logcategory_string_dic[LOG_CAT_L7VSD_SYSTEM_MEMORY]          = "l7vsd_system_memory";
2474         string_logcategory_dic["l7vsd_system_endpoint"]              = LOG_CAT_L7VSD_SYSTEM_ENDPOINT;
2475         string_logcategory_dic["sys_ep"]                             = LOG_CAT_L7VSD_SYSTEM_ENDPOINT;
2476         logcategory_string_dic[LOG_CAT_L7VSD_SYSTEM_ENDPOINT]        = "l7vsd_system_endpoint";
2477         string_logcategory_dic["l7vsd_system_signal"]                = LOG_CAT_L7VSD_SYSTEM_SIGNAL;
2478         string_logcategory_dic["sys_sig"]                            = LOG_CAT_L7VSD_SYSTEM_SIGNAL;
2479         logcategory_string_dic[LOG_CAT_L7VSD_SYSTEM_SIGNAL]          = "l7vsd_system_signal";
2480         string_logcategory_dic["l7vsd_system_environment"]           = LOG_CAT_L7VSD_SYSTEM_ENVIRONMENT;
2481         string_logcategory_dic["sys_env"]                            = LOG_CAT_L7VSD_SYSTEM_ENVIRONMENT;
2482         logcategory_string_dic[LOG_CAT_L7VSD_SYSTEM_ENVIRONMENT]     = "l7vsd_system_environment";
2483         string_logcategory_dic["l7vsd_snmpbridge"]                   = LOG_CAT_L7VSD_SNMPBRIDGE;
2484         string_logcategory_dic["bridge"]                             = LOG_CAT_L7VSD_SNMPBRIDGE;
2485         logcategory_string_dic[LOG_CAT_L7VSD_SNMPBRIDGE]             = "l7vsd_snmpbridge";
2486         string_logcategory_dic["l7vsd_protocol"]                     = LOG_CAT_PROTOCOL;
2487         string_logcategory_dic["prot"]                               = LOG_CAT_PROTOCOL;
2488         logcategory_string_dic[LOG_CAT_PROTOCOL]                     = "l7vsd_protocol";
2489         string_logcategory_dic["l7vsd_schedule"]                     = LOG_CAT_SCHEDULE;
2490         string_logcategory_dic["sched"]                              = LOG_CAT_SCHEDULE;
2491         logcategory_string_dic[LOG_CAT_SCHEDULE]                     = "l7vsd_schedule";
2492         string_logcategory_dic["all"]                                = LOG_CAT_END;
2493
2494         // string snmp logcategory dictionary create
2495         string_snmp_logcategory_dic["snmpagent_start_stop"]               = LOG_CAT_SNMPAGENT_START_STOP;
2496         string_snmp_logcategory_dic["snmp_stastp"]                        = LOG_CAT_SNMPAGENT_START_STOP;
2497         snmp_logcategory_string_dic[LOG_CAT_SNMPAGENT_START_STOP]         = "snmpagent_start_stop";
2498         string_snmp_logcategory_dic["snmpagent_manager_receive"]          = LOG_CAT_SNMPAGENT_MANAGER_RECEIVE;
2499         string_snmp_logcategory_dic["snmp_mngrcv"]                        = LOG_CAT_SNMPAGENT_MANAGER_RECEIVE;
2500         snmp_logcategory_string_dic[LOG_CAT_SNMPAGENT_MANAGER_RECEIVE]    = "snmpagent_manager_receive";
2501         string_snmp_logcategory_dic["snmpagent_manager_send"]             = LOG_CAT_SNMPAGENT_MANAGER_SEND;
2502         string_snmp_logcategory_dic["snmp_mngsnd"]                        = LOG_CAT_SNMPAGENT_MANAGER_SEND;
2503         snmp_logcategory_string_dic[LOG_CAT_SNMPAGENT_MANAGER_SEND]       = "snmpagent_manager_send";
2504         string_snmp_logcategory_dic["snmpagent_l7vsd_receive"]            = LOG_CAT_SNMPAGENT_L7VSD_RECEIVE;
2505         string_snmp_logcategory_dic["snmp_vsdrcv"]                        = LOG_CAT_SNMPAGENT_L7VSD_RECEIVE;
2506         snmp_logcategory_string_dic[LOG_CAT_SNMPAGENT_L7VSD_RECEIVE]      = "snmpagent_l7vsd_receive";
2507         string_snmp_logcategory_dic["snmpagent_l7vsd_send"]               = LOG_CAT_SNMPAGENT_L7VSD_SEND;
2508         string_snmp_logcategory_dic["snmp_vsdsnd"]                        = LOG_CAT_SNMPAGENT_L7VSD_SEND;
2509         snmp_logcategory_string_dic[LOG_CAT_SNMPAGENT_L7VSD_SEND]         = "snmpagent_l7vsd_send";
2510         string_snmp_logcategory_dic["snmpagent_logger"]                   = LOG_CAT_SNMPAGENT_LOGGER;
2511         string_snmp_logcategory_dic["snmp_logger"]                        = LOG_CAT_SNMPAGENT_LOGGER;
2512         snmp_logcategory_string_dic[LOG_CAT_SNMPAGENT_LOGGER]             = "snmpagent_logger";
2513         string_snmp_logcategory_dic["snmpagent_parameter"]                = LOG_CAT_SNMPAGENT_PARAMETER;
2514         string_snmp_logcategory_dic["snmp_para"]                          = LOG_CAT_SNMPAGENT_PARAMETER;
2515         snmp_logcategory_string_dic[LOG_CAT_SNMPAGENT_PARAMETER]          = "snmpagent_parameter";
2516         string_snmp_logcategory_dic["snmpagent_system"]                   = LOG_CAT_SNMPAGENT_SYSTEM;
2517         string_snmp_logcategory_dic["snmp_sys"]                           = LOG_CAT_SNMPAGENT_SYSTEM;
2518         snmp_logcategory_string_dic[LOG_CAT_SNMPAGENT_SYSTEM]             = "snmpagent_system";
2519         string_snmp_logcategory_dic["snmpagent_system_memory"]            = LOG_CAT_SNMPAGENT_SYSTEM_MEMORY;
2520         string_snmp_logcategory_dic["snmp_sys_mem"]                       = LOG_CAT_SNMPAGENT_SYSTEM_MEMORY;
2521         snmp_logcategory_string_dic[LOG_CAT_SNMPAGENT_SYSTEM_MEMORY]      = "snmpagent_system_memory";
2522         string_snmp_logcategory_dic["snmpagent_system_endpoint"]          = LOG_CAT_SNMPAGENT_SYSTEM_ENDPOINT;
2523         string_snmp_logcategory_dic["snmp_sys_ep"]                        = LOG_CAT_SNMPAGENT_SYSTEM_ENDPOINT;
2524         snmp_logcategory_string_dic[LOG_CAT_SNMPAGENT_SYSTEM_ENDPOINT]    = "snmpagent_system_endpoint";
2525         string_snmp_logcategory_dic["snmpagent_system_signal"]            = LOG_CAT_SNMPAGENT_SYSTEM_SIGNAL;
2526         string_snmp_logcategory_dic["snmp_sys_sig"]                       = LOG_CAT_SNMPAGENT_SYSTEM_SIGNAL;
2527         snmp_logcategory_string_dic[LOG_CAT_SNMPAGENT_SYSTEM_SIGNAL]      = "snmpagent_system_signal";
2528         string_snmp_logcategory_dic["snmpagent_system_environment"]       = LOG_CAT_SNMPAGENT_SYSTEM_ENVIRONMENT;
2529         string_snmp_logcategory_dic["snmp_sys_env"]                       = LOG_CAT_SNMPAGENT_SYSTEM_ENVIRONMENT;
2530         snmp_logcategory_string_dic[LOG_CAT_SNMPAGENT_SYSTEM_ENVIRONMENT] = "snmpagent_system_environment";
2531
2532         string_snmp_logcategory_dic["all"] = LOG_CAT_END;
2533
2534         // string log level dictionary create.
2535         string_loglevel_dic["debug"]      = LOG_LV_DEBUG;
2536         loglevel_string_dic[LOG_LV_DEBUG] = "debug";
2537         string_loglevel_dic["info"]       = LOG_LV_INFO;
2538         loglevel_string_dic[LOG_LV_INFO]  = "info";
2539         string_loglevel_dic["warn"]       = LOG_LV_WARN;
2540         loglevel_string_dic[LOG_LV_WARN]  = "warn";
2541         string_loglevel_dic["error"]      = LOG_LV_ERROR;
2542         loglevel_string_dic[LOG_LV_ERROR] = "error";
2543         string_loglevel_dic["fatal"]      = LOG_LV_FATAL;
2544         loglevel_string_dic[LOG_LV_FATAL] = "fatal";
2545
2546         // parameter category dictionary create
2547         string_parameter_dic["all"]            = PARAM_COMP_ALL;
2548         string_parameter_dic["l7vsd"]          = PARAM_COMP_L7VSD;
2549         string_parameter_dic["command"]        = PARAM_COMP_COMMAND;
2550         string_parameter_dic["session"]        = PARAM_COMP_SESSION;
2551         string_parameter_dic["virtualservice"] = PARAM_COMP_VIRTUALSERVICE;
2552         string_parameter_dic["module"]         = PARAM_COMP_MODULE;
2553         string_parameter_dic["replication"]    = PARAM_COMP_REPLICATION;
2554         string_parameter_dic["logger"]         = PARAM_COMP_LOGGER;
2555         string_parameter_dic["l7vsadm"]        = PARAM_COMP_L7VSADM;
2556         string_parameter_dic["snmpagent"]      = PARAM_COMP_SNMPAGENT;
2557         string_parameter_dic["ssl"]            = PARAM_COMP_SSL;
2558
2559         // create disp_result dictionary.
2560         disp_result_dic[l7vsadm_request::CMD_LIST]         = boost::bind(&l7vsadm::disp_list, this);
2561         disp_result_dic[l7vsadm_request::CMD_LIST_KEY]     = boost::bind(&l7vsadm::disp_list_key, this);
2562         disp_result_dic[l7vsadm_request::CMD_LIST_VERBOSE] = boost::bind(&l7vsadm::disp_list_verbose, this);
2563
2564         // response_message_dic create
2565         response_error_message_dic[l7vsd_response::RESPONSE_ERROR]              = "command error : ";
2566         response_error_message_dic[l7vsd_response::RESPONSE_LIST_ERROR]         = "list command error : ";
2567         response_error_message_dic[l7vsd_response::RESPONSE_LIST_VERBOSE_ERROR] = "list verbose error : ";
2568         response_error_message_dic[l7vsd_response::RESPONSE_LIST_KEY_ERROR]     = "list key error : ";
2569         response_error_message_dic[l7vsd_response::RESPONSE_ADD_VS_ERROR]       = "add vs error : ";
2570         response_error_message_dic[l7vsd_response::RESPONSE_DEL_VS_ERROR]       = "del vs error : ";
2571         response_error_message_dic[l7vsd_response::RESPONSE_EDIT_VS_ERROR]      = "edit vs error : ";
2572         response_error_message_dic[l7vsd_response::RESPONSE_FLUSH_VS_ERROR]     = "flush vs error : ";
2573         response_error_message_dic[l7vsd_response::RESPONSE_ADD_RS_ERROR]       = "add rs error : ";
2574         response_error_message_dic[l7vsd_response::RESPONSE_DEL_RS_ERROR]       = "del rs error : ";
2575         response_error_message_dic[l7vsd_response::RESPONSE_EDIT_RS_ERROR]      = "edit rs error : ";
2576         response_error_message_dic[l7vsd_response::RESPONSE_REPLICATION_ERROR]  = "replication command error : ";
2577         response_error_message_dic[l7vsd_response::RESPONSE_LOG_ERROR]          = "log command error : ";
2578         response_error_message_dic[l7vsd_response::RESPONSE_SNMP_ERROR]         = "snmp command error : ";
2579         response_error_message_dic[l7vsd_response::RESPONSE_PARAMETER_ERROR]    = "parameter error : ";
2580
2581         replication_mode_string_dic[replication::REPLICATION_OUT]         = "OUT";
2582         replication_mode_string_dic[replication::REPLICATION_SINGLE]      = "SINGLE";
2583         replication_mode_string_dic[replication::REPLICATION_MASTER]      = "MASTER";
2584         replication_mode_string_dic[replication::REPLICATION_SLAVE]       = "SLAVE";
2585         replication_mode_string_dic[replication::REPLICATION_MASTER_STOP] = "MASTER_STOP";
2586         replication_mode_string_dic[replication::REPLICATION_SLAVE_STOP]  = "SLAVE_STOP";
2587 }
2588
2589 //! Get l7vsadm parameter data
2590 void l7vs::l7vsadm::set_parameter()
2591 {
2592         Logger logger(LOG_CAT_L7VSADM_COMMON, 36, "l7vsadm::set_parameter", __FILE__, __LINE__);
2593
2594         // Get and Set l7vsadm all parameter value.
2595         Parameter param;
2596         error_code err;
2597
2598         // command_wait_interval
2599         command_wait_interval = param.get_int(PARAM_COMP_L7VSADM, "cmd_interval", err);
2600         if (!err) {
2601                 if (command_wait_interval < 0 ||
2602                     command_wait_interval > L7VSADM_MAX_WAIT) {
2603                         // When illegal parameter value, use default parameter value.
2604                         command_wait_interval = L7VSADM_DEFAULT_WAIT_INTERVAL;
2605                         std::stringstream msg;
2606                         msg << boost::format("Illegal cmd_interval parameter value. Use default value(%s).")
2607                                 % L7VSADM_DEFAULT_WAIT_INTERVAL;
2608                         Logger::putLogWarn(LOG_CAT_L7VSADM_COMMON, 1, msg.str(), __FILE__, __LINE__);
2609                 }
2610         } else {
2611                 command_wait_interval = L7VSADM_DEFAULT_WAIT_INTERVAL;
2612                 std::stringstream msg;
2613                 msg << boost::format("Get cmd_interval parameter error. Use default value(%s).")
2614                         % L7VSADM_DEFAULT_WAIT_INTERVAL;
2615                 Logger::putLogWarn(LOG_CAT_L7VSADM_COMMON, 2, msg.str(), __FILE__, __LINE__);
2616         }
2617
2618         //command_wait_count
2619         command_wait_count = param.get_int(PARAM_COMP_L7VSADM, "cmd_count", err);
2620         if (!err) {
2621                 if (command_wait_count < 0 ||
2622                     command_wait_count > L7VSADM_MAX_WAIT) {
2623                         // When illegal parameter value, use default parameter value.
2624                         command_wait_count = L7VSADM_DEFAULT_WAIT_COUNT;
2625                         std::stringstream msg;
2626                         msg << boost::format("Illegal cmd_count parameter value. Use default value(%s).")
2627                                 % L7VSADM_DEFAULT_WAIT_COUNT;
2628                         Logger::putLogWarn(LOG_CAT_L7VSADM_COMMON, 3, msg.str(), __FILE__, __LINE__);
2629                 }
2630         } else {
2631                 command_wait_count = L7VSADM_DEFAULT_WAIT_COUNT;
2632                 std::stringstream msg;
2633                 msg << boost::format("Get cmd_count parameter error. Use default value(%s).")
2634                         % L7VSADM_DEFAULT_WAIT_COUNT;
2635                 Logger::putLogWarn(LOG_CAT_L7VSADM_COMMON, 4, msg.str(), __FILE__, __LINE__);
2636         }
2637
2638         if ((command_wait_interval * command_wait_count) > L7VSADM_MAX_WAIT) {
2639                 // When wait value too long, use default parameter value.
2640                 command_wait_interval = L7VSADM_DEFAULT_WAIT_INTERVAL;
2641                 command_wait_count = L7VSADM_DEFAULT_WAIT_COUNT;
2642                 std::stringstream msg;
2643                 msg << boost::format("Command wait value too long. Use default value(%s).")
2644                         % L7VSADM_DEFAULT_WAIT_COUNT;
2645                 Logger::putLogWarn(LOG_CAT_L7VSADM_COMMON, 9, msg.str(), __FILE__, __LINE__);
2646         }
2647 }
2648
2649 //! l7vsadm command execute
2650 bool l7vs::l7vsadm::execute(int argc, char *argv[])
2651 {
2652         Logger logger(LOG_CAT_L7VSADM_COMMON, 37, "l7vsadm::execute", __FILE__, __LINE__);
2653
2654         /*-------- DEBUG LOG --------*/
2655         if (LOG_LV_DEBUG == Logger::getLogLevel(LOG_CAT_L7VSADM_COMMON)) {
2656                 std::stringstream debugstr;
2657                 debugstr << boost::format("l7vsadm::execute arguments: %s") % argument_debug_dump(argc, argv);
2658                 Logger::putLogDebug(LOG_CAT_L7VSADM_COMMON, 38, debugstr.str(), __FILE__, __LINE__);
2659         }
2660         /*------ DEBUG LOG END ------*/
2661
2662         // set sighanlder
2663         if (0 > set_sighandlers()) {
2664                 std::string buf("set_sighandlers failed.");
2665                 std::cerr << "COMMON ERROR: " << buf << std::endl;
2666                 Logger::putLogError(LOG_CAT_L7VSADM_COMMON, 1, buf, __FILE__, __LINE__);
2667                 return false;
2668         }
2669
2670         // readparam
2671         set_parameter();
2672
2673         // Get l7vsadm execute file path from /proc/(pid)/exe (symbolic link)
2674         char l7vsadm_file_path[256];
2675         ssize_t retsize;
2676         memset(l7vsadm_file_path, 0, sizeof(l7vsadm_file_path));
2677         retsize = readlink("/proc/self/exe", l7vsadm_file_path, sizeof(l7vsadm_file_path));
2678
2679         // L7vsadm command conflict check. (Try l7vsadm execute file lock)
2680         file_lock lock(l7vsadm_file_path, l7vsadm_err);
2681         if (l7vsadm_err) {
2682                 std::cerr << "COMMON ERROR: " << l7vsadm_err.get_message() << std::endl;
2683                 Logger::putLogError(LOG_CAT_L7VSADM_COMMON, 2, l7vsadm_err.get_message(), __FILE__, __LINE__);
2684                 return false;
2685         }
2686
2687         try {
2688                 // l7vsadm file lock wait
2689                 int command_retry_count = 0;
2690                 while (true) {
2691                         // Check signal.
2692                         if (signal_flag) {
2693                                 std::stringstream buf;
2694                                 buf << boost::format("Signal (%d) Received.") % received_sig;
2695                                 l7vsadm_err.setter(true, buf.str());
2696                                 Logger::putLogError(LOG_CAT_L7VSADM_COMMON, 3, buf.str(), __FILE__, __LINE__);
2697                                 break;
2698                         }
2699
2700                         // Try lock l7vsadm file.
2701                         if (lock.try_lock()) {
2702                                 break;
2703                         }
2704
2705                         ++command_retry_count;
2706                         if (command_retry_count > command_wait_count) {
2707                                 // L7vsadm file lock error. (l7vsadm is executing)
2708                                 std::string buf("L7vsadm file lock timeout. (l7vsadm is already executing)");
2709                                 l7vsadm_err.setter(true, buf);
2710                                 Logger::putLogError(LOG_CAT_L7VSADM_COMMON, 4, buf, __FILE__, __LINE__);
2711                                 break;
2712                         }
2713
2714                         std::stringstream buf;
2715                         buf << boost::format("L7vsadm file lock error. (l7vsadm is already executing) (retry %d)") % command_retry_count;
2716                         Logger::putLogWarn(LOG_CAT_L7VSADM_COMMON, 11, buf.str(), __FILE__, __LINE__);
2717
2718                         // Lock retrying.
2719                         boost::xtime xt;
2720                         xtime_get(&xt, boost::TIME_UTC);
2721                         xt.sec += command_wait_interval;
2722                         boost::thread::sleep(xt);
2723                 }
2724
2725                 // display err
2726                 if (l7vsadm_err) {
2727                         std::cerr << "COMMON ERROR: " << l7vsadm_err.get_message() << std::endl;
2728                         return false;
2729                 }
2730
2731                 // no argument, assume list command
2732                 if (1 == argc) {
2733                         request.command = l7vsadm_request::CMD_LIST;
2734                 } else {
2735                         // parse command line
2736                         int pos = 1;
2737                         parse_cmd_map_type::iterator itr = command_dic.find(argv[pos]);
2738                         if (itr != command_dic.end()) {
2739                                 itr->second(argc, argv);
2740                         } else {
2741                                 std::string buf("command not found.");
2742                                 l7vsadm_err.setter(true, buf);
2743                                 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 88, buf, __FILE__, __LINE__);
2744                         }
2745                 }
2746
2747                 // display command parse result
2748                 if (l7vsadm_err) {
2749                         std::cerr << "PARSE ERROR: " << l7vsadm_err.get_message() << std::endl;
2750                         std::cerr << usage() << std::endl;
2751                         return false;
2752                 }
2753
2754                 if (l7vsadm_request::CMD_HELP != request.command) {
2755                         // communicate to l7vsd
2756                         using boost::asio::local::stream_protocol;
2757                         boost::array<char, COMMAND_BUFFER_SIZE> response_buffer;
2758                         response_buffer.assign(0x00);
2759
2760                         // connect
2761                         boost::asio::io_service io;
2762                         stream_protocol::socket s(io);
2763
2764                         // Check signal.
2765                         if (signal_flag) {
2766                                 std::stringstream buf;
2767                                 buf << boost::format("Signal (%d) Received.") % received_sig;
2768                                 l7vsadm_err.setter(true, buf.str());
2769                                 Logger::putLogError(LOG_CAT_L7VSADM_COMMON, 5, buf.str(), __FILE__, __LINE__);
2770                         } else {
2771                                 // Try connect to config socket.
2772                                 boost::system::error_code err;
2773                                 s.connect(stream_protocol::endpoint(L7VS_CONFIG_SOCKNAME), err);
2774                                 if (err) {
2775                                         std::stringstream buf;
2776                                         buf << boost::format("connect() failed: %s.") % err.message();
2777                                         l7vsadm_err.setter(true, buf.str());
2778                                         Logger::putLogError(LOG_CAT_L7VSADM_COMMON, 9, buf.str(), __FILE__, __LINE__);
2779                                 }
2780                         }
2781
2782                         // display err
2783                         if (l7vsadm_err) {
2784                                 std::cerr << "COMMON ERROR: " << l7vsadm_err.get_message() << std::endl;
2785                                 return false;
2786                         }
2787
2788                         /*-------- DEBUG LOG --------*/
2789                         if (LOG_LV_DEBUG == Logger::getLogLevel(LOG_CAT_L7VSADM_COMMON)) {
2790                                 std::stringstream debugstr;
2791                                 debugstr << boost::format("l7vsadm_send_request:%s") % request;
2792                                 Logger::putLogDebug(LOG_CAT_L7VSADM_COMMON, 39, debugstr.str(), __FILE__, __LINE__);
2793                         }
2794                         /*------ DEBUG LOG END ------*/
2795
2796                         // write sockfile
2797                         std::stringstream send_stream;
2798                         boost::archive::text_oarchive oa(send_stream);
2799                         oa << (const l7vs::l7vsadm_request &) request;
2800                         boost::asio::write(s, boost::asio::buffer(send_stream.str()));
2801
2802                         // read sockfile
2803                         s.read_some(boost::asio::buffer(response_buffer));
2804
2805                         std::stringstream recv_stream;
2806                         recv_stream << &(response_buffer[0]);
2807                         boost::archive::text_iarchive ia(recv_stream);
2808                         ia >> response;
2809
2810                         /*-------- DEBUG LOG --------*/
2811                         if (LOG_LV_DEBUG == Logger::getLogLevel(LOG_CAT_L7VSADM_COMMON)) {
2812                                 std::stringstream debugstr;
2813                                 debugstr << boost::format("l7vsadm_recv_response:%s") % response;
2814                                 Logger::putLogDebug(LOG_CAT_L7VSADM_COMMON, 40, debugstr.str(), __FILE__, __LINE__);
2815                         }
2816                         /*------ DEBUG LOG END ------*/
2817
2818                         // close socket
2819                         s.close();
2820
2821                         // display result
2822                         if (l7vsd_response::RESPONSE_OK == response.status) {
2823                                 disp_result_map_type::iterator itr = disp_result_dic.find(request.command);
2824                                 if (itr != disp_result_dic.end())
2825                                         itr->second();
2826                         } else {
2827                                 std::stringstream buf;
2828                                 response_error_message_map_type::iterator itr = response_error_message_dic.find(response.status);
2829                                 if (itr != response_error_message_dic.end())
2830                                         buf << itr->second << response.message;
2831                                 else
2832                                         buf << "COMMAND ERROR: " << response.message;
2833                                 std::cerr << buf.str() << std::endl;
2834                                 Logger::putLogError(LOG_CAT_L7VSADM_COMMON, 7, buf.str(), __FILE__, __LINE__);
2835                                 return false;
2836                         }
2837                 } //if help_mode
2838         } //try
2839         catch (std::exception &e) {
2840                 std::stringstream buf;
2841                 buf << "COMMON ERROR: " << e.what();
2842                 std::cerr << buf.str() << std::endl;
2843                 Logger::putLogError(LOG_CAT_L7VSADM_COMMON, 8, buf.str(), __FILE__, __LINE__);
2844                 return false;
2845         }
2846         return true;
2847 }
2848
2849 //! argument dump for debug
2850 //! @param[in] argument count
2851 //! @param[in] argument value
2852 std::string l7vs::l7vsadm::argument_debug_dump(int argc, char *argv[])
2853 {
2854         std::stringstream buf;
2855         if (!argv) {
2856                 buf << "argument=(null)";
2857         } else {
2858                 buf << boost::format("argument={argc=%d") % argc;
2859                 for (int i = 0; i < argc; ++i) {
2860                         buf << boost::format(", argv[%d]=%s") % i % argv[i];
2861                 }
2862                 buf << "}";
2863         }
2864         return buf.str();
2865 }
2866
2867 //! signal handler function
2868 //! @param[in] signal
2869 static void sig_exit_handler(int sig)
2870 {
2871         received_sig = sig;
2872         signal_flag = true;
2873 }
2874
2875 //! set singal handler function
2876 //! @param[in] signal
2877 //! @param[in] handler function pointer
2878 //! @return 0/success, -1/fail
2879 static int set_sighandler(int sig, void (*handler)(int))
2880 {
2881         struct sigaction act;
2882         int ret;
2883
2884         ret = sigaction(sig, NULL, &act);
2885         if (0 > ret) {
2886                 return ret;
2887         }
2888
2889         act.sa_flags &= ~SA_RESETHAND;
2890         act.sa_handler = handler;
2891
2892         ret = sigaction(sig, &act, NULL);
2893         if (0 > ret) {
2894                 return ret;
2895         }
2896
2897         return 0;
2898 }
2899
2900 //! set all singal handler function
2901 //! @return 0/success, -1/fail
2902 static int set_sighandlers()
2903 {
2904         int ret;
2905
2906 #define SET_SIGHANDLER(sig, handler)            \
2907     do {                                        \
2908         ret = set_sighandler((sig), (handler)); \
2909         if (ret < 0) {                          \
2910             return ret;                         \
2911         }                                       \
2912     } while (0)
2913
2914         SET_SIGHANDLER(SIGHUP,  sig_exit_handler);
2915         SET_SIGHANDLER(SIGINT,  sig_exit_handler);
2916         SET_SIGHANDLER(SIGQUIT, sig_exit_handler);
2917         SET_SIGHANDLER(SIGPIPE, sig_exit_handler);
2918         SET_SIGHANDLER(SIGTERM, sig_exit_handler);
2919         SET_SIGHANDLER(SIGUSR1, sig_exit_handler);
2920         SET_SIGHANDLER(SIGUSR2, sig_exit_handler);
2921
2922 #undef SET_SIGHANDLER
2923
2924         return 0;
2925 }
2926
2927 #ifndef UNIT_TEST
2928 int main(int argc, char *argv[])
2929 {
2930         try {
2931                 l7vs::Logger logger;
2932                 l7vs::Parameter param;
2933                 logger.loadConf();
2934         } catch (...) {
2935         }
2936
2937         l7vs::l7vsadm adm;
2938         if (!adm.execute(argc, argv)) {
2939                 return -1;
2940         }
2941         return 0;
2942 }
2943 #endif //UNIT_TEST