+++ /dev/null
-/*
- 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 <logfunc.hpp>
-
-#include <boost/bind.hpp>
-#include <boost/foreach.hpp>
-
-#include "boost_assert_handler.h"
-#include "dns/dnsmaster.h"
-#include "host/pingerfactory.h"
-
-using namespace std;
-using boost::function;
-using boost::shared_ptr;
-
-using I2n::Logger::GlobalLogger;
-
-//-----------------------------------------------------------------------------
-// PingRotate
-//-----------------------------------------------------------------------------
-
-/**
- * @brief Parameterized constructor.
- *
- * @param io_serv The one @c io_service object that controls async processing
- * @param network_interface The name of the network interface from where to
- * dispatch the pings.
- * @param destination_address The remote address to ping.
- * @param destination_port The remote port to ping.
- * @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 IoServiceItem io_serv,
- const string &network_interface,
- const string &destination_address,
- const uint16_t destination_port,
- const int resolved_ip_ttl_threshold,
- const int ping_reply_timeout,
- const PingProtocolList &protocol_list
-) :
- IoService( io_serv ),
- NetworkInterfaceName( network_interface ),
- Resolver(),
- DestinationAddress( destination_address ),
- DestinationPort( destination_port ),
- ResolvedIpTtlThreshold( resolved_ip_ttl_threshold ),
- PingReplyTimeout( ping_reply_timeout ),
- ProtocolRotate( protocol_list.size() ),
- Ping(),
- PingDoneCallback(),
- DnsResolutionFinished( true ),
- WantToPing( false )
-{
- BOOST_ASSERT( !network_interface.empty() );
- BOOST_ASSERT( !destination_address.empty() );
- BOOST_ASSERT( 0 < destination_port );
- BOOST_ASSERT( 0 < protocol_list.size() );
-
- // fill circular buffer with protocols
- BOOST_FOREACH( const PingProtocol &prot, protocol_list )
- ProtocolRotate.push_back(prot);
-
- init_ping_protocol();
-}
-
-/**
- * @brief Destructor.
- */
-PingRotate::~PingRotate()
-{
-}
-
-/**
- * @brief Ping a destination address from an available local source.
- *
- * @param done_handler Done handler will be called on successful ping or timeout.
- *
- * @return void.
- */
-void PingRotate::ping( function<void(bool)> ping_done_callback )
-{
- BOOST_ASSERT( ( 0 < DestinationPort ) && ( DestinationPort < numeric_limits<uint16_t>::max() ) );
-
- set_ping_done_callback( ping_done_callback );
-
- update_ping_protocol();
-
- WantToPing = true;
- try_to_ping();
-}
-
-void PingRotate::try_to_ping()
-{
- if ( !WantToPing )
- {
- GlobalLogger.info() << "PingRotate: not pinging yet (not requested to)";
- return;
- }
- else if ( !DnsResolutionFinished )
- {
- GlobalLogger.info() << "PingRotate: not pinging yet (DNS not finished)";
- return;
- }
-
- GlobalLogger.info() << "PingRotate: start ping";
- WantToPing = false;
- string destination_ip = Resolver->get_next_ip().get_ip().to_string();
- // TODO: pinger will probably re-create IP from this
- // --> change pingers to accept ip::address
-
- Ping->ping(
- destination_ip,
- DestinationPort,
- boost::bind(&PingRotate::ping_done_handler, this, _1)
- );
-}
-
-void PingRotate::stop_pinging()
-{
- Ping->stop_pinging();
-}
-
-void PingRotate::start_resolving_ping_address() //lint !e1762
-{
- DnsResolutionFinished = false;
- Resolver->async_resolve( boost::bind(&PingRotate::dns_resolve_callback,
- this, _1, _2) );
-}
-
-int PingRotate::get_resolved_ip_count() const
-{
- return Resolver->get_resolved_ip_count();
-}
-
-bool PingRotate::have_up_to_date_ip() const
-{
- return Resolver->have_up_to_date_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 ) const
-{
- PingDoneCallback( ping_success );
-}
-
-void PingRotate::init_ping_protocol()
-{
- get_next_ping_protocol();
-}
-
-void PingRotate::update_ping_protocol()
-{
- if ( can_change_ping_protocol() )
- {
- get_next_ping_protocol();
- }
-}
-
-void PingRotate::get_next_ping_protocol()
-{
- PingProtocol ping_protocol = ProtocolRotate.front();
- ProtocolRotate.pop_front();
- ProtocolRotate.push_back(ping_protocol);
-
- Ping = PingerFactory::createPinger( ping_protocol, IoService, NetworkInterfaceName, PingReplyTimeout );
-
- update_dns_resolver( ping_protocol );
-}
-
-bool PingRotate::can_change_ping_protocol() const
-{
- // TODO can_change_ping_protocol() and get_next_ping_protocol() may be implemented in a Algorithm
- // class that can be exchanged in this class to provide an algorithm neutral class
- return true;
-}
-
-void PingRotate::update_dns_resolver( PingProtocol current_protocol )
-{
- // DNS master caches created resolvers and resolved IPs, so this will
- // probably just return an existing resolver with already resolved IPs for
- // requested protocol ( ICMP/TCP is ignored, only IPv4/v6 is important)
- Resolver = DnsMaster::get_instance()->get_resolver_for(DestinationAddress,
- current_protocol);
- // start resolving if no ips available
- if ( !Resolver->have_up_to_date_ip() )
- start_resolving_ping_address();
-}
-
-void PingRotate::dns_resolve_callback(const bool was_success,
- const int recursion_count)
-{
- GlobalLogger.info() << "PingRotate: dns resolution finished "
- << "with success = " << was_success << " "
- << "and recursion_count = " << recursion_count;
- throw std::runtime_error("Only debugging DNS -- exit by error");
- if (DnsResolutionFinished)
- { // there were probably several calls to async_resolve before it could
- // finish --> ignore this callback
- GlobalLogger.info() << "PingRotate: dns resolve callback called "
- << "but dns is marked as finished already - ignore";
- return;
- }
- else
- {
- DnsResolutionFinished = true;
- try_to_ping();
- }
-}
+++ /dev/null
-/*
- 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 PING_ROTATE_H
-#define PING_ROTATE_H
-
-#include <stdint.h>
-
-#include <string>
-
-#include <boost/asio.hpp>
-#include <boost/function.hpp>
-#include <boost/shared_ptr.hpp>
-#include <boost/circular_buffer.hpp>
-
-#include "dns/resolverbase.h"
-#include "host/pinger.h"
-#include "host/pingprotocol.h"
-
-//-----------------------------------------------------------------------------
-// PingRotate
-//-----------------------------------------------------------------------------
-
-typedef boost::circular_buffer<PingProtocol> CircularProtocolList;
-
-/**
- * @brief This class is a wrapper to the Pingers, and serves to alternate
- * between protocols.
- * Scope: one object per host.
- */
-class PingRotate
-{
-public:
- PingRotate(
- const IoServiceItem io_serv,
- const std::string &network_interface,
- const std::string &destination_address,
- const uint16_t destination_port,
- const int resolved_ip_ttl_threshold,
- const int ping_reply_timeout,
- const PingProtocolList &protocol_list
- );
- virtual ~PingRotate();
-
- void ping( boost::function<void(bool)> ping_done_callback );
-
- void stop_pinging();
-
- void start_resolving_ping_address();
- int get_resolved_ip_count() const;
- bool have_up_to_date_ip() const;
-
-private:
- //
- // Methods
- //
-
- void set_ping_done_callback( boost::function<void(bool)> ping_done_callback );
- void ping_done_handler( bool ping_success ) const;
-
- void init_ping_protocol();
- void update_ping_protocol();
- void get_next_ping_protocol();
- bool can_change_ping_protocol() const;
-
- void update_dns_resolver( PingProtocol current_protocol );
-
- void try_to_ping();
- void dns_resolve_callback(const bool was_success, const int cname_count);
-
- //
- // Attributes
- //
-
- /// The IO service object, which has the loop event
- IoServiceItem IoService;
- /// The network interface name
- std::string NetworkInterfaceName;
- /// The Dns resolver
- ResolverItem Resolver;
- /// The address to ping
- std::string DestinationAddress;
- /// The port to ping at destination host (same port to all protocols in the list)
- uint16_t DestinationPort;
- /// time threshold for address resolution
- int ResolvedIpTtlThreshold;
- /// timeout for ping reply
- const int PingReplyTimeout;
- /// The list of protocols to ping
- CircularProtocolList ProtocolRotate;
- /// Internal boost pinger object
- PingerItem Ping;
- /// The callback function
- boost::function<void(bool)> PingDoneCallback;
- /// a flag whether DNS resolution is finished or currently underway
- bool DnsResolutionFinished;
- /// a flag whether we should ping as soon as dns is ready
- bool WantToPing;
-};
-
-//-----------------------------------------------------------------------------
-// PingRotateItem
-//-----------------------------------------------------------------------------
-
-typedef boost::shared_ptr<PingRotate> PingRotateItem;
-
-#endif // PING_ROTATE_H