OSDN Git Service

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