Added a new class to exchange protocols.
authorGuilherme Maciel Ferreira <guilherme.maciel.ferreira@gmail.com>
Sat, 25 Feb 2012 16:15:26 +0000 (14:15 -0200)
committerGuilherme Maciel Ferreira <guilherme.maciel.ferreira@gmail.com>
Sat, 25 Feb 2012 16:15:26 +0000 (14:15 -0200)
- It simply hides the Pingers objects from the scheduler, changing the protocols at
  will. This process is transparent to the PingScheduler.

src/CMakeLists.txt
src/host/pingrotate.cpp [new file with mode: 0644]
src/host/pingrotate.h [new file with mode: 0644]

index 4f678e8..befa52e 100644 (file)
@@ -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 (file)
index 0000000..c22fbd3
--- /dev/null
@@ -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 <boost/assert.hpp>
+#include <boost/bind.hpp>
+
+#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<void(bool)> 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 (file)
index 0000000..b862417
--- /dev/null
@@ -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 <stdint.h>
+
+#include <string>
+
+#include <boost/asio.hpp>
+#include <boost/function.hpp>
+
+#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<void(bool)> 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<void(bool)> PingDoneCallback;
+};
+
+#endif // PING_ROTATE_H