Added DNS Rechecking of DynDNS Hostname after DNS record ttl timeout.
authorBjoern Sikora <bjoern.sikora@intra2net.com>
Tue, 25 Aug 2009 14:05:31 +0000 (16:05 +0200)
committerBjoern Sikora <bjoern.sikora@intra2net.com>
Tue, 25 Aug 2009 14:05:31 +0000 (16:05 +0200)
13 files changed:
src/config.cpp
src/config.h
src/dhs.cpp
src/dhs.h
src/iphelper.cpp
src/iphelper.h
src/logger.cpp
src/logger.h
src/ods.cpp
src/ods.h
src/service.cpp
src/service.h
src/updater.cpp

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