From: Bjoern Sikora Date: Fri, 28 Jan 2011 16:36:49 +0000 (+0100) Subject: Don't update the same IP more than 2 times in success. X-Git-Tag: v1.1~26 X-Git-Url: http://developer.intra2net.com/git/?p=bpdyndnsd;a=commitdiff_plain;h=4553e833e4358b9bcd1064c30fb5390a9116c0c4 Don't update the same IP more than 2 times in success. - Added config var max_equal_updates_in_success. - Added Logging if IP is burnt. - Changed LastUpdates list to map. - Hold max(max_equal_updates_in_success,max_updates_within_interval) entries in the LastUpdates map. --- diff --git a/src/config.cpp b/src/config.cpp index acc8a27..ff63d8e 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -113,6 +113,7 @@ void Config::define_config_options() ("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.") + ("max_equal_updates_in_succession",po::value()->default_value(-1),"How many updates with the same IP in succession should be made.") ("dns_cache_ttl",po::value()->default_value(-1),"How long a dns record is valid.") ; @@ -210,15 +211,19 @@ 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(); + int max_equal_updates_in_succession = 0; + if ( VariablesMap.count("max_equal_updates_in_succession") ) + max_equal_updates_in_succession = VariablesMap["max_equal_updates_in_succession"].as(); + 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,server,host,login,password,update_interval,max_updates_within_interval,dns_cache_ttl); + Service::Ptr service = create_service(protocol,server,host,login,password,update_interval,max_updates_within_interval,max_equal_updates_in_succession,dns_cache_ttl); if ( service ) { ServiceHolder->add_service(service); - Log->print_service_object("New Service object from command line options:", service->get_protocol(), service->get_hostname(), service->get_login() ,service->get_password(), service->get_update_interval(), service->get_max_updates_within_interval(), service->get_dns_cache_ttl() , service->get_actual_ip(), service->get_last_updates()); + Log->print_service_object("New Service object from command line options:", service->get_protocol(), service->get_hostname(), service->get_login() ,service->get_password(), service->get_update_interval(), service->get_max_updates_within_interval(), service->get_max_equal_updates_in_succession(), service->get_dns_cache_ttl() , service->get_actual_ip(), service->get_last_updates()); } else { @@ -332,7 +337,7 @@ 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& server, const string& hostname, const string& login, const string& password, const int update_interval, const int max_updates_within_interval, const int dns_cache_ttl) +Service::Ptr Config::create_service(const string &protocol, const string& server, const string& hostname, const string& login, const string& password, const int update_interval, const int max_updates_within_interval, const int max_equal_updates_in_succession, const int dns_cache_ttl) { // Test for valid hostname. Must contain 3 parts minimum. list fqhn_parts; @@ -346,44 +351,44 @@ Service::Ptr Config::create_service(const string &protocol, const string& server if(protocol == "dhs") { - Service::Ptr service_dhs(new ServiceDhs(protocol,hostname,login,password,Log,update_interval,max_updates_within_interval,dns_cache_ttl,Proxy,ProxyPort)); + Service::Ptr service_dhs(new ServiceDhs(protocol,hostname,login,password,Log,update_interval,max_updates_within_interval,max_equal_updates_in_succession,dns_cache_ttl,Proxy,ProxyPort)); return service_dhs; } else if(protocol == "ods") { - Service::Ptr service_ods(new ServiceOds(protocol,hostname,login,password,Log,update_interval,max_updates_within_interval,dns_cache_ttl)); + Service::Ptr service_ods(new ServiceOds(protocol,hostname,login,password,Log,update_interval,max_updates_within_interval,max_equal_updates_in_succession,dns_cache_ttl)); return service_ods; } else if(protocol == "dyndns") { - Service::Ptr service_dyndns(new ServiceDyndns(protocol,hostname,login,password,Log,update_interval,max_updates_within_interval,dns_cache_ttl,Proxy,ProxyPort,server)); + Service::Ptr service_dyndns(new ServiceDyndns(protocol,hostname,login,password,Log,update_interval,max_updates_within_interval,max_equal_updates_in_succession,dns_cache_ttl,Proxy,ProxyPort,server)); return service_dyndns; } else if(protocol == "dyns") { - Service::Ptr service_dyns(new ServiceDyns(protocol,hostname,login,password,Log,update_interval,max_updates_within_interval,dns_cache_ttl,Proxy,ProxyPort)); + Service::Ptr service_dyns(new ServiceDyns(protocol,hostname,login,password,Log,update_interval,max_updates_within_interval,max_equal_updates_in_succession,dns_cache_ttl,Proxy,ProxyPort)); return service_dyns; } else if(protocol == "easydns") { - Service::Ptr service_easydns(new ServiceEasydns(protocol,hostname,login,password,Log,update_interval,max_updates_within_interval,dns_cache_ttl,Proxy,ProxyPort)); + Service::Ptr service_easydns(new ServiceEasydns(protocol,hostname,login,password,Log,update_interval,max_updates_within_interval,max_equal_updates_in_succession,dns_cache_ttl,Proxy,ProxyPort)); return service_easydns; } else if(protocol == "tzo") { - Service::Ptr service_tzo(new ServiceTzo(protocol,hostname,login,password,Log,update_interval,max_updates_within_interval,dns_cache_ttl,Proxy,ProxyPort)); + Service::Ptr service_tzo(new ServiceTzo(protocol,hostname,login,password,Log,update_interval,max_updates_within_interval,max_equal_updates_in_succession,dns_cache_ttl,Proxy,ProxyPort)); return service_tzo; } else if(protocol == "zoneedit") { - Service::Ptr service_zoneedit(new ServiceZoneedit(protocol,hostname,login,password,Log,update_interval,max_updates_within_interval,dns_cache_ttl,Proxy,ProxyPort)); + Service::Ptr service_zoneedit(new ServiceZoneedit(protocol,hostname,login,password,Log,update_interval,max_updates_within_interval,max_equal_updates_in_succession,dns_cache_ttl,Proxy,ProxyPort)); return service_zoneedit; } else if(protocol == "gnudip") { if ( !server.empty() ) { - Service::Ptr service_gnudip(new ServiceGnudip(protocol,server,hostname,login,password,Log,update_interval,max_updates_within_interval,dns_cache_ttl,Proxy,ProxyPort)); + Service::Ptr service_gnudip(new ServiceGnudip(protocol,server,hostname,login,password,Log,update_interval,max_updates_within_interval,max_equal_updates_in_succession,dns_cache_ttl,Proxy,ProxyPort)); return service_gnudip; } else @@ -443,15 +448,19 @@ int Config::load_service_config_file(const string& full_filename) if ( vm.count("max_updates_within_interval") ) max_updates_within_interval = vm["max_updates_within_interval"].as(); + int max_equal_updates_in_succession = 0; + if ( vm.count("max_equal_updates_in_succession") ) + max_equal_updates_in_succession = vm["max_equal_updates_in_succession"].as(); + int dns_cache_ttl = 0; if ( vm.count("dns_cache_ttl") ) dns_cache_ttl = vm["dns_cache_ttl"].as(); - Service::Ptr service = create_service(protocol,server,host,login,password,update_interval,max_updates_within_interval,dns_cache_ttl); + Service::Ptr service = create_service(protocol,server,host,login,password,update_interval,max_updates_within_interval,max_equal_updates_in_succession,dns_cache_ttl); if ( service ) { ServiceHolder->add_service(service); - Log->print_service_object("New Service object from config:", service->get_protocol(), service->get_hostname(), service->get_login() ,service->get_password(), service->get_update_interval(), service->get_max_updates_within_interval(), service->get_dns_cache_ttl() , service->get_actual_ip(), service->get_last_updates()); + Log->print_service_object("New Service object from config:", service->get_protocol(), service->get_hostname(), service->get_login() ,service->get_password(), service->get_update_interval(), service->get_max_updates_within_interval(), service->get_max_equal_updates_in_succession(), service->get_dns_cache_ttl() , service->get_actual_ip(), service->get_last_updates()); } else { diff --git a/src/config.hpp b/src/config.hpp index bf836cc..b93c5dc 100644 --- a/src/config.hpp +++ b/src/config.hpp @@ -54,7 +54,7 @@ private: int DialupSleepSeconds; std::string WanIpOverride; - Service::Ptr create_service(const std::string& protocol, const std::string& server, 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); + Service::Ptr create_service(const std::string& protocol, const std::string& server, const std::string& hostname, const std::string& login, const std::string& password, const int update_interval, const int max_updates_within_interval, const int max_equal_updates_in_succession, 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); void define_config_options(); diff --git a/src/logger.cpp b/src/logger.cpp index 5ec6f35..e953a99 100644 --- a/src/logger.cpp +++ b/src/logger.cpp @@ -816,7 +816,7 @@ void Logger::print_deserialized_objects_success() const * @param actual_ip Service's actual_ip. * @param lastupdated Service's lastupdated. */ -void Logger::print_service_object(const string& message, 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 , const string& actual_ip, list lastupdated) const +void Logger::print_service_object(const string& message, const string& protocol, const string& hostname, const string& login, const string& password, const int update_interval, const int max_updates_within_interval, const int max_equal_updates_in_succession, const int dns_cache_ttl , const string& actual_ip, std::map lastupdated) const { int level = 1; if ( level <= Loglevel ) @@ -829,11 +829,12 @@ void Logger::print_service_object(const string& message, const string& protocol, msg << "\t" << "Password: " << password << endl; msg << "\t" << "Update Interval: " << update_interval << endl; msg << "\t" << "Max Updates: " << max_updates_within_interval << endl; + msg << "\t" << "Max equal Updates:" << max_equal_updates_in_succession << endl; msg << "\t" << "DNS Cache TTL: " << dns_cache_ttl << endl; msg << "\t" << "Actual_IP: " << actual_ip << endl; - BOOST_FOREACH( time_t update_time, lastupdated) + for ( std::map::reverse_iterator r_iter = lastupdated.rbegin(); r_iter != lastupdated.rend(); r_iter++ ) { - msg << "\t" << "Lastupdated: " << update_time << endl; + msg << "\t" << "Lastupdated: " << r_iter->first << " -> " << r_iter->second << endl; } log_notice(msg.str()); } @@ -1948,3 +1949,49 @@ void Logger::print_msg( const string& msg ) const log_error(msg); } } + + +/** + * Print the last updates. + * @param ip_host Actual host IP. + * @param max_equal_updates_in_succession Maximal number of updates for the same IP in succession. + * @param last_updates Map with the last updates in it. + * @param hostname The service hostname. + */ +void Logger::print_last_updates( const std::string& ip_host, const int max_equal_updates_in_succession, const std::map& last_updates, const std::string& hostname ) const +{ + int level = 1; + + if ( level <= Loglevel ) + { + ostringstream msg; + msg << "Last updates for " << hostname << " : "; + + int i = 0; + for ( std::map::reverse_iterator r_iter; (r_iter != last_updates.rend()) && (i < max_equal_updates_in_succession); r_iter++ ) + { + msg << r_iter->first << "->" << r_iter->second; + i++; + } + msg << ". Actual internet IP: " << ip_host << endl; + + log_notice(msg.str()); + } +} + + +/** + * Print the burnt IP. + * @param ip_host Actual host IP which is burnt. + * @param hostname The service hostname. + */ +void Logger::print_ip_burnt( const std::string& ip_host, const std::string& hostname ) const +{ + int level = 0; + if ( level <= Loglevel ) + { + ostringstream msg; + msg << "IP address " << ip_host << " was updated too often in succession, host " << hostname << " blocked until IP Address will be different." << endl; + log_error(msg.str()); + } +} diff --git a/src/logger.hpp b/src/logger.hpp index 62e180c..5ba1594 100644 --- a/src/logger.hpp +++ b/src/logger.hpp @@ -146,7 +146,7 @@ public: void print_deserialized_objects_success() const; - void print_service_object(const std::string& message, 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 , const std::string& actual_ip, std::list lastupdated) const; + void print_service_object(const std::string& message, 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 max_equal_updates_in_succession, const int dns_cache_ttl , const std::string& actual_ip, std::map lastupdates) const; void print_exception_serialize(const std::string& errMsg) const; @@ -275,6 +275,10 @@ public: void print_invalid_service_config() const; void print_msg( const std::string& msg ) const; + + void print_last_updates( const std::string& ip_host, const int max_equal_updates_in_succession, const std::map& last_updates, const std::string& hostname ) const; + + void print_ip_burnt( const std::string& ip_host, const std::string& hostname ) const; }; #endif diff --git a/src/serializeservicecontainer.hpp b/src/serializeservicecontainer.hpp index a80eb08..0e89d78 100644 --- a/src/serializeservicecontainer.hpp +++ b/src/serializeservicecontainer.hpp @@ -15,6 +15,7 @@ #include #include +#include #include #include diff --git a/src/service.cpp b/src/service.cpp index 492425f..fa80fd9 100644 --- a/src/service.cpp +++ b/src/service.cpp @@ -26,6 +26,7 @@ Service::Service() , ActualIP("0.0.0.0") , UpdateInterval(15) , MaxUpdatesWithinInterval(3) + , MaxEqualUpdatesInSuccession(2) , DNSCacheTTL(0) , ErrorCount(0) , ErrorServiceBlockedUntil(0) @@ -139,21 +140,25 @@ Logger::Ptr Service::get_logger() const } -void Service::set_last_updates(std::list _last_updates) +/** + * Setter for member LastUpdates. + * @param _last_updates Value to set LastUpdates to. + */ +void Service::set_last_updates(std::map _last_updates) { LastUpdates.clear(); - BOOST_FOREACH( time_t update_time, _last_updates ) + for ( std::map::iterator iter = _last_updates.begin(); iter != _last_updates.end(); iter++ ) { - LastUpdates.push_back(update_time); + LastUpdates.insert(make_pair(iter->first,iter->second)); } } /** - * Getter for member Lastupdated. - * @return Value of member Lastupdated. + * Getter for member LastUpdates. + * @return Value of member LastUpdates. */ -const list Service::get_last_updates() const +const std::map Service::get_last_updates() const { return LastUpdates; } @@ -179,7 +184,6 @@ std::string Service::get_actual_ip() const } - /** * Overloading of comparison operator. * @param other Reference to other Service object. @@ -212,14 +216,12 @@ bool Service::operator!= (const Service& other) const */ bool Service::update_allowed(const time_t current_time, bool changed_to_online) { - list::iterator iter; - int i=0; - - for (iter = LastUpdates.begin(); (iter != LastUpdates.end()) && ( i < MaxUpdatesWithinInterval ); iter++) + int i = 0; + for ( std::map::reverse_iterator r_iter = LastUpdates.rbegin(); (r_iter != LastUpdates.rend()) && ( i < MaxUpdatesWithinInterval ); r_iter++) { - if ( (i == (MaxUpdatesWithinInterval-1)) && ( (*iter + ((time_t)UpdateInterval*60)) >= current_time ) ) + if ( (i == (MaxUpdatesWithinInterval-1)) && ( (r_iter->first + ((time_t)UpdateInterval*60)) >= current_time ) ) { - Log->print_update_not_allowed(changed_to_online, current_time,*iter,MaxUpdatesWithinInterval,get_service_name()); + Log->print_update_not_allowed(changed_to_online,current_time,r_iter->first,MaxUpdatesWithinInterval,get_service_name()); return false; } i++; @@ -253,7 +255,7 @@ void Service::update(const string& ip, const time_t current_time, bool changed_t if ( perform_update(ip) == 0 ) { // if update was successful, we need to set the Lastupdated and ActualIP base member. - set_last_update(current_time); + set_last_update(current_time,ip); ActualIP = ip; Log->print_update_service_successful(service_name); @@ -282,40 +284,54 @@ void Service::update(const string& ip, const time_t current_time, bool changed_t * Sets the given time into the LastUpdates member and deletes expired entries. * @param _timeout Value to set into LastUpdates. */ -void Service::set_last_update(const time_t current_time) +void Service::set_last_update(const time_t current_time, const string& ip) { // Insert value into the list. - LastUpdates.push_front(current_time); + LastUpdates.insert(make_pair(current_time,ip)); + + // Get the maximum of MaxUpdatesWithinInterval and MaxEqualUpdatesInSuccession + int maximum = max(MaxUpdatesWithinInterval,MaxEqualUpdatesInSuccession); // Check for expired entries: // MaxUpdatesWithinInterval given in service config, then use this to check for expired entries. - if ( MaxUpdatesWithinInterval > 0 ) + if ( maximum > 0 ) { - // Delete the oldest entry if there are more than MaxUpdatesWithinInterval+1 entries in the list. - if (LastUpdates.size() > (MaxUpdatesWithinInterval+1)) - LastUpdates.pop_back(); + // Delete the oldest entry if there are more than max(MaxUpdatesWithinInterval,MaxEqualUpdatesInSuccession)+1 entries in the list. + if ( LastUpdates.size() > (size_t)(maximum+1) ) + LastUpdates.erase(LastUpdates.upper_bound(0)); return; } // UpdateInterval given in service config, then use this to check for expired entries. else if ( UpdateInterval > 0 ) { // Delete the oldest entry if it's older than current_time - UpdateInterval(minutes) + 1. - if ( (current_time - ((time_t)UpdateInterval*60) + 1) > LastUpdates.back() ) - LastUpdates.pop_back(); + if ( (current_time - ((time_t)UpdateInterval*60) + 1) > LastUpdates.upper_bound(zero)->first ) + LastUpdates.erase(LastUpdates.upper_bound(0)); return; } // Neither MaxUpdatesWithinInterval nor UpdateInterval are given, so keep fix number of 10 entries. else { if ( LastUpdates.size() > 10 ) - LastUpdates.pop_back(); + LastUpdates.erase(LastUpdates.upper_bound(0)); return; } } /** + * Getter the last updated time. + * @return Value of the last update as time_t. + */ +time_t Service::get_last_update_time( ) +{ + std::map::reverse_iterator r_iter = LastUpdates.rbegin(); + return r_iter->first; +} + + +/** * Setter for member Timeout. * @param _timeout Value to set Timeout to. */ @@ -356,6 +372,26 @@ int Service::get_max_updates_within_interval() const /** + * Setter for member MaxEqualUpdatesInSuccession. + * @param _max_equal_updates_in_succession Value to set MaxEqualUpdatesInSuccession to. + */ +void Service::set_max_equal_updates_in_succession(const int _max_equal_updates_in_succession) +{ + MaxEqualUpdatesInSuccession = _max_equal_updates_in_succession; +} + + +/** + * Getter for member MaxEqualUpdatesInSuccession. + * @return Value of MaxEqualUpdatesInSuccession. + */ +int Service::get_max_equal_updates_in_succession() const +{ + return MaxEqualUpdatesInSuccession; +} + + +/** * Get a unique service identify string * @return A unique service identify string */ diff --git a/src/service.hpp b/src/service.hpp index fd5924f..e0410f1 100644 --- a/src/service.hpp +++ b/src/service.hpp @@ -35,9 +35,10 @@ private: int UpdateInterval; int MaxUpdatesWithinInterval; + int MaxEqualUpdatesInSuccession; int DNSCacheTTL; - std::list LastUpdates; + std::map LastUpdates; int ErrorCount; time_t ErrorServiceBlockedUntil; @@ -54,6 +55,7 @@ private: ar & ActualIP; ar & UpdateInterval; ar & MaxUpdatesWithinInterval; + ar & MaxEqualUpdatesInSuccession; ar & DNSCacheTTL; } @@ -73,7 +75,9 @@ public: bool update_allowed(const time_t current_time, bool changed_to_online); - void set_last_update(const time_t current_time); + void set_last_update(const time_t current_time, const std::string& ip); + + time_t get_last_update_time(); int get_update_interval()const; void set_update_interval(const int _update_interval); @@ -81,6 +85,9 @@ public: int get_max_updates_within_interval() const; void set_max_updates_within_interval(const int _max_updates_within_interval); + int get_max_equal_updates_in_succession() const; + void set_max_equal_updates_in_succession(const int _max_equal_updates_in_succession); + int get_dns_cache_ttl() const; void set_dns_cache_ttl(const int _dns_cache_ttl); @@ -96,8 +103,8 @@ public: void set_password(const std::string& _password); std::string get_password() const; - void set_last_updates(std::list _last_updates); - const std::list get_last_updates() const; + void set_last_updates(std::map _last_updates); + const std::map get_last_updates() const; void set_actual_ip(const std::string& _actual_ip); std::string get_actual_ip() const; diff --git a/src/service_dhs.cpp b/src/service_dhs.cpp index 6dadcc8..c757d54 100644 --- a/src/service_dhs.cpp +++ b/src/service_dhs.cpp @@ -33,7 +33,7 @@ ServiceDhs::ServiceDhs() * @param _login The login name. * @param _password The corresponding password. */ -ServiceDhs::ServiceDhs(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, const string& _proxy, const int _proxy_port) +ServiceDhs::ServiceDhs(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 _max_equal_updates_in_succession, const int _dns_cache_ttl, const string& _proxy, const int _proxy_port) { if ( _update_interval == -1 ) // If _update_interval is default po::option_desc (not specified via config) set_update_interval(15); // use default protocol value @@ -45,6 +45,11 @@ ServiceDhs::ServiceDhs(const string& _protocol, const string& _hostname, const s else set_max_updates_within_interval(_max_updates_within_interval); + if ( _max_equal_updates_in_succession == -1 ) + set_max_equal_updates_in_succession(2); + else + set_max_equal_updates_in_succession(_max_equal_updates_in_succession); + if ( _dns_cache_ttl == -1 ) set_dns_cache_ttl(7200); else diff --git a/src/service_dhs.hpp b/src/service_dhs.hpp index 1cb8ec5..b529a0d 100644 --- a/src/service_dhs.hpp +++ b/src/service_dhs.hpp @@ -44,7 +44,7 @@ public: ServiceDhs(); - ServiceDhs(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, const std::string& proxy, const int proxy_port); + ServiceDhs(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 max_equal_updates_in_succession, const int dns_cache_ttl, const std::string& proxy, const int proxy_port); ~ServiceDhs(); diff --git a/src/service_dyndns.cpp b/src/service_dyndns.cpp index 294ea97..7a53a74 100644 --- a/src/service_dyndns.cpp +++ b/src/service_dyndns.cpp @@ -28,7 +28,7 @@ ServiceDyndns::ServiceDyndns() * @param _login The login name. * @param _password The corresponding password. */ -ServiceDyndns::ServiceDyndns(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, const string& _proxy, const int _proxy_port, const string& _alternative_server) +ServiceDyndns::ServiceDyndns(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 _max_equal_updates_in_succession, const int _dns_cache_ttl, const string& _proxy, const int _proxy_port, const string& _alternative_server) : AlternativeServer(_alternative_server) { if ( _update_interval == -1 ) // If _update_interval is default po::option_desc (not specified via config) @@ -41,6 +41,11 @@ ServiceDyndns::ServiceDyndns(const string& _protocol, const string& _hostname, c else set_max_updates_within_interval(_max_updates_within_interval); + if ( _max_equal_updates_in_succession == -1 ) + set_max_equal_updates_in_succession(2); + else + set_max_equal_updates_in_succession(_max_equal_updates_in_succession); + if ( _dns_cache_ttl == -1 ) set_dns_cache_ttl(60); else diff --git a/src/service_dyndns.hpp b/src/service_dyndns.hpp index fb0da1c..2cbc541 100644 --- a/src/service_dyndns.hpp +++ b/src/service_dyndns.hpp @@ -43,7 +43,7 @@ public: ServiceDyndns(); - ServiceDyndns(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, const std::string& proxy, const int proxy_port, const std::string& _alternative_server = ""); + ServiceDyndns(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 _max_equal_updates_in_succession, const int dns_cache_ttl, const std::string& proxy, const int proxy_port, const std::string& _alternative_server = ""); ~ServiceDyndns(); diff --git a/src/service_dyns.cpp b/src/service_dyns.cpp index 065d216..4bd14e8 100644 --- a/src/service_dyns.cpp +++ b/src/service_dyns.cpp @@ -33,7 +33,7 @@ ServiceDyns::ServiceDyns() * @param _login The login name. * @param _password The corresponding password. */ -ServiceDyns::ServiceDyns(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, const string& _proxy, const int _proxy_port) +ServiceDyns::ServiceDyns(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 _max_equal_updates_in_succession, const int _dns_cache_ttl, const string& _proxy, const int _proxy_port) { if ( _update_interval == -1 ) // If _update_interval is default po::option_desc (not specified via config) set_update_interval(5); // use default protocol value diff --git a/src/service_dyns.hpp b/src/service_dyns.hpp index 2b57139..0f33b38 100644 --- a/src/service_dyns.hpp +++ b/src/service_dyns.hpp @@ -42,7 +42,7 @@ public: ServiceDyns(); - ServiceDyns(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, const std::string& proxy, const int proxy_port); + ServiceDyns(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 _max_equal_updates_in_succession, const int dns_cache_ttl, const std::string& proxy, const int proxy_port); ~ServiceDyns(); diff --git a/src/service_easydns.cpp b/src/service_easydns.cpp index 1660061..89d9a4e 100644 --- a/src/service_easydns.cpp +++ b/src/service_easydns.cpp @@ -33,7 +33,7 @@ ServiceEasydns::ServiceEasydns() * @param _login The login name. * @param _password The corresponding password. */ -ServiceEasydns::ServiceEasydns(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, const string& _proxy, const int _proxy_port) +ServiceEasydns::ServiceEasydns(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 _max_equal_updates_in_succession, const int _dns_cache_ttl, const string& _proxy, const int _proxy_port) { if ( _update_interval == -1 ) // If _update_interval is default po::option_desc (not specified via config) set_update_interval(10); // use default protocol value @@ -45,6 +45,11 @@ ServiceEasydns::ServiceEasydns(const string& _protocol, const string& _hostname, else set_max_updates_within_interval(_max_updates_within_interval); + if ( _max_equal_updates_in_succession == -1 ) + set_max_equal_updates_in_succession(2); + else + set_max_equal_updates_in_succession(_max_equal_updates_in_succession); + if ( _dns_cache_ttl == -1 ) set_dns_cache_ttl(1200); else diff --git a/src/service_easydns.hpp b/src/service_easydns.hpp index e3460f6..7b8dad6 100644 --- a/src/service_easydns.hpp +++ b/src/service_easydns.hpp @@ -46,7 +46,7 @@ public: ServiceEasydns(); - ServiceEasydns(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, const std::string& proxy, const int proxy_port); + ServiceEasydns(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 _max_equal_updates_in_succession, const int dns_cache_ttl, const std::string& proxy, const int proxy_port); ~ServiceEasydns(); diff --git a/src/service_gnudip.cpp b/src/service_gnudip.cpp index e884c63..e72ee5a 100644 --- a/src/service_gnudip.cpp +++ b/src/service_gnudip.cpp @@ -31,7 +31,7 @@ ServiceGnudip::ServiceGnudip() * @param _login The login name. * @param _password The corresponding password. */ -ServiceGnudip::ServiceGnudip(const string& _protocol, const string& _gnudip_server, 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, const string& _proxy, const int _proxy_port) +ServiceGnudip::ServiceGnudip(const string& _protocol, const string& _gnudip_server, 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 _max_equal_updates_in_succession, const int _dns_cache_ttl, const string& _proxy, const int _proxy_port) : GnudipServer(_gnudip_server) { if ( _update_interval == -1 ) // If _update_interval is default po::option_desc (not specified via config) @@ -44,6 +44,11 @@ ServiceGnudip::ServiceGnudip(const string& _protocol, const string& _gnudip_serv else set_max_updates_within_interval(_max_updates_within_interval); + if ( _max_equal_updates_in_succession == -1 ) + set_max_equal_updates_in_succession(2); + else + set_max_equal_updates_in_succession(_max_equal_updates_in_succession); + if ( _dns_cache_ttl == -1 ) set_dns_cache_ttl(60); else diff --git a/src/service_gnudip.hpp b/src/service_gnudip.hpp index 885ed54..4a1e5df 100644 --- a/src/service_gnudip.hpp +++ b/src/service_gnudip.hpp @@ -47,7 +47,7 @@ public: ServiceGnudip(); - ServiceGnudip(const std::string& _protocol, const std::string& _gnudip_server ,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, const std::string& proxy, const int proxy_port); + ServiceGnudip(const std::string& _protocol, const std::string& _gnudip_server ,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 _max_equal_updates_in_succession, const int dns_cache_ttl, const std::string& proxy, const int proxy_port); ~ServiceGnudip(); diff --git a/src/service_ods.cpp b/src/service_ods.cpp index 8f69f8c..ba6df98 100644 --- a/src/service_ods.cpp +++ b/src/service_ods.cpp @@ -28,7 +28,7 @@ ServiceOds::ServiceOds() * @param _login The login name. * @param _password The corresponding password. */ -ServiceOds::ServiceOds(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) +ServiceOds::ServiceOds(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 _max_equal_updates_in_succession, const int _dns_cache_ttl) : UpdateServer("update.ods.org") , Port("7071") { @@ -42,6 +42,11 @@ ServiceOds::ServiceOds(const string& _protocol, const string& _hostname, const s else set_max_updates_within_interval(_max_updates_within_interval); + if ( _max_equal_updates_in_succession == -1 ) + set_max_equal_updates_in_succession(2); + else + set_max_equal_updates_in_succession(_max_equal_updates_in_succession); + if ( _dns_cache_ttl == -1 ) set_dns_cache_ttl(180); else diff --git a/src/service_ods.hpp b/src/service_ods.hpp index 9ac6bf3..85141ca 100644 --- a/src/service_ods.hpp +++ b/src/service_ods.hpp @@ -38,7 +38,7 @@ public: ServiceOds(); - ServiceOds(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); + ServiceOds(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 _max_equal_updates_in_succession, const int dns_cache_ttl); ~ServiceOds(); diff --git a/src/service_tzo.cpp b/src/service_tzo.cpp index 0aa9981..f21c674 100644 --- a/src/service_tzo.cpp +++ b/src/service_tzo.cpp @@ -33,7 +33,7 @@ ServiceTzo::ServiceTzo() * @param _login The login name. * @param _password The corresponding password. */ -ServiceTzo::ServiceTzo(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, const string& _proxy, const int _proxy_port) +ServiceTzo::ServiceTzo(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 _max_equal_updates_in_succession, const int _dns_cache_ttl, const string& _proxy, const int _proxy_port) { if ( _update_interval == -1 ) // If _update_interval is default po::option_desc (not specified via config) set_update_interval(15); // use default protocol value @@ -45,6 +45,11 @@ ServiceTzo::ServiceTzo(const string& _protocol, const string& _hostname, const s else set_max_updates_within_interval(_max_updates_within_interval); + if ( _max_equal_updates_in_succession == -1 ) + set_max_equal_updates_in_succession(2); + else + set_max_equal_updates_in_succession(_max_equal_updates_in_succession); + if ( _dns_cache_ttl == -1 ) set_dns_cache_ttl(60); else diff --git a/src/service_tzo.hpp b/src/service_tzo.hpp index 8daf390..c5b0bae 100644 --- a/src/service_tzo.hpp +++ b/src/service_tzo.hpp @@ -42,7 +42,7 @@ public: ServiceTzo(); - ServiceTzo(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, const std::string& proxy, const int proxy_port); + ServiceTzo(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 _max_equal_updates_in_succession, const int dns_cache_ttl, const std::string& proxy, const int proxy_port); ~ServiceTzo(); diff --git a/src/service_zoneedit.cpp b/src/service_zoneedit.cpp index 9c629c2..16381b2 100644 --- a/src/service_zoneedit.cpp +++ b/src/service_zoneedit.cpp @@ -33,7 +33,7 @@ ServiceZoneedit::ServiceZoneedit() * @param _login The login name. * @param _password The corresponding password. */ -ServiceZoneedit::ServiceZoneedit(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, const string& _proxy, const int _proxy_port) +ServiceZoneedit::ServiceZoneedit(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 _max_equal_updates_in_succession, const int _dns_cache_ttl, const string& _proxy, const int _proxy_port) { if ( _update_interval == -1 ) // If _update_interval is default po::option_desc (not specified via config) set_update_interval(15); // use default protocol value @@ -45,6 +45,11 @@ ServiceZoneedit::ServiceZoneedit(const string& _protocol, const string& _hostnam else set_max_updates_within_interval(_max_updates_within_interval); + if ( _max_equal_updates_in_succession == -1 ) + set_max_equal_updates_in_succession(2); + else + set_max_equal_updates_in_succession(_max_equal_updates_in_succession); + if ( _dns_cache_ttl == -1 ) set_dns_cache_ttl(60); else diff --git a/src/service_zoneedit.hpp b/src/service_zoneedit.hpp index 61c58b7..836cc80 100644 --- a/src/service_zoneedit.hpp +++ b/src/service_zoneedit.hpp @@ -42,7 +42,7 @@ public: ServiceZoneedit(); - ServiceZoneedit(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, const std::string& proxy, const int proxy_port); + ServiceZoneedit(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 _max_equal_updates_in_succession, const int dns_cache_ttl, const std::string& proxy, const int proxy_port); ~ServiceZoneedit(); diff --git a/src/serviceholder.cpp b/src/serviceholder.cpp index 1eee942..c1c02e7 100644 --- a/src/serviceholder.cpp +++ b/src/serviceholder.cpp @@ -68,7 +68,7 @@ int Serviceholder::serialize_services() const BOOST_FOREACH(const Service::Ptr &service, OldServices) { if ( !service->get_last_updates().empty() && - ( service->get_last_updates().front() + ((time_t)service->get_update_interval()*60) ) >= current_time ) /*lint !e1793 */ // UpdateInterval timeout of service isn't expired. + ( service->get_last_update_time() + ((time_t)service->get_update_interval()*60) ) >= current_time ) /*lint !e1793 */ // UpdateInterval timeout of service isn't expired. service_container->add_service(service); } @@ -149,14 +149,14 @@ int Serviceholder::deserialize_services() BOOST_FOREACH(Service::Ptr &old_service, _old_services) { OldServices.push_back(old_service); - Log->print_service_object("Deserialized following Service object:", old_service->get_protocol(), old_service->get_hostname(), old_service->get_login() ,old_service->get_password(), old_service->get_update_interval(), old_service->get_max_updates_within_interval(), old_service->get_dns_cache_ttl() , old_service->get_actual_ip(), old_service->get_last_updates()); + Log->print_service_object("Deserialized following Service object:", old_service->get_protocol(), old_service->get_hostname(), old_service->get_login() ,old_service->get_password(), old_service->get_update_interval(), old_service->get_max_updates_within_interval(), old_service->get_max_equal_updates_in_succession(), old_service->get_dns_cache_ttl() , old_service->get_actual_ip(), old_service->get_last_updates()); BOOST_FOREACH(Service::Ptr &service, Services) { if ( *service == *old_service ) { service->set_last_updates(old_service->get_last_updates()); service->set_actual_ip(old_service->get_actual_ip()); - Log->print_service_object("New Service object with adopted values:", service->get_protocol(), service->get_hostname(), service->get_login() ,service->get_password(), service->get_update_interval(), service->get_max_updates_within_interval(), service->get_dns_cache_ttl() , service->get_actual_ip(), service->get_last_updates()); + Log->print_service_object("New Service object with adopted values:", service->get_protocol(), service->get_hostname(), service->get_login() ,service->get_password(), service->get_update_interval(), service->get_max_updates_within_interval(), service->get_max_equal_updates_in_succession(), service->get_dns_cache_ttl() , service->get_actual_ip(), service->get_last_updates()); // We have adopted the values of the old_service. Just set lastupdated and timeout to 0, so this old_service wont be serialized. old_service->set_update_interval(0); } diff --git a/src/updater.cpp b/src/updater.cpp index 5d32d10..58648f6 100644 --- a/src/updater.cpp +++ b/src/updater.cpp @@ -246,8 +246,37 @@ void Updater::update_services(bool changed_to_online) const time_t current_time = time(NULL); // Try to get the lastupdated time of the actual service if there is one. - if ( !service->get_last_updates().empty() ) - lastupdated = service->get_last_updates().front(); /*lint !e1793 */ + // And check for burnt IP, too. + std::map last_updates = service->get_last_updates(); /*lint !e1793 */ + if ( last_updates.size() > 0 ) + { + bool ip_burnt = true; + string ip_next_to_last_update; + int max_equal_updates_in_succession = service->get_max_equal_updates_in_succession(); + int i = 0; + for ( std::map::reverse_iterator r_iter; (r_iter != last_updates.rend()) && (i < max_equal_updates_in_succession); r_iter++ ) + { + if ( i == 0 ) + lastupdated = r_iter->first; + + if ( ip_host != r_iter->second ) + { + ip_burnt = false; + break; + } + + i++; + } + + Log->print_last_updates(ip_host,max_equal_updates_in_succession,last_updates,service->get_hostname()); + + if ( ip_burnt ) + { + // IP Address is burnt. Too many updates in succession with the same IP. + Log->print_ip_burnt(ip_host,service->get_hostname()); + continue; + } + } Log->print_check_service_update(hostname, current_time, lastupdated);