OSDN Git Service

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