3 * @brief l7vsadm command is l7vsd control application
5 * L7VSD: Linux Virtual Server for Layer7 Load Balancing
6 * Copyright (C) 2009 NTT COMWARE Corporation.
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.
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.
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
23 **********************************************************************/
29 #include <boost/bind.hpp>
30 #include <boost/archive/text_oarchive.hpp>
31 #include <boost/archive/text_iarchive.hpp>
32 #include <boost/format.hpp>
33 #include <boost/algorithm/string.hpp>
37 #include "parameter.h"
38 #include "protocol_module_control.h"
39 #include "schedule_module_control.h"
40 #include "virtualservice_element.h"
41 #include "logger_access_manager.h"
43 #define VS_CONTACT_CLASS_SSL (0x00000001)
45 // global function prototype
46 static void sig_exit_handler(int sig);
47 static int set_sighandler(int sig, void (*handler)(int));
48 static int set_sighandlers();
51 static bool signal_flag = false;
52 static int received_sig = 0;
57 //! list command parsing.
58 //! @param[in] request command
59 //! @param[in] argument count
60 //! @param[in] argument value
61 bool l7vs::l7vsadm::parse_list_func(l7vs::l7vsadm_request::COMMAND_CODE_TAG cmd, int argc, char *argv[])
63 Logger logger(LOG_CAT_L7VSADM_COMMON, 1, "l7vsadm::parse_list_func", __FILE__, __LINE__);
65 request.command = cmd; // set command
67 return true; // option is none. this pattern is true
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__);
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.
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__);
94 // option list functions.
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[])
102 Logger logger(LOG_CAT_L7VSADM_COMMON, 2, "l7vsadm::parse_opt_list_numeric_func", __FILE__, __LINE__);
104 numeric_flag = true; //numeric flag on.
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[])
114 Logger logger(LOG_CAT_L7VSADM_COMMON, 3, "l7vsadm::parse_vs_func", __FILE__, __LINE__);
116 request.command = cmd; // set command
117 if (l7vsadm_request::CMD_FLUSH_VS == cmd) {
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__);
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__);
135 std::map<std::string, int> count_map;
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;
142 if (l7vsadm_request::CMD_EDIT_VS == cmd) {
143 request.vs_element.access_log_flag = -1;
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.
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__);
161 // check virtualservice on response
162 if (l7vsadm_request::CMD_FLUSH_VS == cmd) {
163 // flush vs required no option
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;
174 module = ctrl.load_module(scheduler_name);
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__);
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__);
190 ctrl.unload_module(module);
191 request.vs_element.schedule_module_name = scheduler_name;
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__);
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__);
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__);
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__);
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;
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__);
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["--masq"] == 0 &&
247 count_map["--tproxy"] == 0 &&
248 count_map["-Q"] == 0 &&
249 count_map["--qos-up"] == 0 &&
250 count_map["-q"] == 0 &&
251 count_map["--qos-down"] == 0 &&
252 count_map["-L"] == 0 &&
253 count_map["--access-log"] == 0) {
255 std::string buf("All option omitted for edit vs command.");
256 l7vsadm_err.setter(true, buf);
257 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 116, buf, __FILE__, __LINE__);
263 std::string conflict_option_name;
264 bool is_conflict = false;
266 for (std::map<std::string, int>::iterator itr = count_map.begin() ;
267 itr != count_map.end() ; ++itr) {
268 if (itr->second > 1) {
269 conflict_option_name = itr->first;
275 if (is_conflict == false &&
276 count_map["-t"] == 1 && count_map["--tcp-service"] == 1) {
278 conflict_option_name = "--tcp-service";
281 if (is_conflict == false &&
282 count_map["-m"] == 1 && count_map["--proto-module"] == 1) {
284 conflict_option_name = "--proto-module";
287 if (is_conflict == false &&
288 count_map["-s"] == 1 && count_map["--scheduler"] == 1) {
290 conflict_option_name = "--scheduler";
293 if (is_conflict == false &&
294 count_map["-u"] == 1 && count_map["--upper"] == 1) {
296 conflict_option_name = "--upper";
299 if (is_conflict == false &&
300 count_map["-b"] == 1 && count_map["--bypass"] == 1) {
302 conflict_option_name = "--bypass";
305 if (is_conflict == false &&
306 count_map["-f"] == 1 && count_map["--flag"] == 1) {
308 conflict_option_name = "--flag";
311 if (is_conflict == false &&
312 count_map["--masq"] + count_map["--tproxy"] > 1) {
313 conflict_option_name = "--masq/tproxy";
316 if (is_conflict == false &&
317 count_map["-Q"] == 1 && count_map["--qos-up"] == 1) {
319 conflict_option_name = "--qos-up";
322 if (is_conflict == false &&
323 count_map["-q"] == 1 && count_map["--qos-down"] == 1) {
325 conflict_option_name = "--qos-down";
328 if (is_conflict == false &&
329 count_map["-p"] == 1 && count_map["--udp"] == 1) {
331 conflict_option_name = "--udp";
334 if (is_conflict == false &&
335 count_map["-z"] == 1 && count_map["--ssl"] == 1) {
337 conflict_option_name = "--ssl";
340 if (is_conflict == false &&
341 count_map["-O"] == 1 && count_map["--sockopt"] == 1) {
343 conflict_option_name = "--sockopt";
346 if (is_conflict == false &&
347 count_map["-L"] == 1 && count_map["--access-log"] == 1) {
349 conflict_option_name = "--access-log";
352 if (is_conflict == false &&
353 count_map["-a"] == 1 && count_map["--access-log-name"] == 1) {
354 //-a(--access-log-name)
355 conflict_option_name = "--access-log-name";
359 if (is_conflict == true) {
360 std::stringstream buf;
361 buf << "Option " << conflict_option_name << " is conflict.";
362 l7vsadm_err.setter(true, buf.str());
363 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 120, buf.str(), __FILE__, __LINE__);
367 if (l7vsadm_request::CMD_ADD_VS == cmd &&
368 (count_map["-z"] > 0 || count_map["--ssl"] > 0)) {
369 protocol_module_control &ctrl
370 = protocol_module_control::getInstance();
371 ctrl.initialize(L7VS_MODULE_PATH);
372 protocol_module_base *module;
375 = ctrl.load_module(request.vs_element.protocol_module_name);
377 std::stringstream buf;
378 buf << "protocol module load error(--proto-module): "
379 << request.vs_element.protocol_module_name;
380 l7vsadm_err.setter(true, buf.str());
382 LOG_CAT_L7VSADM_PARSE,
390 // protocol module not found.
391 std::stringstream buf;
392 buf << "protocol module not found(--proto-module): "
393 << request.vs_element.protocol_module_name;
394 l7vsadm_err.setter(true, buf.str());
396 LOG_CAT_L7VSADM_PARSE,
403 bool module_used_flag = module->is_exec_OK(VS_CONTACT_CLASS_SSL);
404 if (module_used_flag == false) {
405 // protocol module not found.
406 std::stringstream buf;
407 buf << "You cannot set \"-z\" option with \"sslid\" protocol module.";
408 l7vsadm_err.setter(true, buf.str());
410 LOG_CAT_L7VSADM_PARSE,
422 // option virtualservice functions.
424 //! target option check
425 //! @param[in] argument position
426 //! @param[in] argument count
427 //! @param[in] argument value
428 bool l7vs::l7vsadm::parse_opt_vs_target_func(int &pos, int argc, char *argv[])
430 Logger logger(LOG_CAT_L7VSADM_COMMON, 4, "l7vsadm::parse_opt_vs_target_func", __FILE__, __LINE__);
433 // target address and port are not specified
434 std::string buf("target endpoint is not specified.(--tcp-service)");
435 l7vsadm_err.setter(true, buf);
436 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 9, buf, __FILE__, __LINE__);
439 // get host endpoint from string
440 std::string src_str = argv[pos];
441 if (request.vs_element.udpmode) {
443 request.vs_element.udp_recv_endpoint = string_to_endpoint<boost::asio::ip::udp>(src_str, err);
445 std::stringstream buf;
446 buf << "target endpoint parse error(--tcp-service): " << err.get_message() << src_str;
447 l7vsadm_err.setter(true, buf.str());
448 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 10, buf.str(), __FILE__, __LINE__);
451 check_endpoint<boost::asio::ip::udp>(request.vs_element.udp_recv_endpoint, true, err);
453 std::stringstream buf;
454 buf << "target endpoint parse error(--tcp-service): " << err.get_message() << src_str;
455 l7vsadm_err.setter(true, buf.str());
456 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 11, buf.str(), __FILE__, __LINE__);
461 request.vs_element.tcp_accept_endpoint = string_to_endpoint<boost::asio::ip::tcp>(src_str, err);
463 std::stringstream buf;
464 buf << "target endpoint parse error(--tcp-service): " << err.get_message() << src_str;
465 l7vsadm_err.setter(true, buf.str());
466 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 12, buf.str(), __FILE__, __LINE__);
469 check_endpoint<boost::asio::ip::tcp>(request.vs_element.tcp_accept_endpoint, true, err);
471 std::stringstream buf;
472 buf << "target endpoint parse error(--tcp-service): " << err.get_message() << src_str;
473 l7vsadm_err.setter(true, buf.str());
474 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 13, buf.str(), __FILE__, __LINE__);
480 //! module option check
481 //! @param[in] argument position
482 //! @param[in] argument count
483 //! @param[in] argument value
484 bool l7vs::l7vsadm::parse_opt_vs_module_func(int &pos, int argc, char *argv[])
486 Logger logger(LOG_CAT_L7VSADM_COMMON, 5, "l7vsadm::parse_opt_vs_module_func", __FILE__, __LINE__);
488 // target protomod name not specified.
489 std::string buf("protocol module name is not specified.(--proto-module)");
490 l7vsadm_err.setter(true, buf);
491 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 14, buf, __FILE__, __LINE__);
494 std::string module_name = argv[pos];
495 if (L7VS_MODNAME_LEN < module_name.length()) {
496 std::string buf("protocol module name is too long.(--proto-module)");
497 l7vsadm_err.setter(true, buf);
498 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 15, buf, __FILE__, __LINE__);
501 protocol_module_control &ctrl = protocol_module_control::getInstance();
502 ctrl.initialize(L7VS_MODULE_PATH);
503 protocol_module_base *module;
505 module = ctrl.load_module(module_name);
507 std::stringstream buf;
508 buf << "protocol module load error(--proto-module): " << module_name;
509 l7vsadm_err.setter(true, buf.str());
510 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 16, buf.str(), __FILE__, __LINE__);
514 // protocol module not found.
515 std::stringstream buf;
516 buf << "protocol module not found(--proto-module): " << module_name;
517 l7vsadm_err.setter(true, buf.str());
518 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 17, buf.str(), __FILE__, __LINE__);
521 module->init_logger_functions(
522 boost::bind(&l7vs::Logger::getLogLevel, l7vs::LOG_CAT_PROTOCOL),
523 boost::bind(&l7vs::Logger::putLogFatal, l7vs::LOG_CAT_PROTOCOL, _1, _2, _3, _4),
524 boost::bind(&l7vs::Logger::putLogError, l7vs::LOG_CAT_PROTOCOL, _1, _2, _3, _4),
525 boost::bind(&l7vs::Logger::putLogWarn, l7vs::LOG_CAT_PROTOCOL, _1, _2, _3, _4),
526 boost::bind(&l7vs::Logger::putLogInfo, l7vs::LOG_CAT_PROTOCOL, _1, _2, _3, _4),
527 boost::bind(&l7vs::Logger::putLogDebug, l7vs::LOG_CAT_PROTOCOL, _1, _2, _3, _4));
528 // create module args.
529 std::vector<std::string> module_args;
531 if (++pos == argc) break; //module option end.
532 parse_opt_map_type::iterator vsitr = vs_option_dic.find(argv[pos]);
533 if (vsitr != vs_option_dic.end()) {
534 --pos; // back for next option
535 break; // module option end.
537 parse_opt_map_type::iterator rsitr = rs_option_dic.find(argv[pos]);
538 if (rsitr != rs_option_dic.end()) {
539 --pos; // back for next option
540 break; // module option end.
542 module_args.push_back(argv[pos]);
544 protocol_module_base::check_message_result module_message = module->check_parameter(module_args);
546 if (!module_message.flag) {
547 // args is not supported.
548 std::stringstream buf;
549 buf << "protocol module argument error(--proto-module): " << module_message.message;
550 l7vsadm_err.setter(true, buf.str());
551 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 18, buf.str(), __FILE__, __LINE__);
554 request.vs_element.protocol_module_name = module_name;
555 BOOST_FOREACH(std::string str, module_args) {
556 request.vs_element.protocol_args.push_back(str);
558 ctrl.unload_module(module);
563 //! scheduler option check.
564 //! @param[in] argument position
565 //! @param[in] argument count
566 //! @param[in] argument value
567 bool l7vs::l7vsadm::parse_opt_vs_scheduler_func(int &pos, int argc, char *argv[])
569 Logger logger(LOG_CAT_L7VSADM_COMMON, 6, "l7vsadm::parse_opt_vs_scheduler_func", __FILE__, __LINE__);
572 // target scheduler name not specified.
573 std::string buf("schedule module name is not specified.(--scheduler)");
574 l7vsadm_err.setter(true, buf);
575 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 19, buf, __FILE__, __LINE__);
578 //schedule module check.
579 std::string scheduler_name = argv[pos];
580 if (L7VS_MODNAME_LEN < scheduler_name.length()) {
581 std::string buf("schedule module name is too long.(--scheduler)");
582 l7vsadm_err.setter(true, buf);
583 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 20, buf, __FILE__, __LINE__);
586 schedule_module_control &ctrl = schedule_module_control::getInstance();
587 ctrl.initialize(L7VS_MODULE_PATH);
588 schedule_module_base *module;
590 module = ctrl.load_module(scheduler_name);
592 std::stringstream buf;
593 buf << "scheduler module load error(--scheduler): " << scheduler_name;
594 l7vsadm_err.setter(true, buf.str());
595 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 21, buf.str(), __FILE__, __LINE__);
599 // schedule module not found
600 std::stringstream buf;
601 buf << "scheduler module not found(--scheduler): " << scheduler_name;
602 l7vsadm_err.setter(true, buf.str());
603 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 22, buf.str(), __FILE__, __LINE__);
606 ctrl.unload_module(module);
607 request.vs_element.schedule_module_name = scheduler_name;
611 //! @param[in] argument position
612 //! @param[in] argument count
613 //! @param[in] argument value
614 bool l7vs::l7vsadm::parse_opt_vs_upper_func(int &pos, int argc, char *argv[])
616 Logger logger(LOG_CAT_L7VSADM_COMMON, 7, "l7vsadm::parse_opt_vs_upper_func", __FILE__, __LINE__);
619 // target max connection number not specified
620 std::string buf("sorry max connection value is not specified.(--upper)");
621 l7vsadm_err.setter(true, buf);
622 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 23, buf, __FILE__, __LINE__);
626 request.vs_element.sorry_maxconnection = boost::lexical_cast<long long>(argv[pos]);
627 if ((0LL > request.vs_element.sorry_maxconnection) ||
628 (100000LL < request.vs_element.sorry_maxconnection)) {
629 std::string buf("invalid sorry max connection value.(--upper)");
630 l7vsadm_err.setter(true, buf);
631 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 24, buf, __FILE__, __LINE__);
634 if (0LL == request.vs_element.sorry_maxconnection)
635 request.vs_element.sorry_maxconnection = LLONG_MAX; // clear value
636 } catch (boost::bad_lexical_cast &e) {
637 std::string buf("invalid sorry max connection value.(--upper)");
638 l7vsadm_err.setter(true, buf);
639 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 25, buf, __FILE__, __LINE__);
642 //check connection limit and zero
645 //! bypass(SorryServer) option check
646 //! @param[in] argument position
647 //! @param[in] argument count
648 //! @param[in] argument value
649 bool l7vs::l7vsadm::parse_opt_vs_bypass_func(int &pos, int argc, char *argv[])
651 Logger logger(LOG_CAT_L7VSADM_COMMON, 8, "l7vsadm::parse_opt_vs_bypass_func", __FILE__, __LINE__);
654 // sorryserver addr and port not specified
655 std::string buf("sorryserver endpoint is not specified.(--bypass)");
656 l7vsadm_err.setter(true, buf);
657 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 26, buf, __FILE__, __LINE__);
660 std::string sorry_endpoint = argv[pos];
662 request.vs_element.sorry_endpoint = string_to_endpoint<boost::asio::ip::tcp>(sorry_endpoint, err);
664 std::stringstream buf;
665 buf << "sorryserver endpoint parse error(--bypass): " << err.get_message() << sorry_endpoint;
666 l7vsadm_err.setter(true, buf.str());
667 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 27, buf.str(), __FILE__, __LINE__);
670 // clear endpoint check (0.0.0.0:0)
671 if (request.vs_element.sorry_endpoint == boost::asio::ip::tcp::endpoint()) {
672 request.vs_element.sorry_endpoint = boost::asio::ip::tcp::endpoint(
673 boost::asio::ip::address::from_string("255.255.255.255"), 0);
675 check_endpoint<boost::asio::ip::tcp>(request.vs_element.sorry_endpoint, false, err);
677 std::stringstream buf;
678 buf << "sorryserver endpoint parse error(--bypass): " << err.get_message() << sorry_endpoint;
679 l7vsadm_err.setter(true, buf.str());
680 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 29, buf.str(), __FILE__, __LINE__);
686 //! virtualservice option flag function
687 //! @param[in] argument position
688 //! @param[in] argument count
689 //! @param[in] argument value
690 bool l7vs::l7vsadm::parse_opt_vs_flag_func(int &pos, int argc, char *argv[])
692 Logger logger(LOG_CAT_L7VSADM_COMMON, 9, "l7vsadm::parse_opt_vs_flag_func", __FILE__, __LINE__);
695 // sorry flag is not specified
696 std::string buf("sorry flag value is not specified.(--flag)");
697 l7vsadm_err.setter(true, buf);
698 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 30, buf, __FILE__, __LINE__);
702 int tmp = boost::lexical_cast<int>(argv[pos]);
703 if ((0 != tmp) && (1 != tmp)) {
704 std::string buf("invalid sorry flag value.(--flag)");
705 l7vsadm_err.setter(true, buf);
706 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 31, buf, __FILE__, __LINE__);
710 request.vs_element.sorry_flag = INT_MAX; // clear value
712 request.vs_element.sorry_flag = 1;
713 } catch (boost::bad_lexical_cast &e) {
714 std::string buf("invalid sorry flag value.(--flag)");
715 l7vsadm_err.setter(true, buf);
716 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 32, buf, __FILE__, __LINE__);
721 //! virtualservice option sorry forward mode function
722 //! @param[in] argument position
723 //! @param[in] argument count
724 //! @param[in] argument value
725 bool l7vs::l7vsadm::parse_opt_vs_fwdmode_func(int &pos, int argc, char *argv[])
727 Logger logger(LOG_CAT_L7VSADM_COMMON, /*XXX*/999, "l7vsadm::parse_opt_vs_fwdmode_func", __FILE__, __LINE__);
729 std::string opt(argv[pos]);
730 if (opt == "--masq") {
731 request.vs_element.sorry_fwdmode = virtualservice_element::FWD_MASQ;
732 } else if (opt == "--tproxy") {
733 #ifdef IP_TRANSPARENT
734 request.vs_element.sorry_fwdmode = virtualservice_element::FWD_TPROXY;
736 std::stringstream buf("tproxy(IP_TRANSPARENT) not supported on this platform.");
737 l7vsadm_err.setter(true, buf.str());
738 Logger::putLogInfo(LOG_CAT_L7VSADM_PARSE, /*XXX*/999, buf.str(), __FILE__, __LINE__);
742 // should never come here
743 std::stringstream buf;
744 buf << boost::format("unknown sorryserver forward mode specified.(%s)") % opt;
745 l7vsadm_err.setter(true, buf.str());
746 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, /*XXX*/999, buf.str(), __FILE__, __LINE__);
751 //! virtualservice option qosupstream function
752 //! @param[in] argument position
753 //! @param[in] argument count
754 //! @param[in] argument value
755 bool l7vs::l7vsadm::parse_opt_vs_qosup_func(int &pos, int argc, char *argv[])
757 Logger logger(LOG_CAT_L7VSADM_COMMON, 10, "l7vsadm::parse_opt_vs_qosup_func", __FILE__, __LINE__);
760 // QoS upstream value is not specified.
761 std::string buf("QoS upstream value is not specified.(--qos-up)");
762 l7vsadm_err.setter(true, buf);
763 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 33, buf, __FILE__, __LINE__);
767 virtualservice_element &elem = request.vs_element; // request virtualservice element reference get.
768 std::string tmp = argv[pos];
769 std::string::reverse_iterator ritr = tmp.rbegin();
770 if (*ritr == 'G' || *ritr == 'g') {
771 std::string strval = tmp.substr(0, tmp.length() - 1);
772 unsigned long long ullval = boost::lexical_cast<unsigned long long> (strval);
774 std::string buf("QoS upstream value is too big.(--qos-up)");
775 l7vsadm_err.setter(true, buf);
776 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 34, buf, __FILE__, __LINE__);
779 elem.qos_upstream = ullval * 1000 * 1000 * 1000; // set qos_upstream
780 } else if (*ritr == 'M' || *ritr == 'm') {
781 std::string strval = tmp.substr(0, tmp.length() - 1);
782 unsigned long long ullval = boost::lexical_cast<unsigned long long> (strval);
784 std::string buf("QoS upstream value is too big.(--qos-up)");
785 l7vsadm_err.setter(true, buf);
786 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 35, buf, __FILE__, __LINE__);
789 elem.qos_upstream = ullval * 1000 * 1000; // set qos_upstream
790 } else if (*ritr == 'K' || *ritr == 'k') {
791 std::string strval = tmp.substr(0, tmp.length() - 1);
792 unsigned long long ullval = boost::lexical_cast<unsigned long long> (strval);
794 std::string buf("QoS upstream value is too big.(--qos-up)");
795 l7vsadm_err.setter(true, buf);
796 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 36, buf, __FILE__, __LINE__);
799 elem.qos_upstream = ullval * 1000; // set qos_upstream
801 unsigned long long ullval = boost::lexical_cast<unsigned long long> (argv[pos]);
803 std::string buf("QoS upstream value is too big.(--qos-up)");
804 l7vsadm_err.setter(true, buf);
805 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 111, buf, __FILE__, __LINE__);
808 elem.qos_upstream = ullval; // set qos_upstream
810 if (0ULL == elem.qos_upstream) {
811 elem.qos_upstream = ULLONG_MAX; // clear value
813 elem.qos_upstream /= 8; //qos convert to bytes per sec to bit per sec
816 } catch (boost::bad_lexical_cast &ex) {
817 std::string buf("invalid QoS upstream value.(--qos-up)");
818 l7vsadm_err.setter(true, buf);
819 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 37, buf, __FILE__, __LINE__);
824 //! virtualservice option qosdownstream function
825 //! @param[in] argument position
826 //! @param[in] argument count
827 //! @param[in] argument value
828 bool l7vs::l7vsadm::parse_opt_vs_qosdown_func(int &pos, int argc, char *argv[])
830 Logger logger(LOG_CAT_L7VSADM_COMMON, 11, "l7vsadm::parse_opt_vs_qosdown_func", __FILE__, __LINE__);
833 // QoS downstream value is not specified
834 std::string buf("QoS downstream value is not specified.(--qos-down)");
835 l7vsadm_err.setter(true, buf);
836 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 38, buf, __FILE__, __LINE__);
840 virtualservice_element &elem = request.vs_element; // request virtualservice element reference get.
841 std::string tmp = argv[pos];
842 std::string::reverse_iterator ritr = tmp.rbegin();
843 if (*ritr == 'G' || *ritr == 'g') {
844 std::string strval = tmp.substr(0, tmp.length() - 1);
845 unsigned long long ullval = boost::lexical_cast<unsigned long long> (strval);
847 std::string buf("QoS downstream value is too big.(--qos-down)");
848 l7vsadm_err.setter(true, buf);
849 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 39, buf, __FILE__, __LINE__);
852 elem.qos_downstream = ullval * 1000 * 1000 * 1000; // set qos_upstream
853 } else if (*ritr == 'M' || *ritr == 'm') {
854 std::string strval = tmp.substr(0, tmp.length() - 1);
855 unsigned long long ullval = boost::lexical_cast<unsigned long long> (strval);
857 std::string buf("QoS downstream value is too big.(--qos-down)");
858 l7vsadm_err.setter(true, buf);
859 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 40, buf, __FILE__, __LINE__);
862 elem.qos_downstream = ullval * 1000 * 1000; // set qos_upstream
863 } else if (*ritr == 'K' || *ritr == 'k') {
864 std::string strval = tmp.substr(0, tmp.length() - 1);
865 unsigned long long ullval = boost::lexical_cast<unsigned long long> (strval);
867 std::string buf("QoS downstream value is too big.(--qos-down)");
868 l7vsadm_err.setter(true, buf);
869 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 41, buf, __FILE__, __LINE__);
872 elem.qos_downstream = ullval * 1000; // set qos_upstream
874 unsigned long long ullval = boost::lexical_cast<unsigned long long> (argv[pos]);
876 std::string buf("QoS downstream value is too big.(--qos-down)");
877 l7vsadm_err.setter(true, buf);
878 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 115, buf, __FILE__, __LINE__);
881 elem.qos_downstream = boost::lexical_cast<unsigned long long> (argv[pos]); // set qos_downstream
883 if (0ULL == elem.qos_downstream) {
884 elem.qos_downstream = ULLONG_MAX; // clear value
886 elem.qos_downstream /= 8; //qos convert to bytes per sec to bit per sec
888 } catch (boost::bad_lexical_cast &ex) {
889 // don' conv qos downstream
890 std::string buf("invalid QoS downstream value.(--qos-down)");
891 l7vsadm_err.setter(true, buf);
892 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 42, buf, __FILE__, __LINE__);
897 //! virtualservice option udp func.
898 //! @param[in] argument position
899 //! @param[in] argument count
900 //! @param[in] argument value
901 bool l7vs::l7vsadm::parse_opt_vs_udp_func(int &pos, int argc, char *argv[])
903 Logger logger(LOG_CAT_L7VSADM_COMMON, 12, "l7vsadm::parse_opt_vs_udp_func", __FILE__, __LINE__);
905 virtualservice_element &elem = request.vs_element; // request virtualservice element reference get.
906 elem.udpmode = true; // udpmode on.
907 boost::asio::ip::tcp::endpoint zeropoint;
908 if (zeropoint != elem.tcp_accept_endpoint) { // address tcp_acceptor endpoint
909 std::stringstream sstream;
910 sstream << elem.tcp_accept_endpoint;
911 std::string endpoint = sstream.str();
913 elem.udp_recv_endpoint = string_to_endpoint<boost::asio::ip::udp>(endpoint, err);
915 std::stringstream buf;
916 buf << "target endpoint parse error(--udp-service): " << err.get_message() << endpoint;
917 l7vsadm_err.setter(true, buf.str());
918 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 43, buf.str(), __FILE__, __LINE__);
921 elem.tcp_accept_endpoint = zeropoint;
923 if (elem.realserver_vector.size() != 0 && elem.realserver_vector.front().tcp_endpoint != zeropoint) {
924 std::stringstream sstream;
925 sstream << elem.realserver_vector.front().tcp_endpoint;
926 std::string endpoint = sstream.str();
928 elem.realserver_vector.front().udp_endpoint = string_to_endpoint<boost::asio::ip::udp> (endpoint, err);
930 std::stringstream buf;
931 buf << "realserver endpoint parse error(--udp-service): " << err.get_message() << endpoint;
932 l7vsadm_err.setter(true, buf.str());
933 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 44, buf.str(), __FILE__, __LINE__);
936 elem.realserver_vector.front().tcp_endpoint = zeropoint;
940 //! virtualservice option ssl_file function
941 //! @param[in] argument position
942 //! @param[in] argument count
943 //! @param[in] argument value
944 bool l7vs::l7vsadm::parse_opt_vs_ssl_file_func(int &pos, int argc, char *argv[])
946 Logger logger(LOG_CAT_L7VSADM_COMMON, 38, "l7vsadm::parse_opt_vs_ssl_file_func", __FILE__, __LINE__);
949 std::string buf("ssl config file is not specified.(--ssl)");
950 l7vsadm_err.setter(true, buf);
951 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 90, buf, __FILE__, __LINE__);
954 // ssl config file check.
955 std::string conf_file_name = argv[pos];
956 if (L7VS_FILENAME_LEN < conf_file_name.length()) {
957 std::string buf("ssl config file name is too long.(--ssl)");
958 l7vsadm_err.setter(true, buf);
959 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 91, buf, __FILE__, __LINE__);
963 if ((fp = fopen(conf_file_name.c_str(), "r")) == NULL) {
964 std::string buf("ssl config file cannot open.(--ssl)");
965 l7vsadm_err.setter(true, buf);
966 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 92, buf, __FILE__, __LINE__);
971 request.vs_element.ssl_file_name = conf_file_name;
975 //! virtualservice option access log function
976 //! @param[in] argument position
977 //! @param[in] argument count
978 //! @param[in] argument value
979 bool l7vs::l7vsadm::parse_opt_vs_access_log_func(int &pos, int argc, char *argv[])
981 Logger logger(LOG_CAT_L7VSADM_COMMON, 39, "l7vsadm::parse_opt_vs_access_log_func", __FILE__, __LINE__);
984 // access log flag is not specified
985 std::string buf("access log flag value is not specified.(--access-log)");
986 l7vsadm_err.setter(true, buf);
987 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 93, buf, __FILE__, __LINE__);
991 int tmp = boost::lexical_cast<int>(argv[pos]);
992 if ((0 != tmp) && (1 != tmp)) {
993 std::string buf("invalid access log flag value.(--access-log)");
994 l7vsadm_err.setter(true, buf);
995 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 94, buf, __FILE__, __LINE__);
998 request.vs_element.access_log_flag = tmp;
999 } catch (boost::bad_lexical_cast &e) {
1000 std::string buf("invalid access log flag value.(--access-log)");
1001 l7vsadm_err.setter(true, buf);
1002 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 95, buf, __FILE__, __LINE__);
1008 //! virtualservice option access_log_logrotate function
1009 //! @param[in] argument position
1010 //! @param[in] argument count
1011 //! @param[in] argument value
1012 bool l7vs::l7vsadm::parse_opt_vs_access_log_logrotate_func(int &pos, int argc, char *argv[])
1014 Logger logger(LOG_CAT_L7VSADM_COMMON, 40, "l7vsadm::parse_opt_vs_accesslog_logrotate_func", __FILE__, __LINE__);
1016 if (++pos >= argc) {
1017 std::string buf("access log file is not specified.(--access-log-name)");
1018 l7vsadm_err.setter(true, buf);
1019 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 96, buf, __FILE__, __LINE__);
1022 // access log file check.
1023 std::string access_log_file_name = argv[pos];
1024 if (L7VS_FILENAME_LEN < access_log_file_name.length()) {
1025 std::string buf("access log file name is too long.(--access-log-name)");
1026 l7vsadm_err.setter(true, buf);
1027 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 97, buf, __FILE__, __LINE__);
1030 if ("/" != access_log_file_name.substr(0, 1)) {
1031 std::string buf("please specify access log filename in fullpath.(--access-log-name)");
1032 l7vsadm_err.setter(true, buf);
1033 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 98, buf, __FILE__, __LINE__);
1037 request.vs_element.access_log_rotate_key_info = "";
1039 // create access log args.
1040 std::vector<std::string> arguments_vector;
1041 virtualservice_element::access_log_rotate_arguments_map_type arguments_map;
1043 if (++pos == argc) break; //access log arguments end.
1044 parse_opt_map_type::iterator vsitr = vs_option_dic.find(argv[pos]);
1045 if (vsitr != vs_option_dic.end()) {
1046 --pos; // back for next option
1047 break; // module option end.
1049 arguments_vector.push_back(argv[pos]);
1051 request.vs_element.access_log_rotate_key_info += argv[pos];
1052 request.vs_element.access_log_rotate_key_info += " ";
1055 boost::algorithm::erase_last(request.vs_element.access_log_rotate_key_info , " ");
1057 if (0 < arguments_vector.size()) {
1058 if (0 == (arguments_vector.size() % 2)) {
1059 for (unsigned int i = 0; i < (arguments_vector.size() - 1); ++i) {
1060 std::pair<virtualservice_element::access_log_rotate_arguments_map_type::iterator, bool> ret =
1061 arguments_map.insert(
1062 virtualservice_element::access_log_rotate_arguments_pair_type(
1063 arguments_vector[i], arguments_vector[i+1]));
1065 std::string buf("access log rotation argument is duplicated.(--access-log-name)");
1066 l7vsadm_err.setter(true, buf);
1067 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 99, buf, __FILE__, __LINE__);
1073 std::string buf("access log rotation argument error.(--access-log-name)");
1074 l7vsadm_err.setter(true, buf);
1075 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 100, buf, __FILE__, __LINE__);
1078 bool ret = logger_access_manager::getInstance().access_log_logrotate_parameter_check(arguments_map);
1080 std::string buf("access log rotation argument error.(--access-log-name)");
1081 l7vsadm_err.setter(true, buf);
1082 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 101, buf, __FILE__, __LINE__);
1087 request.vs_element.access_log_file_name = access_log_file_name;
1088 request.vs_element.access_log_rotate_arguments.clear();
1089 BOOST_FOREACH(virtualservice_element::access_log_rotate_arguments_pair_type pair, arguments_map) {
1090 request.vs_element.access_log_rotate_arguments.insert(pair);
1096 //! virtualservice option socket function
1097 //! @param[in] argument position
1098 //! @param[in] argument count
1099 //! @param[in] argument value
1100 bool l7vs::l7vsadm::parse_opt_vs_socket_func(int &pos, int argc, char *argv[])
1102 Logger logger(LOG_CAT_L7VSADM_COMMON, 41, "l7vsadm::parse_opt_vs_socket_func", __FILE__, __LINE__);
1104 if (++pos >= argc) {
1105 std::string buf("socket option is not specified.(--sockopt)");
1106 l7vsadm_err.setter(true, buf);
1107 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 102, buf, __FILE__, __LINE__);
1111 bool is_set_defer_accept = false;
1112 bool is_set_nodelay = false;
1113 bool is_set_cork = false;
1114 bool is_set_quickack = false;
1116 request.vs_element.socket_option_tcp_defer_accept = 0;
1117 request.vs_element.socket_option_tcp_nodelay = 0;
1118 request.vs_element.socket_option_tcp_cork = 0;
1119 request.vs_element.socket_option_tcp_quickack = 0;
1121 std::string socket_option_string = argv[pos];
1122 std::vector<std::string> socket_options;
1123 boost::split(socket_options, socket_option_string, boost::algorithm::is_any_of(","));
1125 BOOST_FOREACH(std::string option, socket_options) {
1126 if (option == "deferaccept") {
1127 if (!is_set_defer_accept) {
1128 is_set_defer_accept = true;
1129 request.vs_element.socket_option_tcp_defer_accept = 1;
1131 // defer_accept is duplicated
1132 std::stringstream buf;
1133 buf << "socket option deferaccept is duplicated.(--sockopt)";
1134 l7vsadm_err.setter(true, buf.str());
1135 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 103, buf.str(), __FILE__, __LINE__);
1138 } else if (option == "nodelay") {
1139 if (!is_set_nodelay) {
1140 is_set_nodelay = true;
1141 request.vs_element.socket_option_tcp_nodelay = 1;
1143 // nodelay is duplicated
1144 std::stringstream buf;
1145 buf << "socket option nodelay is duplicated.(--sockopt)";
1146 l7vsadm_err.setter(true, buf.str());
1147 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 104, buf.str(), __FILE__, __LINE__);
1150 } else if (option == "cork") {
1153 request.vs_element.socket_option_tcp_cork = 1;
1155 // cork is duplicated
1156 std::stringstream buf;
1157 buf << "socket option cork is duplicated.(--sockopt)";
1158 l7vsadm_err.setter(true, buf.str());
1159 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 105, buf.str(), __FILE__, __LINE__);
1162 } else if (option == "quickackon" || option == "quickackoff") {
1163 if (!is_set_quickack) {
1164 is_set_quickack = true;
1165 request.vs_element.socket_option_tcp_quickack = ((option == "quickackon") ? 1 : 2);
1167 // quickack is duplicated
1168 std::stringstream buf;
1169 buf << "socket option quickack is duplicated.(--sockopt)";
1170 l7vsadm_err.setter(true, buf.str());
1171 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 106, buf.str(), __FILE__, __LINE__);
1175 // unknown socket option
1176 std::stringstream buf;
1177 buf << "unknown socket option.(--sockopt)";
1178 l7vsadm_err.setter(true, buf.str());
1179 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 107, buf.str(), __FILE__, __LINE__);
1184 request.vs_element.socket_option_string = socket_option_string;
1188 //! realserver command parsing.
1189 //! @param[in] request command
1190 //! @param[in] argument count
1191 //! @param[in] argument value
1192 bool l7vs::l7vsadm::parse_rs_func(l7vs::l7vsadm_request::COMMAND_CODE_TAG cmd, int argc, char *argv[])
1194 Logger logger(LOG_CAT_L7VSADM_COMMON, 13, "l7vsadm::parse_rs_func", __FILE__, __LINE__);
1198 std::stringstream buf;
1199 buf << "Argument argc is illegal for ";
1203 l7vsadm_err.setter(true, buf.str());
1204 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 121, buf.str(), __FILE__, __LINE__);
1208 request.command = cmd;
1210 request.vs_element.realserver_vector.push_back(realserver_element());
1212 std::map<std::string, int> count_map;
1213 for (parse_opt_map_type::iterator itr = rs_option_dic.begin() ;
1214 itr != rs_option_dic.end() ; ++itr) {
1215 count_map[ itr->first ] = 0;
1218 for (int pos = 2; pos < argc; ++pos) {
1219 parse_opt_map_type::iterator itr = rs_option_dic.find(argv[pos]);
1220 if (itr != rs_option_dic.end()) {
1221 count_map[ itr->first ]++;
1222 if (! itr->second(pos, argc, argv)) return false;
1224 std::stringstream buf;
1225 buf << "realserver option not found(--real-server): " << argv[pos];
1226 l7vsadm_err.setter(true, buf.str());
1227 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 45, buf.str(), __FILE__, __LINE__);
1232 if (request.vs_element.protocol_module_name.length() == 0) {
1233 //protocol module name error
1234 std::string buf("protocol module is not specified.(--proto-module)");
1235 l7vsadm_err.setter(true, buf);
1236 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 46, buf, __FILE__, __LINE__);
1239 if (request.vs_element.udpmode) {
1240 if (request.vs_element.udp_recv_endpoint == boost::asio::ip::udp::endpoint()) {
1241 // udp mode,but not acceptor endpoint
1242 std::string buf("udp receive endpoint is not specified.(--udp-service)");
1243 l7vsadm_err.setter(true, buf);
1244 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 47, buf, __FILE__, __LINE__);
1247 if (request.vs_element.realserver_vector.front().udp_endpoint == boost::asio::ip::udp::endpoint()) {
1248 // udp mode,but not realserver endpoint
1249 std::string buf("realserver udp endpoint is not specified.(--real-server)");
1250 l7vsadm_err.setter(true, buf);
1251 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 48, buf, __FILE__, __LINE__);
1255 if (request.vs_element.tcp_accept_endpoint == boost::asio::ip::tcp::endpoint()) {
1256 // tcp mode, but not acceptor endpoint
1257 std::string buf("tcp accpeptor endpoint not specified.(--tcp-service)");
1258 l7vsadm_err.setter(true, buf);
1259 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 49, buf, __FILE__, __LINE__);
1262 if (request.vs_element.realserver_vector.front().tcp_endpoint == boost::asio::ip::tcp::endpoint()) {
1263 // tcp mode,but not realserver endpoint
1264 std::string buf("realserver tcp endpoint not specified.(--real-server)");
1265 l7vsadm_err.setter(true, buf);
1266 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 50, buf, __FILE__, __LINE__);
1271 if (l7vsadm_request::CMD_EDIT_RS != cmd) {
1272 // realserver weight default value = 1
1273 if (-1 == request.vs_element.realserver_vector.front().weight) {
1274 request.vs_element.realserver_vector.front().weight = 1;
1276 // realserver forward mode default value = FWD_MASQ
1277 if (realserver_element::FWD_NONE == request.vs_element.realserver_vector.front().fwdmode) {
1278 request.vs_element.realserver_vector.front().fwdmode = realserver_element::FWD_MASQ;
1281 // Existence check of the parameter
1282 if (count_map["-w"] == 0 &&
1283 count_map["--weight"] == 0 &&
1284 count_map["--masq"] == 0 &&
1285 count_map["--tproxy"] == 0) {
1286 std::string buf("All option omitted for edit rs command.");
1287 l7vsadm_err.setter(true, buf);
1288 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 112, buf, __FILE__, __LINE__);
1294 std::string conflict_option_name;
1295 bool is_conflict = false;
1297 for (std::map<std::string, int>::iterator itr = count_map.begin() ;
1298 itr != count_map.end() ; ++itr) {
1299 if (itr->second > 1) {
1300 conflict_option_name = itr->first;
1306 if (is_conflict == false &&
1307 count_map["-t"] == 1 && count_map["--tcp-service"] == 1) {
1309 conflict_option_name = "--tcp-service";
1312 if (is_conflict == false &&
1313 count_map["-m"] == 1 && count_map["--proto-module"] == 1) {
1314 //-m(--proto-module)
1315 conflict_option_name = "--proto-module";
1318 if (is_conflict == false &&
1319 count_map["-r"] == 1 && count_map["--real-server"] == 1) {
1321 conflict_option_name = "--real-server";
1324 if ((is_conflict == false) &&
1325 (count_map["-w"] == 1) && (count_map["--weight"] == 1) &&
1326 (l7vsadm_request::CMD_DEL_RS != cmd)) {
1328 conflict_option_name = "--weight";
1331 if ((is_conflict == false) &&
1332 count_map["--masq"] + count_map["--tproxy"] > 1 &&
1333 (l7vsadm_request::CMD_DEL_RS != cmd)) {
1335 conflict_option_name = "--masq/tproxy";
1339 if (is_conflict == true) {
1340 std::stringstream buf;
1341 buf << "Option " << conflict_option_name << " is conflict.";
1342 l7vsadm_err.setter(true, buf.str());
1343 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 122, buf.str(), __FILE__, __LINE__);
1350 // realserver option functions.
1352 //! realserver weight set
1353 //! @param[in] argument position
1354 //! @param[in] argument count
1355 //! @param[in] argument value
1356 bool l7vs::l7vsadm::parse_opt_rs_weight_func(int &pos, int argc, char *argv[])
1358 Logger logger(LOG_CAT_L7VSADM_COMMON, 14, "l7vsadm::parse_opt_rs_weight_func", __FILE__, __LINE__);
1360 if (++pos >= argc) {
1361 // weight value is not specified
1362 std::string buf("weight value is not specified.(--weight)");
1363 l7vsadm_err.setter(true, buf);
1364 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 51, buf, __FILE__, __LINE__);
1368 request.vs_element.realserver_vector.front().weight = boost::lexical_cast<int>(argv[pos]);
1369 if ((0 > request.vs_element.realserver_vector.front().weight) ||
1370 (100 < request.vs_element.realserver_vector.front().weight)) {
1371 std::string buf("invalid weight value.(--weight)");
1372 l7vsadm_err.setter(true, buf);
1373 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 52, buf, __FILE__, __LINE__);
1376 } catch (boost::bad_lexical_cast &ex) {
1377 // lexical cast error
1378 std::string buf("invalid weight value.(--weight)");
1379 l7vsadm_err.setter(true, buf);
1380 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 53, buf, __FILE__, __LINE__);
1385 //! realserver forward mode set
1386 //! @param[in] argument position
1387 //! @param[in] argument count
1388 //! @param[in] argument value
1389 bool l7vs::l7vsadm::parse_opt_rs_fwdmode_func(int &pos, int argc, char *argv[])
1391 Logger logger(LOG_CAT_L7VSADM_COMMON, /*XXX*/999, "l7vsadm::parse_opt_rs_fwdmode_func", __FILE__, __LINE__);
1393 std::string opt(argv[pos]);
1394 if (opt == "--masq") {
1395 request.vs_element.realserver_vector.front().fwdmode = realserver_element::FWD_MASQ;
1396 } else if (opt == "--tproxy") {
1397 #ifdef IP_TRANSPARENT
1398 request.vs_element.realserver_vector.front().fwdmode = realserver_element::FWD_TPROXY;
1400 std::stringstream buf("tproxy(IP_TRANSPARENT) not supported on this platform.");
1401 l7vsadm_err.setter(true, buf.str());
1402 Logger::putLogInfo(LOG_CAT_L7VSADM_PARSE, /*XXX*/999, buf.str(), __FILE__, __LINE__);
1406 // should never come here
1407 std::stringstream buf;
1408 buf << boost::format("unknown realserver forward mode specified.(%s)") % opt;
1409 l7vsadm_err.setter(true, buf.str());
1410 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, /*XXX*/999, buf.str(), __FILE__, __LINE__);
1416 //! realserver target set
1417 //! @param[in] argument position
1418 //! @param[in] argument count
1419 //! @param[in] argument value
1420 bool l7vs::l7vsadm::parse_opt_rs_realserver_func(int &pos, int argc, char *argv[])
1422 Logger logger(LOG_CAT_L7VSADM_COMMON, 15, "l7vsadm::parse_opt_rs_realserver_func", __FILE__, __LINE__);
1424 if (++pos >= argc) {
1425 // realserver address is not specified
1426 std::string buf("realserver address is not specified.(--real-server)");
1427 l7vsadm_err.setter(true, buf);
1428 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 54, buf, __FILE__, __LINE__);
1431 std::string src_str = argv[pos];
1432 if (request.vs_element.udpmode) {
1434 request.vs_element.realserver_vector.front().udp_endpoint = string_to_endpoint<boost::asio::ip::udp>(src_str, err);
1436 // address string error.
1437 std::stringstream buf;
1438 buf << "realserver endpoint parse error(--real-server): " << err.get_message() << src_str;
1439 l7vsadm_err.setter(true, buf.str());
1440 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 55, buf.str(), __FILE__, __LINE__);
1443 check_endpoint<boost::asio::ip::udp>(request.vs_element.realserver_vector.front().udp_endpoint, false, err);
1445 std::stringstream buf;
1446 buf << "realserver endpoint parse error(--real-server): " << err.get_message() << src_str;
1447 l7vsadm_err.setter(true, buf.str());
1448 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 56, buf.str(), __FILE__, __LINE__);
1453 request.vs_element.realserver_vector.front().tcp_endpoint = string_to_endpoint<boost::asio::ip::tcp>(src_str, err);
1455 // address string error.
1456 std::stringstream buf;
1457 buf << "realserver endpoint parse error(--real-server): " << err.get_message() << src_str;
1458 l7vsadm_err.setter(true, buf.str());
1459 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 57, buf.str(), __FILE__, __LINE__);
1462 check_endpoint<boost::asio::ip::tcp>(request.vs_element.realserver_vector.front().tcp_endpoint, false, err);
1464 std::stringstream buf;
1465 buf << "realserver endpoint parse error(--real-server): " << err.get_message() << src_str;
1466 l7vsadm_err.setter(true, buf.str());
1467 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 58, buf.str(), __FILE__, __LINE__);
1474 //! replication command parsing.
1475 //! @param[in] request command
1476 //! @param[in] argument count
1477 //! @param[in] argument value
1478 bool l7vs::l7vsadm::parse_replication_func(l7vs::l7vsadm_request::COMMAND_CODE_TAG cmd, int argc, char *argv[])
1480 Logger logger(LOG_CAT_L7VSADM_COMMON, 16, "l7vsadm::parse_replication_func", __FILE__, __LINE__);
1482 if (argc < 3 || argc > 4) {
1484 std::stringstream buf;
1485 buf << "Argument argc is illegal for ";
1489 l7vsadm_err.setter(true, buf.str());
1490 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 123, buf.str(), __FILE__, __LINE__);
1494 request.command = cmd;
1496 for (int pos = 2; pos < argc; ++pos) {
1497 parse_opt_map_type::iterator itr = replication_option_dic.find(argv[pos]);
1498 if (itr != replication_option_dic.end()) {
1499 if (! itr->second(pos, argc, argv)) return false;
1501 std::stringstream buf;
1502 buf << "replication option not found(--replication): " << argv[pos];
1503 l7vsadm_err.setter(true, buf.str());
1504 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 59, buf.str(), __FILE__, __LINE__);
1508 if (l7vsadm_request::REP_NONE == request.replication_command) {
1509 // not specified replication command
1510 std::string buf("replication command not specified.(--replication)");
1511 l7vsadm_err.setter(true, buf);
1512 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 60, buf, __FILE__, __LINE__);
1520 // replication option functions.
1522 //! replication switch function
1523 //! @param[in] argument position
1524 //! @param[in] argument count
1525 //! @param[in] argument value
1526 bool l7vs::l7vsadm::parse_opt_replication_switch_func(int &pos, int argc, char *argv[])
1528 Logger logger(LOG_CAT_L7VSADM_COMMON, 17, "l7vsadm::parse_opt_replication_switch_func", __FILE__, __LINE__);
1530 if (request.replication_command != l7vsadm_request::REP_NONE) {
1531 // double command target.
1532 std::string buf("replication option is double specified.(--switch)");
1533 l7vsadm_err.setter(true, buf);
1534 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 61, buf, __FILE__, __LINE__);
1537 if (++pos >= argc) {
1538 // replication switch value is not specified
1539 std::string buf("replication switch option is not specified.(--switch)");
1540 l7vsadm_err.setter(true, buf);
1541 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 62, buf, __FILE__, __LINE__);
1544 parse_opt_map_type::iterator itr = replication_switch_option_dic.find(argv[pos]);
1545 if (itr != replication_switch_option_dic.end()) { // option string function find.
1546 if (! itr->second(pos, argc, argv)) return false; // option string function error.
1547 } else { //option string function not found.
1548 // print option not found message.
1549 std::stringstream buf;
1550 buf << "replication switch option not found(--switch): " << argv[pos];
1551 l7vsadm_err.setter(true, buf.str());
1552 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 63, buf.str(), __FILE__, __LINE__);
1557 //! replication start function
1558 //! @param[in] argument position
1559 //! @param[in] argument count
1560 //! @param[in] argument value
1561 bool l7vs::l7vsadm::parse_opt_replication_start_func(int &pos, int argc, char *argv[])
1563 Logger logger(LOG_CAT_L7VSADM_COMMON, 18, "l7vsadm::parse_opt_replication_start_func", __FILE__, __LINE__);
1565 request.replication_command = l7vsadm_request::REP_START;
1568 //! replication stop function
1569 //! @param[in] argument position
1570 //! @param[in] argument count
1571 //! @param[in] argument value
1572 bool l7vs::l7vsadm::parse_opt_replication_stop_func(int &pos, int argc, char *argv[])
1574 Logger logger(LOG_CAT_L7VSADM_COMMON, 19, "l7vsadm::parse_opt_replication_stop_func", __FILE__, __LINE__);
1576 request.replication_command = l7vsadm_request::REP_STOP;
1579 //! replication force function
1580 //! @param[in] argument position
1581 //! @param[in] argument count
1582 //! @param[in] argument value
1583 bool l7vs::l7vsadm::parse_opt_replication_force_func(int &pos, int argc, char *argv[])
1585 Logger logger(LOG_CAT_L7VSADM_COMMON, 20, "l7vsadm::parse_opt_replication_force_func", __FILE__, __LINE__);
1587 if (request.replication_command != l7vsadm_request::REP_NONE) {
1588 // double command target.
1589 std::string buf("replication option is double specified.(--force)");
1590 l7vsadm_err.setter(true, buf);
1591 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 64, buf, __FILE__, __LINE__);
1594 request.replication_command = l7vsadm_request::REP_FORCE;
1597 //! replication dump function
1598 //! @param[in] argument position
1599 //! @param[in] argument count
1600 //! @param[in] argument value
1601 bool l7vs::l7vsadm::parse_opt_replication_dump_func(int &pos, int argc, char *argv[])
1603 Logger logger(LOG_CAT_L7VSADM_COMMON, 21, "l7vsadm::parse_opt_replication_dump_func", __FILE__, __LINE__);
1605 if (request.replication_command != l7vsadm_request::REP_NONE) {
1606 // double command target.
1607 std::string buf("replication option is double specified.(--dump)");
1608 l7vsadm_err.setter(true, buf);
1609 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 65, buf, __FILE__, __LINE__);
1612 request.replication_command = l7vsadm_request::REP_DUMP;
1616 //! log command parsing.
1617 //! @param[in] request command
1618 //! @param[in] argument count
1619 //! @param[in] argument value
1620 bool l7vs::l7vsadm::parse_log_func(l7vs::l7vsadm_request::COMMAND_CODE_TAG cmd, int argc, char *argv[])
1622 Logger logger(LOG_CAT_L7VSADM_COMMON, 22, "l7vsadm::parse_log_func", __FILE__, __LINE__);
1626 std::stringstream buf;
1627 buf << "Argument argc is illegal for ";
1631 l7vsadm_err.setter(true, buf.str());
1632 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 124, buf.str(), __FILE__, __LINE__);
1636 request.command = cmd;
1638 for (int pos = 2; pos < argc; ++pos) {
1639 parse_opt_map_type::iterator itr = log_option_dic.find(argv[pos]);
1640 if (itr != log_option_dic.end()) { // option string function find.
1641 if (! itr->second(pos, argc, argv)) return false; // option string function error.
1642 } else { //option string function not found.
1643 // print option not found message.
1644 std::stringstream buf;
1645 buf << "log option not found(--log): " << argv[pos];
1646 l7vsadm_err.setter(true, buf.str());
1647 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 66, buf.str(), __FILE__, __LINE__);
1651 if (LOG_CAT_NONE == request.log_category) {
1652 // not specified logcategory
1653 std::string buf("log category is not specified(--category).");
1654 l7vsadm_err.setter(true, buf);
1655 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 67, buf, __FILE__, __LINE__);
1658 if (LOG_LV_NONE == request.log_level) {
1659 // not specified loglevel
1660 std::string buf("log level is not specified.(--level)");
1661 l7vsadm_err.setter(true, buf);
1662 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 68, buf, __FILE__, __LINE__);
1669 // log option function
1671 //! log category set function
1672 //! @param[in] argument position
1673 //! @param[in] argument count
1674 //! @param[in] argument value
1675 bool l7vs::l7vsadm::parse_opt_log_category_func(int &pos, int argc, char *argv[])
1677 Logger logger(LOG_CAT_L7VSADM_COMMON, 23, "l7vsadm::parse_opt_log_category_func", __FILE__, __LINE__);
1679 if (request.log_category != LOG_CAT_NONE) {
1680 // double target commands.
1681 std::stringstream buf;
1684 buf << " conflict.";
1686 l7vsadm_err.setter(true, buf.str());
1687 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 69, buf.str(), __FILE__, __LINE__);
1690 if (++pos >= argc) {
1691 // log category is not specified.
1692 std::string buf("log category is not specified.(--category)");
1693 l7vsadm_err.setter(true, buf);
1694 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 70, buf, __FILE__, __LINE__);
1697 string_logcategory_map_type::iterator itr = string_logcategory_dic.find(argv[pos]);
1698 if (itr != string_logcategory_dic.end()) {
1699 request.log_category = itr->second;
1702 std::stringstream buf;
1703 buf << "log category not found(--category): " << argv[pos];
1704 l7vsadm_err.setter(true, buf.str());
1705 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 71, buf.str(), __FILE__, __LINE__);
1708 //! log level set function
1709 //! @param[in] argument position
1710 //! @param[in] argument count
1711 //! @param[in] argument value
1712 bool l7vs::l7vsadm::parse_opt_log_level_func(int &pos, int argc, char *argv[])
1714 Logger logger(LOG_CAT_L7VSADM_COMMON, 24, "l7vsadm::parse_opt_log_level_func", __FILE__, __LINE__);
1716 if (request.log_level != LOG_LV_NONE) {
1717 // double target commands.
1718 std::stringstream buf;
1721 buf << " conflict.";
1723 l7vsadm_err.setter(true, buf.str());
1724 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 72, buf.str(), __FILE__, __LINE__);
1727 if (++pos >= argc) {
1728 // log level is not specified.
1729 std::string buf("log level is not specified.(--level)");
1730 l7vsadm_err.setter(true, buf);
1731 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 73, buf, __FILE__, __LINE__);
1734 string_loglevel_map_type::iterator itr = string_loglevel_dic.find(argv[pos]);
1735 if (itr != string_loglevel_dic.end()) {
1736 request.log_level = itr->second;
1739 std::stringstream buf;
1740 buf << "log level not found(--level): " << argv[pos];
1741 l7vsadm_err.setter(true, buf.str());
1742 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 74, buf.str(), __FILE__, __LINE__);
1746 //! snmp command parsing
1747 //! @param[in] request command
1748 //! @param[in] argument count
1749 //! @param[in] argument value
1750 bool l7vs::l7vsadm::parse_snmp_func(l7vs::l7vsadm_request::COMMAND_CODE_TAG cmd, int argc, char *argv[])
1752 Logger logger(LOG_CAT_L7VSADM_COMMON, 25, "l7vsadm::parse_snmp_func", __FILE__, __LINE__);
1754 //Argument argc is illegal
1757 std::stringstream buf;
1758 buf << "Argument argc is illegal for ";
1762 l7vsadm_err.setter(true, buf.str());
1763 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 127, buf.str(), __FILE__, __LINE__);
1767 request.command = cmd;
1769 for (int pos = 2; pos < argc; ++pos) {
1770 parse_opt_map_type::iterator itr = snmp_option_dic.find(argv[pos]);
1771 if (itr != snmp_option_dic.end()) { // option string function find.
1772 if (! itr->second(pos, argc, argv)) return false; // option string function error.
1773 } else { //option string function not found.
1774 // print option not found message.
1775 std::string buf = "Invalid option for -S command.";
1776 l7vsadm_err.setter(true, buf);
1777 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 128, buf, __FILE__, __LINE__);
1785 //! snmp refresh set function
1786 //! @param[in] argument position
1787 //! @param[in] argument count
1788 //! @param[in] argument value
1789 bool l7vs::l7vsadm::parse_opt_snmp_refresh_func(int &pos, int argc, char *argv[])
1791 Logger logger(LOG_CAT_L7VSADM_COMMON, 42, "l7vsadm::parse_opt_snmp_refresh_func", __FILE__, __LINE__);
1792 if (request.snmpinfo.option_set_flag & snmp_info::SNMP_REFRESH_ALL_OPTION_FLAG
1793 || request.snmpinfo.option_set_flag & snmp_info::SNMP_REFRESH_OPTION_FLAG) {
1794 // double target commands.
1795 std::stringstream buf;
1798 buf << " is conflict.";
1800 l7vsadm_err.setter(true, buf.str());
1801 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 129, buf.str(), __FILE__, __LINE__);
1806 // don't target logcategory
1807 std::string buf("Invalid option for -S command.");
1808 l7vsadm_err.setter(true, buf);
1809 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 130, buf, __FILE__, __LINE__);
1814 request.snmpinfo.option_set_flag |= snmp_info::SNMP_REFRESH_ALL_OPTION_FLAG;
1816 } else if (argc == 7) {
1817 for (pos = 3; pos < argc; ++pos) {
1818 parse_opt_map_type::iterator itr = snmp_vs_option_dic.find(argv[pos]);
1819 if (itr != snmp_vs_option_dic.end()) {
1820 if (!itr->second(pos, argc, argv)) {
1824 std::string buf("Invalid option value for -r option.");
1825 l7vsadm_err.setter(true, buf);
1826 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 78, buf, __FILE__, __LINE__);
1830 request.snmpinfo.option_set_flag |= snmp_info::SNMP_REFRESH_OPTION_FLAG;
1833 std::string buf("Argument argc is illegal for -S command.");
1834 l7vsadm_err.setter(true, buf);
1835 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 79, buf, __FILE__, __LINE__);
1842 //! snmp virtualservice set function
1843 //! @param[in] argument position
1844 //! @param[in] argument count
1845 //! @param[in] argument value
1846 bool l7vs::l7vsadm::parse_opt_snmp_vs_target_func(int &pos, int argc, char *argv[])
1848 Logger logger(LOG_CAT_L7VSADM_COMMON, 43, "l7vsadm::parse_opt_vs_target_func", __FILE__, __LINE__);
1849 if (request.snmpinfo.option_set_flag & snmp_info::SNMP_TCP_SERVICE_OPTION_FLAG) {
1850 std::stringstream buf;
1853 buf << " is conflict.";
1855 l7vsadm_err.setter(true, buf.str());
1856 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 131, buf.str(), __FILE__, __LINE__);
1860 if (++pos >= argc) {
1861 //don't target recvaddress:port
1862 std::string buf("target endpoint is not specified.");
1863 l7vsadm_err.setter(true, buf);
1864 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 132, buf, __FILE__, __LINE__);
1868 // get host endpoint from string
1870 src_str = argv[pos];
1872 boost::asio::ip::tcp::endpoint tmp_endpoint;
1873 tmp_endpoint = string_to_endpoint<boost::asio::ip::tcp>(src_str, err);
1875 std::stringstream buf;
1876 buf << "target endpoint parse error:" << err.get_message() << src_str;
1877 l7vsadm_err.setter(true, buf.str());
1878 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 133, buf.str(), __FILE__, __LINE__);
1882 request.snmpinfo.vs_endpoint = tmp_endpoint;
1883 request.snmpinfo.option_set_flag |= snmp_info::SNMP_TCP_SERVICE_OPTION_FLAG;
1888 //! snmp module set function
1889 //! @param[in] argument position
1890 //! @param[in] argument count
1891 //! @param[in] argument value
1892 bool l7vs::l7vsadm::parse_opt_snmp_vs_module_func(int &pos, int argc, char *argv[])
1894 Logger logger(LOG_CAT_L7VSADM_COMMON, 44, "l7vsadm::parse_opt_snmp_vs_module_func", __FILE__, __LINE__);
1896 if (request.snmpinfo.option_set_flag & snmp_info::SNMP_PROTOCOL_MODULE_OPTION_FLAG) {
1897 std::stringstream buf;
1900 buf << " is conflict.";
1902 l7vsadm_err.setter(true, buf.str());
1903 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 134, buf.str(), __FILE__, __LINE__);
1907 if (++pos >= argc) {
1908 //don't target protomod name.
1909 std::string buf("protomod name is not specified.");
1910 l7vsadm_err.setter(true, buf);
1911 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 135, buf, __FILE__, __LINE__);
1915 std::string module_name = argv[pos];
1916 if (L7VS_MODNAME_LEN < module_name.length()) {
1917 std::string buf("protomod name is too long.");
1918 l7vsadm_err.setter(true, buf);
1919 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 136, buf, __FILE__, __LINE__);
1923 protocol_module_control &ctrl = protocol_module_control::getInstance();
1924 ctrl.initialize(L7VS_MODULE_PATH);
1925 protocol_module_base *module;
1927 module = ctrl.load_module(module_name);
1929 //don't find protocol module.
1930 std::stringstream buf;
1931 buf << "protocol module not found:" << module_name;
1932 l7vsadm_err.setter(true, buf.str());
1933 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 137, buf.str(), __FILE__, __LINE__);
1938 ctrl.unload_module(module);
1940 request.snmpinfo.option_set_flag |= snmp_info::SNMP_PROTOCOL_MODULE_OPTION_FLAG ;
1941 request.snmpinfo.protocol = module_name;
1946 //! snmp flag set function
1947 //! @param[in] argument position
1948 //! @param[in] argument count
1949 //! @param[in] argument value
1950 bool l7vs::l7vsadm::parse_opt_snmp_flag_func(int &pos, int argc, char *argv[])
1953 Logger logger(LOG_CAT_L7VSADM_COMMON, 45, "l7vsadm::parse_opt_snmp_flag_func", __FILE__, __LINE__);
1954 if (request.snmpinfo.option_set_flag & snmp_info::SNMP_ENABLE_OPTION_FLAG) {
1955 std::stringstream buf;
1958 buf << " is conflict.";
1960 l7vsadm_err.setter(true, buf.str());
1961 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 138, buf.str(), __FILE__, __LINE__);
1966 tmp = boost::lexical_cast< int >(argv[pos]);
1967 } catch (const boost::bad_lexical_cast &ex) {
1968 std::string buf("Invalid option value for -f option.");
1969 l7vsadm_err.setter(true, buf);
1970 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 139, buf, __FILE__, __LINE__);
1974 if (tmp == 0 || tmp == 1) {
1976 request.snmpinfo.enabled = tmp;
1977 request.snmpinfo.option_set_flag |= snmp_info::SNMP_ENABLE_OPTION_FLAG;
1981 std::string buf("Invalid option value for -f option.");
1982 l7vsadm_err.setter(true, buf);
1983 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 140, buf, __FILE__, __LINE__);
1987 std::string buf("Need option value for -f option.");
1988 l7vsadm_err.setter(true, buf);
1989 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 141, buf, __FILE__, __LINE__);
1993 //! snmp interval set function
1994 //! @param[in] argument position
1995 //! @param[in] argument count
1996 //! @param[in] argument value
1997 bool l7vs::l7vsadm::parse_opt_snmp_interval_func(int &pos, int argc, char *argv[])
2000 Logger logger(LOG_CAT_L7VSADM_COMMON, 46, "l7vs::l7vsadm::parse_opt_snmp_interval_func", __FILE__, __LINE__);
2002 if (request.snmpinfo.option_set_flag & snmp_info::SNMP_INTERVAL_OPTION_FLAG) {
2003 std::stringstream buf;
2006 buf << " is conflict.";
2008 l7vsadm_err.setter(true, buf.str());
2009 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 142, buf.str(), __FILE__, __LINE__);
2015 tmp = boost::lexical_cast< int >(argv[pos]);
2016 } catch (const boost::bad_lexical_cast &) {
2017 std::string buf("Invalid option value for -i option.");
2018 l7vsadm_err.setter(true, buf);
2019 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 143, buf, __FILE__, __LINE__);
2024 request.snmpinfo.interval = tmp;
2025 request.snmpinfo.option_set_flag |= snmp_info::SNMP_INTERVAL_OPTION_FLAG;
2029 std::string buf("Invalid option value for -i option.");
2030 l7vsadm_err.setter(true, buf);
2031 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 144, buf, __FILE__, __LINE__);
2035 std::string buf("Need option value for -i option.");
2036 l7vsadm_err.setter(true, buf);
2037 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 145, buf, __FILE__, __LINE__);
2042 //! snmp logtrap set function
2043 //! @param[in] argument position
2044 //! @param[in] argument count
2045 //! @param[in] argument value
2046 bool l7vs::l7vsadm::parse_opt_snmp_log_trap_func(int &pos, int argc, char *argv[])
2049 Logger logger(LOG_CAT_L7VSADM_COMMON, 47, "l7vs::l7vsadm::parse_opt_snmp_log_trap_func", __FILE__, __LINE__);
2051 if (request.snmpinfo.option_set_flag & snmp_info::SNMP_LOGTRAP_OPTION_FLAG) {
2052 std::stringstream buf;
2055 buf << " is conflict.";
2057 l7vsadm_err.setter(true, buf.str());
2058 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 146, buf.str(), __FILE__, __LINE__);
2063 tmp = boost::lexical_cast< int >(argv[pos]);
2064 } catch (const boost::bad_lexical_cast &) {
2065 std::string buf("Invalid option value for -t option.");
2066 l7vsadm_err.setter(true, buf);
2067 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 147, buf, __FILE__, __LINE__);
2070 if (tmp == 0 || tmp == 1) {
2072 request.snmpinfo.logtrap_enabled = tmp;
2073 request.snmpinfo.option_set_flag |= snmp_info::SNMP_LOGTRAP_OPTION_FLAG;
2078 std::string buf("Invalid option value for -t option.");
2079 l7vsadm_err.setter(true, buf);
2080 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 148, buf, __FILE__, __LINE__);
2084 std::string buf("Need option value for -t option.");
2085 l7vsadm_err.setter(true, buf);
2086 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 149, buf, __FILE__, __LINE__);
2092 //! snmp logtrap_level set function
2093 //! @param[in] argument position
2094 //! @param[in] argument count
2095 //! @param[in] argument value
2096 bool l7vs::l7vsadm::parse_opt_snmp_log_trap_level_func(int &pos, int argc, char *argv[])
2098 Logger logger(LOG_CAT_L7VSADM_COMMON, 48, "l7vs::l7vsadm::parse_opt_snmp_log_trap_level_func", __FILE__, __LINE__);
2100 if (request.snmpinfo.option_set_flag & snmp_info::SNMP_LOGTRAP_LEVEL_OPTION_FLAG) {
2101 std::stringstream buf;
2104 buf << " is conflict.";
2106 l7vsadm_err.setter(true, buf.str());
2107 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 150, buf.str(), __FILE__, __LINE__);
2112 string_loglevel_map_type::iterator itr = string_loglevel_dic.find(argv[pos]);
2113 if (itr != string_loglevel_dic.end()) {
2114 request.snmpinfo.logtrap_level = itr->second;
2115 request.snmpinfo.option_set_flag |= snmp_info::SNMP_LOGTRAP_LEVEL_OPTION_FLAG;
2119 std::stringstream buf;
2120 buf << "No such Log-Level " << argv[pos] << ".";
2121 l7vsadm_err.setter(true, buf.str());
2122 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 151, buf.str(), __FILE__, __LINE__);
2126 std::string buf("Need option value for -l option.");
2127 l7vsadm_err.setter(true, buf);
2128 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 152, buf, __FILE__, __LINE__);
2135 //! parameter command parsing
2136 //! @param[in] request command
2137 //! @param[in] argument count
2138 //! @param[in] argument value
2139 bool l7vs::l7vsadm::parse_parameter_func(l7vs::l7vsadm_request::COMMAND_CODE_TAG cmd, int argc, char *argv[])
2141 Logger logger(LOG_CAT_L7VSADM_COMMON, 28, "l7vsadm::parse_parameter_func", __FILE__, __LINE__);
2145 std::stringstream buf;
2146 buf << "Argument argc is illegal for ";
2150 l7vsadm_err.setter(true, buf.str());
2151 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 126, buf.str(), __FILE__, __LINE__);
2155 request.command = cmd;
2157 for (int pos = 2; pos < argc; ++pos) {
2158 parse_opt_map_type::iterator itr = parameter_option_dic.find(argv[pos]);
2159 if (itr != parameter_option_dic.end()) { // option string function find.
2160 if (! itr->second(pos, argc, argv)) return false; // option string function error.
2161 } else { //option string function not found.
2162 // print option not found message.
2163 std::stringstream buf;
2164 buf << "parameter option not found(--parameter): " << argv[pos];
2165 l7vsadm_err.setter(true, buf.str());
2166 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 84, buf.str(), __FILE__, __LINE__);
2171 if (PARAM_COMP_NOCAT == request.reload_param) {
2172 // not specified reload_param
2173 std::string buf("reload component is not specified.(--reload)");
2174 l7vsadm_err.setter(true, buf);
2175 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 85, buf, __FILE__, __LINE__);
2182 // parameter command
2184 //! parameter reload component parsing
2185 //! @param[in] argument position
2186 //! @param[in] argument count
2187 //! @param[in] argument value
2188 bool l7vs::l7vsadm::parse_opt_parameter_reload_func(int &pos, int argc, char *argv[])
2190 Logger logger(LOG_CAT_L7VSADM_COMMON, 29, "l7vsadm::parse_opt_parameter_reload_func", __FILE__, __LINE__);
2192 if (++pos >= argc) {
2193 // reload component is not specified
2194 std::string buf("reload component is not specified.(--reload)");
2195 l7vsadm_err.setter(true, buf);
2196 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 86, buf, __FILE__, __LINE__);
2199 string_parameter_map_type::iterator itr = string_parameter_dic.find(argv[pos]);
2200 if (itr != string_parameter_dic.end()) {
2201 request.reload_param = itr->second;
2204 std::stringstream buf;
2205 buf << "reload component not found(--reload): " << argv[pos];
2206 l7vsadm_err.setter(true, buf.str());
2207 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 87, buf.str(), __FILE__, __LINE__);
2211 //! help command parsing
2212 //! @param[in] request command
2213 //! @param[in] argument count
2214 //! @param[in] argument value
2215 bool l7vs::l7vsadm::parse_help_func(l7vs::l7vsadm_request::COMMAND_CODE_TAG cmd, int argc, char *argv[])
2217 Logger logger(LOG_CAT_L7VSADM_COMMON, 30, "l7vsadm::parse_help_func", __FILE__, __LINE__);
2219 request.command = cmd;
2221 std::cout << usage();
2225 " --add-service -A add virtual service with options\n"
2226 " --edit-service -E edit virtual service with options\n"
2227 " --delete-service -D delete virtual service with options\n"
2228 " --flush -C flush virtual service\n"
2229 " --add-server -a add real server with options\n"
2230 " --edit-server -e edit real server with options\n"
2231 " --delete-server -d delete real server with options\n"
2232 " --replication -R control replication-function\n"
2233 " --log -L control logger-function\n"
2234 " --snmp -S control SNMP Agent-function\n"
2235 " --parameter -P control parameter-function\n"
2236 " --list -l list the table\n"
2237 " --verbose -V list the table in verbose format\n"
2238 " --key -K list the table in key setting format\n"
2239 " --help -h show usage\n"
2244 " --tcp-service -t service-address service-address is host:port\n"
2245 " --proto-module -m proto-module protocol module name and module argument\n"
2247 " --scheduler -s scheduler one of rr,lc,wrr\n"
2248 " --upper -u connection-count maximum number of connections\n"
2249 " --bypass -b sorry-server sorry server address is host:port\n"
2250 " --tproxy set sorry server connection to IP transparent mode.\n"
2251 " --masq set sorry server connection to IP masquerade mode.\n"
2253 " --flag -f sorry-flag sorry status set to virtual service\n"
2254 " --qos-up -Q QoSval-up QoS Threshold(bps) set to real server direction\n"
2255 " --qos-down -q QoSval-down QoS Threshold(bps) set to client direction\n"
2256 " --ssl -z ssl-config-file SSL configuration file(Use SSL)\n"
2257 " --sockopt -O socket-option deferaccept,nodelay,cork,quickackon or quickackoff set to socket option\n"
2258 " --access-log -L access-log-flag access log flag 0(none) or 1(output)\n"
2259 " --access-log-name -a access-log-file access log file\n"
2260 " [logrotate-args]\n"
2261 " --real-server -r server-address server-address is host:port\n"
2262 " --weight -w weight scheduling weight set to real server\n"
2263 " --tproxy set real server connection to IP transparent mode.\n"
2264 " --masq set real server connection to IP masquerade mode.\n"
2265 " --switch -s replication-switch start or stop replication\n"
2266 " --force -f force replication start\n"
2267 " --dump -d dump replication memory\n"
2268 " --category -c log-category set log category for l7vsd or SNMP Agent\n"
2269 " --level -l log-level set log level for l7vsd or SNMP Agent\n"
2270 " --reload -r reload-parameter reload specified config parameter\n"
2271 " --numeric -n list the table in numeric\n"
2272 " --flag -f snmp-flag start or stop snmp function 0(off) 1(on)\n"
2273 " --interval -i update-interval set collect snmp cache collect interval(s)\n"
2274 " --logtrap -t log-trap-flag start or stop log trap function 0(off) 1(on)\n"
2275 " --logtraplevel -l log-trap-level set log trap level for snmp\n"
2276 " --refresh -r clear statistic info for snmp\n"
2283 std::string l7vs::l7vsadm::usage()
2285 Logger logger(LOG_CAT_L7VSADM_COMMON, 31, "l7vsadm::usage", __FILE__, __LINE__);
2287 std::stringstream stream;
2290 " l7vsadm -A -t service-address -m proto-module [module-args]\n"
2291 " [-s scheduler] [-u connection-count] [-b sorry-server] [--masq|tproxy]\n"
2292 " [-f sorry-flag] [-Q QoSval-up] [-q QoSval-down] [-z ssl-config-file]\n"
2293 " [-O socket-option] [-L access-log-flag] [-a access-log-file [logrotate-args]]\n"
2294 " l7vsadm -E -t service-address -m proto-module [module-args]\n"
2295 " [-s scheduler] [-u connection-count] [-b sorry-server] [--masq|tproxy]\n"
2296 " [-f sorry-flag] [-Q QoSval-up] [-q QoSval-down] [-L access-log-flag]\n"
2297 " l7vsadm -D -t service-address -m proto-module [module-args]\n"
2299 " l7vsadm -a|e -t service-address -m proto-module [module-args]\n"
2300 " -r server-address [-w weight] [--masq|tproxy]\n"
2301 " l7vsadm -d -t service-address -m proto-module [module-args]\n"
2302 " -r server-address\n"
2303 " l7vsadm -R -s replication-switch\n"
2306 " l7vsadm -L -c log-category -l log-level\n"
2307 " l7vsadm -S [-f snmp-flag] [-i update-interval] [-t log-trap-flag] [-l log-trap-level]\n"
2308 " l7vsadm -S -r [-t service-address -m proto-module]\n"
2309 " l7vsadm -P -r reload-parameter\n"
2310 " l7vsadm -l [-n]\n"
2311 " l7vsadm -V [-n]\n"
2312 " l7vsadm -K [-n]\n"
2315 return stream.str();
2318 //! disp_list function
2319 void l7vs::l7vsadm::disp_list()
2321 Logger logger(LOG_CAT_L7VSADM_COMMON, 32, "l7vsadm::disp_list", __FILE__, __LINE__);
2323 std::stringstream buf;
2324 buf << boost::format("Layer-7 Virtual Server version %s\n") % VERSION;
2325 buf << "Prot LocalAddress:Port ProtoMod Scheduler\n";
2326 buf << " -> RemoteAddress:Port Forward Weight ActiveConn InactConn\n";
2327 BOOST_FOREACH(virtualservice_element vse, response.virtualservice_status_list) {
2328 std::string vsepstr;
2330 vsepstr = endpoint_to_string<boost::asio::ip::udp>(vse.udp_recv_endpoint, numeric_flag);
2332 vsepstr = endpoint_to_string<boost::asio::ip::tcp>(vse.tcp_accept_endpoint, numeric_flag);
2334 buf << boost::format("%s %s %s %s\n")
2335 % (vse.udpmode ? "UDP" : "TCP")
2337 % vse.protocol_module_name
2338 % vse.schedule_module_name;
2339 BOOST_FOREACH(realserver_element rse, vse.realserver_vector) {
2340 std::string rsepstr;
2342 rsepstr = endpoint_to_string<boost::asio::ip::udp>(rse.udp_endpoint, numeric_flag);
2344 rsepstr = endpoint_to_string<boost::asio::ip::tcp>(rse.tcp_endpoint, numeric_flag);
2346 buf << boost::format(" -> %-28s %-7s %-6d %-10d %-10d\n")
2348 % rse.get_fwdmode_str()
2354 std::cout << buf.str();
2357 //! disp_list_key function
2358 void l7vs::l7vsadm::disp_list_key()
2360 Logger logger(LOG_CAT_L7VSADM_COMMON, 33, "l7vsadm::disp_list_key", __FILE__, __LINE__);
2362 std::stringstream buf;
2363 buf << boost::format("Layer-7 Virtual Server version %s\n") % VERSION;
2364 buf << "Prot LocalAddress:Port ProtoMod Scheduler\n";
2365 buf << " SSL_config_file\n";
2366 buf << " Socket option\n";
2367 buf << " Access_log_flag\n";
2368 buf << " Access_log_file\n";
2369 buf << " Access_log_rotate option\n";
2370 buf << " -> RemoteAddress:Port Forward Weight ActiveConn InactConn\n";
2371 BOOST_FOREACH(virtualservice_element vse, response.virtualservice_status_list) {
2372 std::string vsepstr;
2374 vsepstr = endpoint_to_string<boost::asio::ip::udp>(vse.udp_recv_endpoint, numeric_flag);
2376 vsepstr = endpoint_to_string<boost::asio::ip::tcp>(vse.tcp_accept_endpoint, numeric_flag);
2378 buf << boost::format("%s %s %s %s\n")
2379 % (vse.udpmode ? "UDP" : "TCP")
2381 % vse.protocol_module_name
2382 % vse.schedule_module_name;
2383 buf << boost::format(" %s\n")
2384 % ((0 == vse.ssl_file_name.length()) ? "none" : vse.ssl_file_name);
2385 buf << boost::format(" %s\n")
2386 % ((0 == vse.socket_option_string.length()) ? "none" : vse.socket_option_string);
2387 buf << boost::format(" %d\n") % vse.access_log_flag;
2388 buf << boost::format(" %s\n")
2389 % ((0 == vse.access_log_file_name.length()) ? "none" : vse.access_log_file_name);
2390 buf << boost::format(" %s\n")
2391 % ((0 == vse.access_log_rotate_key_info.length()) ? "none" : vse.access_log_rotate_key_info);
2393 BOOST_FOREACH(realserver_element rse, vse.realserver_vector) {
2394 std::string rsepstr;
2396 rsepstr = endpoint_to_string<boost::asio::ip::udp>(rse.udp_endpoint, numeric_flag);
2398 rsepstr = endpoint_to_string<boost::asio::ip::tcp>(rse.tcp_endpoint, numeric_flag);
2399 buf << boost::format(" -> %-28s %-7s %-6d %-10d %-10d\n")
2401 % rse.get_fwdmode_str()
2407 std::cout << buf.str();
2410 //! disp_list_verbose function
2411 void l7vs::l7vsadm::disp_list_verbose()
2413 Logger logger(LOG_CAT_L7VSADM_COMMON, 34, "l7vsadm::disp_list_verbose", __FILE__, __LINE__);
2415 unsigned long long output_qos_upstream_value;
2416 unsigned long long output_qos_downstream_value;
2417 const int MAX_TIME_FORMAT_LEN = 20;
2418 char snmp_start_date[MAX_TIME_FORMAT_LEN] = {0};
2419 char snmp_last_request_date[MAX_TIME_FORMAT_LEN] = {0};
2420 char snmp_last_trap_date[MAX_TIME_FORMAT_LEN] = {0};
2422 std::stringstream buf;
2423 buf << boost::format("Layer-7 Virtual Server version %s\n") % VERSION;
2426 buf << "L7vsd Log Level:\n";
2427 buf << "Category Level\n";
2428 typedef std::pair<LOG_CATEGORY_TAG, LOG_LEVEL_TAG> logstatus_type;
2429 BOOST_FOREACH(logstatus_type logstatus, response.log_status_list) {
2430 buf << boost::format("%-30s %s\n")
2431 % logcategory_string_dic[logstatus.first]
2432 % loglevel_string_dic[logstatus.second];
2437 buf << "Replication Mode:\n";
2438 buf << boost::format("%s\n") % replication_mode_string_dic[response.replication_mode_status];
2441 //disp snmp agent status
2442 buf << "SNMPAgent:\n";
2443 if (!response.snmpinfo.enabled) {
2444 boost::format fmtter("%-30s inactive\n"
2455 fmtter % "Agent Status";
2456 fmtter % "log trap status";
2457 fmtter % "log trap level";
2458 fmtter % "cache update interval";
2459 fmtter % "start date";
2460 fmtter % "last request date";
2461 fmtter % "last trap date";
2462 fmtter % "total GET requests";
2463 fmtter % "total SET requests";
2464 fmtter % "total trap counts";
2466 buf << fmtter.str();
2468 strftime(snmp_start_date, sizeof(snmp_start_date), "%Y-%m-%d %H:%M:%S", localtime(&response.snmpinfo.start_date));
2469 strftime(snmp_last_request_date, sizeof(snmp_start_date), "%Y-%m-%d %H:%M:%S", localtime(&response.snmpinfo.request_last_date));
2470 strftime(snmp_last_trap_date, sizeof(snmp_start_date), "%Y-%m-%d %H:%M:%S", localtime(&response.snmpinfo.trap_last_date));
2472 boost::format fmtter("%-30s active\n"
2483 fmtter % "Agent Status";
2484 fmtter % "log trap status";
2485 fmtter % (response.snmpinfo.logtrap_enabled ? "on" : "off");
2486 fmtter % "log trap level";
2487 fmtter % (response.snmpinfo.logtrap_enabled ? loglevel_string_dic[response.snmpinfo.logtrap_level] : "none");
2488 fmtter % "cache update interval" % response.snmpinfo.interval;
2489 fmtter % "start date" % (response.snmpinfo.start_date == 0 ? "none" : snmp_start_date);
2490 fmtter % "last request date" % (response.snmpinfo.request_last_date == 0 ? "none" : snmp_last_request_date);
2491 fmtter % "last trap date" % (response.snmpinfo.trap_last_date == 0 ? "none" : snmp_last_trap_date);
2492 fmtter % "total GET requests" % response.snmpinfo.snmp_get_requests;
2493 fmtter % "total SET requests" % response.snmpinfo.snmp_set_requests;
2494 fmtter % "total trap counts" % response.snmpinfo.snmp_trap_count;
2495 buf << fmtter.str();
2502 buf << "Prot LocalAddress:Port ProtoMod Scheduler Protomod_opt_string\n";
2503 buf << " -> RemoteAddress:Port Forward Weight ActiveConn InactConn\n";
2504 BOOST_FOREACH(virtualservice_element vse, response.virtualservice_status_list) {
2505 std::string vsepstr;
2507 vsepstr = endpoint_to_string<boost::asio::ip::udp>(vse.udp_recv_endpoint, numeric_flag);
2509 vsepstr = endpoint_to_string<boost::asio::ip::tcp>(vse.tcp_accept_endpoint, numeric_flag);
2512 if (vse.qos_upstream == ULLONG_MAX) {
2513 output_qos_upstream_value = 0;
2515 output_qos_upstream_value = vse.qos_upstream * 8;
2518 if (vse.qos_downstream == ULLONG_MAX) {
2519 output_qos_downstream_value = 0;
2521 output_qos_downstream_value = vse.qos_downstream * 8;
2524 buf << boost::format("%s %s %s %s %s\n")
2525 % (vse.udpmode ? "UDP" : "TCP")
2527 % vse.protocol_module_name
2528 % vse.schedule_module_name
2529 % vse.protocol_module_for_indication_options;
2531 BOOST_FOREACH(realserver_element rse, vse.realserver_vector) {
2532 std::string rsepstr;
2534 rsepstr = endpoint_to_string<boost::asio::ip::udp>(rse.udp_endpoint, numeric_flag);
2536 rsepstr = endpoint_to_string<boost::asio::ip::tcp>(rse.tcp_endpoint, numeric_flag);
2538 buf << boost::format(" -> %-28s %-7s %-6d %-10d %-10d\n")
2540 % rse.get_fwdmode_str()
2547 std::string sorryepstr;
2548 std::string sorry_flag_str;
2549 boost::asio::ip::tcp::endpoint zeropoint;
2550 if (zeropoint == vse.sorry_endpoint) {
2551 sorryepstr = "none";
2553 sorryepstr = endpoint_to_string<boost::asio::ip::tcp>(vse.sorry_endpoint,
2554 numeric_flag) + " " + vse.get_fwdmode_str();
2557 if (vse.sorry_flag) {
2558 sorry_flag_str = "on";
2560 sorry_flag_str = "off";
2563 buf << boost::format(" Bypass Settings:\n"
2564 " Sorry Server %s\n"
2565 " Max Connection %lld\n"
2568 % vse.sorry_maxconnection
2572 buf << boost::format(" SSL Settings:\n"
2573 " SSL Config File %s\n")
2574 % ((0 == vse.ssl_file_name.length()) ? "none" : vse.ssl_file_name);
2576 buf << boost::format(" Logging Settings:\n"
2578 " Access Log File %s\n"
2579 " Access Log Rotate %s\n")
2580 % ((0 == vse.access_log_flag) ? "off" : "on")
2581 % ((0 == vse.access_log_file_name.length()) ? "none" : vse.access_log_file_name)
2582 % ((0 == vse.access_log_rotate_verbose_info.length()) ? "none" : vse.access_log_rotate_verbose_info);
2584 buf << boost::format(" Socket Settings:\n"
2585 " TCP_DEFER_ACCEPT %s\n"
2588 " TCP_QUICKACK %s\n")
2589 % ((0 == vse.socket_option_tcp_defer_accept) ? "disable" : "enable")
2590 % ((0 == vse.socket_option_tcp_nodelay) ? "disable" : "enable")
2591 % ((0 == vse.socket_option_tcp_cork) ? "disable" : "enable")
2592 % ((0 == vse.socket_option_tcp_quickack) ? "auto" : ((1 == vse.socket_option_tcp_quickack) ? "enable" : "disable"));
2595 buf << boost::format(" Throughput:\n"
2596 " Current Upload / Limit %f Mbps / %f Mbps\n"
2597 " Current Download / Limit %f Mbps / %f Mbps\n")
2598 % ((double)vse.throughput_upstream * 8 / (1000 * 1000)) % ((double)output_qos_upstream_value / (1000 * 1000))
2599 % ((double)vse.throughput_downstream * 8 / (1000 * 1000)) % ((double)output_qos_downstream_value / (1000 * 1000));
2601 buf << boost::format(" Statistics:\n"
2602 " HTTP Total Requests %lld\n"
2603 " HTTP GET Requests %lld\n"
2604 " HTTP POST Requests %lld\n")
2605 % vse.http_total_count % vse.http_get_count % vse.http_post_count;
2609 std::cout << buf.str();
2611 //! l7vsadm constructor.
2612 //! create including all dictionary.
2613 l7vs::l7vsadm::l7vsadm()
2614 : numeric_flag(false),
2615 command_wait_interval(L7VSADM_DEFAULT_WAIT_INTERVAL),
2616 command_wait_count(L7VSADM_DEFAULT_WAIT_COUNT)
2618 Logger logger(LOG_CAT_L7VSADM_COMMON, 35, "l7vsadm::l7vsadm(constructor)", __FILE__, __LINE__);
2620 // create command dictionary.
2621 command_dic["-l"] = boost::bind(&l7vsadm::parse_list_func, this, l7vsadm_request::CMD_LIST, _1, _2);
2622 command_dic["--list"] = boost::bind(&l7vsadm::parse_list_func, this, l7vsadm_request::CMD_LIST, _1, _2);
2623 command_dic["-V"] = boost::bind(&l7vsadm::parse_list_func, this, l7vsadm_request::CMD_LIST_VERBOSE, _1, _2);
2624 command_dic["--verbose"] = boost::bind(&l7vsadm::parse_list_func, this, l7vsadm_request::CMD_LIST_VERBOSE, _1, _2);
2625 command_dic["-K"] = boost::bind(&l7vsadm::parse_list_func, this, l7vsadm_request::CMD_LIST_KEY, _1, _2);
2626 command_dic["--key"] = boost::bind(&l7vsadm::parse_list_func, this, l7vsadm_request::CMD_LIST_KEY, _1, _2);
2627 command_dic["-A"] = boost::bind(&l7vsadm::parse_vs_func, this, l7vsadm_request::CMD_ADD_VS, _1, _2);
2628 command_dic["--add-service"] = boost::bind(&l7vsadm::parse_vs_func, this, l7vsadm_request::CMD_ADD_VS, _1, _2);
2629 command_dic["-D"] = boost::bind(&l7vsadm::parse_vs_func, this, l7vsadm_request::CMD_DEL_VS, _1, _2);
2630 command_dic["--delete-service"] = boost::bind(&l7vsadm::parse_vs_func, this, l7vsadm_request::CMD_DEL_VS, _1, _2);
2631 command_dic["-E"] = boost::bind(&l7vsadm::parse_vs_func, this, l7vsadm_request::CMD_EDIT_VS, _1, _2);
2632 command_dic["--edit-service"] = boost::bind(&l7vsadm::parse_vs_func, this, l7vsadm_request::CMD_EDIT_VS, _1, _2);
2633 command_dic["-C"] = boost::bind(&l7vsadm::parse_vs_func, this, l7vsadm_request::CMD_FLUSH_VS, _1, _2);
2634 command_dic["--flush"] = boost::bind(&l7vsadm::parse_vs_func, this, l7vsadm_request::CMD_FLUSH_VS, _1, _2);
2635 command_dic["-a"] = boost::bind(&l7vsadm::parse_rs_func, this, l7vsadm_request::CMD_ADD_RS, _1, _2);
2636 command_dic["--add-server"] = boost::bind(&l7vsadm::parse_rs_func, this, l7vsadm_request::CMD_ADD_RS, _1, _2);
2637 command_dic["-d"] = boost::bind(&l7vsadm::parse_rs_func, this, l7vsadm_request::CMD_DEL_RS, _1, _2);
2638 command_dic["--delete-server"] = boost::bind(&l7vsadm::parse_rs_func, this, l7vsadm_request::CMD_DEL_RS, _1, _2);
2639 command_dic["-e"] = boost::bind(&l7vsadm::parse_rs_func, this, l7vsadm_request::CMD_EDIT_RS, _1, _2);
2640 command_dic["--edit-server"] = boost::bind(&l7vsadm::parse_rs_func, this, l7vsadm_request::CMD_EDIT_RS, _1, _2);
2641 command_dic["-R"] = boost::bind(&l7vsadm::parse_replication_func, this, l7vsadm_request::CMD_REPLICATION, _1, _2);
2642 command_dic["--replication"] = boost::bind(&l7vsadm::parse_replication_func, this, l7vsadm_request::CMD_REPLICATION, _1, _2);
2643 command_dic["-L"] = boost::bind(&l7vsadm::parse_log_func, this, l7vsadm_request::CMD_LOG, _1, _2);
2644 command_dic["--log"] = boost::bind(&l7vsadm::parse_log_func, this, l7vsadm_request::CMD_LOG, _1, _2);
2645 command_dic["-S"] = boost::bind(&l7vsadm::parse_snmp_func, this, l7vsadm_request::CMD_SNMP, _1, _2);
2646 command_dic["--snmp"] = boost::bind(&l7vsadm::parse_snmp_func, this, l7vsadm_request::CMD_SNMP, _1, _2);
2647 command_dic["-P"] = boost::bind(&l7vsadm::parse_parameter_func, this, l7vsadm_request::CMD_PARAMETER, _1, _2);
2648 command_dic["--parameter"] = boost::bind(&l7vsadm::parse_parameter_func, this, l7vsadm_request::CMD_PARAMETER, _1, _2);
2649 command_dic["-h"] = boost::bind(&l7vsadm::parse_help_func, this, l7vsadm_request::CMD_HELP, _1, _2);
2650 command_dic["--help"] = boost::bind(&l7vsadm::parse_help_func, this, l7vsadm_request::CMD_HELP, _1, _2);
2652 // create list option dictionary.
2653 list_option_dic["-n"] = boost::bind(&l7vsadm::parse_opt_list_numeric_func, this, _1, _2, _3);
2654 list_option_dic["--numeric"] = boost::bind(&l7vsadm::parse_opt_list_numeric_func, this, _1, _2, _3);
2656 // create virtualservice option dictionary
2657 vs_option_dic["-t"] = boost::bind(&l7vsadm::parse_opt_vs_target_func, this, _1, _2, _3);
2658 vs_option_dic["--tcp-service"] = boost::bind(&l7vsadm::parse_opt_vs_target_func, this, _1, _2, _3);
2659 vs_option_dic["-m"] = boost::bind(&l7vsadm::parse_opt_vs_module_func, this, _1, _2, _3);
2660 vs_option_dic["--proto-module"] = boost::bind(&l7vsadm::parse_opt_vs_module_func, this, _1, _2, _3);
2661 vs_option_dic["-s"] = boost::bind(&l7vsadm::parse_opt_vs_scheduler_func, this, _1, _2, _3);
2662 vs_option_dic["--scheduler"] = boost::bind(&l7vsadm::parse_opt_vs_scheduler_func, this, _1, _2, _3);
2663 vs_option_dic["-u"] = boost::bind(&l7vsadm::parse_opt_vs_upper_func, this, _1, _2, _3);
2664 vs_option_dic["--upper"] = boost::bind(&l7vsadm::parse_opt_vs_upper_func, this, _1, _2, _3);
2665 vs_option_dic["-b"] = boost::bind(&l7vsadm::parse_opt_vs_bypass_func, this, _1, _2, _3);
2666 vs_option_dic["--bypass"] = boost::bind(&l7vsadm::parse_opt_vs_bypass_func, this, _1, _2, _3);
2667 vs_option_dic["--tproxy"] = boost::bind(&l7vsadm::parse_opt_vs_fwdmode_func, this, _1, _2, _3);
2668 vs_option_dic["--masq"] = boost::bind(&l7vsadm::parse_opt_vs_fwdmode_func, this, _1, _2, _3);
2669 vs_option_dic["-f"] = boost::bind(&l7vsadm::parse_opt_vs_flag_func, this, _1, _2, _3);
2670 vs_option_dic["--flag"] = boost::bind(&l7vsadm::parse_opt_vs_flag_func, this, _1, _2, _3);
2671 vs_option_dic["-Q"] = boost::bind(&l7vsadm::parse_opt_vs_qosup_func, this, _1, _2, _3);
2672 vs_option_dic["--qos-up"] = boost::bind(&l7vsadm::parse_opt_vs_qosup_func, this, _1, _2, _3);
2673 vs_option_dic["-q"] = boost::bind(&l7vsadm::parse_opt_vs_qosdown_func, this, _1, _2, _3);
2674 vs_option_dic["--qos-down"] = boost::bind(&l7vsadm::parse_opt_vs_qosdown_func, this, _1, _2, _3);
2675 vs_option_dic["-p"] = boost::bind(&l7vsadm::parse_opt_vs_udp_func, this, _1, _2, _3);
2676 vs_option_dic["--udp"] = boost::bind(&l7vsadm::parse_opt_vs_udp_func, this, _1, _2, _3);
2677 vs_option_dic["-z"] = boost::bind(&l7vsadm::parse_opt_vs_ssl_file_func, this, _1, _2, _3);
2678 vs_option_dic["--ssl"] = boost::bind(&l7vsadm::parse_opt_vs_ssl_file_func, this, _1, _2, _3);
2679 vs_option_dic["-O"] = boost::bind(&l7vsadm::parse_opt_vs_socket_func, this, _1, _2, _3);
2680 vs_option_dic["--sockopt"] = boost::bind(&l7vsadm::parse_opt_vs_socket_func, this, _1, _2, _3);
2681 vs_option_dic["-L"] = boost::bind(&l7vsadm::parse_opt_vs_access_log_func, this, _1, _2, _3);
2682 vs_option_dic["--access-log"] = boost::bind(&l7vsadm::parse_opt_vs_access_log_func, this, _1, _2, _3);
2683 vs_option_dic["-a"] = boost::bind(&l7vsadm::parse_opt_vs_access_log_logrotate_func, this, _1, _2, _3);
2684 vs_option_dic["--access-log-name"] = boost::bind(&l7vsadm::parse_opt_vs_access_log_logrotate_func, this, _1, _2, _3);
2686 // create realserver option dictionary
2687 rs_option_dic["-t"] = boost::bind(&l7vsadm::parse_opt_vs_target_func, this, _1, _2, _3);
2688 rs_option_dic["--tcp-service"] = boost::bind(&l7vsadm::parse_opt_vs_target_func, this, _1, _2, _3);
2689 rs_option_dic["-w"] = boost::bind(&l7vsadm::parse_opt_rs_weight_func, this, _1, _2, _3);
2690 rs_option_dic["--weight"] = boost::bind(&l7vsadm::parse_opt_rs_weight_func, this, _1, _2, _3);
2691 rs_option_dic["--tproxy"] = boost::bind(&l7vsadm::parse_opt_rs_fwdmode_func, this, _1, _2, _3);
2692 rs_option_dic["--masq"] = boost::bind(&l7vsadm::parse_opt_rs_fwdmode_func, this, _1, _2, _3);
2693 rs_option_dic["-m"] = boost::bind(&l7vsadm::parse_opt_vs_module_func, this, _1, _2, _3);
2694 rs_option_dic["--proto-module"] = boost::bind(&l7vsadm::parse_opt_vs_module_func, this, _1, _2, _3);
2695 rs_option_dic["-p"] = boost::bind(&l7vsadm::parse_opt_vs_udp_func, this, _1, _2, _3);
2696 rs_option_dic["--udp"] = boost::bind(&l7vsadm::parse_opt_vs_udp_func, this, _1, _2, _3);
2697 rs_option_dic["-r"] = boost::bind(&l7vsadm::parse_opt_rs_realserver_func, this, _1, _2, _3);
2698 rs_option_dic["--real-server"] = boost::bind(&l7vsadm::parse_opt_rs_realserver_func, this, _1, _2, _3);
2700 // create replication option dictionary
2701 replication_option_dic["-s"] = boost::bind(&l7vsadm::parse_opt_replication_switch_func, this, _1, _2, _3);
2702 replication_option_dic["--switch"] = boost::bind(&l7vsadm::parse_opt_replication_switch_func, this, _1, _2, _3);
2703 replication_switch_option_dic["start"] = boost::bind(&l7vsadm::parse_opt_replication_start_func, this, _1, _2, _3);
2704 replication_switch_option_dic["stop"] = boost::bind(&l7vsadm::parse_opt_replication_stop_func, this, _1, _2, _3);
2705 replication_option_dic["-f"] = boost::bind(&l7vsadm::parse_opt_replication_force_func, this, _1, _2, _3);
2706 replication_option_dic["--force"] = boost::bind(&l7vsadm::parse_opt_replication_force_func, this, _1, _2, _3);
2707 replication_option_dic["-d"] = boost::bind(&l7vsadm::parse_opt_replication_dump_func, this, _1, _2, _3);
2708 replication_option_dic["--dump"] = boost::bind(&l7vsadm::parse_opt_replication_dump_func, this, _1, _2, _3);
2710 // create log option function dictionary create
2711 log_option_dic["-c"] = boost::bind(&l7vsadm::parse_opt_log_category_func, this, _1, _2, _3);
2712 log_option_dic["--category"] = boost::bind(&l7vsadm::parse_opt_log_category_func, this, _1, _2, _3);
2713 log_option_dic["-l"] = boost::bind(&l7vsadm::parse_opt_log_level_func, this, _1, _2, _3);
2714 log_option_dic["--level"] = boost::bind(&l7vsadm::parse_opt_log_level_func, this, _1, _2, _3);
2716 // snmp agent option function dictionary create
2717 snmp_option_dic["-r"] = boost::bind(&l7vsadm::parse_opt_snmp_refresh_func, this, _1, _2, _3);
2718 snmp_option_dic["--refresh"] = boost::bind(&l7vsadm::parse_opt_snmp_refresh_func, this, _1, _2, _3);
2719 snmp_option_dic["-f"] = boost::bind(&l7vsadm::parse_opt_snmp_flag_func, this, _1, _2, _3);
2720 snmp_option_dic["--flag"] = boost::bind(&l7vsadm::parse_opt_snmp_flag_func, this, _1, _2, _3);
2721 snmp_option_dic["-i"] = boost::bind(&l7vsadm::parse_opt_snmp_interval_func, this, _1, _2, _3);
2722 snmp_option_dic["--interval"] = boost::bind(&l7vsadm::parse_opt_snmp_interval_func, this, _1, _2, _3);
2723 snmp_option_dic["-t"] = boost::bind(&l7vsadm::parse_opt_snmp_log_trap_func, this, _1, _2, _3);
2724 snmp_option_dic["--logtrap"] = boost::bind(&l7vsadm::parse_opt_snmp_log_trap_func, this, _1, _2, _3);
2725 snmp_option_dic["-l"] = boost::bind(&l7vsadm::parse_opt_snmp_log_trap_level_func, this, _1, _2, _3);
2726 snmp_option_dic["--logtraplevel"] = boost::bind(&l7vsadm::parse_opt_snmp_log_trap_level_func, this, _1, _2, _3);
2727 snmp_vs_option_dic["-t"] = boost::bind(&l7vsadm::parse_opt_snmp_vs_target_func, this, _1, _2, _3);
2728 snmp_vs_option_dic["--tcp-service"] = boost::bind(&l7vsadm::parse_opt_snmp_vs_target_func, this, _1, _2, _3);
2729 snmp_vs_option_dic["-m"] = boost::bind(&l7vsadm::parse_opt_snmp_vs_module_func, this, _1, _2, _3);
2730 snmp_vs_option_dic["--proto-module"] = boost::bind(&l7vsadm::parse_opt_snmp_vs_module_func, this, _1, _2, _3);
2731 // parameter option function dictionary create
2732 parameter_option_dic["-r"] = boost::bind(&l7vsadm::parse_opt_parameter_reload_func, this, _1, _2, _3);
2733 parameter_option_dic["--reload"] = boost::bind(&l7vsadm::parse_opt_parameter_reload_func, this, _1, _2, _3);
2735 // string logcategory dictionary create
2736 string_logcategory_dic["l7vsd_network"] = LOG_CAT_L7VSD_NETWORK;
2737 string_logcategory_dic["nw"] = LOG_CAT_L7VSD_NETWORK;
2738 logcategory_string_dic[LOG_CAT_L7VSD_NETWORK] = "l7vsd_network";
2739 string_logcategory_dic["l7vsd_network_qos"] = LOG_CAT_L7VSD_NETWORK_QOS;
2740 string_logcategory_dic["nw_qos"] = LOG_CAT_L7VSD_NETWORK_QOS;
2741 logcategory_string_dic[LOG_CAT_L7VSD_NETWORK_QOS] = "l7vsd_network_qos";
2742 string_logcategory_dic["l7vsd_network_bandwidth"] = LOG_CAT_L7VSD_NETWORK_BANDWIDTH;
2743 string_logcategory_dic["nw_bw"] = LOG_CAT_L7VSD_NETWORK_BANDWIDTH;
2744 logcategory_string_dic[LOG_CAT_L7VSD_NETWORK_BANDWIDTH] = "l7vsd_network_bandwidth";
2745 string_logcategory_dic["l7vsd_network_num_connection"] = LOG_CAT_L7VSD_NETWORK_NUM_CONNECTION;
2746 string_logcategory_dic["nw_conn"] = LOG_CAT_L7VSD_NETWORK_NUM_CONNECTION;
2747 logcategory_string_dic[LOG_CAT_L7VSD_NETWORK_NUM_CONNECTION] = "l7vsd_network_num_connection";
2748 string_logcategory_dic["l7vsd_network_access"] = LOG_CAT_L7VSD_NETWORK_ACCESS;
2749 string_logcategory_dic["nw_acc"] = LOG_CAT_L7VSD_NETWORK_ACCESS;
2750 logcategory_string_dic[LOG_CAT_L7VSD_NETWORK_ACCESS] = "l7vsd_network_access";
2751 string_logcategory_dic["l7vsd_mainthread"] = LOG_CAT_L7VSD_MAINTHREAD;
2752 string_logcategory_dic["mth"] = LOG_CAT_L7VSD_MAINTHREAD;
2753 logcategory_string_dic[LOG_CAT_L7VSD_MAINTHREAD] = "l7vsd_mainthread";
2754 string_logcategory_dic["l7vsd_virtualservice"] = LOG_CAT_L7VSD_VIRTUALSERVICE;
2755 string_logcategory_dic["vs"] = LOG_CAT_L7VSD_VIRTUALSERVICE;
2756 logcategory_string_dic[LOG_CAT_L7VSD_VIRTUALSERVICE] = "l7vsd_virtualservice";
2757 string_logcategory_dic["l7vsd_virtualservice_thread"] = LOG_CAT_L7VSD_VIRTUALSERVICE_THREAD;
2758 string_logcategory_dic["vs_th"] = LOG_CAT_L7VSD_VIRTUALSERVICE_THREAD;
2759 logcategory_string_dic[LOG_CAT_L7VSD_VIRTUALSERVICE_THREAD] = "l7vsd_virtualservice_thread";
2760 string_logcategory_dic["l7vsd_session"] = LOG_CAT_L7VSD_SESSION;
2761 string_logcategory_dic["ss"] = LOG_CAT_L7VSD_SESSION;
2762 logcategory_string_dic[LOG_CAT_L7VSD_SESSION] = "l7vsd_session";
2763 string_logcategory_dic["l7vsd_session_thread"] = LOG_CAT_L7VSD_SESSION_THREAD;
2764 string_logcategory_dic["ss_th"] = LOG_CAT_L7VSD_SESSION_THREAD;
2765 logcategory_string_dic[LOG_CAT_L7VSD_SESSION_THREAD] = "l7vsd_session_thread";
2766 string_logcategory_dic["l7vsd_realserver"] = LOG_CAT_L7VSD_REALSERVER;
2767 string_logcategory_dic["rs"] = LOG_CAT_L7VSD_REALSERVER;
2768 logcategory_string_dic[LOG_CAT_L7VSD_REALSERVER] = "l7vsd_realserver";
2769 string_logcategory_dic["l7vsd_sorryserver"] = LOG_CAT_L7VSD_SORRYSERVER;
2770 string_logcategory_dic["sorry"] = LOG_CAT_L7VSD_SORRYSERVER;
2771 logcategory_string_dic[LOG_CAT_L7VSD_SORRYSERVER] = "l7vsd_sorryserver";
2772 string_logcategory_dic["l7vsd_module"] = LOG_CAT_L7VSD_MODULE;
2773 string_logcategory_dic["mod"] = LOG_CAT_L7VSD_MODULE;
2774 logcategory_string_dic[LOG_CAT_L7VSD_MODULE] = "l7vsd_module";
2775 string_logcategory_dic["l7vsd_replication"] = LOG_CAT_L7VSD_REPLICATION;
2776 string_logcategory_dic["rep"] = LOG_CAT_L7VSD_REPLICATION;
2777 logcategory_string_dic[LOG_CAT_L7VSD_REPLICATION] = "l7vsd_replication";
2778 string_logcategory_dic["l7vsd_replication_sendthread"] = LOG_CAT_L7VSD_REPLICATION_SENDTHREAD;
2779 string_logcategory_dic["rep_sth"] = LOG_CAT_L7VSD_REPLICATION_SENDTHREAD;
2780 logcategory_string_dic[LOG_CAT_L7VSD_REPLICATION_SENDTHREAD] = "l7vsd_replication_sendthread";
2781 string_logcategory_dic["l7vsd_parameter"] = LOG_CAT_L7VSD_PARAMETER;
2782 string_logcategory_dic["para"] = LOG_CAT_L7VSD_PARAMETER;
2783 logcategory_string_dic[LOG_CAT_L7VSD_PARAMETER] = "l7vsd_parameter";
2784 string_logcategory_dic["l7vsd_logger"] = LOG_CAT_L7VSD_LOGGER;
2785 string_logcategory_dic["logger"] = LOG_CAT_L7VSD_LOGGER;
2786 logcategory_string_dic[LOG_CAT_L7VSD_LOGGER] = "l7vsd_logger";
2787 string_logcategory_dic["l7vsd_command"] = LOG_CAT_L7VSD_COMMAND;
2788 string_logcategory_dic["cmd"] = LOG_CAT_L7VSD_COMMAND;
2789 logcategory_string_dic[LOG_CAT_L7VSD_COMMAND] = "l7vsd_command";
2790 string_logcategory_dic["l7vsd_start_stop"] = LOG_CAT_L7VSD_START_STOP;
2791 string_logcategory_dic["stastp"] = LOG_CAT_L7VSD_START_STOP;
2792 logcategory_string_dic[LOG_CAT_L7VSD_START_STOP] = "l7vsd_start_stop";
2793 string_logcategory_dic["l7vsd_system"] = LOG_CAT_L7VSD_SYSTEM;
2794 string_logcategory_dic["sys"] = LOG_CAT_L7VSD_SYSTEM;
2795 logcategory_string_dic[LOG_CAT_L7VSD_SYSTEM] = "l7vsd_system";
2796 string_logcategory_dic["l7vsd_system_memory"] = LOG_CAT_L7VSD_SYSTEM_MEMORY;
2797 string_logcategory_dic["sys_mem"] = LOG_CAT_L7VSD_SYSTEM_MEMORY;
2798 logcategory_string_dic[LOG_CAT_L7VSD_SYSTEM_MEMORY] = "l7vsd_system_memory";
2799 string_logcategory_dic["l7vsd_system_endpoint"] = LOG_CAT_L7VSD_SYSTEM_ENDPOINT;
2800 string_logcategory_dic["sys_ep"] = LOG_CAT_L7VSD_SYSTEM_ENDPOINT;
2801 logcategory_string_dic[LOG_CAT_L7VSD_SYSTEM_ENDPOINT] = "l7vsd_system_endpoint";
2802 string_logcategory_dic["l7vsd_system_signal"] = LOG_CAT_L7VSD_SYSTEM_SIGNAL;
2803 string_logcategory_dic["sys_sig"] = LOG_CAT_L7VSD_SYSTEM_SIGNAL;
2804 logcategory_string_dic[LOG_CAT_L7VSD_SYSTEM_SIGNAL] = "l7vsd_system_signal";
2805 string_logcategory_dic["l7vsd_system_environment"] = LOG_CAT_L7VSD_SYSTEM_ENVIRONMENT;
2806 string_logcategory_dic["sys_env"] = LOG_CAT_L7VSD_SYSTEM_ENVIRONMENT;
2807 logcategory_string_dic[LOG_CAT_L7VSD_SYSTEM_ENVIRONMENT] = "l7vsd_system_environment";
2808 string_logcategory_dic["l7vsd_snmpagent"] = LOG_CAT_L7VSD_SNMPAGENT;
2809 string_logcategory_dic["agent"] = LOG_CAT_L7VSD_SNMPAGENT;
2810 logcategory_string_dic[LOG_CAT_L7VSD_SNMPAGENT] = "l7vsd_snmpagent";
2811 string_logcategory_dic["l7vsd_protocol"] = LOG_CAT_PROTOCOL;
2812 string_logcategory_dic["prot"] = LOG_CAT_PROTOCOL;
2813 logcategory_string_dic[LOG_CAT_PROTOCOL] = "l7vsd_protocol";
2814 string_logcategory_dic["l7vsd_schedule"] = LOG_CAT_SCHEDULE;
2815 string_logcategory_dic["sched"] = LOG_CAT_SCHEDULE;
2816 logcategory_string_dic[LOG_CAT_SCHEDULE] = "l7vsd_schedule";
2817 string_logcategory_dic["all"] = LOG_CAT_END;
2819 // string log level dictionary create.
2820 string_loglevel_dic["debug"] = LOG_LV_DEBUG;
2821 loglevel_string_dic[LOG_LV_DEBUG] = "debug";
2822 string_loglevel_dic["info"] = LOG_LV_INFO;
2823 loglevel_string_dic[LOG_LV_INFO] = "info";
2824 string_loglevel_dic["warn"] = LOG_LV_WARN;
2825 loglevel_string_dic[LOG_LV_WARN] = "warn";
2826 string_loglevel_dic["error"] = LOG_LV_ERROR;
2827 loglevel_string_dic[LOG_LV_ERROR] = "error";
2828 string_loglevel_dic["fatal"] = LOG_LV_FATAL;
2829 loglevel_string_dic[LOG_LV_FATAL] = "fatal";
2831 // parameter category dictionary create
2832 string_parameter_dic["all"] = PARAM_COMP_ALL;
2833 string_parameter_dic["l7vsd"] = PARAM_COMP_L7VSD;
2834 string_parameter_dic["command"] = PARAM_COMP_COMMAND;
2835 string_parameter_dic["session"] = PARAM_COMP_SESSION;
2836 string_parameter_dic["virtualservice"] = PARAM_COMP_VIRTUALSERVICE;
2837 string_parameter_dic["module"] = PARAM_COMP_MODULE;
2838 string_parameter_dic["replication"] = PARAM_COMP_REPLICATION;
2839 string_parameter_dic["logger"] = PARAM_COMP_LOGGER;
2840 string_parameter_dic["l7vsadm"] = PARAM_COMP_L7VSADM;
2841 string_parameter_dic["snmpagent"] = PARAM_COMP_SNMPAGENT;
2842 string_parameter_dic["ssl"] = PARAM_COMP_SSL;
2844 // create disp_result dictionary.
2845 disp_result_dic[l7vsadm_request::CMD_LIST] = boost::bind(&l7vsadm::disp_list, this);
2846 disp_result_dic[l7vsadm_request::CMD_LIST_KEY] = boost::bind(&l7vsadm::disp_list_key, this);
2847 disp_result_dic[l7vsadm_request::CMD_LIST_VERBOSE] = boost::bind(&l7vsadm::disp_list_verbose, this);
2849 // response_message_dic create
2850 response_error_message_dic[l7vsd_response::RESPONSE_ERROR] = "command error : ";
2851 response_error_message_dic[l7vsd_response::RESPONSE_LIST_ERROR] = "list command error : ";
2852 response_error_message_dic[l7vsd_response::RESPONSE_LIST_VERBOSE_ERROR] = "list verbose error : ";
2853 response_error_message_dic[l7vsd_response::RESPONSE_LIST_KEY_ERROR] = "list key error : ";
2854 response_error_message_dic[l7vsd_response::RESPONSE_ADD_VS_ERROR] = "add vs error : ";
2855 response_error_message_dic[l7vsd_response::RESPONSE_DEL_VS_ERROR] = "del vs error : ";
2856 response_error_message_dic[l7vsd_response::RESPONSE_EDIT_VS_ERROR] = "edit vs error : ";
2857 response_error_message_dic[l7vsd_response::RESPONSE_FLUSH_VS_ERROR] = "flush vs error : ";
2858 response_error_message_dic[l7vsd_response::RESPONSE_ADD_RS_ERROR] = "add rs error : ";
2859 response_error_message_dic[l7vsd_response::RESPONSE_DEL_RS_ERROR] = "del rs error : ";
2860 response_error_message_dic[l7vsd_response::RESPONSE_EDIT_RS_ERROR] = "edit rs error : ";
2861 response_error_message_dic[l7vsd_response::RESPONSE_REPLICATION_ERROR] = "replication command error : ";
2862 response_error_message_dic[l7vsd_response::RESPONSE_LOG_ERROR] = "log command error : ";
2863 response_error_message_dic[l7vsd_response::RESPONSE_SNMP_ERROR] = "snmp command error : ";
2864 response_error_message_dic[l7vsd_response::RESPONSE_PARAMETER_ERROR] = "parameter error : ";
2866 replication_mode_string_dic[replication::REPLICATION_OUT] = "OUT";
2867 replication_mode_string_dic[replication::REPLICATION_SINGLE] = "SINGLE";
2868 replication_mode_string_dic[replication::REPLICATION_MASTER] = "MASTER";
2869 replication_mode_string_dic[replication::REPLICATION_SLAVE] = "SLAVE";
2870 replication_mode_string_dic[replication::REPLICATION_MASTER_STOP] = "MASTER_STOP";
2871 replication_mode_string_dic[replication::REPLICATION_SLAVE_STOP] = "SLAVE_STOP";
2874 //! Get l7vsadm parameter data
2875 void l7vs::l7vsadm::set_parameter()
2877 Logger logger(LOG_CAT_L7VSADM_COMMON, 36, "l7vsadm::set_parameter", __FILE__, __LINE__);
2879 // Get and Set l7vsadm all parameter value.
2883 // command_wait_interval
2884 command_wait_interval = param.get_int(PARAM_COMP_L7VSADM, "cmd_interval", err);
2886 if (command_wait_interval < 0 ||
2887 command_wait_interval > L7VSADM_MAX_WAIT) {
2888 // When illegal parameter value, use default parameter value.
2889 command_wait_interval = L7VSADM_DEFAULT_WAIT_INTERVAL;
2890 std::stringstream msg;
2891 msg << boost::format("Illegal cmd_interval parameter value. Use default value(%s).")
2892 % L7VSADM_DEFAULT_WAIT_INTERVAL;
2893 Logger::putLogWarn(LOG_CAT_L7VSADM_COMMON, 1, msg.str(), __FILE__, __LINE__);
2896 command_wait_interval = L7VSADM_DEFAULT_WAIT_INTERVAL;
2897 std::stringstream msg;
2898 msg << boost::format("Get cmd_interval parameter error. Use default value(%s).")
2899 % L7VSADM_DEFAULT_WAIT_INTERVAL;
2900 Logger::putLogWarn(LOG_CAT_L7VSADM_COMMON, 2, msg.str(), __FILE__, __LINE__);
2903 //command_wait_count
2904 command_wait_count = param.get_int(PARAM_COMP_L7VSADM, "cmd_count", err);
2906 if (command_wait_count < 0 ||
2907 command_wait_count > L7VSADM_MAX_WAIT) {
2908 // When illegal parameter value, use default parameter value.
2909 command_wait_count = L7VSADM_DEFAULT_WAIT_COUNT;
2910 std::stringstream msg;
2911 msg << boost::format("Illegal cmd_count parameter value. Use default value(%s).")
2912 % L7VSADM_DEFAULT_WAIT_COUNT;
2913 Logger::putLogWarn(LOG_CAT_L7VSADM_COMMON, 3, msg.str(), __FILE__, __LINE__);
2916 command_wait_count = L7VSADM_DEFAULT_WAIT_COUNT;
2917 std::stringstream msg;
2918 msg << boost::format("Get cmd_count parameter error. Use default value(%s).")
2919 % L7VSADM_DEFAULT_WAIT_COUNT;
2920 Logger::putLogWarn(LOG_CAT_L7VSADM_COMMON, 4, msg.str(), __FILE__, __LINE__);
2923 if ((command_wait_interval * command_wait_count) > L7VSADM_MAX_WAIT) {
2924 // When wait value too long, use default parameter value.
2925 command_wait_interval = L7VSADM_DEFAULT_WAIT_INTERVAL;
2926 command_wait_count = L7VSADM_DEFAULT_WAIT_COUNT;
2927 std::stringstream msg;
2928 msg << boost::format("Command wait value too long. Use default value(%s).")
2929 % L7VSADM_DEFAULT_WAIT_COUNT;
2930 Logger::putLogWarn(LOG_CAT_L7VSADM_COMMON, 9, msg.str(), __FILE__, __LINE__);
2934 //! l7vsadm command execute
2935 bool l7vs::l7vsadm::execute(int argc, char *argv[])
2937 Logger logger(LOG_CAT_L7VSADM_COMMON, 37, "l7vsadm::execute", __FILE__, __LINE__);
2939 /*-------- DEBUG LOG --------*/
2940 if (LOG_LV_DEBUG == Logger::getLogLevel(LOG_CAT_L7VSADM_COMMON)) {
2941 std::stringstream debugstr;
2942 debugstr << boost::format("l7vsadm::execute arguments: %s") % argument_debug_dump(argc, argv);
2943 Logger::putLogDebug(LOG_CAT_L7VSADM_COMMON, 38, debugstr.str(), __FILE__, __LINE__);
2945 /*------ DEBUG LOG END ------*/
2948 if (0 > set_sighandlers()) {
2949 std::string buf("set_sighandlers failed.");
2950 std::cerr << "COMMON ERROR: " << buf << std::endl;
2951 Logger::putLogError(LOG_CAT_L7VSADM_COMMON, 1, buf, __FILE__, __LINE__);
2958 // Get l7vsadm execute file path from /proc/(pid)/exe (symbolic link)
2959 char l7vsadm_file_path[256];
2961 memset(l7vsadm_file_path, 0, sizeof(l7vsadm_file_path));
2962 retsize = readlink("/proc/self/exe", l7vsadm_file_path, sizeof(l7vsadm_file_path));
2964 // L7vsadm command conflict check. (Try l7vsadm execute file lock)
2965 file_lock lock(l7vsadm_file_path, l7vsadm_err);
2967 std::cerr << "COMMON ERROR: " << l7vsadm_err.get_message() << std::endl;
2968 Logger::putLogError(LOG_CAT_L7VSADM_COMMON, 2, l7vsadm_err.get_message(), __FILE__, __LINE__);
2973 // l7vsadm file lock wait
2974 int command_retry_count = 0;
2978 std::stringstream buf;
2979 buf << boost::format("Signal (%d) Received.") % received_sig;
2980 l7vsadm_err.setter(true, buf.str());
2981 Logger::putLogError(LOG_CAT_L7VSADM_COMMON, 3, buf.str(), __FILE__, __LINE__);
2985 // Try lock l7vsadm file.
2986 if (lock.try_lock()) {
2990 ++command_retry_count;
2991 if (command_retry_count > command_wait_count) {
2992 // L7vsadm file lock error. (l7vsadm is executing)
2993 std::string buf("L7vsadm file lock timeout. (l7vsadm is already executing)");
2994 l7vsadm_err.setter(true, buf);
2995 Logger::putLogError(LOG_CAT_L7VSADM_COMMON, 4, buf, __FILE__, __LINE__);
2999 std::stringstream buf;
3000 buf << boost::format("L7vsadm file lock error. (l7vsadm is already executing) (retry %d)") % command_retry_count;
3001 Logger::putLogWarn(LOG_CAT_L7VSADM_COMMON, 11, buf.str(), __FILE__, __LINE__);
3005 xtime_get(&xt, boost::TIME_UTC);
3006 xt.sec += command_wait_interval;
3007 boost::thread::sleep(xt);
3012 std::cerr << "COMMON ERROR: " << l7vsadm_err.get_message() << std::endl;
3016 // no argument, assume list command
3018 request.command = l7vsadm_request::CMD_LIST;
3020 // parse command line
3022 parse_cmd_map_type::iterator itr = command_dic.find(argv[pos]);
3023 if (itr != command_dic.end()) {
3024 itr->second(argc, argv);
3026 std::string buf("command not found.");
3027 l7vsadm_err.setter(true, buf);
3028 Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 88, buf, __FILE__, __LINE__);
3032 // display command parse result
3034 std::cerr << "PARSE ERROR: " << l7vsadm_err.get_message() << std::endl;
3035 std::cerr << usage() << std::endl;
3039 if (l7vsadm_request::CMD_HELP != request.command) {
3040 // communicate to l7vsd
3041 using boost::asio::local::stream_protocol;
3042 boost::array<char, COMMAND_BUFFER_SIZE> response_buffer;
3043 response_buffer.assign(0x00);
3046 boost::asio::io_service io;
3047 stream_protocol::socket s(io);
3051 std::stringstream buf;
3052 buf << boost::format("Signal (%d) Received.") % received_sig;
3053 l7vsadm_err.setter(true, buf.str());
3054 Logger::putLogError(LOG_CAT_L7VSADM_COMMON, 5, buf.str(), __FILE__, __LINE__);
3056 // Try connect to config socket.
3057 boost::system::error_code err;
3058 s.connect(stream_protocol::endpoint(L7VS_CONFIG_SOCKNAME), err);
3060 std::stringstream buf;
3061 buf << boost::format("connect() failed: %s.") % err.message();
3062 l7vsadm_err.setter(true, buf.str());
3063 Logger::putLogError(LOG_CAT_L7VSADM_COMMON, 9, buf.str(), __FILE__, __LINE__);
3069 std::cerr << "COMMON ERROR: " << l7vsadm_err.get_message() << std::endl;
3073 /*-------- DEBUG LOG --------*/
3074 if (LOG_LV_DEBUG == Logger::getLogLevel(LOG_CAT_L7VSADM_COMMON)) {
3075 std::stringstream debugstr;
3076 debugstr << boost::format("l7vsadm_send_request:%s") % request;
3077 Logger::putLogDebug(LOG_CAT_L7VSADM_COMMON, 39, debugstr.str(), __FILE__, __LINE__);
3079 /*------ DEBUG LOG END ------*/
3082 std::stringstream send_stream;
3083 boost::archive::text_oarchive oa(send_stream);
3084 oa << (const l7vs::l7vsadm_request &) request;
3085 boost::asio::write(s, boost::asio::buffer(send_stream.str()));
3088 s.read_some(boost::asio::buffer(response_buffer));
3090 std::stringstream recv_stream;
3091 recv_stream << &(response_buffer[0]);
3092 boost::archive::text_iarchive ia(recv_stream);
3095 /*-------- DEBUG LOG --------*/
3096 if (LOG_LV_DEBUG == Logger::getLogLevel(LOG_CAT_L7VSADM_COMMON)) {
3097 std::stringstream debugstr;
3098 debugstr << boost::format("l7vsadm_recv_response:%s") % response;
3099 Logger::putLogDebug(LOG_CAT_L7VSADM_COMMON, 40, debugstr.str(), __FILE__, __LINE__);
3101 /*------ DEBUG LOG END ------*/
3107 if (l7vsd_response::RESPONSE_OK == response.status) {
3108 disp_result_map_type::iterator itr = disp_result_dic.find(request.command);
3109 if (itr != disp_result_dic.end())
3112 std::stringstream buf;
3113 response_error_message_map_type::iterator itr = response_error_message_dic.find(response.status);
3114 if (itr != response_error_message_dic.end())
3115 buf << itr->second << response.message;
3117 buf << "COMMAND ERROR: " << response.message;
3118 std::cerr << buf.str() << std::endl;
3119 Logger::putLogError(LOG_CAT_L7VSADM_COMMON, 7, buf.str(), __FILE__, __LINE__);
3124 catch (std::exception &e) {
3125 std::stringstream buf;
3126 buf << "COMMON ERROR: " << e.what();
3127 std::cerr << buf.str() << std::endl;
3128 Logger::putLogError(LOG_CAT_L7VSADM_COMMON, 8, buf.str(), __FILE__, __LINE__);
3134 //! argument dump for debug
3135 //! @param[in] argument count
3136 //! @param[in] argument value
3137 std::string l7vs::l7vsadm::argument_debug_dump(int argc, char *argv[])
3139 std::stringstream buf;
3141 buf << "argument=(null)";
3143 buf << boost::format("argument={argc=%d") % argc;
3144 for (int i = 0; i < argc; ++i) {
3145 buf << boost::format(", argv[%d]=%s") % i % argv[i];
3152 //! signal handler function
3153 //! @param[in] signal
3154 static void sig_exit_handler(int sig)
3160 //! set signal handler function
3161 //! @param[in] signal
3162 //! @param[in] handler function pointer
3163 //! @return 0/success, -1/fail
3164 static int set_sighandler(int sig, void (*handler)(int))
3166 struct sigaction act;
3169 ret = sigaction(sig, NULL, &act);
3174 act.sa_flags &= ~SA_RESETHAND;
3175 act.sa_handler = handler;
3177 ret = sigaction(sig, &act, NULL);
3185 //! set all signal handler function
3186 //! @return 0/success, -1/fail
3187 static int set_sighandlers()
3191 #define SET_SIGHANDLER(sig, handler) \
3193 ret = set_sighandler((sig), (handler)); \
3199 SET_SIGHANDLER(SIGHUP, sig_exit_handler);
3200 SET_SIGHANDLER(SIGINT, sig_exit_handler);
3201 SET_SIGHANDLER(SIGQUIT, sig_exit_handler);
3202 SET_SIGHANDLER(SIGPIPE, sig_exit_handler);
3203 SET_SIGHANDLER(SIGTERM, sig_exit_handler);
3204 SET_SIGHANDLER(SIGUSR1, sig_exit_handler);
3205 SET_SIGHANDLER(SIGUSR2, sig_exit_handler);
3207 #undef SET_SIGHANDLER
3213 int main(int argc, char *argv[])
3216 l7vs::Logger logger;
3217 l7vs::Parameter param;
3223 if (!adm.execute(argc, argv)) {