OSDN Git Service

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