Introduced new class IPHelper which should perform DNS and webcheck IP queries.
authorBjoern Sikora <bjoern.sikora@intra2net.com>
Tue, 11 Aug 2009 14:36:47 +0000 (16:36 +0200)
committerBjoern Sikora <bjoern.sikora@intra2net.com>
Tue, 11 Aug 2009 14:36:47 +0000 (16:36 +0200)
src/config.cpp
src/config.h
src/iphelper.cpp [new file with mode: 0644]
src/iphelper.h [new file with mode: 0644]
src/logger.cpp
src/logger.h
src/main.cpp
src/updater.cpp
src/updater.h

index af4308c..45ab17c 100644 (file)
@@ -109,19 +109,19 @@ Config::~Config()
  * This function serializes all Service objects in Services and OldServices (where the update Timeout isn't expired) into a specified file.
  * @return 0 if all is fine, -1 if output file could not be opened for reading or error while serializing.
  */
-int Config::serialize_services() const
+int Config::serialize_services()
 {
     // Put Services and OldServices into Serviceholder.
     Serviceholder::Ptr service_holder(new Serviceholder());
 
-    BOOST_FOREACH(Service::Ptr service, Services)
+    BOOST_FOREACH(Service::Ptr &service, Services)
     {
         service_holder->add_service(service);
     }
 
     int current_time = time(NULL);
 
-    BOOST_FOREACH(Service::Ptr service, OldServices)
+    BOOST_FOREACH(Service::Ptr &service, OldServices)
     {
         if ( ( service->get_lastupdated() + service->get_timeout() ) >= current_time )  // Update Timeout of service isn't expired.
             service_holder->add_service(service);
@@ -198,11 +198,11 @@ int Config::deserialize_services()
         // Put all de-serialized Services into OldServices member and
         // compare new Services (generated from config file and cmd) with old Services (de-serialized from object file)
         // if identical Service was found, adopt the value from old Service to recover Services' state.
-        BOOST_FOREACH(Service::Ptr old_service, _old_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_actual_ip(), old_service->get_lastupdated());
-            BOOST_FOREACH(Service::Ptr service, Services)
+            BOOST_FOREACH(Service::Ptr &service, Services)
             {
                 if ( *service == *old_service )
                 {
@@ -537,13 +537,13 @@ bool Config::get_daemon_mode() const
  */
 void Config::delete_services()
 {
-    BOOST_FOREACH( Service::Ptr service, Services )
+    BOOST_FOREACH( Service::Ptr &service, Services )
     {
         service.reset();
     }
     Services.clear();
 
-    BOOST_FOREACH( Service::Ptr service, OldServices )
+    BOOST_FOREACH( Service::Ptr &service, OldServices )
     {
         service.reset();
     }
index 65cff88..bca6199 100644 (file)
@@ -54,7 +54,7 @@ public:
 
     ~Config();
 
-    int serialize_services() const;
+    int serialize_services();
 
     int deserialize_services();
 
diff --git a/src/iphelper.cpp b/src/iphelper.cpp
new file mode 100644 (file)
index 0000000..9e9bfff
--- /dev/null
@@ -0,0 +1,151 @@
+/** @file
+ * @brief IPHelper class implementation. This class represents a Helper to get the actual IP.
+ *
+ *
+ *
+ * @copyright Intra2net AG
+ * @license GPLv2
+*/
+
+#include "iphelper.h"
+#include <boost/asio.hpp>
+
+using namespace std;
+
+namespace net = boost::asio;
+
+/**
+ * Default constructor.
+ */
+IPHelper::IPHelper()
+    : Hostname("")
+    , WebcheckUrl("")
+    , WebcheckUrlAlt("")
+    , Log(new Logger)
+    , UseIPv6(false)
+{
+}
+
+
+/**
+ * Constructor.
+ */
+IPHelper::IPHelper(Logger::Ptr _log)
+    : Hostname("")
+    , WebcheckUrl("")
+    , WebcheckUrlAlt("")
+    , Log(new Logger)
+    , UseIPv6(false)
+{
+    Log = _log;
+}
+
+
+/**
+ * Default destructor
+ */
+IPHelper::~IPHelper()
+{
+}
+
+
+/**
+ * Initializes the ip helper.
+ */
+int IPHelper::init_hostname()
+{
+    Hostname = net::ip::host_name();
+
+    Log->print_hostname(Hostname);
+
+    return 0;
+}
+
+
+/**
+ * Get the actual IP of this host through a conventional DNS query or through a IP webcheck URL if configured so.
+ * @return A string representation of the actual IP in dotted format or an empty string if something went wrong.
+ */
+string IPHelper::get_actual_ip() const
+{
+    if ( WebcheckUrl == "" )
+    {
+        return dns_query();
+    }
+    else
+    {
+        return webcheck_ip();
+    }
+    return "";
+}
+
+void IPHelper::set_hostname(const string& _hostname)
+{
+    Hostname = _hostname;
+}
+
+
+/**
+ * Get the actual IP of this host through a DNS query.
+ * @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 ip_addr_v4 = "";
+    string ip_addr_v6 = "";
+
+    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::iterator endpoint_iterator = resolver.resolve(query);
+        net::ip::tcp::resolver::iterator end;
+        while(endpoint_iterator != end)
+        {
+            net::ip::tcp::endpoint endpoint = endpoint_iterator->endpoint();
+            net::ip::address ip = endpoint.address();
+            if ( ip.is_v4() )
+                ip_addr_v4 = ip.to_string();
+            else if ( ip.is_v6() )
+                ip_addr_v6 = ip.to_string();
+            Log->print_own_ip(ip_addr_v4, ip_addr_v6);
+            endpoint_iterator++;
+        }
+        io_service.reset();
+    }
+    catch(exception& e)
+    {
+        Log->print_error_hostname_to_ip(e.what(),Hostname);
+        return "";
+    }
+
+    if ( (UseIPv6 == true) && (ip_addr_v6 != "") )
+        return ip_addr_v6;
+
+    return ip_addr_v4;
+}
+
+
+/**
+ * Get the actual IP of this host through a IP webcheck URL.
+ * @return A string representation of the actual IP in dotted format or an empty string if something went wrong.
+ */
+string IPHelper::webcheck_ip() const
+{
+    string ip_addr = "127.0.0.1";
+
+    return ip_addr;
+}
+
+
+/**
+ * Setter for both members WebcheckUrl and WebcheckUrlAlt
+ * @param _webcheck_url The primary webcheck URL.
+ * @param _webcheck_url_alt The fallback webcheck URL.
+ */
+void IPHelper::set_webcheck_urls(std::string& _webcheck_url, std::string& _webcheck_url_alt)
+{
+
+}
diff --git a/src/iphelper.h b/src/iphelper.h
new file mode 100644 (file)
index 0000000..00163ea
--- /dev/null
@@ -0,0 +1,54 @@
+/** @file
+ * @brief IPHelper class header. This class represents a Helper to get the actual IP.
+ *
+ *
+ *
+ * @copyright Intra2net AG
+ * @license GPLv2
+*/
+
+#ifndef IPHELPER_H
+#define IPHELPER_H
+
+#include "logger.h"
+
+#include <boost/shared_ptr.hpp>
+
+/**
+       @author Bjoern Sikora <bjoern.sikora@intra2net.com>
+*/
+class IPHelper
+{
+private:
+    std::string Hostname;
+    std::string WebcheckUrl;
+    std::string WebcheckUrlAlt;
+
+    bool UseIPv6;
+
+    Logger::Ptr Log;
+
+public:
+
+    typedef boost::shared_ptr<IPHelper> Ptr;
+
+    IPHelper();
+
+    IPHelper(Logger::Ptr);
+
+    ~IPHelper();
+
+    void set_hostname(const std::string&);
+
+    std::string get_actual_ip() const;
+
+    std::string dns_query() const;
+
+    std::string webcheck_ip() const;
+
+    void set_webcheck_urls(std::string&, std::string&);
+
+    int init_hostname();
+};
+
+#endif
index 3a24b22..d8c2bc1 100644 (file)
@@ -669,6 +669,10 @@ void Logger::print_error_kill_child(const int pid) const
 }
 
 
+/**
+ * Child was killed by parent because of error.
+ * @param pid The pid (child) killed.
+ */
 void Logger::print_child_killed(const int pid) const
 {
     if ( 0 <= Loglevel )
@@ -693,3 +697,50 @@ void Logger::print_no_object_file(const std::string& object_file) const
         log_warning(msg.str());
     }
 }
+
+
+/**
+ * Prints out the given hostname
+ * @param hostname Hostname as string.
+ */
+void Logger::print_hostname(const std::string& hostname) const
+{
+    if ( 1 <= Loglevel )
+    {
+        ostringstream msg;
+        msg << "Detected following hostname of localhost: " << hostname << endl;
+        log_notice(msg.str());
+    }
+}
+
+
+/**
+ * Prints out the detected own ip address
+ * @param ip_addr String representation of the detected ip.
+ */
+void Logger::print_own_ip(const std::string& ip_addr_v4, const std::string& ip_addr_v6) const
+{
+    if ( 1 <= Loglevel )
+    {
+        ostringstream msg;
+        msg << "Detected following IPv4-Address of this host: " << ip_addr_v4 << endl;
+        msg << "Detected following IPv6-Address of this host: " << ip_addr_v6 << endl;
+        log_notice(msg.str());
+    }
+}
+
+
+/**
+ * Exception while trying to resolve hostname to ip.
+ * @param exception The exception caught.
+ * @param hostname The hostname.
+ */
+void Logger::print_error_hostname_to_ip(const std::string& exception, const std::string& hostname) const
+{
+    if ( 1 <= Loglevel )
+    {
+        ostringstream msg;
+        msg << "Could not resolve the hostname: " << hostname << "to an IP-Address: " << exception << endl;
+        log_error(msg.str());
+    }
+}
index b47bb12..1eb88db 100644 (file)
@@ -124,6 +124,12 @@ public:
     void print_child_killed(const int) const;
 
     void print_no_object_file(const std::string&) const;
+
+    void print_hostname(const std::string&) const;
+
+    void print_own_ip(const std::string&, const std::string&) const;
+
+    void print_error_hostname_to_ip(const std::string&, const std::string&) const;
 };
 
 #endif
index 60b7196..c421f36 100644 (file)
@@ -35,6 +35,7 @@
 #include "service.cpp"
 #include "serviceholder.cpp"
 #include "updater.cpp"
+#include "iphelper.cpp"
 
 
 using namespace std;
@@ -232,6 +233,10 @@ int main(int argc, char *argv[])
     if ( init_signals() != 0)
         return -1;
 
+    // init the ip_helper
+    if ( updater->init_ip_helper() != 0 )
+        return -1;
+
     // init daemon_mode if enabled
     if ( init_daemon_mode(updater->get_config()->get_daemon_mode()) != 0 )
         return -1;
index d3103ad..947dcbb 100644 (file)
@@ -21,10 +21,17 @@ Updater::Updater()
     // Initialize program wide Logger, at this point we don't know where to log and with which loglevel.
     Logger::Ptr _log(new Logger);
     Log = _log;
+    _log.reset();
 
     // initialize Config
     Config::Ptr _config(new Config(Log));
     Conf = _config;
+    _config.reset();
+
+    // initialize IPHelper
+    IPHelper::Ptr _iphelp(new IPHelper(Log));
+    IPHelp = _iphelp;
+    _iphelp.reset();
 }
 
 
@@ -102,6 +109,18 @@ Logger::Ptr Updater::get_logger() const
 
 
 /**
+ * Init the IPHelp member with needed values.
+ * @return 0 if all is fine, -1 otherwise.
+ */
+int Updater::init_ip_helper()
+{
+    IPHelp->init_hostname();
+
+    return 0;
+}
+
+
+/**
  * Reloading the config. Delete all Service objects and then init new Service objects from config files.
  */
 int Updater::reload_config()
@@ -141,7 +160,7 @@ void Updater::update_services()
 {
     list<Service::Ptr> services = this->Conf->get_services();
 
-    string ip = "192.168.1.1";
+    string ip = IPHelp->get_actual_ip();
 
     BOOST_FOREACH(Service::Ptr &service, services )
     {
index 347b311..0e3bbca 100644 (file)
@@ -12,6 +12,7 @@
 
 #include "config.h"
 #include "logger.h"
+#include "iphelper.h"
 
 #include <boost/shared_ptr.hpp>
 
@@ -23,6 +24,7 @@ private:
 
     Config::Ptr Conf;
     Logger::Ptr Log;
+    IPHelper::Ptr IPHelp;
 
 public:
 
@@ -45,6 +47,8 @@ public:
     int reload_config();
 
     void init_log_facility();
+
+    int init_ip_helper();
 };
 
 #endif