Don't update the same IP more than 2 times in success.
authorBjoern Sikora <bjoern.sikora@intra2net.com>
Fri, 28 Jan 2011 16:36:49 +0000 (17:36 +0100)
committerBjoern Sikora <bjoern.sikora@intra2net.com>
Fri, 28 Jan 2011 16:36:49 +0000 (17:36 +0100)
 - 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.

25 files changed:
src/config.cpp
src/config.hpp
src/logger.cpp
src/logger.hpp
src/serializeservicecontainer.hpp
src/service.cpp
src/service.hpp
src/service_dhs.cpp
src/service_dhs.hpp
src/service_dyndns.cpp
src/service_dyndns.hpp
src/service_dyns.cpp
src/service_dyns.hpp
src/service_easydns.cpp
src/service_easydns.hpp
src/service_gnudip.cpp
src/service_gnudip.hpp
src/service_ods.cpp
src/service_ods.hpp
src/service_tzo.cpp
src/service_tzo.hpp
src/service_zoneedit.cpp
src/service_zoneedit.hpp
src/serviceholder.cpp
src/updater.cpp

index acc8a27..ff63d8e 100644 (file)
@@ -113,6 +113,7 @@ void Config::define_config_options()
         ("password",po::value<string>(),"Corresponding password.")
         ("update_interval",po::value<int>()->default_value(-1),"Update interval in minutes.")
         ("max_updates_within_interval",po::value<int>()->default_value(-1),"How many updates can be made in one interval.")
+        ("max_equal_updates_in_succession",po::value<int>()->default_value(-1),"How many updates with the same IP in succession should be made.")
         ("dns_cache_ttl",po::value<int>()->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>();
 
+            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>();
+
             int dns_cache_ttl = 0;
             if ( VariablesMap.count("dns_cache_ttl") )
                 dns_cache_ttl = VariablesMap["dns_cache_ttl"].as<int>();
 
-            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<string> 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>();
 
+                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>();
+
                 int dns_cache_ttl = 0;
                 if ( vm.count("dns_cache_ttl") )
                     dns_cache_ttl = vm["dns_cache_ttl"].as<int>();
 
-                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
                 {
index bf836cc..b93c5dc 100644 (file)
@@ -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();
index 5ec6f35..e953a99 100644 (file)
@@ -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<time_t> 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<time_t,std::string> 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<time_t,std::string>::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<time_t,std::string>& 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<time_t,std::string>::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());
+    }
+}
index 62e180c..5ba1594 100644 (file)
@@ -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<time_t> 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<time_t,std::string> 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<time_t,std::string>& last_updates, const std::string& hostname ) const;
+
+    void print_ip_burnt( const std::string& ip_host, const std::string& hostname ) const;
 };
 
 #endif
index a80eb08..0e89d78 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <boost/serialization/list.hpp>
 #include <boost/serialization/vector.hpp>
+#include <boost/serialization/map.hpp>
 #include <boost/serialization/shared_ptr.hpp>
 #include <boost/serialization/export.hpp>
 
index 492425f..fa80fd9 100644 (file)
@@ -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<time_t> _last_updates)
+/**
+ * Setter for member LastUpdates.
+ * @param _last_updates Value to set LastUpdates to.
+ */
+void Service::set_last_updates(std::map<time_t,std::string> _last_updates)
 {
     LastUpdates.clear();
-    BOOST_FOREACH( time_t update_time, _last_updates )
+    for ( std::map<time_t,std::string>::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<time_t> Service::get_last_updates() const
+const std::map<time_t,std::string> 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<time_t>::iterator iter;
-    int i=0;
-
-    for (iter = LastUpdates.begin(); (iter != LastUpdates.end()) && ( i < MaxUpdatesWithinInterval ); iter++)
+    int i = 0;
+    for ( std::map<time_t,std::string>::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<time_t,std::string>::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
  */
index fd5924f..e0410f1 100644 (file)
@@ -35,9 +35,10 @@ private:
 
     int UpdateInterval;
     int MaxUpdatesWithinInterval;
+    int MaxEqualUpdatesInSuccession;
     int DNSCacheTTL;
 
-    std::list<time_t> LastUpdates;
+    std::map<time_t,std::string> 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<time_t> _last_updates);
-    const std::list<time_t> get_last_updates() const;
+    void set_last_updates(std::map<time_t,std::string> _last_updates);
+    const std::map<time_t,std::string> get_last_updates() const;
 
     void set_actual_ip(const std::string& _actual_ip);
     std::string get_actual_ip() const;
index 6dadcc8..c757d54 100644 (file)
@@ -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
index 1cb8ec5..b529a0d 100644 (file)
@@ -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();
 
index 294ea97..7a53a74 100644 (file)
@@ -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
index fb0da1c..2cbc541 100644 (file)
@@ -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();
 
index 065d216..4bd14e8 100644 (file)
@@ -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
index 2b57139..0f33b38 100644 (file)
@@ -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();
 
index 1660061..89d9a4e 100644 (file)
@@ -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
index e3460f6..7b8dad6 100644 (file)
@@ -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();
 
index e884c63..e72ee5a 100644 (file)
@@ -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
index 885ed54..4a1e5df 100644 (file)
@@ -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();
 
index 8f69f8c..ba6df98 100644 (file)
@@ -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
index 9ac6bf3..85141ca 100644 (file)
@@ -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();
 
index 0aa9981..f21c674 100644 (file)
@@ -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
index 8daf390..c5b0bae 100644 (file)
@@ -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();
 
index 9c629c2..16381b2 100644 (file)
@@ -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
index 61c58b7..836cc80 100644 (file)
@@ -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();
 
index 1eee942..c1c02e7 100644 (file)
@@ -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);
                 }
index 5d32d10..58648f6 100644 (file)
@@ -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<time_t,std::string> 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<time_t,std::string>::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);