OSDN Git Service

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