OSDN Git Service

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