Add exception safety to load of the DNS disk cache
authorThomas Jarosch <thomas.jarosch@intra2net.com>
Wed, 7 Apr 2021 09:29:02 +0000 (11:29 +0200)
committerThomas Jarosch <thomas.jarosch@intra2net.com>
Wed, 7 Apr 2021 09:29:02 +0000 (11:29 +0200)
A corrupted cache might throw an exception in the middle
of an unserialize operation. This might leave our DnsCache class
with an undefined data state.

Solution: Unserialize into local variables first, then do a
atomic swap() once everything could be parsed correctly.

src/dns/dnscache.cpp

index 37d62c9..c097aea 100644 (file)
@@ -171,16 +171,22 @@ void DnsCache::load_from_cachefile()
             std::ifstream ifs( CacheFile.c_str() );
             boost::archive::xml_iarchive ia(ifs);
 
+            ip_map_type new_IpCache;
+            cname_map_type new_CnameCache;
             std::string cache_save_time_str;
 
-            ia & BOOST_SERIALIZATION_NVP(IpCache);
-            ia & BOOST_SERIALIZATION_NVP(CnameCache);
+            ia & BOOST_SERIALIZATION_NVP(new_IpCache);
+            ia & BOOST_SERIALIZATION_NVP(new_CnameCache);
             ia & BOOST_SERIALIZATION_NVP(cache_save_time_str);
 
-            boost::posix_time::ptime cache_save_time
+            const boost::posix_time::ptime cache_save_time
                     = boost::posix_time::from_iso_string(cache_save_time_str);
             GlobalLogger.info() << "DnsCache: loaded from file " << CacheFile;
 
+            // atomic switch over
+            IpCache.swap(new_IpCache);
+            CnameCache.swap(new_CnameCache);
+
             check_timestamps(cache_save_time);
         }
         catch (boost::archive::archive_exception &exc)