added option min-time-between-resolves-option and tests for it
[pingcheck] / src / dns / dnscache.cpp
index c79ef83..4c524e7 100644 (file)
@@ -49,6 +49,10 @@ namespace Config
     int MaxRetrievalRecursions = 10;
 }
 
+// -----------------------------------------------------------------------------
+// Cname
+// -----------------------------------------------------------------------------
+
 Cname::Cname()
     : Host()
     , Ttl()
@@ -65,15 +69,21 @@ Cname::Cname(const std::string &host, const TimeToLive &ttl)
 {}
 
 
+// -----------------------------------------------------------------------------
+// DNS Cache constructor / destructor
+// -----------------------------------------------------------------------------
+
 const string DnsCache::DoNotUseCacheFile = "do not use cache file!";
 
 DnsCache::DnsCache(const IoServiceItem &io_serv,
-                   const std::string &cache_file)
+                   const std::string &cache_file,
+                   const uint32_t min_time_between_resolves)
     : IpCache()
     , CnameCache()
     , SaveTimer( *io_serv )
     , CacheFile( cache_file )
     , HasChanged( false )
+    , MinTimeBetweenResolves( min_time_between_resolves )
 {
     // load cache from file
     load_from_cachefile();
@@ -97,6 +107,10 @@ DnsCache::~DnsCache()
 }
 
 
+// -----------------------------------------------------------------------------
+// LOAD / SAVE
+// -----------------------------------------------------------------------------
+
 void DnsCache::schedule_save(const boost::system::error_code &error)
 {
     // just in case: ensure SaveTimer is cancelled
@@ -190,6 +204,10 @@ void DnsCache::load_from_cachefile()
 }
 
 
+// -----------------------------------------------------------------------------
+// UPDATE
+// -----------------------------------------------------------------------------
+
 // warn if hostname is empty and remove trailing dot
 std::string DnsCache::key_for_hostname(const std::string &hostname) const
 {
@@ -217,9 +235,26 @@ void DnsCache::update(const std::string &hostname,
             << " removes CNAME to " << get_cname(hostname).Host << "!";
         update(hostname, Cname());   // overwrite with "empty" cname
     }
+    // ensure min ttl of MinTimeBetweenResolves
+    HostAddressVec ips_checked;
+    BOOST_FOREACH( const HostAddress &addr, new_ips )
+    {
+        if ( addr.get_ttl().get_value() < MinTimeBetweenResolves )
+        {
+            GlobalLogger.info() << "DnsCache: Correcting TTL of IP for "
+                << hostname << " from " << addr.get_ttl().get_value() << "s to "
+                << MinTimeBetweenResolves << "s because was too short";
+            ips_checked.push_back( HostAddress( addr.get_ip(),
+                                                MinTimeBetweenResolves) );
+        }
+        else
+            ips_checked.push_back(addr);
+    }
+
     GlobalLogger.info() << "DnsCache: update IPs for " << key
-                        << " to " << new_ips.size() << "-list";
-    IpCache[key] = new_ips;
+                        << " to " << ips_checked.size() << "-list";
+
+    IpCache[key] = ips_checked;
     HasChanged = true;
 }
 
@@ -239,6 +274,15 @@ void DnsCache::update(const std::string &hostname,
     Cname to_save = Cname(key_for_hostname(cname.Host),
                           cname.Ttl);
 
+    // ensure min ttl of MinTimeBetweenResolves
+    if ( to_save.Ttl.get_value() < MinTimeBetweenResolves )
+    {
+        GlobalLogger.info() << "DnsCache: Correcting TTL of CNAME of "
+            << hostname << " from " << to_save.Ttl.get_value() << "s to "
+            << MinTimeBetweenResolves << "s because was too short";
+        to_save.Ttl = TimeToLive(MinTimeBetweenResolves);
+    }
+
     GlobalLogger.info() << "DnsCache: update CNAME for " << key
                         << " to " << to_save.Host;
     CnameCache[key] = to_save;
@@ -246,6 +290,10 @@ void DnsCache::update(const std::string &hostname,
 }
 
 
+// -----------------------------------------------------------------------------
+// RETRIEVAL
+// -----------------------------------------------------------------------------
+
 /**
  * @returns empty list if no (up to date) ips for hostname in cache
  */