OSDN Git Service

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