fixed 2 bugs and made clearer that Long-term timer in DnsResolver is not affected...
[pingcheck] / src / dns / dnsresolver.cpp
index 0ac9828..07eeac3 100644 (file)
@@ -73,6 +73,7 @@ DnsResolver::DnsResolver(IoServiceItem &io_serv,
     , RandomIdGenerator()
     , RequestId( 0 )
     , OperationCancelled( false )
+    , LongermTimerIsActive( false )
 {
     std::stringstream temp;
     temp << "Dns(" << ResolverBase::Hostname << "): ";
@@ -125,6 +126,7 @@ void DnsResolver::do_resolve()
     ResolveTimeoutTimer.cancel();
     PauseBeforeRetryTimer.cancel();
     StaleDataLongtermTimer.cancel();
+    LongermTimerIsActive = false;
 
     // create DNS request
     boost::net::dns::message dns_message( ResolverBase::Hostname, Protocol );
@@ -362,6 +364,7 @@ void DnsResolver::handle_unavailable()
                          this, boost::asio::placeholders::error
             )
     );
+    LongermTimerIsActive = true;
 
     // for now, admit failure
     bool was_success = false;
@@ -460,7 +463,7 @@ void DnsResolver::handle_cname(const std::vector<src_cname_pair> &result_cnames)
             // treat a CNAME as a partial result: not enough to run callbacks
             // from finalize_resolve, but enough to stop timers and reset
             // RetryCount --> name resolution can take longer
-            stop_trying();
+            stop_trying(true);
         }
     }
 }
@@ -476,15 +479,18 @@ void DnsResolver::cname_resolve_callback(const bool was_success,
         return;
     }
     else if (was_success)
+    {
         GlobalLogger.debug() << LogPrefix << "CNAME resolution succeeded";
+        finalize_resolve(was_success, cname_count+1);
+    }
     else
+    {
         GlobalLogger.info() << LogPrefix << "CNAME resolution failed";
         // no use to schedule retry in this case since cname resolver must have
         // failed several times and we can only re-start the same procedure with
-        // the same information
-
-    // cname counts like one more recursion step ...
-    finalize_resolve(was_success, cname_count+1);
+        // the same information. But can re-try later
+        handle_unavailable();
+    }
 }
 
 
@@ -507,7 +513,7 @@ void DnsResolver::finalize_resolve(const bool was_success,
                                             << "waiting for DNS reply!";
 
     // stop timers
-    stop_trying();
+    stop_trying(was_success);
 
     // schedule callbacks, clearing callback list
     ResolverBase::schedule_callbacks(was_success, cname_count);
@@ -520,31 +526,61 @@ void DnsResolver::finalize_resolve(const bool was_success,
 }
 
 
-void DnsResolver::stop_trying()
+/**
+ * arg was_success determines if stop trying forever or just for the moment
+ * --> determines if we cancel StaleDataLongtermTimer or not
+ */
+void DnsResolver::stop_trying(bool was_success)
 {
     // cancel timers
     GlobalLogger.debug() << LogPrefix << "Cancelling timers";
     ResolveTimeoutTimer.cancel();
     PauseBeforeRetryTimer.cancel();
-    StaleDataLongtermTimer.cancel();
+
+    if (was_success)
+    {
+        StaleDataLongtermTimer.cancel();
+        LongermTimerIsActive = false;
+    }
 
     // clean up
     RetryCount = 0;
 }
 
 
-bool DnsResolver::is_resolving()
+/**
+ * return true if resolver is currently resolving
+ *
+ * Is true from call to async_resolve until callbacks
+ * --> returns true if waiting for result or (short-term) retry
+ *
+ * However, does NOT tell you if the (long-term) stale timeout is active! 
+ *   That timer has no effect on result, need to check is_waiting_to_resolve
+ *   for that
+ */
+bool DnsResolver::is_resolving() const
 {
     return IsResolving;
 }
 
 
 /**
+ * returns true if either is_resolving or the long-term timer is active
+ * 
+ * is_resolving returns true if the short-term retry timer is active
+ */
+bool DnsResolver::is_waiting_to_resolve() const
+{
+    return IsResolving || LongermTimerIsActive;
+}
+
+
+/**
  * cancel a earlier call to async_resolve
  *
  * callbacks will be called with was_success=false; all internal operations
  * will be cancelled and internal callbacks (timers, dns results) have no
- * effect any more
+ * effect any more; cancels also the long-term stale-data timer
  */
 void DnsResolver::cancel_resolve()
 {
@@ -570,6 +606,9 @@ void DnsResolver::cancel_resolve()
     int cname_count = 1;
     finalize_resolve(was_success, cname_count);
 
+    // also cancel the long-term timer
+    StaleDataLongtermTimer.cancel();
+
     // set after finalize_resolve, so can check in finalize_resolve that 
     // OperationCancelled is never true
     OperationCancelled = true;
@@ -692,7 +731,7 @@ HostAddress DnsResolver::get_next_ip(bool check_up_to_date)
 
     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;
+        << "; TTL thresh=" << ttl_thresh << "s 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
@@ -700,9 +739,15 @@ HostAddress DnsResolver::get_next_ip(bool check_up_to_date)
     {
         // check index since cache size may have changed since last call
         if (NextIpIndex >= n_ips)
+        {
+            GlobalLogger.debug() << LogPrefix << "Reset NextIpIndex";
             NextIpIndex = 0;
+        }
         else if ( n_iter >= n_ips)
+        {
+            GlobalLogger.debug() << LogPrefix << "No IP found";
             return HostAddress();   // have checked all candidates
+        }
         else
         {   // there are candidates left to consider
             return_candidate = cached_data[NextIpIndex++];
@@ -710,7 +755,7 @@ HostAddress DnsResolver::get_next_ip(bool check_up_to_date)
                 return return_candidate;
             else if (cached_data[NextIpIndex].get_ttl().get_updated_value()
                      > ttl_thresh)
-                return cached_data[++NextIpIndex];
+                return return_candidate;
             else
                 ++n_iter;
         }