Block service for a short period of time on too many update errors
[bpdyndnsd] / src / service.cpp
index 0294615..dcc7fa1 100644 (file)
 
 using namespace std;
 
+/// Number of update errors until a service will be blocked
+const int MaxErrorCount = 3;
+/// Number of seconds a service will be blocked if MaxErrorCount is reached
+const int ErrorBlockServiceSeconds = 15 * 60;
 
 /**
  * Default Constructor
@@ -23,6 +27,8 @@ Service::Service()
     , UpdateInterval(0)
     , MaxUpdatesWithinInterval(0)
     , DNSCacheTTL(0)
+    , ErrorCount(0)
+    , ErrorServiceBlockedUntil(0)
     , Log(new Logger())
 {
 }
@@ -227,7 +233,16 @@ bool Service::update_allowed(const time_t current_time)
  */
 void Service::update(const string& ip, const time_t current_time)
 {
-    Log->print_update_service(get_service_name());
+    const std::string service_name = get_service_name();
+
+    // Check if service is blocked for a short period of time (because of update errors)
+    if (ErrorServiceBlockedUntil && current_time < ErrorServiceBlockedUntil)
+    {
+        Log->print_update_service_is_blocked(service_name, ErrorServiceBlockedUntil - current_time);
+        return;
+    }
+
+    Log->print_update_service(service_name);
 
     // test if update is permitted by UpdateInterval Status
     if ( update_allowed(current_time) )
@@ -237,12 +252,24 @@ void Service::update(const string& ip, const time_t current_time)
             // if update was successful, we need to set the Lastupdated and ActualIP base member.
             set_last_update(current_time);
             ActualIP = ip;
-            Log->print_update_service_successful(get_service_name());
+            Log->print_update_service_successful(service_name);
+
+            ErrorCount = 0;
+            ErrorServiceBlockedUntil = 0;
         }
         else
         {
             // problem while trying to update service
-            Log->print_update_service_failure(get_service_name());
+            Log->print_update_service_failure(service_name);
+
+            ++ErrorCount;
+            if (ErrorCount >= MaxErrorCount)
+            {
+                Log->print_block_service(service_name, ErrorBlockServiceSeconds);
+
+                ErrorServiceBlockedUntil = time(NULL) + ErrorBlockServiceSeconds;
+                ErrorCount = 0;
+            }
         }
     }
 }