OSDN Git Service

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