OSDN Git Service

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