From: Christian Herdtweck Date: Thu, 9 Apr 2015 12:01:33 +0000 (+0200) Subject: done except for saving/loading cache; not being used yet but does compile (except... X-Git-Url: http://developer.intra2net.com/git/?a=commitdiff_plain;h=4e7b6ff9f44ae46da44258a527763bba42301d91;p=pingcheck done except for saving/loading cache; not being used yet but does compile (except for linker error caused by old dns system still in CMakeLists.txt) --- diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e956995..1645316 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -62,8 +62,9 @@ set(SOURCES config/option/maxaddressresolutionattemptsoption.cpp config/option/resolvedipttlthresholdoption.cpp dns_neww/dnscache.cpp - dns_neww/dnsmaster.cpp + dns_neww/resolverbase.cpp dns_neww/dnsresolver.cpp + dns_neww/dnsmaster.cpp dns/dnsresolver.cpp dns/dnsresolverfactory.cpp dns/hostaddress.cpp diff --git a/src/dns_neww/dnscache.cpp b/src/dns_neww/dnscache.cpp index 9e1b004..f7ae74f 100644 --- a/src/dns_neww/dnscache.cpp +++ b/src/dns_neww/dnscache.cpp @@ -118,7 +118,7 @@ void DnsCache::load_from_cachefile() * @returns true if changed cache; returns false if new_data is same as cache */ void DnsCache::update(const std::string &hostname, - const HostAddressList &new_data) + const HostAddressVec &new_data) { GlobalLogger.info() << "DNS Cache: update IPs for " << hostname << " to " << new_data.size() << "-list"; @@ -127,7 +127,7 @@ void DnsCache::update(const std::string &hostname, } -HostAddressList DnsCache::get_data(const std::string &hostname) +HostAddressVec& DnsCache::get_data(const std::string &hostname) { GlobalLogger.info() << "DNS Cache: request IPs for " << hostname << " --> " << DataCache[hostname].size() << "-list"; diff --git a/src/dns_neww/dnscache.h b/src/dns_neww/dnscache.h index 4e5d889..9600901 100644 --- a/src/dns_neww/dnscache.h +++ b/src/dns_neww/dnscache.h @@ -32,7 +32,8 @@ #include "host/pinger.h" // for IoserviceItem #include "dns/hostaddress.h" -typedef std::map cache_map_type; +typedef std::vector HostAddressVec; +typedef std::map cache_map_type; class DnsCache { @@ -42,8 +43,8 @@ public: ~DnsCache(); // accessed from ResolverBase subclasses - void update(const std::string &host_name, const HostAddressList &new_data); - HostAddressList get_data(const std::string &hostname); + void update(const std::string &host_name, const HostAddressVec &new_data); + HostAddressVec& get_data(const std::string &hostname); // variables private: diff --git a/src/dns_neww/dnsmaster.cpp b/src/dns_neww/dnsmaster.cpp index 17b3dde..5c791a7 100644 --- a/src/dns_neww/dnsmaster.cpp +++ b/src/dns_neww/dnsmaster.cpp @@ -24,15 +24,12 @@ #include #include -#include #include #include "dns_neww/ippseudoresolver.h" #include "dns_neww/dnsresolver.h" using boost::bind; -using boost::posix_time::seconds; -using boost::posix_time::minutes; using I2n::Logger::GlobalLogger; @@ -59,9 +56,9 @@ DnsMaster::DnsMaster(const IoServiceItem &io_serv, const boost::asio::ip::address &name_server, const DnsCacheItem &cache) : IoService( io_serv ) - , ResolverMap() , NameServer( name_server ) , Cache(cache) + , ResolverMap() { } @@ -87,14 +84,18 @@ ResolverItem& DnsMaster::get_resolver_for( const std::string &hostname ) { GlobalLogger.info() << "Creating PseudoResolver for IP " << hostname; - ResolverItem new_resolver( new IpPseudoResolver(hostname, Cache) ); + ResolverItem new_resolver( new IpPseudoResolver(IoService, + hostname, + Cache) ); master->ResolverMap[hostname] = new_resolver; } else { GlobalLogger.info() << "Creating Resolver for host " << hostname; - ResolverItem new_resolver( new DnsResolver(hostname, Cache, - IoService, NameServer) ); + ResolverItem new_resolver( new DnsResolver(IoService, + hostname, + Cache, + NameServer) ); master->ResolverMap[hostname] = new_resolver; } } diff --git a/src/dns_neww/dnsmaster.h b/src/dns_neww/dnsmaster.h index 28ad1f4..028e831 100644 --- a/src/dns_neww/dnsmaster.h +++ b/src/dns_neww/dnsmaster.h @@ -68,7 +68,7 @@ private: DnsMaster(const IoServiceItem &io_serv, const boost::asio::ip::address &name_server, - const std::string &cache_file); + const DnsCacheItem &cache); public: static DnsMasterItem& get_instance(); ~DnsMaster(); @@ -76,9 +76,9 @@ public: // variables private: IoServiceItem IoService; + const boost::asio::ip::address NameServer; DnsCacheItem Cache; resolver_map_type ResolverMap; - const boost::asio::ip::address NameServer; // functions diff --git a/src/dns_neww/dnsresolver.cpp b/src/dns_neww/dnsresolver.cpp index bbdc066..35bd772 100644 --- a/src/dns_neww/dnsresolver.cpp +++ b/src/dns_neww/dnsresolver.cpp @@ -18,12 +18,25 @@ on this file might be covered by the GNU General Public License. Christian Herdtweck, Intra2net AG 2015 + + with code copied from boost::net::dns::resolve.hpp + by Andreas Haberstroh (andreas at ibusy dot com) + from https://github.com/softwareace/Boost.DNS */ #include "dns_neww/dnsresolver.h" +#include +#include +#include +#include +#include + #include + using I2n::Logger::GlobalLogger; +using boost::posix_time::seconds; +using boost::posix_time::minutes; namespace Config { @@ -35,20 +48,18 @@ namespace Config const int MaxRetryCount = 5; } -DnsResolver::DnsResolver(const std::string &hostname, +DnsResolver::DnsResolver(IoServiceItem &io_serv, + const std::string &hostname, const DnsCacheItem cache, - IoServiceItem &io_serv, const boost::asio::ip::address &name_server) - : ResolverBase( hostname, cache ) - , IoService( io_serv ) + : ResolverBase( io_serv, hostname, cache ) , Socket( *io_serv, ip::udp::endpoint(ip::udp::v4(), 0) ) - , ReplyBuffer() - , NameServer( name_server, DNS_PORT ) + , ReceiveBuffer() + , NameServer( name_server, Config::DNS_PORT ) , ResolveTimeoutTimer( *io_serv ) , PauseBeforeRetryTimer( *io_serv ) , StaleDataLongtermTimer( *io_serv ) - , CallbackList() - , HostAddressList::const_iterator() + , NextIpIndex( 0 ) , RetryCount( 0 ) , IsResolving( false ) { } @@ -61,24 +72,14 @@ DnsResolver::DnsResolver(const std::string &hostname, /** * copied here code from boost::net::dns::resolve.hpp, since want async * operation and that is used only internally, there - * --> give credit to Andreas Haberstroh (andreas at ibusy dot com) - * from https://github.com/softwareace/Boost.DNS - * - * callbacks should be of type - * void resolve_callback(const boost::system::error_code &error, - * const bool was_success, - * const int cname_count) */ -DnsResolver::async_resolve(const callback_type callback) +void DnsResolver::do_resolve() { - // remember callback - CallbackList.push(callback); - // check if resolving already - if (isResolving) + if (IsResolving) { GlobalLogger.info() - << "Call to async_resolve ignored since resolving already"; + << "Call to do_resolve ignored since resolving already"; return; } @@ -88,13 +89,13 @@ DnsResolver::async_resolve(const callback_type callback) StaleDataLongtermTimer.cancel(); // create DNS request - boost::net::dns::message dns_message( host_dns_address, + boost::net::dns::message dns_message( ResolverBase::Hostname, boost::net::dns::type_all ); dns_message.recursive(false); - dns_message.action(dns::message::query); - dns_message.opcode(dns::message::squery); - dns_message.id(UniqueID); - dns_buffer_t request_buffer; + dns_message.action(boost::net::dns::message::query); + dns_message.opcode(boost::net::dns::message::squery); + dns_message.id(Config::UniqueID); + boost::net::dns_buffer_t request_buffer; dns_message.encode(request_buffer); // setup receipt of reply @@ -104,12 +105,14 @@ DnsResolver::async_resolve(const callback_type callback) boost::bind( &DnsResolver::handle_dns_result, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred) - ) + ); // schedule timeout - (void) ResolveTimeoutTimer.expires_from_now(seconds(ResolveTimeoutSeconds)); - ResolveTimeout.async_wait( bind( &DnsResolver::handle_resolve_timeout, - this, boost::asio::placeholders::error) ); + (void) ResolveTimeoutTimer.expires_from_now( + seconds(Config::ResolveTimeoutSeconds)); + ResolveTimeoutTimer.async_wait( boost::bind( + &DnsResolver::handle_resolve_timeout, + this, boost::asio::placeholders::error) ); // send dns request Socket.send_to( boost::asio::buffer(request_buffer.get_array()), @@ -117,18 +120,18 @@ DnsResolver::async_resolve(const callback_type callback) } -void handle_dns_result(const boost::system::error_code &error, +void DnsResolver::handle_dns_result(const boost::system::error_code &error, const std::size_t bytes_transferred) { if ( error == boost::asio::error::operation_aborted ) // cancelled { - resolve_log.info() << "DNS resolve operation was cancelled"; + GlobalLogger.info() << "DNS resolve operation was cancelled"; bool was_success = false; finalize_resolve(was_success); } else if (error) { - resolve_log.info() << "DNS resolve resulted in error " << error + GlobalLogger.info() << "DNS resolve resulted in error " << error << " --> treat like unavailable"; handle_unavailable(); return; @@ -137,39 +140,47 @@ void handle_dns_result(const boost::system::error_code &error, // next 3(+1) lines copied from boost/net/dns/resolver.hpp: // clamp the recvBuffer with the number of bytes transferred or decode buffr ReceiveBuffer.length(bytes_transferred); - message result_message(); + boost::net::dns::message result_message; result_message.decode( ReceiveBuffer ); - if (result_message.answers().size == 0) + // work with a regular pointer to list of answers since result_message is + // owner of data and that exists until end of function + // Items in answers list are shared_ptr to resource_base_t + boost::net::dns::rr_list_t *answers = result_message.answers(); + if (answers->size() == 0) handle_unavailable(); // loop over answers, remembering ips and cnames - typedef boost::shared_ptr rr_item_type; - typedef boost::shared_ptr cname_item_type; - HostAddressList ip_list; - std::vector cname_list; - BOOST_FOREACH( rr_item_type rr_item, result_message.answers() ) + HostAddressVec result_ips; + std::vector result_cnames; + using boost::net::dns::resource_base_t; + BOOST_FOREACH( boost::shared_ptr rr_item, *answers ) { - GlobalLogger.debug() << std::showbase << std::hex << rr_item->rtype() - << ": "; + GlobalLogger.debug() << std::showbase << std::hex + << static_cast(rr_item->rtype()) << ": "; uint32_t ttl = rr_item->ttl(); - type_t rr_type = rr_item->rtype(); + boost::net::dns::type_t rr_type = rr_item->rtype(); if (rr_type == boost::net::dns::type_a) { // 'A' resource records carry IPv4 addresses - std::string ip = ( dynamic_cast (rr_item.get()) ) - ->address(); - ip_list.push_back( HostAddress(ip, ttl) ); + boost::asio::ip::address_v4 ip = + ( dynamic_cast (rr_item.get()) ) + ->address(); + result_ips.push_back( HostAddress(ip, ttl) ); } else if (rr_type == boost::net::dns::type_a6) { // 'AAAA' resource records carry IPv6 addresses - std::string ip = ( dynamic_cast (rr_item.get()) ) - ->address(); - ip_list.push_back( HostAddress(ip, ttl) ); + boost::asio::ip::address_v6 ip = + ( dynamic_cast (rr_item.get()) ) + ->address(); + result_ips.push_back( HostAddress(ip, ttl) ); } else if (rr_type == boost::net::dns::type_cname) { // 'CNAME' resource records that carry aliases - cname_list.push_back(dynamic_cast(rr_item)); + std::string cname = + (dynamic_cast(rr_item.get())) + ->canonicalname(); + result_cnames.push_back( cname ); } else if (rr_type == boost::net::dns::type_ns) GlobalLogger.debug() << "NS resource"; @@ -191,25 +202,25 @@ void handle_dns_result(const boost::system::error_code &error, GlobalLogger.debug() << "unknown resource type"; } - GlobalLogger.info() << "Have " << ip_list.size() << " IPs and " - << cname_list.size() << " CNAMEs"; + GlobalLogger.info() << "Have " << result_ips.size() << " IPs and " + << result_cnames.size() << " CNAMEs"; // We expect either one single CNAME and no IPs or a list of IPs. // But deal with other cases as well - if (ip_list.empty() && cname_list.empty()) + if (result_ips.empty() && result_cnames.empty()) handle_unavailable(); // we just got crap, this is a dead end - else if ( !ip_list.empty() && !cname_list.empty()) + else if ( !result_ips.empty() && !result_cnames.empty()) GlobalLogger.warning() << "Have CNAMEs AND IPs --> deal with both!"; - BOOST_FOREACH( const cname_resource &cname, cname_list ) + BOOST_FOREACH( const std::string &cname, result_cnames ) handle_cname(cname); // will schedule another DNS call - if ( !ip_list.empty() ) - handle_ips(ip_list); + if ( !result_ips.empty() ) + handle_ips(result_ips); } -void DnsResolver::handle_ips(const HostAddressList &ips) +void DnsResolver::handle_ips(const HostAddressVec &ips) { // save in cache ResolverBase::update_cache( ips ); @@ -223,10 +234,11 @@ void DnsResolver::handle_ips(const HostAddressList &ips) void DnsResolver::handle_unavailable() { // schedule new attempt in quite a while - StaleDataLongtermTimer.expires_from_now(minutes(StaleDataLongtermMinutes)); + StaleDataLongtermTimer.expires_from_now( + minutes(Config::StaleDataLongtermMinutes)); StaleDataLongtermTimer.async_wait( - bind( &DnsResolver::wait_timer_timeout_handler, - this, boost::asio::placeholders::error + boost::bind( &DnsResolver::wait_timer_timeout_handler, + this, boost::asio::placeholders::error ) ); @@ -240,46 +252,24 @@ void DnsResolver::handle_cname(const std::string &canonical_name) // get resolver for canonical name ResolverItem resolver = DnsMaster::get_instance() ->get_resolver_for(canonical_name); - resolver->async_resolve( - bind( &DnsResolver::cname_resolve_callback, - this, boost::asio::placeholders::error, - canonical_name, _1, _2 - ) - ); + callback_type callback = boost::bind( &DnsResolver::cname_resolve_callback, + this, canonical_name, _1, _2 ); + resolver->async_resolve( callback ); stop_trying(); } -void cname_resolve_callback(const boost::system::error_code &error, - const std::string &canonical_name, - const bool was_success, - const int cname_count) +void DnsResolver::cname_resolve_callback(const std::string &canonical_name, + const bool was_success, + const int cname_count) { - bool was_success = true; - - if ( error == boost::asio::error::operation_aborted ) // cancelled - { - GlobalLogger.warning() - << "Recursive resolution of cname was cancelled!"; - was_success = false; - } - else if (error) - { - GlobalLogger.warning() << "Error " << error - << " waiting for callback from cname resolution!" - was_success = false; - } if (was_success) - { // tell cache to return cname's ips if queried for our hostname + // tell cache to return cname's ips if queried for our hostname ResolverBase::update_cache( ResolverBase::get_cached_results(canonical_name) ); - } else - { GlobalLogger.info() << "Cname resolution failed"; - was_success = false; - } finalize_resolve(was_success, cname_count+1); } @@ -294,13 +284,7 @@ void DnsResolver::finalize_resolve(const bool was_success, // else was called already from handle_cname // schedule callbacks, clearing callback list - while ( !CallbackList.empty ) - { - IoService.post( bind( CallbackList.front(), - boost::asio::placeholders::error, - was_success, cname_count ) ); - CallbackList.pop(); - } + ResolverBase::schedule_callbacks(was_success, cname_count); // finalize GlobalLogger.notice() << "Done resolving" @@ -321,7 +305,7 @@ void DnsResolver::stop_trying() RetryCount = 0; } -viod DnsResolver::handle_resolve_timeout(const boost::system::error_code &error) +void DnsResolver::handle_resolve_timeout(const boost::system::error_code &error) { if ( error == boost::asio::error::operation_aborted ) // cancelled { @@ -340,7 +324,7 @@ viod DnsResolver::handle_resolve_timeout(const boost::system::error_code &error) // increment timer ++RetryCount; - if (RetryCount > MaxRetryCount) + if (RetryCount > Config::MaxRetryCount) { handle_unavailable(); RetryCount = 0; @@ -348,10 +332,10 @@ viod DnsResolver::handle_resolve_timeout(const boost::system::error_code &error) else { // schedule retry PauseBeforeRetryTimer.expires_from_now( - seconds(PauseBeforeRetrySeconds)); + seconds(Config::PauseBeforeRetrySeconds)); PauseBeforeRetryTimer.async_wait( - bind( &DnsResolver::wait_timer_timeout_handler, - this, boost::asio::placeholders::error) ); + boost::bind( &DnsResolver::wait_timer_timeout_handler, + this, boost::asio::placeholders::error) ); } } @@ -366,7 +350,7 @@ void DnsResolver::wait_timer_timeout_handler( else { GlobalLogger.info() << "Done waiting --> re-try resolve"; - async_resolve(); + do_resolve(); } } @@ -375,14 +359,17 @@ void DnsResolver::wait_timer_timeout_handler( // RETRIEVAL //============================================================================== -HostAddress& DnsResolver::get_next_ip() +HostAddress DnsResolver::get_next_ip() { // get cached data - ResolverBase::get_cached_results(); + HostAddressVec cached_data = ResolverBase::get_cached_results(); // if no results cached, return default-constructed HostAddress (0.0.0.0) if ( cached_data.empty() ) - return HostAddress; + { + HostAddress return_value; + return return_value; + } // check validity of index (cache may have changed since last call) if (NextIpIndex >= cached_data.size()) diff --git a/src/dns_neww/dnsresolver.h b/src/dns_neww/dnsresolver.h index 6141d92..4565cb1 100644 --- a/src/dns_neww/dnsresolver.h +++ b/src/dns_neww/dnsresolver.h @@ -25,21 +25,16 @@ #include "dns_neww/dnsmaster.h" -#include #include #include #include #include #include -#include "host/pinger.h" // for IoServiceItem #include "dns_neww/resolverbase.h" #include "dns_neww/dnsmaster.h" #include "dns_neww/dnscache.h" -typedef std::list callback_list_type; - -typedef std::queue IpTtlVec; class DnsResolver : public ResolverBase { @@ -48,27 +43,30 @@ public: // constructor accessible from friend DnsMaster public: - friend DnsResolverItem DnsMaster::get_resolver_for(const std::string&); + friend ResolverItem& DnsMaster::get_resolver_for( + const std::string &hostname); private: - DnsResolver(const std::string &hostname, + DnsResolver(IoServiceItem &io_serv, + const std::string &hostname, const DnsCacheItem cache, - IoServiceItem &io_serv, const boost::asio::ip::address &name_server); -// only real public functions (called from pingers) +// only real public function (called from pingers) public: - void async_resolve(const callback_type &callback); - HostAddress& get_next_ip(); + HostAddress get_next_ip(); + +// implementation of ResolverBase::async_resolve +protected: + void do_resolve(); private: void handle_resolve_timeout(const boost::system::error_code &error); void handle_dns_result(const boost::system::error_code &error, const std::size_t bytes_transferred); - void handle_unavailable(const boost::system::error_code &error); - void handle_ips(const boost::system::error_code &error, - const IpTtlVec &ips); - void handle_cname(const boost::system::error_code &error); - void cname_resolve_callback(const boost::system::error_code &error, + void handle_unavailable(); + void handle_ips(const HostAddressVec &ips); + void handle_cname(const std::string &canonical_name); + void cname_resolve_callback(const std::string &canonical_name, const bool was_success, const int cname_count); void finalize_resolve(const bool success, const int cname_count=0); @@ -76,15 +74,13 @@ private: void wait_timer_timeout_handler(const boost::system::error_code &error); private: - IoServiceItem IoService; boost::asio::ip::udp::socket Socket; - boost::net::dns_buffer_t ReplyBuffer; + boost::net::dns_buffer_t ReceiveBuffer; boost::asio::ip::udp::endpoint NameServer; boost::asio::deadline_timer ResolveTimeoutTimer; boost::asio::deadline_timer PauseBeforeRetryTimer; boost::asio::deadline_timer StaleDataLongtermTimer; - callback_list_type CallbackList; - int NextIpIndex; + std::size_t NextIpIndex; int RetryCount; bool IsResolving; }; diff --git a/src/dns_neww/ippseudoresolver.h b/src/dns_neww/ippseudoresolver.h index 72edf8f..f5fd006 100644 --- a/src/dns_neww/ippseudoresolver.h +++ b/src/dns_neww/ippseudoresolver.h @@ -23,6 +23,8 @@ #ifndef IP_PSEUDO_RESOLVER_H #define IP_PSEUDO_RESOLVER_H +#include +#include "dns/hostaddress.h" #include "dns_neww/resolverbase.h" #include "dns_neww/dnsmaster.h" @@ -47,22 +49,25 @@ public: friend ResolverItem& DnsMaster::get_resolver_for( const std::string &hostname); private: - IpPseudoResolver(const std::string &ip, + IpPseudoResolver(const IoServiceItem io_serv, + const std::string &ip_string, const DnsCacheItem &cache ) - : ResolverBase( ip, cache ) - , Ip( ip, Config::DefaultTtl ) + : ResolverBase( io_serv, ip_string, cache ) + , IpAddress( boost::asio::ip::address::from_string(ip_string), + Config::DefaultTtl ) {} private: - HostAddress Ip; + HostAddress IpAddress; -// only functions, inherited from ResolverBase +// only real public function public: - HostAddress& get_next_ip() { return Ip; } - void async_resolve(const callback_type &callback) - { - IoService.post( bind(callback, true, 0) ); - } + HostAddress get_next_ip() { return IpAddress; } + +// implementation of ResolverBase::async_resolve +protected: + void do_resolve() + { ResolverBase::schedule_callbacks(true, 0); } }; #endif diff --git a/src/dns_neww/resolverbase.cpp b/src/dns_neww/resolverbase.cpp new file mode 100644 index 0000000..2dccf4e --- /dev/null +++ b/src/dns_neww/resolverbase.cpp @@ -0,0 +1,80 @@ +/* + 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. + + Christian Herdtweck, Intra2net AG 2015 + */ + +#include "dns_neww/resolverbase.h" +#include "dns_neww/dnsmaster.h" + +#include + +ResolverBase::~ResolverBase() +{ + DnsMaster::get_instance()->unregister_resolver(Hostname); +} + +/** + * callbacks should be of type + * void resolve_callback(const bool was_success, + * const int cname_count) + */ +void ResolverBase::async_resolve(const callback_type &callback) +{ + // remember callback + CallbackList.push(callback); + + // let subclass do the resolving + do_resolve(); +} + +ResolverBase::ResolverBase(const IoServiceItem &io_serv, + const std::string &hostname, + const DnsCacheItem &cache ) + : IoService( io_serv ) + , Hostname( hostname ) + , Cache( cache ) + , CallbackList() +{} + +void ResolverBase::update_cache( const HostAddressVec &new_results ) const +{ Cache->update( Hostname, new_results ); } + +HostAddressVec& ResolverBase::get_cached_results(const std::string host) const +{ + if (host.empty()) + return Cache->get_data( Hostname ); + else + return Cache->get_data( host ); +} + +void ResolverBase::schedule_callbacks(const bool was_success, + const int cname_count) +{ + while ( !CallbackList.empty() ) + { + callback_type callback = CallbackList.front(); + CallbackList.pop(); + IoService->post( boost::bind( callback, + was_success, cname_count ) ); + } +} + +// (created using vim -- the world's best text editor) + diff --git a/src/dns_neww/resolverbase.h b/src/dns_neww/resolverbase.h index 8daab9f..cbd6ae6 100644 --- a/src/dns_neww/resolverbase.h +++ b/src/dns_neww/resolverbase.h @@ -24,16 +24,15 @@ #define RESOLVER_BASE_H #include +#include +#include +#include "host/pinger.h" #include "dns/hostaddress.h" #include "dns_neww/dnscache.h" -#include "dns_neww/dnsmaster.h" - -class ResolverBase; -typedef boost::shared_ptr ResolverItem; - -typedef void (*callback_type)(const bool, const int); +typedef boost::function callback_type; +typedef std::queue callback_list_type; /** * @brief: abstract base class for DnsResolver and IpPseudoResolver @@ -41,39 +40,44 @@ typedef void (*callback_type)(const bool, const int); class ResolverBase { public: - virtual HostAddress& get_next_ip() = 0; - virtual void async_resolve(const callback_type &callback) = 0; - virtual ~ResolverBase() - { - DnsMaster::get_instance()->unregister(Hostname); - } + virtual HostAddress get_next_ip() = 0; + + virtual ~ResolverBase(); + + /** + * callbacks should be of type + * void resolve_callback(const bool was_success, + * const int cname_count) + */ + void async_resolve(const callback_type &callback); protected: - ResolverBase(const std::string &hostname, - const DnsCacheItem &cache ) - : Hostname( hostname ) - , Cache( cache ) - {} + ResolverBase(const IoServiceItem &io_serv, + const std::string &hostname, + const DnsCacheItem &cache ); // variables -private: +protected: + IoServiceItem IoService; std::string Hostname; DnsCacheItem Cache; + callback_list_type CallbackList; // functions for subclasses protected: - void update_cache( const HostAddressList &new_results ) const - { Cache->update( Hostname, new_results ); } - - HostAddressList get_cached_results(const std::string host="") const - { - if (host.empty()) - return Cache->get_data( Hostname ); - else - return Cache->get_data( host ); - } + virtual void do_resolve() = 0; + + void update_cache( const HostAddressVec &new_results ) const; + + HostAddressVec& get_cached_results(const std::string host="") const; + + void schedule_callbacks(const bool was_success, + const int cname_count); + }; +typedef boost::shared_ptr ResolverItem; + #endif // (created using vim -- the world's best text editor)