OSDN Git Service

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