Changeset 724a835 in nscp


Ignore:
Timestamp:
07/29/12 22:39:38 (10 months ago)
Author:
Michael Medin <michael@…>
Branches:
master, 0.4.1, 0.4.2
Children:
f14ab71
Parents:
d6194a0
Message:
  • Tracked down a few memory leaks when connections time-out.
  • Added test cases for connection timeouts in lua NRPE test suite
  • Improved the LUA module a bit
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • changelog

    rd6194a0 r724a835  
    44 * Fix dependonservice LanManWorkStation (old win) 
    55 * Fix RtlStringFromGUID problem on NT4 
     6 
     72012-07-29 MickeM 
     8 * Tracked down a few memoryleaks when connections time-out. 
     9 * Added testcases for connection timeouts in lua NRPE test suite 
     10 * Improved the LUA module a bit 
    611 
    7122012-07-26 MickeM 
  • include/nrpe/packet.hpp

    rd6194a0 r724a835  
    109109      char *tmp = new char[buffer.size()+1]; 
    110110      copy( buffer.begin(), buffer.end(), tmp); 
    111       readFrom(tmp, buffer.size()); 
     111      try { 
     112        readFrom(tmp, buffer.size()); 
     113      } catch (nrpe::nrpe_packet_exception &e) { 
     114        delete [] tmp; 
     115        throw e; 
     116      } 
    112117      delete [] tmp; 
    113118    }; 
  • include/nrpe/server/protocol.hpp

    ra48fd4c r724a835  
    8888        iterator_type old_begin = begin; 
    8989        boost::tie(result, begin) = parser_.digest(begin, end); 
    90         if (begin == old_begin) { 
    91           log_error(__FILE__, __LINE__, "Digester failed to parse chunk, giving up."); 
    92           return false; 
    93         } 
    9490        if (result) { 
    9591          nrpe::packet response; 
     
    106102          set_state(got_request); 
    107103          return true; 
     104        } else if (begin == old_begin) { 
     105          log_error(__FILE__, __LINE__, "Digester failed to parse chunk, giving up."); 
     106          return false; 
    108107        } 
    109108      } 
  • include/socket/client.hpp

    rd6194a0 r724a835  
    3636      virtual ~connection() { 
    3737        try { 
    38           stop_timer(); 
     38          cancel_timer(); 
    3939        } catch (const std::exception &e) { 
    4040          handler_->log_error(__FILE__, __LINE__, std::string("Failed to close connection: ") + e.what()); 
     
    5454        timer_.async_wait(boost::bind(&connection::on_timeout, this->shared_from_this(),  boost::asio::placeholders::error)); 
    5555      } 
    56       void stop_timer() { 
     56      void cancel_timer() { 
     57        trace("cancel_timer()"); 
    5758        timer_.cancel(); 
    5859      } 
     
    9495        do_process(); 
    9596        if (!wait()) { 
    96           stop_timer(); 
    97           close(); 
     97          close_socket(); 
     98          timer_result_.reset(); 
     99          wait(); 
    98100          return protocol_.get_timeout_response(); 
    99101        } 
    100         stop_timer(); 
     102        cancel_timer(); 
    101103        return protocol_.get_response(); 
    102104      } 
     
    104106      virtual void shutdown() { 
    105107        trace("shutdown()"); 
     108        cancel_timer(); 
     109        close_socket(); 
     110      }; 
     111 
     112 
     113      virtual void close_socket() { 
     114        trace("close_socket()"); 
    106115        boost::system::error_code ignored_ec; 
    107         if (get_socket().is_open()) 
     116        if (get_socket().is_open()) { 
    108117          get_socket().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec); 
    109       }; 
    110  
    111  
    112       virtual void close() { 
    113         trace("close()"); 
    114         boost::system::error_code ignored_ec; 
    115         if (get_socket().is_open()) 
    116           get_socket().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec); 
    117         get_socket().close(ignored_ec); 
     118          get_socket().close(ignored_ec); 
     119        } 
    118120      } 
    119121 
     
    142144        } else { 
    143145          handler_->log_error(__FILE__, __LINE__, "Failed to read data: " + e.message()); 
     146          cancel_timer(); 
    144147        } 
    145148      } 
     
    154157        } else { 
    155158          handler_->log_error(__FILE__, __LINE__, "Failed to send data: " + e.message()); 
     159          cancel_timer(); 
    156160        } 
    157161      } 
     
    200204      virtual ~tcp_connection() { 
    201205        try { 
    202           this->close(); 
     206          this->close_socket(); 
    203207        } catch (const std::exception &e) { 
    204208          this->log_error(__FILE__, __LINE__, std::string("Failed to close connection: ") + e.what()); 
     
    241245      virtual ~ssl_connection() { 
    242246        try { 
    243           this->close(); 
     247          this->close_socket(); 
    244248        } catch (const std::exception &e) { 
    245249          this->log_error(__FILE__, __LINE__, std::string("Failed to close connection: ") + e.what()); 
     
    276280 
    277281    template<class protocol_type> 
    278     class client { 
     282    class client : boost::noncopyable { 
    279283      boost::shared_ptr<connection<protocol_type> > connection_; 
    280284      boost::asio::io_service io_service_; 
     
    331335      void shutdown() { 
    332336        connection_->shutdown(); 
     337        connection_.reset(); 
    333338      }; 
    334339 
  • include/socket/connection.hpp

    rc3f233d r724a835  
    4949      } 
    5050 
    51       virtual boost::asio::ip::tcp::socket& socket() = 0; 
     51      virtual boost::asio::ip::tcp::socket& get_socket() = 0; 
    5252 
    5353      ////////////////////////////////////////////////////////////////////////// 
     
    5959          do_process(); 
    6060        } else { 
    61           stop(); 
    62         } 
    63       } 
    64  
    65       virtual void stop() { 
    66         trace("stop()"); 
    67         cancel_timer(); 
     61          on_done(false); 
     62        } 
     63      } 
     64      void cancel_socket() { 
     65        trace("cancel_socket()"); 
    6866        boost::system::error_code ignored_ec; 
    69         socket().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec); 
     67        if (get_socket().is_open()) { 
     68          trace("socket.shutdown()"); 
     69          get_socket().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec); 
     70          get_socket().close(ignored_ec); 
     71        } 
     72      } 
     73 
     74      virtual void on_done(bool all_ok) { 
     75        trace(std::string("on_done(") + (all_ok?"true":"false") + ")"); 
     76        try { 
     77          cancel_timer(); 
     78          cancel_socket(); 
     79        } catch (...) { 
     80          protocol_->log_error(__FILE__, __LINE__, "Failed to close connection"); 
     81        } 
    7082      } 
    7183 
     
    7890 
    7991      virtual void cancel_timer() { 
     92        trace("cancel_timer()"); 
    8093        timer_.cancel(); 
    8194      } 
     
    8497        if (e != boost::asio::error::operation_aborted) { 
    8598          trace("timeout()"); 
    86           boost::system::error_code ignored_ec; 
    87           socket().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec); 
     99          on_done(false); 
    88100        } 
    89101      } 
     
    100112          start_write_request(buf(protocol_->get_outbound())); 
    101113        } else { 
    102           stop(); 
     114          on_done(true); 
    103115        } 
    104116      } 
     
    106118      virtual void start_read_request() = 0; 
    107119      virtual void handle_read_request(const boost::system::error_code& e, std::size_t bytes_transferred) { 
    108         trace("handle_read_request(" + strEx::s::xtos(bytes_transferred) + ")"); 
     120        trace("handle_read_request(" + e.message() + ", " + strEx::s::xtos(bytes_transferred) + ")"); 
    109121        if (!e) { 
    110122          if (protocol_->on_read(buffer_.begin(), buffer_.begin() + bytes_transferred)) { 
    111123            do_process(); 
    112124          } else { 
    113             stop(); 
     125            on_done(false); 
    114126          } 
    115127        } else { 
    116128          protocol_->log_error(__FILE__, __LINE__, "Failed to read data: " + e.message()); 
     129          on_done(false); 
    117130        } 
    118131      } 
     
    120133      virtual void start_write_request(const boost::asio::const_buffer& response) = 0; 
    121134      virtual void handle_write_response(const boost::system::error_code& e, std::size_t bytes_transferred) { 
    122         trace("handle_write_response(" + strEx::s::xtos(bytes_transferred) + ")"); 
     135        trace("handle_write_response(" + e.message() + ", " + strEx::s::xtos(bytes_transferred) + ")"); 
    123136        if (!e) { 
    124137          protocol_->on_write(); 
     
    126139        } else { 
    127140          protocol_->log_error(__FILE__, __LINE__, "Failed to send data: " + e.message()); 
     141          on_done(false); 
    128142        } 
    129143      } 
     
    163177      } 
    164178 
    165       virtual boost::asio::ip::tcp::socket& socket() { 
     179      virtual boost::asio::ip::tcp::socket& get_socket() { 
    166180        return socket_; 
    167181      } 
     
    197211 
    198212 
    199       virtual boost::asio::ip::tcp::socket& socket() { 
     213      virtual boost::asio::ip::tcp::socket& get_socket() { 
    200214        return ssl_socket_.next_layer(); 
    201215      } 
     
    215229        else { 
    216230          parent_type::protocol_->log_error(__FILE__, __LINE__, "Failed to establish secure connection: " + e.message()); 
     231          parent_type::on_done(false); 
    217232        } 
    218233      } 
  • include/socket/server.hpp

    ra48fd4c r724a835  
    114114          acceptor_.listen(protocol_->get_info().back_log); 
    115115 
    116         acceptor_.async_accept(new_connection_->socket(),accept_strand_.wrap( 
     116        acceptor_.async_accept(new_connection_->get_socket(),accept_strand_.wrap( 
    117117          boost::bind(&server::handle_accept, this, boost::asio::placeholders::error) 
    118118          )); 
     
    133133        if (!e) { 
    134134          std::list<std::string> errors; 
    135           if (protocol_->on_accept(new_connection_->socket())) { 
     135          if (protocol_->on_accept(new_connection_->get_socket())) { 
    136136            new_connection_->start(); 
    137137          } else { 
    138             new_connection_->stop(); 
     138            new_connection_->on_done(false); 
    139139          } 
    140140 
    141141          new_connection_.reset(create_connection()); 
    142142 
    143           acceptor_.async_accept(new_connection_->socket(), 
     143          acceptor_.async_accept(new_connection_->get_socket(), 
    144144            accept_strand_.wrap( 
    145145            boost::bind(&server::handle_accept, this, boost::asio::placeholders::error) 
  • modules/LUAScript/lua_wrappers.hpp

    rd6194a0 r724a835  
    453453      , script(script) 
    454454    { 
    455       std::wcout << _T("+++"); 
    456455    } 
    457456 
    458457    virtual ~lua_script_instance() { 
    459       std::wcout << _T("---"); 
    460458    } 
    461459 
  • modules/LUAScript/script_wrapper.hpp

    rd6194a0 r724a835  
    516516    lua_script(nscapi::core_wrapper* core, const int plugin_id, boost::shared_ptr<lua_wrappers::lua_registry> registry, const std::string alias, const std::string base_path, const std::string script)  
    517517      : script_instance(core, plugin_id, registry, alias, script), base_path_(base_path) { 
    518         std::wcout << _T("AAA"); 
    519518    } 
    520519  public: 
    521520    virtual ~lua_script() { 
    522       std::wcout << _T("XXX"); 
    523521    } 
    524522 
     
    532530 
    533531    void load() { 
    534       std::wcout << _T("lll"); 
    535532      lua_wrappers::lua_instance_manager::set_script(get_lua_state(), shared_from_this()); 
    536533      lua_wrappers::lua_wrapper lua(get_lua_state()); 
     
    542539      if (lua.pcall(0, 0, 0) != 0) 
    543540        throw lua_wrappers::LUAException(_T("Failed to execute script: ") + get_wscript() + _T(": ") + lua.pop_string()); 
    544       std::wcout << _T("LLL"); 
    545541    } 
    546542    std::wstring get_wscript() const { 
     
    548544    } 
    549545    void unload() { 
    550       std::wcout << _T("uuu"); 
    551546      lua_wrappers::lua_wrapper lua(get_lua_state()); 
    552547      lua.gc(LUA_GCCOLLECT, 0); 
    553548      lua_wrappers::lua_instance_manager::remove_script(shared_from_this()); 
    554       std::wcout << _T("UUU"); 
    555       std::wcout << shared_from_this().use_count(); 
    556549    } 
    557550    void reload() { 
  • scripts/lua/lib/test_helper.lua

    rd6194a0 r724a835  
    8080function TestResult:print(indent) 
    8181  indent = indent or 0 
    82   pad = string.rep(' ', indent) 
     82  local pad = string.rep(' ', indent) 
    8383  if self.status then 
    8484    core:log("info", pad .. "[OK ] - " .. self.message) 
     
    9393function TestResult:print_failed(indent) 
    9494  indent = indent or 0 
    95   pad = string.rep(' ', indent) 
     95  local pad = string.rep(' ', indent) 
    9696  if not self.status then 
    9797    core:log("error", pad .. "[ERR] - " .. self.message) 
    9898  end 
    9999  if # self.children > 0 then 
    100     for i,v in ipairs(self.children) do v:print(indent+2) end 
     100    for i,v in ipairs(self.children) do v:print_failed(indent+2) end 
    101101  end 
    102102end 
  • scripts/lua/test_nrpe.lua

    rd6194a0 r724a835  
    105105 
    106106function TestNRPE:handler(req) 
    107   msg = self:get_response(args[0]) 
     107  local msg = self:get_response(args[0]) 
    108108  msg.got_response = true 
    109109  self:set_response(msg) 
     
    132132    enc = host:add_metadata() 
    133133    enc:set_key("timeout") 
    134     enc:set_value('5') 
     134    enc:set_value('10') 
    135135  end 
    136136 
     
    147147  result_code, response = core:query('nrpe_forward', serialized) 
    148148  response_message = protobuf.Plugin.QueryResponseMessage.parsefromstring(response) 
    149   --print(response_message:get_payload(1):get_message()) 
    150149 
    151150 
     
    165164      break 
    166165    else 
    167       log(string.format('Waiting for %s (%s/%s)', uid,tag,target)) 
     166      core:log(string.format('Waiting for %s (%s/%s)', uid,tag,target)) 
    168167      --sleep(500) 
    169168    end 
     
    217216end 
    218217 
     218function TestNRPE:test_timeout(ssl, server_timeout, client_timeout, length) 
     219 
     220  local conf = Settings() 
     221  local core = Core() 
     222  conf:set_bool('/settings/NRPE/test_nrpe_server', 'use ssl', ssl) 
     223  conf:set_int('/settings/NRPE/test_nrpe_server', 'timeout', server_timeout) 
     224  conf:set_bool('/settings/NRPE/test_nrpe_server', 'allow arguments', true) 
     225  conf:set_int('/settings/NRPE/test_nrpe_server', 'payload length', length) 
     226  core:reload('test_nrpe_server') 
     227 
     228  conf:set_string('/settings/NRPE/test_nrpe_client/targets/default', 'address', 'nrpe://127.0.0.1:15666') 
     229  conf:set_bool('/settings/NRPE/test_nrpe_client/targets/default', 'use ssl', ssl) 
     230  conf:set_int('/settings/NRPE/test_nrpe_client/targets/default', 'timeout', client_timeout) 
     231  conf:set_int('/settings/NRPE/test_nrpe_client/targets/default', 'payload length', length) 
     232 
     233  core:reload('test_nrpe_client') 
     234 
     235  local result = test.TestResult:new{message="Testing timeouts ssl: "..tostring(ssl)..", server: "..tostring(server_timeout)..", client: "..tostring(client_timeout)} 
     236   
     237   
     238 
     239  local msg = protobuf.Plugin.QueryRequestMessage.new() 
     240  hdr = msg:get_header() 
     241  hdr:set_version(1) 
     242  hdr:set_recipient_id('test') 
     243  host = hdr:add_hosts() 
     244  host:set_address("127.0.0.1:15666") 
     245  host:set_id('test') 
     246 
     247  uid = string.random(12) 
     248  payload = msg:add_payload() 
     249  payload:set_command('check_py_nrpe_test_s') 
     250  payload:set_arguments(1, uid) 
     251  rmsg = self:get_request(uid) 
     252  rmsg.status = 'ok' 
     253  rmsg.message = 'Hello: Timeout' 
     254  rmsg.perfdata = '' 
     255  self:set_request(rmsg) 
     256  serialized = msg:serialized() 
     257  result_code, response = core:query('nrpe_forward', serialized) 
     258  response_message = protobuf.Plugin.QueryResponseMessage.parsefromstring(response) 
     259 
     260 
     261  found = False 
     262  for i = 0,10 do 
     263    if (self:has_response(uid)) then 
     264      rmsg = self:get_response(uid) 
     265      result:add_message(false, string.format('Testing to recieve message using')) 
     266      self:del_response(uid) 
     267      found = true 
     268      break 
     269    else 
     270      core:log(string.format('Timeout waiting for %s', uid)) 
     271      --sleep(500) 
     272    end 
     273  end 
     274  if (found) then 
     275    result:add_message(false, string.format('Making sure timeout message was never delivered')) 
     276  end 
     277   
     278  return result 
     279end 
    219280 
    220281function TestNRPE:run() 
     
    225286  result:add(self:do_one_test(true, 65536)) 
    226287  result:add(self:do_one_test(true, 1048576)) 
     288 
     289  result:add(self:test_timeout(false, 30, 1, 10485760)) 
     290  result:add(self:test_timeout(false, 1, 30, 10485760)) 
     291  result:add(self:test_timeout(true, 30, 1, 10485760)) 
     292  result:add(self:test_timeout(true, 1, 30, 10485760)) 
    227293  return result 
    228294end 
Note: See TracChangeset for help on using the changeset viewer.