From 1ece191b61b3333abdd41595f0aaa7d5e85cc8f6 Mon Sep 17 00:00:00 2001 From: Christian Herdtweck Date: Mon, 26 Jan 2015 17:32:01 +0100 Subject: [PATCH] start removing socket use from IcmpPinger to only have IcmpPacketDistributor deal with raw data --- src/host/pinger.h | 2 +- src/host/pingerfactory.cpp | 1 - src/icmp/icmppaketdistributor.cpp | 100 +++++++++++----- src/icmp/icmppaketdistributor.h | 51 +++++---- src/icmp/icmppinger.cpp | 244 ++++++++++++------------------------- src/icmp/icmppinger.h | 25 ++--- src/main.cpp | 2 +- 7 files changed, 188 insertions(+), 237 deletions(-) diff --git a/src/host/pinger.h b/src/host/pinger.h index 705e40e..72a4839 100644 --- a/src/host/pinger.h +++ b/src/host/pinger.h @@ -66,7 +66,7 @@ protected: virtual ~Pinger(); Pinger::WeakPtr get_myself() const; - void set_myself(const Pinger::WeakPtr &myself); + virtual void set_myself(const Pinger::WeakPtr &myself); private: Pinger::WeakPtr Myself; diff --git a/src/host/pingerfactory.cpp b/src/host/pingerfactory.cpp index 17285a2..e14ff5c 100644 --- a/src/host/pingerfactory.cpp +++ b/src/host/pingerfactory.cpp @@ -30,7 +30,6 @@ #include #include "boost_assert_handler.h" -#include "icmp/icmppaketdistributor.h" #include "icmp/icmppinger.h" #include "tcp/tcppinger.h" diff --git a/src/icmp/icmppaketdistributor.cpp b/src/icmp/icmppaketdistributor.cpp index 1772b32..bfa090d 100644 --- a/src/icmp/icmppaketdistributor.cpp +++ b/src/icmp/icmppaketdistributor.cpp @@ -22,12 +22,14 @@ #include "icmppaketdistributor.h" +#include #include #include #include #include #include "boost_assert_handler.h" +#include "icmp/icmppacketfactory.h" using I2n::Logger::GlobalLogger; @@ -35,10 +37,10 @@ using boost::asio::ip::icmp; static const std::size_t SOCKET_BUFFER_SIZE = 65536; // 64kB -typedef std::set::iterator PingerListIterator; +typedef std::set::iterator PingerListIterator; -bool IcmpPaketDistributorInstanceIdentifierComparator::operator() ( +bool IcmpPacketDistributorInstanceIdentifierComparator::operator() ( const DistributorInstanceIdentifier &a, const DistributorInstanceIdentifier &b ) const { @@ -63,13 +65,13 @@ bool IcmpPaketDistributorInstanceIdentifierComparator::operator() ( } //----------------------------------------------------------------------------- -// Definition of IcmpPaketDistributor +// Definition of IcmpPacketDistributor //----------------------------------------------------------------------------- -map_type IcmpPaketDistributor::Instances; // initialize +map_type IcmpPacketDistributor::Instances; // initialize -IcmpPaketDistributorItem IcmpPaketDistributor::get_distributor( +IcmpPacketDistributorItem IcmpPacketDistributor::get_distributor( const icmp::socket::protocol_type &protocol, const std::string &network_interface, const IoServiceItem io_serv ) @@ -79,9 +81,9 @@ IcmpPaketDistributorItem IcmpPaketDistributor::get_distributor( // check if there is an instance for this protocol and interface if ( Instances.count(identifier) == 0 ) { // need to create an instance for this protocol and network interface - GlobalLogger.info() << "Creating IcmpPaketDistributor for interface " + GlobalLogger.info() << "Creating IcmpPacketDistributor for interface " << network_interface << std::endl; - IcmpPaketDistributorItem new_instance( new IcmpPaketDistributor( + IcmpPacketDistributorItem new_instance( new IcmpPacketDistributor( protocol, network_interface, io_serv ) ); Instances[identifier] = new_instance; } @@ -93,7 +95,7 @@ IcmpPaketDistributorItem IcmpPaketDistributor::get_distributor( } -IcmpPaketDistributorItem IcmpPaketDistributor::get_distributor( +IcmpPacketDistributorItem IcmpPacketDistributor::get_distributor( const icmp::socket::protocol_type &protocol, const std::string &network_interface ) { @@ -106,22 +108,22 @@ IcmpPaketDistributorItem IcmpPaketDistributor::get_distributor( } -IcmpPaketDistributor::IcmpPaketDistributor( +IcmpPacketDistributor::IcmpPacketDistributor( const icmp::socket::protocol_type &protocol, const std::string &network_interface, const IoServiceItem io_serv ): - Socket( *io_serv, protocol ), Protocol( protocol ), ReplyBuffer(), PingerList() { + Socket = SocketItem( new icmp::socket(*io_serv, protocol) ); NetworkInterface - NetInterface( network_interface, Socket ); + NetInterface( network_interface, *Socket ); if ( !NetInterface.bind() ) { GlobalLogger.error() - << "Trouble creating IcmpPaketDistributor for interface " + << "Trouble creating IcmpPacketDistributor for interface " << network_interface// << " and protocol " << protocol << ": could not bind the socket with the local interface. " << ::strerror( errno ) << std::endl; @@ -131,18 +133,18 @@ IcmpPaketDistributor::IcmpPaketDistributor( } -void IcmpPaketDistributor::register_receive_handler() +void IcmpPacketDistributor::register_receive_handler() { // Waiting for a reply, We prepare the buffer to receive up to SOCKET_BUFFER_SIZE bytes - Socket.async_receive( + Socket->async_receive( ReplyBuffer.prepare( SOCKET_BUFFER_SIZE ), - boost::bind( &IcmpPaketDistributor::handle_receive, this, + boost::bind( &IcmpPacketDistributor::handle_receive, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred ) ); } -void IcmpPaketDistributor::handle_receive( const boost::system::error_code &error, +void IcmpPacketDistributor::handle_receive( const boost::system::error_code &error, const size_t &bytes_transferred ) { if ( error ) @@ -158,32 +160,66 @@ void IcmpPaketDistributor::handle_receive( const boost::system::error_code &erro // can extract it using a std::istream object. ReplyBuffer.commit( bytes_transferred ); - GlobalLogger.info() << "received paket in distributor" << std::endl; + GlobalLogger.info() << "received packet in distributor" << std::endl; + try + { + std::istream is( &ReplyBuffer ); + if ( !is ) + { + GlobalLogger.error() << "Can't handle ReplyBuffer" << std::endl; + return; + } + + // Decode the reply packet. + IcmpPacketItem icmp_packet = IcmpPacketFactory::create_icmp_packet( Protocol, is ); + if ( !icmp_packet ) + { + GlobalLogger.warning() << "Ignoring broken ICMP packet" << std::endl; + } + + // check which pinger wants this packet + bool packet_matches = false; + BOOST_FOREACH( IcmpPingerItem pinger, PingerList ) + { + packet_matches |= pinger->handle_receive_icmp_packet(icmp_packet, bytes_received); + if (packet_matches) + break; + } + + if (!packet_matches) + GlobalLogger.warning() << "Packet did not match any pinger" << std::endl; + + catch ( ... ) + { + GlobalLogger.notice() << "Exception during ICMP parse." << std::endl; + } + + // re-register receive handler register_receive_handler(); } -bool IcmpPaketDistributor::register_pinger( const PingerItem new_pinger ) +bool IcmpPacketDistributor::register_pinger( const IcmpPingerItem new_pinger ) { std::pair result = PingerList.insert(new_pinger); bool was_new = result.second; if (was_new) - GlobalLogger.info() << "Register new pinger with IcmpPaketDistributor" << std::endl; + GlobalLogger.info() << "Register new pinger with IcmpPacketDistributor" << std::endl; else - GlobalLogger.warning() << "Pinger to register was already known in IcmpPaketDistributor" + GlobalLogger.warning() << "Pinger to register was already known in IcmpPacketDistributor" << std::endl; return was_new; } -bool IcmpPaketDistributor::unregister_pinger( const PingerItem old_pinger ) +bool IcmpPacketDistributor::unregister_pinger( const IcmpPingerItem old_pinger ) { int n_erased = PingerList.erase(old_pinger); bool was_erased = n_erased > 0; if (was_erased) - GlobalLogger.info() << "Removed pinger from IcmpPaketDistributor" << std::endl; + GlobalLogger.info() << "Removed pinger from IcmpPacketDistributor" << std::endl; else - GlobalLogger.warning() << "Could not find pinger to remove from IcmpPaketDistributor" + GlobalLogger.warning() << "Could not find pinger to remove from IcmpPacketDistributor" << std::endl; return was_erased; } @@ -191,7 +227,7 @@ bool IcmpPaketDistributor::unregister_pinger( const PingerItem old_pinger ) /** * @brief for all instances: close sockets, unregister all pingers */ -void IcmpPaketDistributor::clean_up_all() +void IcmpPacketDistributor::clean_up_all() { BOOST_FOREACH( map_type::value_type &instance, Instances ) instance.second->clean_up(); @@ -199,28 +235,32 @@ void IcmpPaketDistributor::clean_up_all() Instances.clear(); } -void IcmpPaketDistributor::clean_up() +void IcmpPacketDistributor::clean_up() { if (PingerList.size() > 0) GlobalLogger.warning() << "There were still " << PingerList.size() - << " pingers registered in IcmpPaketDistributor!" << std::endl; + << " pingers registered in IcmpPacketDistributor!" << std::endl; PingerList.clear(); boost::system::error_code error; - //Socket.shutdown(icmp::socket::shutdown_both, error); // both=send and receive + //Socket->shutdown(icmp::socket::shutdown_both, error); // both=send and receive //if ( error ) // GlobalLogger.warning() << "Received error " << error << " when shutting down ICMP socket"; // always gave an error system:9 (probably EBADF: Bad file descriptor) - Socket.close(error); + Socket->close(error); if ( error ) GlobalLogger.warning() << "Received error " << error << " when closing ICMP socket"; } -IcmpPaketDistributor::~IcmpPaketDistributor() +IcmpPacketDistributor::~IcmpPacketDistributor() { - GlobalLogger.info() << "Destroying IcmpPaketDistributor" << std::endl; + GlobalLogger.info() << "Destroying IcmpPacketDistributor" << std::endl; } +SocketItem IcmpPacketDistributor::get_socket() const +{ + return Socket; +} // (created using vim -- the world's best text editor) diff --git a/src/icmp/icmppaketdistributor.h b/src/icmp/icmppaketdistributor.h index fbcf711..af475b2 100644 --- a/src/icmp/icmppaketdistributor.h +++ b/src/icmp/icmppaketdistributor.h @@ -35,52 +35,59 @@ using boost::asio::ip::icmp; // for each IP protocol (v4/v6) and each network interface (string), -// there can only be one IcmpPaketDistributor instance +// there can only be one IcmpPacketDistributor instance typedef std::pair DistributorInstanceIdentifier; -struct IcmpPaketDistributorInstanceIdentifierComparator +struct IcmpPacketDistributorInstanceIdentifierComparator { bool operator() ( const DistributorInstanceIdentifier &a, const DistributorInstanceIdentifier &b ) const ; }; -class IcmpPaketDistributor; +class IcmpPacketDistributor; -typedef boost::shared_ptr IcmpPaketDistributorItem; -typedef std::map map_type; +typedef boost::shared_ptr IcmpPacketDistributorItem; +typedef std::map map_type; + +typedef boost::shared_ptr SocketItem; //----------------------------------------------------------------------------- -// IcmpPaketDistributor +// IcmpPacketDistributor //----------------------------------------------------------------------------- -class IcmpPaketDistributor +class IcmpPacketDistributor { public: - bool register_pinger( const PingerItem new_pinger ); - bool unregister_pinger( const PingerItem old_pinger ); + bool register_pinger( const IcmpPingerItem &new_pinger ); + bool unregister_pinger( const IcmpPingerItem &old_pinger ); + + SocketItem get_socket() const; - static IcmpPaketDistributorItem get_distributor( + static IcmpPacketDistributorItem get_distributor( const icmp::socket::protocol_type &protocol, const std::string &network_interface, - const IoServiceItem io_serv ); + const IoServiceItem io_serv + ); - static IcmpPaketDistributorItem get_distributor( + static IcmpPacketDistributorItem get_distributor( const icmp::socket::protocol_type &protocol, - const std::string &network_interface ); + const std::string &network_interface + ); static void clean_up_all(); - ~IcmpPaketDistributor(); + ~IcmpPacketDistributor(); private: - // hide away constructor, copy constructor and copy operator - IcmpPaketDistributor( + // hide away constructor, copy constructor and assignment operator + IcmpPacketDistributor( const icmp::socket::protocol_type &protocol, const std::string &network_interface, - const IoServiceItem io_serv ); - IcmpPaketDistributor(IcmpPaketDistributor const&); - void operator=(IcmpPaketDistributor const&); + const IoServiceItem io_serv + ); + IcmpPacketDistributor(IcmpPacketDistributor const&); + void operator=(IcmpPacketDistributor const&); void register_receive_handler(); void handle_receive( const boost::system::error_code &error, @@ -90,7 +97,7 @@ private: private: /// The socket object - icmp::socket Socket; + SocketItem Socket; /// Network layer protocol used to ping, IPv4 or IPv6 icmp::socket::protocol_type Protocol; @@ -98,7 +105,7 @@ private: /// The buffer where the data received will be placed boost::asio::streambuf ReplyBuffer; - std::set PingerList; + std::set PingerList; /// Instances, one for each (protocol, interface) - pair static map_type Instances; diff --git a/src/icmp/icmppinger.cpp b/src/icmp/icmppinger.cpp index 8a43eed..af2b8d7 100644 --- a/src/icmp/icmppinger.cpp +++ b/src/icmp/icmppinger.cpp @@ -7,9 +7,7 @@ #include "icmp/icmppinger.h" #include -#include -#include #include #include @@ -22,7 +20,6 @@ #include "boost_assert_handler.h" #include "icmp/icmppacketfactory.h" -#include "icmp/icmppaketdistributor.h" using namespace std; using boost::asio::const_buffers_1; @@ -39,8 +36,36 @@ using I2n::Logger::GlobalLogger; // IcmpPinger //----------------------------------------------------------------------------- -/// size of buffer used to read from socket in [bytes] -static const std::size_t SOCKET_BUFFER_SIZE = 65536; // 64kB +/** + * @brief factory function for IcmpPingers, ensures that set_myself is set + * + * @returns a shared pointer to a Pinger + */ +PingerItem IcmpPinger::create( + const IoServiceItem io_serv, + const icmp::socket::protocol_type &protocol, + const string &source_network_interface, + const int echo_reply_timeout_in_sec ) +{ + // get distributor + IcmpPacketDistributorItem distributor = IcmpPacketDistributor::get_distributor( + icmp::v4(), source_network_interface, io_serv); + + // create pinger + IcmpPinger *ptr = new IcmpPinger(io_serv, protocol, echo_reply_timeout_in_sec); + IcmpPingerItem shared_ptr_(ptr); + Pinger::WeakPtr weak_ptr( shared_ptr_ ); + + // keep weak pointer to self + //shared_ptr_->set_myself( weak_ptr ); //Error: Pinger::set_myself is protected + ptr->set_myself( weak_ptr ); + + // register in distributor + distributor->register_pinger(shared_ptr_); + + // done, return shared ptr + return shared_ptr_; +} /** * @brief Parameterized constructor. @@ -54,32 +79,19 @@ static const std::size_t SOCKET_BUFFER_SIZE = 65536; // 64kB IcmpPinger::IcmpPinger( const IoServiceItem io_serv, const icmp::socket::protocol_type &protocol, - const string &source_network_interface, const int echo_reply_timeout_in_sec ) : DestinationEndpoint(), Protocol( protocol ), - Socket( *io_serv, Protocol ), - NetInterface( source_network_interface, Socket ), IcmpPacketReceiveTimer( *io_serv ), Identifier( 0 ), SequenceNumber( 0 ), TimeSent( microsec_clock::universal_time() ), - ReplyBuffer(), ReplyReceived( false ), EchoReplyTimeoutInSec( echo_reply_timeout_in_sec ), PingerStatus( PingStatus_NotSent ), - PingDoneCallback(), - ReceiveHandlerInPlace( false ) + PingDoneCallback() { - if ( !NetInterface.bind() ) - { - GlobalLogger.error() - << DestinationEndpoint.address().to_string() - << ": could not bind the socket with the local interface. " - << ::strerror( errno ) << endl; - } - // Create "unique" identifier boost::uuids::random_generator random_gen; boost::uuids::uuid random_tag = random_gen(); @@ -119,19 +131,13 @@ void IcmpPinger::ping( set_destination_endpoint( destination_ip ); - if (start_send()) - start_receive(); - else - GlobalLogger.info() - << DestinationEndpoint.address().to_string() - << ": not scheduling receive since send failed." << endl; - // there might still be an old handler in place... cancel? + start_send(); } void IcmpPinger::stop_pinging() { - IcmpPaketDistributor::get_distributor(Protocol, NetInterface.get_name()) - ->unregister_pinger( get_myself().lock() ); + IcmpPingerItem icmp_item = boost::const_pointer_cast( get_myself().lock() ); + PacketDistributor->unregister_pinger( icmp_item ); } @@ -180,7 +186,7 @@ bool IcmpPinger::send_echo_request( const IcmpPacketItem icmp_packet ) << ": sending ping" << endl; const_buffers_1 data = request_buffer.data(); // Block until send the data - bytes_sent = Socket.send_to( data, DestinationEndpoint ); + bytes_sent = PacketDistributor->get_socket()->send_to( data, DestinationEndpoint ); if ( bytes_sent != buffer_size( data ) ) { GlobalLogger.error() @@ -250,168 +256,72 @@ void IcmpPinger::handle_timeout(const boost::system::error_code& error) PingDoneCallback( ping_success ); } -void IcmpPinger::start_receive() -{ - if ( ReceiveHandlerInPlace ) - { - GlobalLogger.info() - << DestinationEndpoint.address().to_string() - << ": Receive Handler in place, do not schedule another one" << endl; - return; - } - - // Waiting for a reply, We prepare the buffer to receive up to SOCKET_BUFFER_SIZE bytes - Socket.async_receive( - ReplyBuffer.prepare( SOCKET_BUFFER_SIZE ), - boost::bind( &IcmpPinger::handle_receive_icmp_packet, this, boost::asio::placeholders::error, - boost::asio::placeholders::bytes_transferred ) - ); - ReceiveHandlerInPlace = true; -} /** * @brief Receive ICMP packets - * Note: Will receive -all- ICMP packets from the kernel. So if the packet doesn't match - * our criteria, we have to schedule another start_receive() requests. The timeout stays the same. - * - * In the future we might redesign the code to handle all ICMP packets - * from a single raw socket. - * * @param bytes_transferred Number of bytes transferred. - * @return void + * @return true if packet matches a request from this pinger, false otherwise **/ -void IcmpPinger::handle_receive_icmp_packet( const boost::system::error_code &error, - const size_t &bytes_transferred ) +bool IcmpPinger::handle_receive_icmp_packet(const IcmpPacketItem icmp_packet, + const size_t bytes_transferred ) { - - ReceiveHandlerInPlace = false; - - if ( error ) - { - GlobalLogger.warning() - << DestinationEndpoint.address().to_string() - << ": Received error " << error - << " in ICMP packet handler; end handler and schedule another."; - start_receive(); - return; - } if ( ReplyReceived ) + // continue, might be an old packet + // or return false right away, do not want packet anyway... + return false; + + // We can receive all ICMP packets received by the host, so we need to + // filter out only the echo replies that match our identifier, + // expected sequence number, and destination host address (receive just + // the ICMP packets from the host we had ping). + + bool does_match = false; + if ( icmp_packet->match_echo_reply( + Identifier, SequenceNumber, + DestinationEndpoint.address() ) ) { GlobalLogger.info() - << DestinationEndpoint.address().to_string() - << ": Got another call to handler, probably due to earlier timeout. " - << "Ignore it." << endl; - return; - } - - // The actual number of bytes received is committed to the buffer so that we - // can extract it using a std::istream object. - ReplyBuffer.commit( bytes_transferred ); - - try - { - istream is( &ReplyBuffer ); - if ( !is ) - { - GlobalLogger.error() - << DestinationEndpoint.address().to_string() - << ": Can't handle ReplyBuffer" << endl; - return; - } - - // Decode the reply packet. - IcmpPacketItem icmp_packet = IcmpPacketFactory::create_icmp_packet( Protocol, is ); - if ( !icmp_packet ) - { - GlobalLogger.warning() - << DestinationEndpoint.address().to_string() - << ": Ignoring broken ICMP packet" << endl; - return; - } - - // We can receive all ICMP packets received by the host, so we need to - // filter out only the echo replies that match the our identifier, - // expected sequence number, and destination host address (receive just - // the ICMP packets from the host we had ping). - - if ( icmp_packet->match_echo_reply( - Identifier, SequenceNumber, - DestinationEndpoint.address() ) ) - { - GlobalLogger.info() - << DestinationEndpoint.address().to_string() - << ": Received reply" << endl; + << DestinationEndpoint.address().to_string() + << ": Received reply" << endl; - ReplyReceived = true; + ReplyReceived = true; + does_match = true; - icmp_packet->print_echo_reply( bytes_transferred, TimeSent ); + icmp_packet->print_echo_reply( bytes_transferred, TimeSent ); - set_ping_status( PingStatus_SuccessReply ); + set_ping_status( PingStatus_SuccessReply ); - IcmpPacketReceiveTimer.cancel(); //lint !e534 - } - else if ( icmp_packet->match_destination_unreachable( - Identifier, SequenceNumber, - DestinationEndpoint.address() ) ) - { - GlobalLogger.info() - << DestinationEndpoint.address().to_string() - << ": Received destination unreachable" << endl; + IcmpPacketReceiveTimer.cancel(); //lint !e534 + } + else if ( icmp_packet->match_destination_unreachable( + Identifier, SequenceNumber, + DestinationEndpoint.address() ) ) + { + GlobalLogger.info() + << DestinationEndpoint.address().to_string() + << ": Received destination unreachable" << endl; - ReplyReceived = true; + ReplyReceived = true; + does_match = true; - icmp_packet->print_destination_unreachable(); + icmp_packet->print_destination_unreachable(); - set_ping_status( PingStatus_FailureDestinationUnreachable ); + set_ping_status( PingStatus_FailureDestinationUnreachable ); - IcmpPacketReceiveTimer.cancel(); //lint !e534 - } - // Unknown ICMP reply, start another receive till timeout - else - { - GlobalLogger.info() - << DestinationEndpoint.address().to_string() - << ": Received packet that does not match" << endl; - start_receive(); - } + IcmpPacketReceiveTimer.cancel(); //lint !e534 } - catch ( ... ) + // Unknown ICMP reply, start another receive till timeout + else { - GlobalLogger.notice() + GlobalLogger.info() << DestinationEndpoint.address().to_string() - << ": exception during ICMP parse. " - << "Starting another receive till timeout." << endl; - start_receive(); + << ": Received packet that does not match" << endl; } + + return does_match; } void IcmpPinger::set_ping_status( PingStatus ping_status ) { PingerStatus = ping_status; } - - -PingerItem IcmpPinger::create( - const IoServiceItem io_serv, - const icmp::socket::protocol_type &protocol, - const string &source_network_interface, - const int echo_reply_timeout_in_sec ) -{ - // create pinger - IcmpPinger *ptr = new IcmpPinger(io_serv, protocol, source_network_interface, - echo_reply_timeout_in_sec); - PingerItem shared_ptr(ptr); - Pinger::WeakPtr weak_ptr( shared_ptr ); - - // keep weak pointer to self - ptr->set_myself( weak_ptr ); - // shared_ptr->set_myself( weak_ptr ); Error: Pinger::set_myself is protected - - // register in distributor - IcmpPaketDistributor::get_distributor(icmp::v4(), source_network_interface, io_serv) - ->register_pinger(shared_ptr); - - // done, return shared ptr - return shared_ptr; -} - diff --git a/src/icmp/icmppinger.h b/src/icmp/icmppinger.h index 1ad9b63..d9b0026 100644 --- a/src/icmp/icmppinger.h +++ b/src/icmp/icmppinger.h @@ -14,11 +14,15 @@ #include #include +#include -#include "host/networkinterface.hpp" #include "host/pinger.h" #include "host/pingstatus.h" #include "icmp/icmppacket.h" +#include "icmp/icmppaketdistributor.h" + +class IcmpPinger; +typedef boost::shared_ptr IcmpPingerItem; //----------------------------------------------------------------------------- // IcmpPinger @@ -52,7 +56,6 @@ private: IcmpPinger( const IoServiceItem io_serv, const boost::asio::ip::icmp::socket::protocol_type &protocol, - const std::string &source_network_interface, const int echo_reply_timeout_in_sec ); @@ -63,21 +66,19 @@ private: void schedule_timeout_echo_reply(); void handle_timeout(const boost::system::error_code &error); - void start_receive(); - void handle_receive_icmp_packet( const boost::system::error_code &error, - const std::size_t &bytes_transferred ); + bool handle_receive_icmp_packet(const IcmpPacketItem icmp_packet, + const size_t bytes_transferred + ); void set_ping_status( PingStatus ping_status ); private: + IcmpPacketDistributorItem PacketDistributor; + /// The destination host boost::asio::ip::icmp::endpoint DestinationEndpoint; /// Network layer protocol used to ping, IPv4 or IPv6 boost::asio::ip::icmp::socket::protocol_type Protocol; - /// The socket object - boost::asio::ip::icmp::socket Socket; - /// This object represents the network interface - NetworkInterface NetInterface; /// The timer of ICMP packet receive, triggers the timeout to avoid infinite /// wait boost::asio::deadline_timer IcmpPacketReceiveTimer; @@ -87,8 +88,6 @@ private: uint16_t SequenceNumber; /// The time when the last ICMP packet was sent boost::posix_time::ptime TimeSent; - /// The buffer where the data received will be placed - boost::asio::streambuf ReplyBuffer; /// Flag to indicate if we got a reply or not bool ReplyReceived; /// The amount of time to wait for the reply @@ -97,10 +96,6 @@ private: PingStatus PingerStatus; /// Callback to notify when the ping is done (got reply/timeout) boost::function< void(bool) > PingDoneCallback; - /// flag that have registered a handler, so do not accumulate handlers with timeouts - bool ReceiveHandlerInPlace; }; -typedef boost::shared_ptr IcmpPingerItem; - #endif // ICMP_PINGER_H diff --git a/src/main.cpp b/src/main.cpp index 3b69d10..6c5f4b1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -308,7 +308,7 @@ void stop_pingers( scheduler->stop_pinging(); } - IcmpPaketDistributor::clean_up_all(); + IcmpPacketDistributor::clean_up_all(); } -- 1.7.1