From 0b72647e44e5e30860eb6fd6052b28de772df580 Mon Sep 17 00:00:00 2001 From: Guilherme Maciel Ferreira Date: Sat, 25 Feb 2012 14:15:26 -0200 Subject: [PATCH] Added a new class to exchange protocols. - It simply hides the Pingers objects from the scheduler, changing the protocols at will. This process is transparent to the PingScheduler. --- src/CMakeLists.txt | 1 + src/host/pingrotate.cpp | 121 +++++++++++++++++++++++++++++++++++++++++++++++ src/host/pingrotate.h | 84 ++++++++++++++++++++++++++++++++ 3 files changed, 206 insertions(+), 0 deletions(-) create mode 100644 src/host/pingrotate.cpp create mode 100644 src/host/pingrotate.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4f678e8..befa52e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -66,6 +66,7 @@ set(SOURCES host/pingerfactory.cpp host/pinginterval.cpp host/pingprotocol.cpp + host/pingrotate.cpp host/pingscheduler.cpp icmp/icmpdestinationunreachablemessage.cpp icmp/icmpechoreplymessage.cpp diff --git a/src/host/pingrotate.cpp b/src/host/pingrotate.cpp new file mode 100644 index 0000000..c22fbd3 --- /dev/null +++ b/src/host/pingrotate.cpp @@ -0,0 +1,121 @@ +/* + The software in this package is distributed under the GNU General + Public License version 2 (with a special exception described below). + + A copy of GNU General Public License (GPL) is included in this distribution, + in the file COPYING.GPL. + + As a special exception, if other files instantiate templates or use macros + or inline functions from this file, or you compile this file and link it + with other works to produce a work based on this file, this file + does not by itself cause the resulting work to be covered + by the GNU General Public License. + + However the source code for this file must still be made available + in accordance with section (3) of the GNU General Public License. + + This exception does not invalidate any other reasons why a work based + on this file might be covered by the GNU General Public License. + */ + +#include "host/pingrotate.h" + +#include +#include + +#include "host/pingerfactory.h" + +using namespace std; +using boost::asio::io_service; +using boost::function; + +//----------------------------------------------------------------------------- +// PingRotate +//----------------------------------------------------------------------------- + +/** + * @brief Parameterized constructor. + * + * @param io_serv The @c io_service object. + * @param network_interface The name of the network interface from where to + * dispatch the pings. + * @param protocol_rotation_list A list of protocols to be used to ping the + * host. The protocols will be used in the order they are in the list. + */ +PingRotate::PingRotate( + io_service &io_serv, + const string &network_interface, + PingProtocolList protocol_rotation_list +) : + IoService( io_serv ), + NetworkInterfaceName( network_interface ), + ProtocolList( protocol_rotation_list ), + Ping(), + PingDoneCallback() +{ + BOOST_ASSERT( !network_interface.empty() ); + BOOST_ASSERT( 0 < protocol_rotation_list.size() ); + + get_next_ping_protocol(); +} + +/** + * @brief Destructor. + */ +PingRotate::~PingRotate() +{ +} + +/** + * @brief Ping a destination address from an available local source. + * + * @param destination_ip The address of the host to ping. + * @param destination_port The port at the destination host to ping. + * @param done_handler Done handler will be called on successful ping or timeout. + * + * @return void. + */ +void PingRotate::ping( + const string &destination_ip, + const uint16_t destination_port, + function ping_done_callback +) +{ + BOOST_ASSERT( !destination_ip.empty() ); + + PingDoneCallback = ping_done_callback; + + Ping->ping( + destination_ip, + destination_port, + boost::bind(&PingRotate::ping_done_handler, this, _1) + ); +} + +void PingRotate::ping_done_handler( bool ping_success ) +{ + PingDoneCallback( ping_success ); + + if ( can_change_ping_protocol() ) + { + get_next_ping_protocol(); + } +} + +void PingRotate::get_next_ping_protocol() +{ + if ( 1 <= ProtocolList.size() ) + { + PingProtocol ping_protocol = ProtocolList.front(); + + ProtocolList.pop_front(); + ProtocolList.push_back( ping_protocol ); + + Ping = PingerFactory::createPinger( ping_protocol, IoService, NetworkInterfaceName ); + } +} + +bool PingRotate::can_change_ping_protocol() const +{ + return true; +} diff --git a/src/host/pingrotate.h b/src/host/pingrotate.h new file mode 100644 index 0000000..b862417 --- /dev/null +++ b/src/host/pingrotate.h @@ -0,0 +1,84 @@ +/* + The software in this package is distributed under the GNU General + Public License version 2 (with a special exception described below). + + A copy of GNU General Public License (GPL) is included in this distribution, + in the file COPYING.GPL. + + As a special exception, if other files instantiate templates or use macros + or inline functions from this file, or you compile this file and link it + with other works to produce a work based on this file, this file + does not by itself cause the resulting work to be covered + by the GNU General Public License. + + However the source code for this file must still be made available + in accordance with section (3) of the GNU General Public License. + + This exception does not invalidate any other reasons why a work based + on this file might be covered by the GNU General Public License. + */ + +#ifndef PIN_GROTATE_H +#define PIN_GROTATE_H + +#include + +#include + +#include +#include + +#include "host/pinger.h" +#include "host/pingprotocol.h" + +//----------------------------------------------------------------------------- +// PingRotate +//----------------------------------------------------------------------------- + +/** + * @brief This class is a wrapper to the Pingers, and serves to alternate + * between protocols. + * Scope: one object per host. + */ +class PingRotate : public Pinger +{ +public: + PingRotate( + boost::asio::io_service &io_serv, + const std::string &network_interface, + PingProtocolList protocol_rotation_list + ); + virtual ~PingRotate(); + + virtual void ping( + const std::string &destination_ip, + const uint16_t destination_port, + boost::function ping_done_callback + ); + +private: + // + // Methods + // + + void ping_done_handler( bool ping_success ); + void get_next_ping_protocol(); + bool can_change_ping_protocol() const; + + // + // Attributes + // + + /// The IO service object, which has the loop event + boost::asio::io_service &IoService; + /// The network interface name + std::string NetworkInterfaceName; + /// The list of protocols to ping + PingProtocolList ProtocolList; + /// Internal boost pinger object + PingerItem Ping; + /// The callback function + boost::function PingDoneCallback; +}; + +#endif // PING_ROTATE_H -- 1.7.1