// remember cname list (if there were any)
BOOST_FOREACH( const src_cname_pair &host_and_cname, result_cnames )
- {
- GlobalLogger.info() << LogPrefix << "Remember CNAME "
- << host_and_cname.first << " --> " << host_and_cname.second.Host;
ResolverBase::update_cache(host_and_cname.first, host_and_cname.second);
- }
if ( !result_ips.empty() )
handle_ips( result_ips );
// RETRIEVAL
//==============================================================================
-HostAddress DnsResolver::get_next_ip()
+HostAddress DnsResolver::get_next_ip(bool check_up_to_date)
{
// get cached data
+ // (do not use arg check_up_to_date here in order to give NextIpIndex
+ // a chance to stay above number of outdate IPs)
HostAddressVec cached_data = ResolverBase::get_cached_ips_recursively();
// if no results cached, return default-constructed HostAddress (0.0.0.0)
+ HostAddress return_candidate;
if ( cached_data.empty() )
{
- HostAddress return_value;
- return return_value;
+ GlobalLogger.debug() << LogPrefix << "Get next IP: nothing cached";
+ return return_candidate;
}
- // check validity of index (cache may have changed since last call)
- if (NextIpIndex >= cached_data.size())
- NextIpIndex = 0;
+ int n_iter = 0;
+ std::size_t n_ips = cached_data.size();
+ uint32_t ttl_thresh = static_cast<uint32_t>( DnsMaster::get_instance()
+ ->get_resolved_ip_ttl_threshold() );
- // return next IP
- return cached_data[NextIpIndex++];
+ GlobalLogger.info() << LogPrefix << "Get next IP from cached result of "
+ << n_ips << " IPs; first index to consider is " << NextIpIndex
+ << "; TTL thresh = " << ttl_thresh << " is used: " << check_up_to_date;
+
+ // loop until we have found a cached result (that is up to date)
+ // or until we have tried all cached IPs
+ while (true)
+ {
+ // check index since cache size may have changed since last call
+ if (NextIpIndex >= n_ips)
+ NextIpIndex = 0;
+ else if ( n_iter >= n_ips)
+ return HostAddress(); // have checked all candidates
+ else
+ { // there are candidates left to consider
+ return_candidate = cached_data[NextIpIndex++];
+ if (!check_up_to_date)
+ return return_candidate;
+ else if (cached_data[NextIpIndex].get_ttl().get_updated_value()
+ > ttl_thresh)
+ return cached_data[++NextIpIndex];
+ else
+ ++n_iter;
+ }
+ }
}
bool DnsResolver::have_up_to_date_ip()
{
- return ! ResolverBase::get_cached_ips_recursively("", true).empty();
+ return get_resolved_ip_count() > 0;
}
int DnsResolver::get_resolved_ip_count()
{
- return ResolverBase::get_cached_ips_recursively().size();
+ return ResolverBase::get_cached_ips_recursively("", true).size();
}
// (created using vim -- the world's best text editor)