#include <filefunc.hxx> // I2n::file_exists
#include <boost/foreach.hpp>
#include <boost/bind.hpp>
-#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/asio/placeholders.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/map.hpp>
namespace Config
{
- int SaveTimerSeconds = 60;
+ const int SAVE_TIMER_SECONDS = 60;
+ const int CACHE_TIME_WARP_THRESH_HOURS = 24;
}
// -----------------------------------------------------------------------------
load_from_cachefile();
// schedule next save
- (void) SaveTimer.expires_from_now( seconds( Config::SaveTimerSeconds ) );
+ (void) SaveTimer.expires_from_now( seconds( Config::SAVE_TIMER_SECONDS ) );
SaveTimer.async_wait( bind( &DnsCache::schedule_save, this,
boost::asio::placeholders::error ) );
}
save_to_cachefile();
// schedule next save
- (void) SaveTimer.expires_from_now( seconds( Config::SaveTimerSeconds ) );
+ (void) SaveTimer.expires_from_now( seconds( Config::SAVE_TIMER_SECONDS ) );
SaveTimer.async_wait( bind( &DnsCache::schedule_save, this,
boost::asio::placeholders::error ) );
}
{
try
{
+ // remember time of save
+ std::string cache_save_time_str = boost::posix_time::to_iso_string(
+ boost::posix_time::second_clock::universal_time() );
+
std::ofstream ofs( CacheFile.c_str() );
boost::archive::xml_oarchive oa(ofs);
- //oa << boost::serialization::make_nvp("IpCache", IpCache);
- //oa << boost::serialization::make_nvp("CnameCache", CnameCache);
oa & BOOST_SERIALIZATION_NVP(IpCache);
oa & BOOST_SERIALIZATION_NVP(CnameCache);
+ oa & BOOST_SERIALIZATION_NVP(cache_save_time_str);
GlobalLogger.info() << "DnsCache: saved to cache file "
<< CacheFile;
std::ifstream ifs( CacheFile.c_str() );
boost::archive::xml_iarchive ia(ifs);
+ std::string cache_save_time_str;
+
ia & BOOST_SERIALIZATION_NVP(IpCache);
ia & BOOST_SERIALIZATION_NVP(CnameCache);
+ ia & BOOST_SERIALIZATION_NVP(cache_save_time_str);
+
+ boost::posix_time::ptime cache_save_time
+ = boost::posix_time::from_iso_string(cache_save_time_str);
GlobalLogger.info() << "DnsCache: loaded from file " << CacheFile;
+
+ check_timestamps(cache_save_time);
}
catch (boost::archive::archive_exception &exc)
{
}
+/**
+ * @brief check that loaded cache really is from the past
+ *
+ * Added this to avoid trouble in case the system time is changed into the past.
+ * In that cast would have TTLs here in cache that are valid much too long.
+ *
+ * Therefore check SaveCacheTime and if that is in the future, set all TTLs to 0
+ *
+ * @returns true if had to re-set timestamps
+ */
+bool DnsCache::check_timestamps(const boost::posix_time::ptime &cache_save_time)
+{
+ // check if CacheSaveTime is in the future
+ boost::posix_time::ptime now
+ = boost::posix_time::second_clock::universal_time()
+ + boost::posix_time::hours( Config::CACHE_TIME_WARP_THRESH_HOURS );
+ if (now > cache_save_time)
+ { // Cache was saved in the past -- everything alright
+ return false;
+ }
+
+ GlobalLogger.warning() << "DnsCache: loaded cache from the future (saved "
+ << cache_save_time << ")! Resetting all TTLs to 0.";
+
+ // reset TTLs in IP cache
+ BOOST_FOREACH( const ip_map_type::value_type key_and_ip, IpCache )
+ {
+ HostAddressVec addr_reset;
+ BOOST_FOREACH( HostAddress address, key_and_ip.second )
+ addr_reset.push_back( HostAddress( address.get_ip(), 0 ) );
+ IpCache[key_and_ip.first] = addr_reset;
+ }
+
+ // reset TTLs in CNAME cache
+ BOOST_FOREACH( const cname_map_type::value_type key_and_cname, CnameCache )
+ CnameCache[key_and_cname.first] = Cname( key_and_cname.second.Host,
+ TimeToLive(0) );
+
+ return true;
+}
+
+
// -----------------------------------------------------------------------------
// UPDATE
// -----------------------------------------------------------------------------