merged PingRotate into PingScheduler; fixed save/load of cache to/from file; started...
[pingcheck] / src / dns / dnsresolver.cpp
index 1e236d3..3240e31 100644 (file)
@@ -234,11 +234,7 @@ void DnsResolver::handle_dns_result(const boost::system::error_code &error,
 
     // 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 );
@@ -674,34 +670,61 @@ void DnsResolver::wait_timer_timeout_handler(
 // 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)