OSDN Git Service

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