#include <boost/asio/ip/tcp_raw_protocol.hpp>
#include <boost/system/system_error.hpp>
-#include "host/pingrotate.h"
#include "icmp/icmppinger.h"
#include "tcp/tcppinger.h"
* @param io_serv The @c io_service object.
* @param network_interface The network interface name from where the ping
* packet will be sent.
+ * @param destination_address The remote address to ping.
+ * @param destination_port The remote port to ping.
+ * @param nameserver Server to resolve the addresses.
+ *
* @return a Pinger object to able to ping using the given list of protocols.
*/
-PingerItem PingerFactory::createPinger(
+PingRotateItem PingerFactory::createPinger(
const PingProtocolList &protocol_list,
const shared_ptr<io_service> io_serv,
- const string &network_interface
+ const string &network_interface,
+ const string &destination_address,
+ const uint16_t destination_port,
+ const string &nameserver
)
{
BOOST_ASSERT( 0 < protocol_list.size() );
BOOST_ASSERT( !network_interface.empty() );
-
- return PingerItem(
- new PingRotate( io_serv, network_interface, protocol_list )
- );
+ BOOST_ASSERT( !destination_address.empty() );
+ BOOST_ASSERT( 0 < destination_port );
+ BOOST_ASSERT( !nameserver.empty() );
+
+ return PingRotateItem( new PingRotate(
+ io_serv,
+ network_interface,
+ destination_address,
+ destination_port,
+ nameserver,
+ protocol_list
+ ) );
}
#include "host/pinger.h"
#include "host/pingprotocol.h"
+#include "host/pingrotate.h"
//-----------------------------------------------------------------------------
// PingerFactory
const std::string &network_interface
);
- static PingerItem createPinger(
+ static PingRotateItem createPinger(
const PingProtocolList &protocol_list,
const boost::shared_ptr<boost::asio::io_service> io_serv,
- const std::string &network_interface
+ const std::string &network_interface,
+ const std::string &destination_address,
+ const uint16_t destination_port,
+ const std::string &nameserver
);
private:
* @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
+ * @param destination_address The remote address to ping.
+ * @param destination_port The remote port to ping.
+ * @param nameserver Server to resolve the addresses.
+ * @param protocol_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(
const shared_ptr<io_service> io_serv,
const string &network_interface,
- PingProtocolList protocol_rotation_list
+ const string &destination_address,
+ const uint16_t destination_port,
+ const string &nameserver,
+ const PingProtocolList protocol_list
) :
IoService( io_serv ),
NetworkInterfaceName( network_interface ),
- ProtocolList( protocol_rotation_list ),
+ IpList( destination_address, nameserver ),
+ DestinationPort( destination_port ),
+ ProtocolList( protocol_list ),
Ping(),
PingDoneCallback()
{
BOOST_ASSERT( !network_interface.empty() );
- BOOST_ASSERT( 0 < protocol_rotation_list.size() );
-
- get_next_ping_protocol();
+ BOOST_ASSERT( !destination_address.empty() );
+ BOOST_ASSERT( 0 < destination_port );
+ BOOST_ASSERT( !nameserver.empty() );
+ BOOST_ASSERT( 0 < protocol_list.size() );
}
/**
/**
* @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
-)
+void PingRotate::ping( function<void(bool)> ping_done_callback )
{
- BOOST_ASSERT( !destination_ip.empty() );
+ BOOST_ASSERT( ( 0 < DestinationPort ) && ( DestinationPort < numeric_limits<uint16_t>::max() ) );
- PingDoneCallback = ping_done_callback;
+ set_ping_done_callback( ping_done_callback );
+
+ string destination_ip = IpList.get_next_ip();
+
+ update_ping_protocol();
Ping->ping(
destination_ip,
- destination_port,
+ DestinationPort,
boost::bind(&PingRotate::ping_done_handler, this, _1)
);
}
+bool PingRotate::resolve_ping_address()
+{
+ return IpList.resolve();
+}
+
+int PingRotate::get_resolved_ip_count() const
+{
+ return IpList.get_resolved_ip_count();
+}
+
+bool PingRotate::expired_resolved_ip() const
+{
+ return IpList.expired_resolved_ip();
+}
+
+void PingRotate::set_ping_done_callback( function<void(bool)> ping_done_callback )
+{
+ PingDoneCallback = ping_done_callback;
+}
+
void PingRotate::ping_done_handler( bool ping_success )
{
PingDoneCallback( ping_success );
-
- update_ping_protocol();
}
void PingRotate::update_ping_protocol()
#include <boost/function.hpp>
#include <boost/shared_ptr.hpp>
+#include "dns/dnsresolver.h"
#include "host/pinger.h"
#include "host/pingprotocol.h"
* between protocols.
* Scope: one object per host.
*/
-class PingRotate : public Pinger
+class PingRotate
{
public:
PingRotate(
const boost::shared_ptr<boost::asio::io_service> io_serv,
const std::string &network_interface,
- PingProtocolList protocol_rotation_list
+ const std::string &destination_address,
+ const uint16_t destination_port,
+ const std::string &nameserver,
+ const PingProtocolList protocol_list
);
virtual ~PingRotate();
- virtual void ping(
- const std::string &destination_ip,
- const uint16_t destination_port,
- boost::function<void(bool)> ping_done_callback
- );
+ void ping( boost::function<void(bool)> ping_done_callback );
+
+ bool resolve_ping_address();
+ int get_resolved_ip_count() const;
+ bool expired_resolved_ip() const;
private:
//
// Methods
//
+ void set_ping_done_callback( boost::function<void(bool)> ping_done_callback );
void ping_done_handler( bool ping_success );
+
void update_ping_protocol();
void get_next_ping_protocol();
bool can_change_ping_protocol() const;
boost::shared_ptr<boost::asio::io_service> IoService;
/// The network interface name
std::string NetworkInterfaceName;
+ /// The list of IPs which are aliases to the host DNS
+ DnsResolver IpList;
+ /// The port to ping at destination host (same port to all protocols in the list)
+ uint16_t DestinationPort;
/// The list of protocols to ping
PingProtocolList ProtocolList;
/// Internal boost pinger object
boost::function<void(bool)> PingDoneCallback;
};
+//-----------------------------------------------------------------------------
+// PingRotateItem
+//-----------------------------------------------------------------------------
+
+typedef boost::shared_ptr<PingRotate> PingRotateItem;
+
#endif // PING_ROTATE_H
NextPingTimer( IoService ),
TimeSentLastPing( microsec_clock::universal_time() ),
PingIntervalInSec( ping_interval_in_sec ),
- IpList( destination_address, nameserver ),
- DestinationPort( destination_port ),
HostAnalyzer( destination_address, ping_fail_percentage_limit, link_analyzer ),
Ping(),
Thread()
shared_ptr<io_service> io_serv( &IoService );
- Ping = PingerFactory::createPinger( ping_protocol_list, io_serv, network_interface );
+ Ping = PingerFactory::createPinger(
+ ping_protocol_list,
+ io_serv,
+ network_interface,
+ destination_address,
+ destination_port,
+ nameserver
+ );
}
/**
IoService.stop();
}
+void PingScheduler::update_ping_address()
+{
+ // TODO this code is similar to the one at start_pinging(), make it simple!
+ if ( Ping->expired_resolved_ip() )
+ {
+ GlobalLogger.info() << "Updating DNS ... ";
+ bool address_resolved = resolve_ping_address();
+ if ( !address_resolved )
+ {
+ GlobalLogger.error() << "Error: could not update host IP, may use outdated address"
+ << endl;
+ }
+ }
+}
+
bool PingScheduler::resolve_ping_address()
{
- bool address_resolved = IpList.resolve();
+ bool address_resolved = Ping->resolve_ping_address();
if ( !address_resolved )
{
return false;
}
- int resolved_ip_count = IpList.get_resolved_ip_count();
+ int resolved_ip_count = Ping->get_resolved_ip_count();
HostAnalyzer.set_resolved_ip_count( resolved_ip_count );
return true;
}
-void PingScheduler::ping(
- const string &destination_ip,
- const uint16_t destination_port
-)
+void PingScheduler::ping()
{
- BOOST_ASSERT( !destination_ip.empty() );
- BOOST_ASSERT( ( 0 < destination_port ) && ( destination_port < numeric_limits<uint16_t>::max() ) );
-
- Ping->ping(
- destination_ip,
- destination_port,
- boost::bind(&PingScheduler::ping_done_handler, this, _1)
- );
+ Ping->ping( boost::bind(&PingScheduler::ping_done_handler, this, _1) );
}
void PingScheduler::setup_next_ping()
{
- BOOST_ASSERT( 1 <= IpList.get_resolved_ip_count() );
-
- // TODO this code is similar to the one at start_pinging(), make it simple!
- if ( IpList.expired_resolved_ip() )
- {
- GlobalLogger.info() << "Updating DNS ... ";
- bool address_resolved = resolve_ping_address();
- if ( !address_resolved )
- {
- GlobalLogger.error() << "Error: could not update host IP, may use outdated address"
- << endl;
- }
- }
+ BOOST_ASSERT( 1 <= Ping->get_resolved_ip_count() );
- string destination_ip = IpList.get_next_ip();
+ update_ping_address();
- ping( destination_ip, DestinationPort );
+ ping();
}
void PingScheduler::ping_done_handler( bool ping_success )
#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
-#include "dns/dnsresolver.h"
#include "link/linkstatus.h"
#include "host/hoststatus.h"
#include "host/pinger.h"
#include "host/pinginterval.h"
#include "host/pingprotocol.h"
+#include "host/pingrotate.h"
//-----------------------------------------------------------------------------
// PingScheduler
bool start_pinging();
void stop_pinging();
+ void update_ping_address();
bool resolve_ping_address();
- void ping(
- const std::string &destination_ip,
- const uint16_t destination_port
- );
+
+ void ping();
void ping_done_handler(bool ping_success);
void setup_next_ping();
boost::posix_time::ptime TimeSentLastPing;
/// Interval between each ping to the same host
PingInterval PingIntervalInSec;
- /// The list of IPs which are aliases to the host DNS
- DnsResolver IpList;
- /// The port to ping at destination host
- uint16_t DestinationPort;
/// Object responsible to evaluate the status of the host
HostStatus HostAnalyzer;
/// Internal boost pinger object
- PingerItem Ping;
+ PingRotateItem Ping;
/// Thread object
boost::thread Thread;