From 9490a7bd6e35c74dea82e3d200ff1566b84bfa5c Mon Sep 17 00:00:00 2001 From: Christian Herdtweck Date: Fri, 10 Apr 2015 14:22:03 +0200 Subject: [PATCH] adjusted rest of pingchecker to use new dns in very trivial fasion; compiles but need to re-design async calls in scheduler --- doc/pingcheck_icmp_distributor.graphml | 14 ++---- src/CMakeLists.txt | 8 ++-- src/dns_neww/resolverbase.cpp | 1 - src/host/pingerfactory.cpp | 4 -- src/host/pingerfactory.h | 1 - src/host/pingrotate.cpp | 83 +++++++++++++++++++++++++------- src/host/pingrotate.h | 20 +++++--- src/host/pingscheduler.cpp | 11 +---- src/host/pingscheduler.h | 3 - src/main.cpp | 18 +++++-- 10 files changed, 100 insertions(+), 63 deletions(-) diff --git a/doc/pingcheck_icmp_distributor.graphml b/doc/pingcheck_icmp_distributor.graphml index 6652dcc..d6248fc 100644 --- a/doc/pingcheck_icmp_distributor.graphml +++ b/doc/pingcheck_icmp_distributor.graphml @@ -1579,10 +1579,10 @@ PingIntervalInSec - + - expired_resolved_ip + have_up_to_date_ip @@ -1614,10 +1614,10 @@ PingIntervalInSec - + - expired_resolved_ip + have_up_to_date_ip @@ -1646,7 +1646,6 @@ PingIntervalInSec - @@ -1734,7 +1733,6 @@ PingIntervalInSec - @@ -1752,7 +1750,6 @@ PingIntervalInSec - @@ -3149,7 +3146,6 @@ shared_ptrs - @@ -3198,7 +3194,6 @@ shared_ptrs - @@ -3209,7 +3204,6 @@ shared_ptrs - diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b7e366d..0289bdb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -62,14 +62,14 @@ set(SOURCES config/option/maxaddressresolutionattemptsoption.cpp config/option/resolvedipttlthresholdoption.cpp config/option/dnscachefileoption.cpp + #dns/dnsresolver.cpp + #dns/dnsresolverfactory.cpp + dns/hostaddress.cpp + dns/timetolive.cpp dns_neww/dnscache.cpp dns_neww/resolverbase.cpp dns_neww/dnsresolver.cpp dns_neww/dnsmaster.cpp - dns/dnsresolver.cpp - dns/dnsresolverfactory.cpp - dns/hostaddress.cpp - dns/timetolive.cpp host/hoststatus.cpp host/loglevel.cpp host/logoutput.cpp diff --git a/src/dns_neww/resolverbase.cpp b/src/dns_neww/resolverbase.cpp index 2dccf4e..2587e63 100644 --- a/src/dns_neww/resolverbase.cpp +++ b/src/dns_neww/resolverbase.cpp @@ -27,7 +27,6 @@ ResolverBase::~ResolverBase() { - DnsMaster::get_instance()->unregister_resolver(Hostname); } /** diff --git a/src/host/pingerfactory.cpp b/src/host/pingerfactory.cpp index e14ff5c..085ef6f 100644 --- a/src/host/pingerfactory.cpp +++ b/src/host/pingerfactory.cpp @@ -133,7 +133,6 @@ PingerItem PingerFactory::createPinger( * 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. */ @@ -143,7 +142,6 @@ PingRotateItem PingerFactory::createPinger( const string &network_interface, const string &destination_address, const uint16_t destination_port, - const string &nameserver, const int resolved_ip_ttl_threshold, const int ping_reply_timeout ) @@ -152,14 +150,12 @@ PingRotateItem PingerFactory::createPinger( BOOST_ASSERT( !network_interface.empty() ); 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, resolved_ip_ttl_threshold, ping_reply_timeout, protocol_list diff --git a/src/host/pingerfactory.h b/src/host/pingerfactory.h index 118ec24..b735ecf 100644 --- a/src/host/pingerfactory.h +++ b/src/host/pingerfactory.h @@ -50,7 +50,6 @@ public: const std::string &network_interface, const std::string &destination_address, const uint16_t destination_port, - const std::string &nameserver, const int resolved_ip_ttl_threshold, const int ping_reply_timeout ); diff --git a/src/host/pingrotate.cpp b/src/host/pingrotate.cpp index 5f41ba0..018e812 100644 --- a/src/host/pingrotate.cpp +++ b/src/host/pingrotate.cpp @@ -20,17 +20,21 @@ #include "host/pingrotate.h" +#include + #include #include #include "boost_assert_handler.h" -#include "dns/dnsresolverfactory.h" +#include "dns_neww/dnsmaster.h" #include "host/pingerfactory.h" using namespace std; using boost::function; using boost::shared_ptr; +using I2n::Logger::GlobalLogger; + //----------------------------------------------------------------------------- // PingRotate //----------------------------------------------------------------------------- @@ -43,7 +47,6 @@ using boost::shared_ptr; * dispatch the pings. * @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. */ @@ -52,27 +55,26 @@ PingRotate::PingRotate( const string &network_interface, const string &destination_address, const uint16_t destination_port, - const string &nameserver, const int resolved_ip_ttl_threshold, const int ping_reply_timeout, const PingProtocolList &protocol_list ) : IoService( io_serv ), NetworkInterfaceName( network_interface ), - IpList(), - DestinationAddess( destination_address ), + Resolver(), + DestinationAddress( destination_address ), DestinationPort( destination_port ), - Nameserver( nameserver ), ResolvedIpTtlThreshold( resolved_ip_ttl_threshold ), PingReplyTimeout( ping_reply_timeout ), ProtocolRotate( protocol_list.size() ), Ping(), - PingDoneCallback() + PingDoneCallback(), + DnsResolutionFinished( true ), + WantToPing( false ) { BOOST_ASSERT( !network_interface.empty() ); BOOST_ASSERT( !destination_address.empty() ); BOOST_ASSERT( 0 < destination_port ); - BOOST_ASSERT( !nameserver.empty() ); BOOST_ASSERT( 0 < protocol_list.size() ); // fill circular buffer with protocols @@ -104,7 +106,28 @@ void PingRotate::ping( function ping_done_callback ) update_ping_protocol(); - string destination_ip = IpList->get_next_ip(); + 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, @@ -118,19 +141,21 @@ void PingRotate::stop_pinging() Ping->stop_pinging(); } -bool PingRotate::resolve_ping_address() //lint !e1762 +void PingRotate::start_resolving_ping_address() //lint !e1762 { - return IpList->resolve(); + DnsResolutionFinished = false; + Resolver->async_resolve( boost::bind(&PingRotate::dns_resolve_callback, + this, _1, _2) ); } int PingRotate::get_resolved_ip_count() const { - return IpList->get_resolved_ip_count(); + return Resolver->get_resolved_ip_count(); } bool PingRotate::have_up_to_date_ip() const { - return IpList->have_up_to_date_ip(); + return Resolver->have_up_to_date_ip(); } void PingRotate::set_ping_done_callback( function ping_done_callback ) @@ -176,10 +201,32 @@ bool PingRotate::can_change_ping_protocol() const void PingRotate::update_dns_resolver( PingProtocol current_protocol ) { - IpList = DnsResolverFactory::createResolver( DestinationAddess, Nameserver, ResolvedIpTtlThreshold, 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(); +} - // when the protocol change, there is a chance that the IP version required by the new - // protocol differ from the previous one, thus it is required to resolve the address again. - // FIXME add some intelligence here to decide if the new protocol requires to update the DNS - resolve_ping_address(); //lint !e534 +void PingRotate::dns_resolve_callback(const bool was_success, + const int cname_count) +{ + GlobalLogger.info() << "PingRotate: dns resolution finished " + << "with success = " << was_success << " " + << "and cname_count = " << cname_count; + 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(); + } } diff --git a/src/host/pingrotate.h b/src/host/pingrotate.h index db298b0..d70b653 100644 --- a/src/host/pingrotate.h +++ b/src/host/pingrotate.h @@ -30,7 +30,7 @@ #include #include -#include "dns/dnsresolver.h" +#include "dns_neww/resolverbase.h" #include "host/pinger.h" #include "host/pingprotocol.h" @@ -53,7 +53,6 @@ public: const std::string &network_interface, const std::string &destination_address, const uint16_t destination_port, - const std::string &nameserver, const int resolved_ip_ttl_threshold, const int ping_reply_timeout, const PingProtocolList &protocol_list @@ -64,7 +63,7 @@ public: void stop_pinging(); - bool resolve_ping_address(); + void start_resolving_ping_address(); int get_resolved_ip_count() const; bool have_up_to_date_ip() const; @@ -83,6 +82,9 @@ private: void update_dns_resolver( PingProtocol current_protocol ); + void try_to_ping(); + void dns_resolve_callback(const bool was_success, const int cname_count); + // // Attributes // @@ -91,14 +93,12 @@ private: IoServiceItem IoService; /// The network interface name std::string NetworkInterfaceName; - /// The list of IPs which are aliases to the host DNS - DnsResolverItem IpList; + /// The Dns resolver + ResolverItem Resolver; /// The address to ping - std::string DestinationAddess; + std::string DestinationAddress; /// The port to ping at destination host (same port to all protocols in the list) uint16_t DestinationPort; - /// Server to resolve the addresses - std::string Nameserver; /// time threshold for address resolution int ResolvedIpTtlThreshold; /// timeout for ping reply @@ -109,6 +109,10 @@ private: PingerItem Ping; /// The callback function boost::function 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; }; //----------------------------------------------------------------------------- diff --git a/src/host/pingscheduler.cpp b/src/host/pingscheduler.cpp index a4042ff..ed82e8a 100644 --- a/src/host/pingscheduler.cpp +++ b/src/host/pingscheduler.cpp @@ -27,7 +27,6 @@ on this file might be covered by the GNU General Public License. #include #include "boost_assert_handler.h" -#include "dns/dnsresolver.h" #include "host/pingerfactory.h" #include "icmp/icmppinger.h" #include "link/linkstatus.h" @@ -56,7 +55,6 @@ using I2n::Logger::GlobalLogger; * @param ping_protocol_list A list of protocols to use. * @param ping_interval_in_sec Amount of time between each ping. * @param ping_fail_percentage_limit Maximum amount of pings that can fail. - * @param nameserver Server to resolve the addresses. * @param link_analyzer The object to monitor the link status. * @param first_delay Delay in seconds from start_pinging to first ping attempt */ @@ -68,8 +66,6 @@ PingScheduler::PingScheduler( const PingProtocolList &ping_protocol_list, const long ping_interval_in_sec, const int ping_fail_percentage_limit, - const string &nameserver, - const int max_address_resolution_attempts, const int ping_reply_timeout, const int resolved_ip_ttl_threshold, LinkStatusItem link_analyzer, @@ -84,7 +80,6 @@ PingScheduler::PingScheduler( HostAnalyzer( destination_address, ping_fail_percentage_limit, link_analyzer ), FirstDelay( first_delay ), AddressResolutionAttempts( 0 ), - MaxAddressResolutionAttempts( max_address_resolution_attempts ), EverHadAnyIP( false ), Ping() { @@ -93,7 +88,6 @@ PingScheduler::PingScheduler( BOOST_ASSERT( 0 < destination_port ); BOOST_ASSERT( 0 < ping_interval_in_sec ); BOOST_ASSERT( (0 <= ping_fail_percentage_limit) && (ping_fail_percentage_limit <= 100) ); - BOOST_ASSERT( !nameserver.empty() ); Ping = PingerFactory::createPinger( ping_protocol_list, @@ -101,7 +95,6 @@ PingScheduler::PingScheduler( network_interface, destination_address, destination_port, - nameserver, resolved_ip_ttl_threshold, ping_reply_timeout ); @@ -169,7 +162,7 @@ void PingScheduler::resolve_and_ping(const boost::system::error_code &error) // determine if address resolution is required if ( !ips_up_to_date ) { - ips_up_to_date = Ping->resolve_ping_address(); // try to resolve + Ping->start_resolving_ping_address(); // try to resolve if ( ips_up_to_date ) { EverHadAnyIP = true; @@ -189,7 +182,7 @@ void PingScheduler::resolve_and_ping(const boost::system::error_code &error) else { // no IPs --> try again later, possibly report offline before AddressResolutionAttempts++; - if (AddressResolutionAttempts >= MaxAddressResolutionAttempts) + if (AddressResolutionAttempts >= 10) //MaxAddressResolutionAttempts) { GlobalLogger.notice() << "No IPs after " << AddressResolutionAttempts << " DNS queries!"; HostAnalyzer.report_dns_resolution_failure(); diff --git a/src/host/pingscheduler.h b/src/host/pingscheduler.h index 0dc8761..75598b9 100644 --- a/src/host/pingscheduler.h +++ b/src/host/pingscheduler.h @@ -55,8 +55,6 @@ public: const PingProtocolList &ping_protocol_list, const long ping_interval_in_sec, const int ping_fail_percentage_limit, - const std::string &nameserver, - const int max_address_resolution_attempts, const int ping_reply_timeout, const int resolved_ip_ttl_threshold, LinkStatusItem link_analyzer, @@ -99,7 +97,6 @@ private: int FirstDelay; /// number of attempts at Address Resolution int AddressResolutionAttempts; - int MaxAddressResolutionAttempts; /// flag whether any DNS lookup succeeded // (comparing get_ip_count to 0 might violate assertion in dnsresolver.cpp) bool EverHadAnyIP; diff --git a/src/main.cpp b/src/main.cpp index 8385b44..0dbfaec 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -38,10 +38,10 @@ on this file might be covered by the GNU General Public License. #include "config/host.h" #include "link/linkstatus.h" #include "host/loglevel.h" -#include "host/pingerfactory.h" #include "host/pingprotocol.h" #include "host/pingscheduler.h" #include "icmp/icmppinger.h" // contains IcmpPacketDistributor +#include "dns_neww/dnsmaster.h" using namespace std; @@ -233,9 +233,7 @@ void init_pingers( ) { string default_network_interface = configuration->get_source_network_interface(); - string nameserver = configuration->get_nameserver(); int ping_fail_limit = configuration->get_ping_fail_limit(); - int max_address_resolution_attempts = configuration->get_max_address_resolution_attempts(); int ping_reply_timeout = configuration->get_ping_reply_timeout(); int resolved_ip_ttl_threshold = configuration->get_resolved_ip_ttl_threshold(); @@ -275,8 +273,6 @@ void init_pingers( protocol_list, ping_interval_in_sec, ping_fail_limit, - nameserver, - max_address_resolution_attempts, ping_reply_timeout, resolved_ip_ttl_threshold, status_notifier, @@ -502,6 +498,18 @@ int main( int argc, const char *argv[] ) io_service_temp.swap( io_service ); io_service_temp.reset(); + // create Dns master + boost::asio::ip::address name_server_ip = + boost::asio::ip::address::from_string( + configuration->get_nameserver() ); + + DnsMaster::create_master( + io_service, + name_server_ip, + configuration->get_resolved_ip_ttl_threshold(), + configuration->get_max_address_resolution_attempts(), + configuration->get_dns_cache_file() ); + init_pingers( io_service, configuration, status_notifier, &scheduler_list ); install_signal_handlers( io_service, log_level ); -- 1.7.1