Fix 'occurred' typo
[bpdyndnsd] / src / updater.cpp
index b474264..7c3b021 100644 (file)
@@ -7,9 +7,9 @@
  * @license GPLv2
 */
 
-#include "updater.h"
+#include "updater.hpp"
 
-#include "serviceholder.h"
+#include "serviceholder.hpp"
 
 
 #include <boost/foreach.hpp>
 using namespace std;
 
 
+/// Server error threshold: When the host IP is not current, the DNS TTL expired
+/// and we already sent an update.
+const int ServerErrorTTLExpiredThreshold = 15 * 60;
+
+
 /**
  * Default constructor which initializes the member Conf.
  */
@@ -121,7 +126,7 @@ int Updater::init_config_from_cmd(int argc, char *argv[]) const
 
 /**
  * Load the main config and the service definition files in config path.
- * @return 0 if all is fine, 
+ * @return 0 if all is fine,
  */
 int Updater::init_config_from_files() const
 {
@@ -145,7 +150,7 @@ int Updater::init_config_from_files() const
 
 /**
  * Init all Helper classes
- * @return 
+ * @return
  */
 int Updater::init_helper_classes()
 {
@@ -210,92 +215,102 @@ void Updater::init_log_facility() const
 {
     Log->set_log_facility(Conf->get_loglevel(),Conf->get_syslog(),Conf->get_external_warning_log(),Conf->get_external_warning_level(),Conf->get_external_log_only_once());
     Log->print_init_log_facility();
+
+    Log->set_log_passwords(Conf->get_log_passwords());
 }
 
 
 /**
  * Update all configured services.
+ * @param changed_to_online True if we just changed to online, false if we were already online
  */
-void Updater::update_services() const
+void Updater::update_services(bool changed_to_online) const
 {
     // Get all services from the ServiceHolder.
     list<Service::Ptr> services = ServiceHolder->get_services();
 
     // Get the actual IP of this host.
-    string ip_host = IPAddrHelp->get_actual_ip(Conf->get_webcheck_enabled());
+    string ip_host = IPAddrHelp->get_actual_ip(Conf->get_webcheck_enabled(), changed_to_online, Conf->get_wan_ip_override());
+    if ( ip_host.empty() )
+    {
+        Log->print_no_wan_ip(changed_to_online);
+        return;
+    } else
+    {
+        Log->print_external_wan_ip(changed_to_online, ip_host);
+    }
 
-    if ( !ip_host.empty() )
+    BOOST_FOREACH(Service::Ptr &service, services )
     {
-        BOOST_FOREACH(Service::Ptr &service, services )
-        {
-            string ip_last_update = service->get_actual_ip();
-            string hostname = service->get_hostname();
-            time_t lastupdated = 0;
-            time_t current_time = time(NULL);
+        string ip_last_update = service->get_actual_ip();
+        string hostname = service->get_hostname();
+        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().size() > 0 )
-                lastupdated = service->get_last_updates().front(); /*lint !e1793 */
+        // Get the last update time of the service.
+        time_t lastupdated = service->get_last_update_time();
 
-            Log->print_check_service_update(hostname, current_time, lastupdated);
+        Log->print_check_service_update(hostname, current_time, lastupdated);
 
-            // Do a DNS Query for the dynamic hostname.
-            string ip_dns_recheck = IPAddrHelp->dns_query(hostname);
+        // Do a DNS Query for the dynamic hostname.
+        string ip_dns_recheck = IPAddrHelp->dns_query(hostname);
 
-            Log->print_cached_dns_entry(hostname, ip_dns_recheck, ip_last_update, ip_host);
+        Log->print_cached_dns_entry(hostname, ip_dns_recheck, ip_last_update, ip_host);
+
+        // Test if the DNS-Record could not be found.
+        // If DNS-Record was not found but service was not activated, the hostname could be deactivated, offline or not existent. In this case try a ordinary update.
+        if ( ip_dns_recheck.empty() && service->get_activated() )
+        {
+            Log->print_dns_lookup_failed(changed_to_online, hostname);
+            continue;
+        }
+
+        // Test if the actual DNS-Record differs from the host's IP.
+        if (ip_host == ip_dns_recheck )
+        {
+            Log->print_no_update_needed(changed_to_online, hostname, ip_dns_recheck, ip_last_update, ip_host, lastupdated);
+            // No update needed
+            continue;
+        }
 
-            // Test if the DNS-Record could not be found.
-            if ( ip_dns_recheck.empty() )
+        // Check if the IP set in last update differs from the actual host's ip.
+        if ( ip_last_update != ip_host )
+        {
+            // Update
+            if ( !ip_dns_recheck.empty() )
+            {
+                Log->print_update_service(hostname, ip_dns_recheck, ip_last_update, ip_host, lastupdated);
+            }
+            else
             {
-                // Next in BOOST_FOREACH
+                // Service gets updated the first time and no DNS-Record was found. This is either a initial update or the hostname is really not available.
+                Log->print_update_service(hostname, "<NO IP SET>", ip_last_update, ip_host, lastupdated);
             }
-            // Test if the actual DNS-Record differs from the host's IP.
-            else if ( ip_host != ip_dns_recheck )
+
+            service->update(ip_host, current_time, changed_to_online);
+        }
+        else
+        {
+            int dns_cache_ttl = service->get_dns_cache_ttl();
+
+            // Add server error threshold so we don't jam the server with updates for the same IP
+            // in case the server doesn't hand out the already sent IP via DNS
+            // (might indicate a server error).
+            dns_cache_ttl += ServerErrorTTLExpiredThreshold;
+
+            // Check if DNS Cache TTL is expired, if so, then update the same IP again.
+            if ( (lastupdated + dns_cache_ttl) < current_time )
             {
-                // Check if the service will be updated for the first time.
-                if ( lastupdated == 0 )
-                {
-                    // Update for the firt time.
-                    Log->print_update_service_firttime(hostname, ip_dns_recheck, ip_host);
-                    service->update(ip_host,current_time);
-                }
-                else
-                {
-                    // We already have updated, check if the IP set in last update differs from the actual host's ip.
-                    if ( ip_last_update != ip_host )
-                    {
-                        // Update
-                        Log->print_update_service(hostname, ip_dns_recheck, ip_last_update, ip_host, lastupdated);
-                        service->update(ip_host,current_time);
-                    }
-                    else
-                    {
-                        int dns_cache_ttl = service->get_dns_cache_ttl();
-                        // Check if DNS Cache TTL is expired, if so, then update the same IP again.
-                        if ( (lastupdated + dns_cache_ttl) < current_time )
-                        {
-                            // Update
-                            Log->print_update_service_ttl_expired(hostname, ip_dns_recheck, ip_last_update, ip_host, lastupdated, dns_cache_ttl, current_time);
-                            service->update(ip_host,current_time);
-                        }
-                        else
-                        {
-                            // DNS cache TTL isn't expired
-                            Log->print_update_service_ttl_not_expired(hostname, ip_dns_recheck, ip_last_update, ip_host, lastupdated, dns_cache_ttl, current_time);
-                        }
-                    }
-                }
+                // Update
+                Log->print_update_service_ttl_expired(hostname, ip_dns_recheck, ip_last_update, ip_host, lastupdated, dns_cache_ttl, current_time);
+                service->update(ip_host, current_time, changed_to_online);
             }
             else
             {
-                Log->print_no_update_needed(hostname, ip_dns_recheck, ip_last_update, ip_host, lastupdated);
+                // DNS cache TTL isn't expired
+                Log->print_update_service_ttl_not_expired(changed_to_online, hostname, ip_dns_recheck, ip_last_update, ip_host, lastupdated, dns_cache_ttl, current_time);
             }
         }
     }
-    else
-    {
-        Log->print_no_wan_ip();
-    }
 }