#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>
+#include "dns/dnsmaster.h"
+
using boost::bind;
using boost::posix_time::seconds;
using I2n::Logger::GlobalLogger;
namespace Config
{
int SaveTimerSeconds = 60;
+ int MaxRetrievalRecursions = 10;
}
-
-
DnsCache::DnsCache(const IoServiceItem &io_serv,
const std::string &cache_file)
: IpCache()
void DnsCache::update(const std::string &hostname,
- const std::string &cname)
+ const Cname &cname)
{
GlobalLogger.info() << "DnsCache: update CNAME for " << hostname
- << " to " << cname;
+ << " to " << cname.first;
CnameCache[hostname] = cname;
HasChanged = true;
}
-void DnsCache::update_ttl(const std::string &hostname,
+void DnsCache::update(const std::string &hostname,
const uint32_t new_ttl)
{
GlobalLogger.info() << "DnsCache: ensure TTL for IPs for " << hostname
}
-HostAddressVec& DnsCache::get_ips(const std::string &hostname)
+HostAddressVec DnsCache::get_ips(const std::string &hostname,
+ const bool check_up_to_date)
{
+ HostAddressVec result = IpCache[hostname];
+ if (check_up_to_date)
+ {
+ HostAddressVec result_up_to_date;
+ int threshold = DnsMaster::get_instance()
+ ->get_resolved_ip_ttl_threshold();
+ BOOST_FOREACH( const HostAddress &addr, result )
+ {
+ if (addr.get_ttl().get_updated_value() > threshold)
+ result_up_to_date.push_back(addr);
+ }
+ GlobalLogger.debug() << "DnsCache: From cached list of size "
+ << result.size() << " return " << result_up_to_date.size()
+ << " since rest out of date";
+ result = result_up_to_date;
+ }
GlobalLogger.info() << "DnsCache: request IPs for " << hostname
- << " --> " << IpCache[hostname].size() << "-list";
- return IpCache[hostname];
+ << " --> " << result.size() << "-list";
+ return result;
}
-std::string& DnsCache::get_cname(const std::string &hostname)
+std::string DnsCache::get_cname(const std::string &hostname,
+ const bool check_up_to_date)
{
+ Cname result_obj = CnameCache[hostname];
GlobalLogger.info() << "DnsCache: request CNAME for " << hostname
- << " --> \"" << CnameCache[hostname] << "\"";
- return CnameCache[hostname];
+ << " --> \"" << result_obj.first << "\"";
+ if (check_up_to_date)
+ {
+ if (result_obj.second.get_updated_value() > DnsMaster::get_instance()
+ ->get_resolved_ip_ttl_threshold())
+ return result_obj.first;
+ else
+ {
+ GlobalLogger.debug() << "DnsCache: Cname is out of date";
+ return "";
+ }
+ }
+ else
+ return result_obj.first;
}
-HostAddressVec& DnsCache::get_ips_recursive(const std::string &hostname)
+// underlying assumption in this function: for a hostname, the cache has either
+// a list of IPs saved or a cname saved, but never both
+HostAddressVec DnsCache::get_ips_recursive(const std::string &hostname,
+ const bool check_up_to_date)
{
std::string current_host = hostname;
- HostAddressVec& result = get_ips(current_host);
+ HostAddressVec result = get_ips(current_host);
+ int n_recursions = 0;
while ( result.empty() )
{
- current_host = get_cname(current_host);
+ current_host = get_cname(current_host, check_up_to_date);
if (current_host.empty())
break;
+ else if (++n_recursions >= Config::MaxRetrievalRecursions)
+ {
+ GlobalLogger.warning() << "DnsCache: reached recursion limit of "
+ << n_recursions << " in recursive IP retrieval!";
+ break;
+ }
else
- result = get_ips(current_host);
+ result = get_ips(current_host, check_up_to_date);
}
return result;
}