config/option/pingreplytimeoutoption.cpp
config/option/maxaddressresolutionattemptsoption.cpp
config/option/resolvedipttlthresholdoption.cpp
+ config/option/mintimebetweenresolvesoption.cpp
config/option/dnscachefileoption.cpp
dns/timetolive.cpp
dns/hostaddress.cpp
PingReplyTimeout( 30 ),
MaxAddressResolutionAttempts( 10 ),
ResolvedIpTtlThreshold( 10 ),
+ MinTimeBetweenResolves( 10 ),
DnsCacheFile(""),
Hosts(),
RatioRandomHosts( 1.0f ),
ResolvedIpTtlThreshold = resolved_ip_ttl_threshold;
}
+int Configuration::get_min_time_between_resolves() const
+{
+ return MinTimeBetweenResolves;
+}
+void Configuration::set_min_time_between_resolves( const int min_time_between_resolves )
+{
+ BOOST_ASSERT(min_time_between_resolves >= 0 );
+ MinTimeBetweenResolves = min_time_between_resolves;
+}
+
void Configuration::set_dns_cache_file( const std::string &dns_cache_file)
{
BOOST_ASSERT( !dns_cache_file.empty() );
void set_resolved_ip_ttl_threshold(
const int resolved_ip_ttl_threshold );
+ int get_min_time_between_resolves() const;
+ void set_min_time_between_resolves(
+ const int min_time_between_resolves );
+
std::string get_dns_cache_file() const;
void set_dns_cache_file(const std::string &dns_cache_file);
int PingReplyTimeout;
int MaxAddressResolutionAttempts;
int ResolvedIpTtlThreshold;
+ int MinTimeBetweenResolves;
std::string DnsCacheFile;
HostList Hosts;
float RatioRandomHosts;
#include "config/option/pingreplytimeoutoption.h"
#include "config/option/maxaddressresolutionattemptsoption.h"
#include "config/option/resolvedipttlthresholdoption.h"
+#include "config/option/mintimebetweenresolvesoption.h"
#include "config/option/dnscachefileoption.h"
using namespace std;
ConfigurationOptionItem resolved_ip_ttl_threshold( new ResolvedIpTtlThresholdOption );
ConfigOptions.push_back( resolved_ip_ttl_threshold );
+ ConfigurationOptionItem min_time_between_resolves( new MinTimeBetweenResolvesOption );
+ ConfigOptions.push_back( min_time_between_resolves );
+
ConfigurationOptionItem ratio_random_hosts( new RatioRandomHostsOption );
ConfigOptions.push_back( ratio_random_hosts );
--- /dev/null
+/*
+ The software in this package is distributed under the GNU General
+ Public License version 2 (with a special exception described below).
+
+ A copy of GNU General Public License (GPL) is included in this distribution,
+ in the file COPYING.GPL.
+
+ As a special exception, if other files instantiate templates or use macros
+ or inline functions from this file, or you compile this file and link it
+ with other works to produce a work based on this file, this file
+ does not by itself cause the resulting work to be covered
+ by the GNU General Public License.
+
+ However the source code for this file must still be made available
+ in accordance with section (3) of the GNU General Public License.
+
+ This exception does not invalidate any other reasons why a work based
+ on this file might be covered by the GNU General Public License.
+ */
+
+#include "config/option/mintimebetweenresolvesoption.h"
+
+#include <logfunc.hpp>
+
+using namespace std;
+using boost::program_options::value;
+using boost::program_options::variables_map;
+using I2n::Logger::GlobalLogger;
+
+//-----------------------------------------------------------------------------
+// MinTimeBetweenResolvesOption
+//-----------------------------------------------------------------------------
+
+MinTimeBetweenResolvesOption::MinTimeBetweenResolvesOption() :
+ ConfigurationOption(
+ "min-time-between-resolves",
+ value<int>()->default_value( 10 ),
+ "Minimum time in seconds between calls to DNS resolve of same address"
+ )
+{
+}
+
+MinTimeBetweenResolvesOption::~MinTimeBetweenResolvesOption()
+{
+}
+
+bool MinTimeBetweenResolvesOption::parse(
+ const variables_map& vm,
+ Configuration *configuration
+)
+{
+ // default-source-network-interface
+ if ( 1 <= vm.count( get_command_string() ) )
+ {
+ int thresh = vm[ get_command_string() ].as<int> ();
+ configuration->set_min_time_between_resolves( thresh );
+
+ GlobalLogger.info() << get_command_string() << "="
+ << thresh << endl;
+
+ return true;
+ }
+
+ return false;
+}
--- /dev/null
+/*
+ The software in this package is distributed under the GNU General
+ Public License version 2 (with a special exception described below).
+
+ A copy of GNU General Public License (GPL) is included in this distribution,
+ in the file COPYING.GPL.
+
+ As a special exception, if other files instantiate templates or use macros
+ or inline functions from this file, or you compile this file and link it
+ with other works to produce a work based on this file, this file
+ does not by itself cause the resulting work to be covered
+ by the GNU General Public License.
+
+ However the source code for this file must still be made available
+ in accordance with section (3) of the GNU General Public License.
+
+ This exception does not invalidate any other reasons why a work based
+ on this file might be covered by the GNU General Public License.
+ */
+
+#ifndef MIN_TIME_BETWEEN_RESOLVES_OPTION_H
+#define MIN_TIME_BETWEEN_RESOLVES_OPTION_H
+
+#include <boost/program_options.hpp>
+
+#include "config/option/configurationoption.h"
+
+//-----------------------------------------------------------------------------
+// MinTimeBetweenResolvesOption
+//-----------------------------------------------------------------------------
+
+/**
+ * @brief This class represents the "min-time-between-resolves"
+ * configuration option.
+ */
+class MinTimeBetweenResolvesOption : public ConfigurationOption
+{
+public:
+ MinTimeBetweenResolvesOption();
+ virtual ~MinTimeBetweenResolvesOption();
+
+ virtual bool parse(
+ const boost::program_options::variables_map &vm,
+ Configuration *configuration
+ );
+
+};
+
+#endif // MIN_TIME_BETWEEN_RESOLVES_OPTION_H
int MaxRetrievalRecursions = 10;
}
+// -----------------------------------------------------------------------------
+// Cname
+// -----------------------------------------------------------------------------
+
Cname::Cname()
: Host()
, 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();
}
+// -----------------------------------------------------------------------------
+// LOAD / SAVE
+// -----------------------------------------------------------------------------
+
void DnsCache::schedule_save(const boost::system::error_code &error)
{
// just in case: ensure SaveTimer is cancelled
}
+// -----------------------------------------------------------------------------
+// UPDATE
+// -----------------------------------------------------------------------------
+
// warn if hostname is empty and remove trailing dot
std::string DnsCache::key_for_hostname(const std::string &hostname) const
{
<< " 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;
}
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;
}
+// -----------------------------------------------------------------------------
+// RETRIEVAL
+// -----------------------------------------------------------------------------
+
/**
* @returns empty list if no (up to date) ips for hostname in cache
*/
static const std::string DoNotUseCacheFile;
DnsCache( const IoServiceItem &io_serv,
- const std::string &cache_file );
+ const std::string &cache_file,
+ const uint32_t min_time_between_resolves );
~DnsCache();
// accessed from ResolverBase subclasses
boost::asio::deadline_timer SaveTimer;
std::string CacheFile;
bool HasChanged;
+ uint32_t MinTimeBetweenResolves;
// internal functions
private:
void DnsMaster::create_master(const IoServiceItem &io_serv,
const boost::asio::ip::address &default_name_server,
const int resolved_ip_ttl_threshold,
+ const int min_time_between_resolves,
const int max_address_resolution_attempts,
const std::string &cache_file)
{
GlobalLogger.info() << "DnsMaster: Creating cache";
- DnsCacheItem cache( new DnsCache(io_serv, cache_file) );
- create_master(io_serv, default_name_server, resolved_ip_ttl_threshold,
- max_address_resolution_attempts, cache);
+ DnsCacheItem cache(
+ new DnsCache(io_serv,
+ cache_file,
+ static_cast<uint32_t>(min_time_between_resolves)
+ )
+ );
+ create_master(io_serv,
+ default_name_server,
+ resolved_ip_ttl_threshold,
+ max_address_resolution_attempts,
+ cache);
}
void DnsMaster::create_master(const IoServiceItem &io_serv,
static void create_master(const IoServiceItem &io_serv,
const boost::asio::ip::address &default_name_server,
const int resolved_ip_ttl_threshold,
+ const int min_time_between_resolves,
const int max_address_resolution_attempts,
const std::string &cache_file);
static void create_master(const IoServiceItem &io_serv,
io_service,
name_server_ip,
configuration->get_resolved_ip_ttl_threshold(),
+ configuration->get_min_time_between_resolves(),
configuration->get_max_address_resolution_attempts(),
configuration->get_dns_cache_file() );
${CMAKE_SOURCE_DIR}/src/config/option/pingreplytimeoutoption.cpp
${CMAKE_SOURCE_DIR}/src/config/option/maxaddressresolutionattemptsoption.cpp
${CMAKE_SOURCE_DIR}/src/config/option/resolvedipttlthresholdoption.cpp
+ ${CMAKE_SOURCE_DIR}/src/config/option/mintimebetweenresolvesoption.cpp
${CMAKE_SOURCE_DIR}/src/config/option/dnscachefileoption.cpp
${CMAKE_SOURCE_DIR}/src/host/loglevel.cpp
${CMAKE_SOURCE_DIR}/src/host/logoutput.cpp
${CMAKE_SOURCE_DIR}/src/config/option/pingreplytimeoutoption.cpp
${CMAKE_SOURCE_DIR}/src/config/option/maxaddressresolutionattemptsoption.cpp
${CMAKE_SOURCE_DIR}/src/config/option/resolvedipttlthresholdoption.cpp
+ ${CMAKE_SOURCE_DIR}/src/config/option/mintimebetweenresolvesoption.cpp
${CMAKE_SOURCE_DIR}/src/config/option/dnscachefileoption.cpp
${CMAKE_SOURCE_DIR}/src/host/loglevel.cpp
${CMAKE_SOURCE_DIR}/src/host/logoutput.cpp
${CMAKE_SOURCE_DIR}/src/config/option/pingreplytimeoutoption.cpp
${CMAKE_SOURCE_DIR}/src/config/option/maxaddressresolutionattemptsoption.cpp
${CMAKE_SOURCE_DIR}/src/config/option/resolvedipttlthresholdoption.cpp
+ ${CMAKE_SOURCE_DIR}/src/config/option/mintimebetweenresolvesoption.cpp
${CMAKE_SOURCE_DIR}/src/config/option/dnscachefileoption.cpp
${CMAKE_SOURCE_DIR}/src/host/loglevel.cpp
${CMAKE_SOURCE_DIR}/src/host/logoutput.cpp
// if this assert fails, you must add or remove one of the options in the
// test below. Will probably find them all in
// src/config/configurationoptions.cpp constructor
- BOOST_CHECK_EQUAL( options.size(), 17 );
+ BOOST_CHECK_EQUAL( options.size(), 18 );
BOOST_CHECK_EQUAL( option_present( options, "hosts-down-limit" ), true );
BOOST_CHECK_EQUAL( option_present( options, "link-down-interval" ), true );
BOOST_CHECK_EQUAL( option_present( options, "ping-reply-timeout" ), true );
BOOST_CHECK_EQUAL( option_present( options, "max-address-resolution-attempts" ), true );
BOOST_CHECK_EQUAL( option_present( options, "resolved-ip-ttl-threshold" ), true );
+ BOOST_CHECK_EQUAL( option_present( options, "min-time-between-resolves" ), true );
BOOST_CHECK_EQUAL( option_present( options, "dns-cache-file" ), true );
BOOST_CHECK_EQUAL( option_present( options, "ratio-random-hosts" ), true );
BOOST_CHECK_EQUAL( option_present( options, "host.name" ), true );
// constants for master
address name_server = address::from_string("127.0.0.1");
-int resolved_ip_ttl_threshold = 3;
+int resolved_ip_ttl_threshold = 5;
+uint32_t min_time_between_resolves = 3; // should be < resolved_ip_ttl_threshold
int max_address_resolution_attempts = 2;
std::string cache_file = DnsCache::DoNotUseCacheFile;
// DNS Cache
DnsCacheItem cache_temp = DnsCacheItem(
- new DnsCache(IoService, cache_file) );
+ new DnsCache(IoService, cache_file, min_time_between_resolves) );
cache_temp.swap( Cache );
cache_temp.reset();
fill_cache();
Cache->update("cname3.test", Cname("cname2.test", 37) );
}
- {
+ { // for cache_outdated_test
HostAddressVec ips;
ips.push_back( HostAddress( address::from_string("192.168.42.4"),
0 ) );
Cname("host_outdated.test", resolved_ip_ttl_threshold+1));
}
+ { // for cache_ttl_below_thresh_test
+ // TTLs < min_time_between_resolves should be corrected
+ HostAddressVec ips;
+ ips.push_back( HostAddress( address::from_string("192.128.42.8"),
+ 1 ) );
+ Cache->update("host_ttl_below_thresh.test", ips);
+
+ Cache->update( "cname_ttl_below_thresh.test",
+ Cname("host_ttl_below_thresh.test", 2) );
+ }
+
BOOST_TEST_MESSAGE( "Done filling cache." );
}
BOOST_AUTO_TEST_CASE( cache_retrieve_ip1 )
{
HostAddressVec ips = Cache->get_ips("host1.test");
- BOOST_CHECK_EQUAL( ips.size(), 1 );
+ BOOST_REQUIRE_EQUAL( ips.size(), 1 );
HostAddress ip = ips.front();
BOOST_CHECK( ip.is_valid() );
BOOST_CHECK_EQUAL( ip.get_ip().to_string(), "192.168.42.1" );
{
// should get IP from host1 but ttl from cname since is smaller
HostAddressVec ips = Cache->get_ips_recursive("cname.test");
- BOOST_CHECK_EQUAL( ips.size(), 1 );
+ BOOST_REQUIRE_EQUAL( ips.size(), 1 );
HostAddress ip = ips.front();
BOOST_CHECK( ip.is_valid() );
BOOST_CHECK_EQUAL( ip.get_ip().to_string(), "192.168.42.1" );
{
// should get IP from host1 but ttl from cname2 since is smaller
HostAddressVec ips = Cache->get_ips_recursive("cname3.test");
- BOOST_CHECK_EQUAL( ips.size(), 1 );
+ BOOST_REQUIRE_EQUAL( ips.size(), 1 );
HostAddress ip = ips.front();
BOOST_CHECK( ip.is_valid() );
BOOST_CHECK_EQUAL( ip.get_ip().to_string(), "192.168.42.1" );
std::stringstream file_name;
file_name << DATA_DIR_STRING << "/" << "dns_cache_example.xml";
BOOST_TEST_MESSAGE( "loading cache from file " << file_name.str() );
- DnsCache loaded_cache( IoService, file_name.str() );
+ DnsCache loaded_cache( IoService,
+ file_name.str(),
+ min_time_between_resolves );
HostAddressVec ips = loaded_cache.get_ips("abc.xyz");
- BOOST_CHECK_EQUAL( ips.size(), 1 );
+ BOOST_REQUIRE_EQUAL( ips.size(), 1 );
HostAddress ip = ips.front();
BOOST_CHECK_EQUAL( ip.get_ip().to_string(), "11.22.33.44" );
BOOST_CHECK_EQUAL( ip.get_ttl().get_value(), 567 );
BOOST_CHECK_EQUAL( ips.size(), 1 );
}
+BOOST_AUTO_TEST_CASE( cache_ttl_below_thresh_test )
+{
+ // in fill_cache,
+ HostAddressVec ips = Cache->get_ips("host_ttl_below_thresh.test", false);
+ BOOST_REQUIRE_EQUAL( ips.size(), 1 );
+ HostAddress ip = ips.front();
+ BOOST_CHECK_EQUAL( ip.get_ttl().get_value(), min_time_between_resolves );
+ Cname cname = Cache->get_cname("cname_ttl_below_thresh.test", false);
+ BOOST_CHECK_EQUAL( cname.Ttl.get_value(), min_time_between_resolves );
+}
BOOST_AUTO_TEST_SUITE_END() // of TestDnsCache