From: Guilherme Maciel Ferreira Date: Mon, 18 Apr 2011 10:46:45 +0000 (+0200) Subject: Implemented feature: cache DNS requests info only until DNS reply is valid (TTL). X-Git-Tag: v1.0~72 X-Git-Url: http://developer.intra2net.com/git/?a=commitdiff_plain;h=101be5cec8af2c91499656703aff0f25769f105e;p=pingcheck Implemented feature: cache DNS requests info only until DNS reply is valid (TTL). - created a class TimeToLive which is self updatable, and can get the ttl updated - before each ping checks if the address is valid, if not, builds another IP list (which renews the ttl) --- diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index be4b8e9..82dbcbe 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -27,6 +27,7 @@ set(SOURCES config/host.cpp dns/dnsresolver.cpp dns/hostaddress.cpp + dns/timetolive.cpp host/boostpinger.cpp host/hoststatusanalyzer.cpp host/pingscheduler.cpp diff --git a/src/dns/dnsresolver.cpp b/src/dns/dnsresolver.cpp index bd33585..dea6720 100644 --- a/src/dns/dnsresolver.cpp +++ b/src/dns/dnsresolver.cpp @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -60,6 +61,8 @@ bool DnsResolver::resolve() return false; } + ResolvedHostAddressList.clear(); + for ( rr_list_t::iterator riter = answers->begin(); riter != answers->end(); ++riter ) @@ -77,7 +80,7 @@ bool DnsResolver::resolve() HostAddress resolved_host( ip, ttl ); ResolvedHostAddressList.push_back( resolved_host ); - cout << "- " << ip << endl; + cout << "- " << ip << " [" << ttl << "s]" << endl; } } } @@ -116,13 +119,29 @@ string DnsResolver::get_next_ip() HostAddress host_address = ResolvedHostAddressList.front(); ResolvedHostAddressList.pop_front(); string destination_ip = host_address.get_ip(); + int ttl = host_address.get_ttl().get_updated_value(); ResolvedHostAddressList.push_back( host_address ); size_t list_size_after = ResolvedHostAddressList.size(); + BOOST_ASSERT( 0 < ttl ); BOOST_ASSERT( list_size_before == list_size_after ); - // TODO check the ttl of the resolved IP, if it is next to zero, call the resolve again - return destination_ip; } + +bool DnsResolver::expired_resolved_ip() +{ + const int threshold = 10; // TODO configurable + + BOOST_FOREACH( HostAddress host_address, ResolvedHostAddressList ) + { + int ttl = host_address.get_ttl().get_updated_value(); + if ( ttl <= threshold ) + { + return true; + } + } + + return false; +} diff --git a/src/dns/dnsresolver.h b/src/dns/dnsresolver.h index 0ef5e7c..1d3b024 100644 --- a/src/dns/dnsresolver.h +++ b/src/dns/dnsresolver.h @@ -21,8 +21,11 @@ public: bool resolve(); int get_resolved_ip_count() const; + std::string get_next_ip(); + bool expired_resolved_ip(); + private: std::list ResolvedHostAddressList; const std::string HostDnsAddress; diff --git a/src/dns/hostaddress.cpp b/src/dns/hostaddress.cpp index a7cc69c..9aa92d4 100644 --- a/src/dns/hostaddress.cpp +++ b/src/dns/hostaddress.cpp @@ -1,5 +1,7 @@ #include "dns/hostaddress.h" +#include + using namespace std; //----------------------------------------------------------------------------- @@ -13,7 +15,7 @@ HostAddress::HostAddress() : } HostAddress::HostAddress( - string ip, + const string &ip, int ttl ) : Ip( ip ), @@ -25,23 +27,24 @@ HostAddress::~HostAddress() { } -void HostAddress::set_ip( string ip ) +string HostAddress::get_ip() const { - this->Ip = ip; + return Ip; } -string HostAddress::get_ip() const +void HostAddress::set_ip( const string &ip ) { - return Ip; + BOOST_ASSERT( !ip.empty() ); + + Ip = ip; } -int HostAddress::get_ttl() const +TimeToLive HostAddress::get_ttl() const { return Ttl; } -void HostAddress::set_ttl( int ttl ) +void HostAddress::set_ttl( const TimeToLive &ttl ) { - this->Ttl = ttl; + Ttl = ttl; } - diff --git a/src/dns/hostaddress.h b/src/dns/hostaddress.h index 061b798..7ffd031 100644 --- a/src/dns/hostaddress.h +++ b/src/dns/hostaddress.h @@ -1,10 +1,10 @@ #ifndef HOSTADDRESS_H_ #define HOSTADDRESS_H_ -#include - #include +#include "dns/timetolive.h" + //----------------------------------------------------------------------------- // HostAddress //----------------------------------------------------------------------------- @@ -13,18 +13,21 @@ class HostAddress { public: HostAddress(); - HostAddress( std::string ip, int ttl ); + HostAddress( + const std::string &ip, + int ttl + ); ~HostAddress(); std::string get_ip() const; - void set_ip( std::string ip ); + void set_ip( const std::string &ip ); - int get_ttl() const; - void set_ttl( int ttl ); + TimeToLive get_ttl() const; + void set_ttl( const TimeToLive &ttl ); private: std::string Ip; - int Ttl; + TimeToLive Ttl; }; diff --git a/src/dns/timetolive.cpp b/src/dns/timetolive.cpp new file mode 100644 index 0000000..21e02c1 --- /dev/null +++ b/src/dns/timetolive.cpp @@ -0,0 +1,46 @@ +#include "dns/timetolive.h" + +#include + +using boost::date_time::time_resolution_traits_adapted64_impl; +using boost::posix_time::microsec_clock; +using boost::posix_time::ptime; + +//----------------------------------------------------------------------------- +// TimeToLive +//----------------------------------------------------------------------------- + +TimeToLive::TimeToLive( int ttl ) : + Ttl( ttl ), + TtlSetTime( microsec_clock::universal_time() ) +{ +} + +TimeToLive::~TimeToLive() +{ +} + +int TimeToLive::get_value() const +{ + return Ttl; +} + +void TimeToLive::set_value( const int ttl ) +{ + BOOST_ASSERT( 0 < ttl ); + + Ttl = ttl; + TtlSetTime = microsec_clock::universal_time(); +} + +int TimeToLive::get_updated_value() const +{ + ptime now = microsec_clock::universal_time(); + int elapsed_seconds = static_cast ( + (now - TtlSetTime).total_seconds() + ); + int original_ttl = get_value(); + int remaining_seconds = original_ttl - elapsed_seconds; + + return remaining_seconds; +} diff --git a/src/dns/timetolive.h b/src/dns/timetolive.h new file mode 100644 index 0000000..4f17302 --- /dev/null +++ b/src/dns/timetolive.h @@ -0,0 +1,26 @@ +#ifndef TIMETOLIVE_H +#define TIMETOLIVE_H + +#include + +//----------------------------------------------------------------------------- +// TimeToLive +//----------------------------------------------------------------------------- + +class TimeToLive +{ +public: + TimeToLive( int ttl = 0 ); + ~TimeToLive(); + + int get_value() const; + void set_value( const int ttl ); + + int get_updated_value() const; + +private: + int Ttl; + boost::posix_time::ptime TtlSetTime; +}; + +#endif /* TIMETOLIVE_H */ diff --git a/src/host/pingscheduler.cpp b/src/host/pingscheduler.cpp index 5a05c34..7620b33 100644 --- a/src/host/pingscheduler.cpp +++ b/src/host/pingscheduler.cpp @@ -5,12 +5,13 @@ #include #include "dns/dnsresolver.h" -#include "link/linkstatusanalyzer.h" #include "host/boostpinger.h" +#include "link/linkstatusanalyzer.h" using namespace std; using boost::asio::io_service; using boost::bind; +using boost::date_time::time_resolution_traits_adapted64_impl; using boost::posix_time::microsec_clock; using boost::posix_time::ptime; using boost::posix_time::seconds; @@ -46,9 +47,6 @@ PingScheduler::~PingScheduler() bool PingScheduler::start_pinging() { - // TODO the DNS resolution is called only once. Find a way to resolve when - // the TTL ends - // TODO does the DNS keeps the same number of IPs? bool address_resolved = resolve_ping_address(); if ( !address_resolved ) { @@ -93,6 +91,18 @@ 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() ) + { + cout << "Updating DNS ... "; // TODO + bool address_resolved = resolve_ping_address(); + if ( !address_resolved ) + { + cerr << "Error: could not update host IP, may use outdated address" + << endl; + } + } + string destination_ip = IpList.get_next_ip(); bool ping_success = ping( destination_ip ); @@ -143,8 +153,9 @@ void PingScheduler::update_ping_interval() void PingScheduler::update_ping_elapsed_time() { ptime now = microsec_clock::universal_time(); - cout << "- Time elapsed since last ping: " - << (now - TimeSentLastPing).total_seconds() << "s" + time_resolution_traits_adapted64_impl::int_type elapsed_time_in_sec = + (now - TimeSentLastPing).total_seconds(); + cout << "- Time elapsed since last ping: " << elapsed_time_in_sec << "s" << endl; // TODO output log TimeSentLastPing = microsec_clock::universal_time();