From: Bjoern Sikora Date: Tue, 25 Aug 2009 14:05:31 +0000 (+0200) Subject: Added DNS Rechecking of DynDNS Hostname after DNS record ttl timeout. X-Git-Tag: v1.1~217 X-Git-Url: http://developer.intra2net.com/git/?a=commitdiff_plain;h=c3dea5dc96ddee1f167ca74665023a5d08c49087;p=bpdyndnsd Added DNS Rechecking of DynDNS Hostname after DNS record ttl timeout. --- diff --git a/src/config.cpp b/src/config.cpp index 64b950d..79f35c1 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -54,6 +54,7 @@ Config::Config(Logger::Ptr _log, Serviceholder::Ptr _serviceholder) ("password",po::value(),"Corresponding password.") ("update_interval",po::value()->default_value(-1),"Update interval in minutes.") ("max_updates_within_interval",po::value()->default_value(-1),"How many updates can be made in one interval.") + ("dns_cache_ttl",po::value()->default_value(-1),"How long a dns record is valid.") ; // Available command line only options @@ -148,7 +149,11 @@ int Config::parse_cmd_line(int argc, char *argv[]) if ( VariablesMap.count("max_updates_within_interval") ) max_updates_within_interval = VariablesMap["max_updates_within_interval"].as(); - Service::Ptr service = create_service(protocol,host,login,password,update_interval,max_updates_within_interval); + int dns_cache_ttl = 0; + if ( VariablesMap.count("dns_cache_ttl") ) + dns_cache_ttl = VariablesMap["dns_cache_ttl"].as(); + + Service::Ptr service = create_service(protocol,host,login,password,update_interval,max_updates_within_interval,dns_cache_ttl); if ( service ) { ServiceHolder->add_service(service); @@ -219,16 +224,16 @@ int Config::parse_cmd_line(int argc, char *argv[]) * @param password Password. * @return A pointer to the created Service object. */ -Service::Ptr Config::create_service(const string &protocol,const string &hostname, const string &login, const string &password, const int update_interval, const int max_updates_within_interval) +Service::Ptr Config::create_service(const string &protocol,const string &hostname, const string &login, const string &password, const int update_interval, const int max_updates_within_interval, const int dns_cache_ttl) { if(protocol == "dhs") { - Service::Ptr service_dhs(new DHS(protocol,hostname,login,password,Log,update_interval,max_updates_within_interval)); + Service::Ptr service_dhs(new DHS(protocol,hostname,login,password,Log,update_interval,max_updates_within_interval,dns_cache_ttl)); return service_dhs; } else if(protocol == "ods") { - Service::Ptr service_ods(new ODS(protocol,hostname,login,password,Log,update_interval,max_updates_within_interval)); + Service::Ptr service_ods(new ODS(protocol,hostname,login,password,Log,update_interval,max_updates_within_interval,dns_cache_ttl)); return service_ods; } else @@ -277,7 +282,11 @@ int Config::load_service_config_file(const string& full_filename) if ( VariablesMap.count("max_updates_within_interval") ) max_updates_within_interval = VariablesMap["max_updates_within_interval"].as(); - Service::Ptr service = create_service(protocol,host,login,password,update_interval,max_updates_within_interval); + int dns_cache_ttl = 0; + if ( VariablesMap.count("dns_cache_ttl") ) + dns_cache_ttl = VariablesMap["dns_cache_ttl"].as(); + + Service::Ptr service = create_service(protocol,host,login,password,update_interval,max_updates_within_interval,dns_cache_ttl); if ( service ) { ServiceHolder->add_service(service); diff --git a/src/config.h b/src/config.h index 4489ab7..36006f8 100644 --- a/src/config.h +++ b/src/config.h @@ -41,7 +41,7 @@ private: std::string WebcheckIpUrl; std::string WebcheckIpUrlAlt; - Service::Ptr create_service(const std::string &protocol,const std::string &hostname, const std::string &login, const std::string &password, const int update_interval, const int max_updates_within_interval); + Service::Ptr create_service(const std::string &protocol,const std::string &hostname, const std::string &login, const std::string &password, const int update_interval, const int max_updates_within_interval, const int dns_cache_ttl); int load_main_config_file(const std::string& full_filename); int load_service_config_file(const std::string& full_filename); diff --git a/src/dhs.cpp b/src/dhs.cpp index ae8623c..9027a3a 100644 --- a/src/dhs.cpp +++ b/src/dhs.cpp @@ -28,7 +28,7 @@ DHS::DHS() * @param _login The login name. * @param _password The corresponding password. */ -DHS::DHS(const string& _protocol, const string& _hostname, const string& _login, const string& _password, const Logger::Ptr& _logger, const int _update_interval, const int _max_updates_within_interval) +DHS::DHS(const string& _protocol, const string& _hostname, const string& _login, const string& _password, const Logger::Ptr& _logger, const int _update_interval, const int _max_updates_within_interval, const int _dns_cache_ttl) { if ( _update_interval == -1 ) // If _update_interval is default po::option_desc (not specified via config) set_update_interval(0); // use default protocol value @@ -40,6 +40,11 @@ DHS::DHS(const string& _protocol, const string& _hostname, const string& _login, else set_max_updates_within_interval(_max_updates_within_interval); + if ( _dns_cache_ttl == -1 ) + set_dns_cache_ttl(180); + else + set_dns_cache_ttl(_dns_cache_ttl); + set_protocol(_protocol); set_hostname(_hostname); set_login(_login); @@ -57,33 +62,6 @@ DHS::~DHS() /** - * Service update method which should implement the corresponding service protocol. - * @param ip The new ip to set for the hostname. - */ -void DHS::update(const string& ip) -{ - // If actual service ip (ip set in last update) differs present host ip, then update - if ( get_actual_ip() != ip ) - { - get_logger()->print_update_service("DHS"); - - if ( perform_update(ip) == 0 ) - { - // if update was successful, we need to set the Lastupdated and ActualIP base member. - get_last_updates()->push_front(time(NULL)); - set_actual_ip(ip); - get_logger()->print_update_service_successful("DHS"); - } - else - { - // problem while trying to update service - // TODO: error logging - } - } -} - - -/** * Performs the Service update. * @param ip IP Address to set. * @return 0 if all is fine, -1 otherwise. diff --git a/src/dhs.h b/src/dhs.h index c91e2bf..9f95ca9 100644 --- a/src/dhs.h +++ b/src/dhs.h @@ -34,12 +34,10 @@ public: DHS(); - DHS(const std::string& _protocol, const std::string& _hostname, const std::string& _login, const std::string& _password, const Logger::Ptr& _logger, const int _update_interval, const int _max_updates_within_interval); + DHS(const std::string& _protocol, const std::string& _hostname, const std::string& _login, const std::string& _password, const Logger::Ptr& _logger, const int _update_interval, const int _max_updates_within_interval, const int dns_cache_ttl); ~DHS(); - void update(const std::string& ip); - int perform_update(const std::string& ip); }; diff --git a/src/iphelper.cpp b/src/iphelper.cpp index f988621..9704b59 100644 --- a/src/iphelper.cpp +++ b/src/iphelper.cpp @@ -61,7 +61,7 @@ string IPHelper::get_actual_ip() const string ip; if ( WebcheckIpUrl.empty() ) { - ip = dns_query(); + ip = dns_query(""); } else { @@ -76,19 +76,24 @@ string IPHelper::get_actual_ip() const /** * Get the actual IP of this host through a DNS query. + * @param _hostname The hostname for the dns lookup, if empty string, then perform a dns lookup to the local hostname. * @return A string representation of the actual IP in dotted format or an empty string if something went wrong. */ -string IPHelper::dns_query() const +string IPHelper::dns_query(const string& _hostname) const { string ip_addr_v4; string ip_addr_v6; + string hostname = Hostname; + if ( !_hostname.empty() ) + hostname = _hostname; + try { // BOOST asio isn't the simplest way to perform a DNS lookup, but it works just fine. net::io_service io_service; net::ip::tcp::resolver resolver(io_service); - net::ip::tcp::resolver::query query(Hostname, "0"); + net::ip::tcp::resolver::query query(hostname, "0"); net::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query); net::ip::tcp::resolver::iterator end; while(endpoint_iterator != end) @@ -99,16 +104,16 @@ string IPHelper::dns_query() const ip_addr_v4 = ip.to_string(); else if ( ip.is_v6() ) ip_addr_v6 = ip.to_string(); - Log->print_own_ipv4(ip_addr_v4); + Log->print_own_ipv4(ip_addr_v4, hostname); if ( UseIPv6 == true ) - Log->print_own_ipv6(ip_addr_v6); + Log->print_own_ipv6(ip_addr_v6, hostname); endpoint_iterator++; } io_service.reset(); } catch(exception& e) { - Log->print_error_hostname_to_ip(e.what(),Hostname); + Log->print_error_hostname_to_ip(e.what(),hostname); return ""; } diff --git a/src/iphelper.h b/src/iphelper.h index be61154..7b6fdbb 100644 --- a/src/iphelper.h +++ b/src/iphelper.h @@ -41,7 +41,7 @@ public: std::string get_actual_ip() const; - std::string dns_query() const; + std::string dns_query(const std::string& _hostname) const; std::string webcheck_ip() const; diff --git a/src/logger.cpp b/src/logger.cpp index 1e5178c..96797bd 100644 --- a/src/logger.cpp +++ b/src/logger.cpp @@ -725,12 +725,12 @@ void Logger::print_hostname(const string& hostname) const * Prints out the detected own ipv4 address * @param ip_addr String representation of the detected ip. */ -void Logger::print_own_ipv4(const string& ip_addr_v4) const +void Logger::print_own_ipv4(const string& ip_addr_v4, const string& hostname) const { if ( 1 <= Loglevel ) { ostringstream msg; - msg << "Detected following IPv4-Address of this host: " << ip_addr_v4 << endl; + msg << "Detected following IPv4-Address of host: " << hostname << " : " << ip_addr_v4 << endl; log_notice(msg.str()); } } @@ -740,12 +740,12 @@ void Logger::print_own_ipv4(const string& ip_addr_v4) const * Prints out the detected own ipv5 address * @param ip_addr String representation of the detected ip. */ -void Logger::print_own_ipv6(const string& ip_addr_v6) const +void Logger::print_own_ipv6(const string& ip_addr_v6, const string& hostname) const { if ( 1 <= Loglevel ) { ostringstream msg; - msg << "Detected following IPv6-Address of this host: " << ip_addr_v6 << endl; + msg << "Detected following IPv6-Address of host: " << hostname << " : " << ip_addr_v6 << endl; log_notice(msg.str()); } } @@ -761,7 +761,7 @@ void Logger::print_error_hostname_to_ip(const string& exception, const string& h if ( 1 <= Loglevel ) { ostringstream msg; - msg << "Could not resolve the hostname: " << hostname << "to an IP-Address: " << exception << endl; + msg << "Could not resolve the hostname: " << hostname << " to an IP-Address: " << exception << endl; log_error(msg.str()); } } diff --git a/src/logger.h b/src/logger.h index 078021f..1a08f15 100644 --- a/src/logger.h +++ b/src/logger.h @@ -127,9 +127,9 @@ public: void print_hostname(const std::string& hostname) const; - void print_own_ipv4(const std::string& ip_addr_v4) const; + void print_own_ipv4(const std::string& ip_addr_v4, const std::string& hostname) const; - void print_own_ipv6(const std::string& ip_addr_v6) const; + void print_own_ipv6(const std::string& ip_addr_v6, const std::string& hostname) const; void print_error_hostname_to_ip(const std::string& exception, const std::string& hostname) const; diff --git a/src/ods.cpp b/src/ods.cpp index 0ef8b6e..1d02d54 100644 --- a/src/ods.cpp +++ b/src/ods.cpp @@ -28,7 +28,7 @@ ODS::ODS() * @param _login The login name. * @param _password The corresponding password. */ -ODS::ODS(const string& _protocol, const string& _hostname, const string& _login, const string& _password, const Logger::Ptr& _logger, const int _update_interval, const int _max_updates_within_interval) +ODS::ODS(const string& _protocol, const string& _hostname, const string& _login, const string& _password, const Logger::Ptr& _logger, const int _update_interval, const int _max_updates_within_interval, const int _dns_cache_ttl) { if ( _update_interval == -1 ) // If _update_interval is default po::option_desc (not specified via config) set_update_interval(15); // use default protocol value @@ -40,6 +40,11 @@ ODS::ODS(const string& _protocol, const string& _hostname, const string& _login, else set_max_updates_within_interval(_max_updates_within_interval); + if ( _dns_cache_ttl == -1 ) + set_dns_cache_ttl(180); + else + set_dns_cache_ttl(_dns_cache_ttl); + set_protocol(_protocol); set_hostname(_hostname); set_login(_login); @@ -57,39 +62,6 @@ ODS::~ODS() /** - * Service update method which should implement the corresponding service protocol. - * @param ip The new ip to set for the hostname. - */ -void ODS::update(const string& ip) -{ - if ( get_actual_ip() != ip ) - { - int current_time = time(NULL); - get_logger()->print_update_service("ODS"); - - // test if update is permitted by UpdateInterval Status - if ( update_allowed(current_time) ) - { - - if ( perform_update(ip) == 0 ) - { - // if update was successful, we need to set the Lastupdated and ActualIP base member. - get_last_updates()->push_front(time(NULL)); - set_actual_ip(ip); - get_logger()->print_update_service_successful("ODS"); - } - else - { - // problem while trying to update service - get_logger()->print_update_service_failure("ODS"); - } - - } - } -} - - -/** * Performs the Service update. * @param ip IP Address to set. * @return 0 if all is fine, -1 otherwise. diff --git a/src/ods.h b/src/ods.h index c74329e..d2bf628 100644 --- a/src/ods.h +++ b/src/ods.h @@ -34,12 +34,10 @@ public: ODS(); - ODS(const std::string& _protocol, const std::string& _hostname, const std::string& _login, const std::string& _password, const Logger::Ptr& _logger, const int _update_interval, const int _max_updates_within_interval); + ODS(const std::string& _protocol, const std::string& _hostname, const std::string& _login, const std::string& _password, const Logger::Ptr& _logger, const int _update_interval, const int _max_updates_within_interval, const int dns_cache_ttl); ~ODS(); - void update(const std::string& ip); - int perform_update(const std::string& ip); }; diff --git a/src/service.cpp b/src/service.cpp index bd55016..704da13 100644 --- a/src/service.cpp +++ b/src/service.cpp @@ -233,7 +233,7 @@ bool Service::update_allowed(const int current_time) { if ( (i == (MaxUpdatesWithinInterval-1)) && ( (*iter + (UpdateInterval*60)) >= current_time ) ) { - Log->print_update_not_allowed(current_time,*iter,MaxUpdatesWithinInterval,"ODS"); + Log->print_update_not_allowed(current_time,*iter,MaxUpdatesWithinInterval,get_service_name()); return false; } i++; @@ -243,6 +243,33 @@ bool Service::update_allowed(const int current_time) /** + * Service update method, common to each service. + * @param ip The new ip to set for the hostname. + */ +void Service::update(const string& ip, const int current_time) +{ + Log->print_update_service(get_service_name()); + + // test if update is permitted by UpdateInterval Status + if ( update_allowed(current_time) ) + { + if ( perform_update(ip) == 0 ) + { + // if update was successful, we need to set the Lastupdated and ActualIP base member. + LastUpdates.push_front(current_time); + ActualIP = ip; + Log->print_update_service_successful(get_service_name()); + } + else + { + // problem while trying to update service + Log->print_update_service_failure(get_service_name()); + } + } +} + + +/** * Setter for member Timeout. * @param _timeout Value to set Timeout to. */ @@ -280,3 +307,39 @@ int Service::get_max_updates_within_interval() const { return MaxUpdatesWithinInterval; } + + +/** + * Get a unique service identify string + * @return A unique service identify string + */ +string Service::get_service_name() const +{ + string service_name; + + service_name.append(Protocol); + service_name.append(" "); + service_name.append(Hostname); + + return service_name; +} + + +/** + * Get member DNSCacheTTL + * @return DNSCacheTTL + */ +int Service::get_dns_cache_ttl() const +{ + return DNSCacheTTL; +} + + +/** + * Set member DNSCacheTTL + * @param _dns_cache_ttl DNSCacheTTL + */ +void Service::set_dns_cache_ttl(const int _dns_cache_ttl) +{ + DNSCacheTTL = _dns_cache_ttl; +} diff --git a/src/service.h b/src/service.h index 9b5c184..8af8c24 100644 --- a/src/service.h +++ b/src/service.h @@ -32,6 +32,7 @@ private: int UpdateInterval; int MaxUpdatesWithinInterval; + int DNSCacheTTL; std::list LastUpdates; @@ -49,7 +50,11 @@ public: virtual ~Service(); - virtual void update(const std::string& ip) = 0; + virtual int perform_update(const std::string& ip) = 0; + + void update(const std::string& ip, const int current_time); + + bool update_allowed(const int current_time); int get_update_interval()const; void set_update_interval(const int _update_interval); @@ -57,6 +62,9 @@ public: int get_max_updates_within_interval() const; void set_max_updates_within_interval(const int _max_updates_within_interval); + int get_dns_cache_ttl() const; + void set_dns_cache_ttl(const int _dns_cache_ttl); + void set_protocol(const std::string& _protocol); std::string get_protocol() const; @@ -78,7 +86,7 @@ public: void set_logger(const Logger::Ptr& _log); Logger::Ptr get_logger() const; - bool update_allowed(const int current_time); + std::string get_service_name() const; bool operator== (const Service& other) const; bool operator!= (const Service& other) const; diff --git a/src/updater.cpp b/src/updater.cpp index 5ca26cf..6bc1239 100644 --- a/src/updater.cpp +++ b/src/updater.cpp @@ -181,7 +181,18 @@ void Updater::update_services() { BOOST_FOREACH(Service::Ptr &service, services ) { - service->update(ip); + string dns_recheck_ip = ip; + int current_time = time(NULL); + + int lastupdated = 0; + if ( service->get_last_updates()->size() > 0 ) + lastupdated = service->get_last_updates()->front(); + + if ( (lastupdated != 0) && ((lastupdated + service->get_dns_cache_ttl()) < current_time) ) + dns_recheck_ip = IPHelp->dns_query(service->get_hostname()); + + if ( (service->get_actual_ip() != ip) || (dns_recheck_ip != ip) ) + service->update(ip,current_time); } } }