Firt shot on DHS Protocol implementation. At this point only Error handling is missing.
authorBjoern Sikora <bjoern.sikora@intra2net.com>
Wed, 2 Sep 2009 10:01:17 +0000 (12:01 +0200)
committerBjoern Sikora <bjoern.sikora@intra2net.com>
Wed, 2 Sep 2009 10:01:17 +0000 (12:01 +0200)
src/dhs.cpp
src/dhs.h
src/httphelper.cpp
src/httphelper.h
src/logger.cpp
src/logger.h

index 49bd832..dd3fc80 100644 (file)
@@ -10,6 +10,7 @@
 #include "dhs.h"
 
 #include <time.h>
+#include <boost/foreach.hpp>
 
 using namespace std;
 
@@ -31,17 +32,17 @@ DHS::DHS()
 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, 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(0);              // use default protocol value
+        set_update_interval(15);              // use default protocol value
     else
         set_update_interval(_update_interval);
 
     if ( _max_updates_within_interval == -1 )
-        set_max_updates_within_interval(0);
+        set_max_updates_within_interval(3);
     else
         set_max_updates_within_interval(_max_updates_within_interval);
 
     if ( _dns_cache_ttl == -1 )
-        set_dns_cache_ttl(180);
+        set_dns_cache_ttl(7200);
     else
         set_dns_cache_ttl(_dns_cache_ttl);
 
@@ -52,9 +53,20 @@ DHS::DHS(const string& _protocol, const string& _hostname, const string& _login,
     set_logger(_logger);
 
     // create http helper class
-    HTTPHelper::Ptr _http_help(new HTTPHelper(_logger,_proxy,_proxy_port));
+    HTTPHelper::Ptr _http_help(new HTTPHelper(_logger,_proxy,_proxy_port,_login,_password));
     HTTPHelp = _http_help;
     _http_help.reset();
+
+    // extract domain part from hostname
+    list<string> host_domain_part = separate_domain_and_host_part(get_hostname());
+    if ( host_domain_part.size() <= 1 )
+    {
+        BaseUrl = assemble_base_url(host_domain_part.front(),"");
+    }
+    else
+    {
+        BaseUrl = assemble_base_url(host_domain_part.front(),host_domain_part.back());
+    }
 }
 
 
@@ -67,13 +79,109 @@ DHS::~DHS()
 
 
 /**
+ * Assemble the dhs update url from the given hostname and domain part
+ * @param hostname The hostname to update IP for.
+ * @param domain_part The domain_part in which the hostname is located.
+ * @return The assembled update url without IP.
+ */
+string DHS::assemble_base_url(const string& hostname, const string& domain_part) const
+{
+    string base_url;
+    if ( !domain_part.empty() )
+    {
+        base_url = "http://members.dhs.org";
+        base_url.append("/nic/hosts?hostscmd=edit&hostscmdstage=2&type=4&domain=");
+        base_url.append(domain_part);
+        base_url.append("&hostname=");
+        base_url.append(hostname);
+        base_url.append("&updatetype=Online&ip=");
+    }
+    else
+    {
+        base_url = "http://members.dhs.org";
+        base_url.append("/nic/hosts?hostscmd=edit&hostscmdstage=2&type=4&hostname=");
+        base_url.append(hostname);
+        base_url.append("&updatetype=Online&ip=");
+    }
+    return base_url;
+}
+
+
+/**
+ * Separates the hostname from the domain part.
+ * @param fqdn Hostname with domain part.
+ * @return A list with 2 elements (first element is the hostname, second element the domain part), or a list with 1 element if the domain part couldn't be determined.
+ */
+list<string> DHS::separate_domain_and_host_part(const string& fqdn) const
+{
+    list<string> splitted = split(fqdn,".");
+
+    if ( splitted.size() > 1 )
+    {
+        string host = splitted.front();
+        splitted.pop_front();
+
+        string domain = splitted.front();
+        splitted.pop_front();
+
+        BOOST_FOREACH(string domain_part, splitted)
+        {
+            domain.append(".");
+            domain.append(domain_part);
+        }
+
+        splitted.clear();
+        splitted.push_back(host);
+        splitted.push_back(domain);
+    }
+
+    return splitted;
+}
+
+
+/**
+ * Splitts a string into single tokens useing given delimiters
+ * @param str String to split
+ * @param delimiters Deliminters to use
+ * @return A list with the single tokens
+ */
+list<string> DHS::split(const string& str,const string& delimiters) const
+{
+    list<string> tokens;
+    // Skip delimiters at beginning.
+    string::size_type lastPos = str.find_first_not_of(delimiters, 0);
+    // Find first "non-delimiter".
+    string::size_type pos = str.find_first_of(delimiters, lastPos);
+
+    while (string::npos != pos || string::npos != lastPos)
+    {
+        // Found a token, add it to the list.
+        tokens.push_back(str.substr(lastPos, pos - lastPos));
+        // Skip delimiters.  Note the "not_of"
+        lastPos = str.find_first_not_of(delimiters, pos);
+        // Find next "non-delimiter"
+        pos = str.find_first_of(delimiters, lastPos);
+    }
+    return tokens;
+}
+
+
+/**
  * Performs the Service update.
  * @param ip IP Address to set.
  * @return 0 if all is fine, -1 otherwise.
  */
 int DHS::perform_update(const std::string& ip)
 {
+    BaseUrl.append(ip);
+
+    cout << "BASE URL: " << BaseUrl << endl;
+
+    string output = HTTPHelp->http_get(BaseUrl);
+
+    cout << "OUTPUT: " << output << endl;
 
+    // TODO: check output for failure, we have to parse html :-(
 
     return 0;
 }
index 54c85c2..54e818b 100644 (file)
--- a/src/dhs.h
+++ b/src/dhs.h
@@ -17,7 +17,7 @@
 
 #include <boost/serialization/array.hpp>
 #include <boost/shared_ptr.hpp>
-
+#include <list>
 
 class DHS : public Service
 {
@@ -28,8 +28,16 @@ private:
     template<class Archive>
     void serialize(Archive & ar, const unsigned int version);
 
+    std::string BaseUrl;
+
     HTTPHelper::Ptr HTTPHelp;
 
+    std::list<std::string> split(const std::string& str,const std::string& delimiters) const;
+
+    std::list<std::string> separate_domain_and_host_part(const std::string& str) const;
+
+    std::string assemble_base_url(const std::string& hostname, const std::string& domain_part) const;
+
 public:
 
     typedef boost::shared_ptr<DHS> Ptr;
index 927f2b3..2b4b3ac 100644 (file)
@@ -16,12 +16,14 @@ HTTPHelper::HTTPHelper()
 {
 }
 
-HTTPHelper::HTTPHelper(Logger::Ptr _log, string _proxy, int _proxy_port)
+HTTPHelper::HTTPHelper(Logger::Ptr _log, const string& _proxy, const int _proxy_port, const string& _username, const string& _password)
 {
     Log = _log;
     Proxy = _proxy;
     ProxyPort = _proxy_port;
     CurlEasyHandle = init_curl(CurlWritedataBuff, CurlErrBuff);
+
+    set_curl_auth(_username,_password);
 }
 
 
@@ -30,7 +32,6 @@ HTTPHelper::~HTTPHelper()
 }
 
 
-
 /**
  * Perform a HTTP GET operation
  * @param url URL for HTTP GET operation
@@ -91,6 +92,18 @@ void HTTPHelper::set_curl_url(const string& url)
 
 
 /**
+ * Sets HTTP AUTH parameters
+ * @param username The username for HTTP AUTH
+ * @param password The password for HTTP AUTH
+ */
+void HTTPHelper::set_curl_auth(const string& username, const string& password)
+{
+    curl_easy_setopt(CurlEasyHandle,CURLOPT_USERNAME,username.c_str());
+    curl_easy_setopt(CurlEasyHandle,CURLOPT_PASSWORD,password.c_str());
+}
+
+
+/**
  * Callback Function is called every time CURL is receiving data from HTTPS-Server and will copy all received Data to the given stream pointer
  * @param inBuffer Pointer to input.
  * @param size How many mem blocks are received
index 67c894f..b5cb9d2 100644 (file)
@@ -28,26 +28,26 @@ private:
 
     Logger::Ptr Log;
 
+    void set_curl_url(const std::string& url);
+
+    void set_curl_auth(const std::string& username, const std::string& password);
+
 public:
 
     typedef boost::shared_ptr<HTTPHelper> Ptr;
 
     HTTPHelper();
 
-    HTTPHelper(Logger::Ptr _log, std::string _proxy, int _proxy_port);
+    HTTPHelper(Logger::Ptr _log, const std::string& _proxy, const int _proxy_port, const std::string& _username, const std::string& _password);
 
     ~HTTPHelper();
 
     CURL* init_curl(std::string& curl_writedata_buff, char* curl_err_buff) const;
 
-
-    std::string http_get(const std::string& url);
-
-    void set_curl_url(const std::string& url);
+    std::string http_get(const std::string& ip);
 
     // libcurl is a C library, so we have to make the callback member function static :-(
     static int http_receive(char *inBuffer, size_t size, size_t nmemb, std::string *outBuffer);
-
 };
 
 #endif
index 61d0cb0..d0ad8d2 100644 (file)
@@ -1151,6 +1151,7 @@ void Logger::print_multiple_main_conf_option(const string& main_conf_file, const
 
 /**
  * Missing proxy option in main config file.
+ * @param main_conf_filename The concerning config file.
  */
 void Logger::print_missing_conf_proxy_option(const string& main_conf_filename) const
 {
@@ -1162,3 +1163,19 @@ void Logger::print_missing_conf_proxy_option(const string& main_conf_filename) c
         log_error(msg.str(),level);
     }
 }
+
+
+/**
+ * There is no domain part in the given hostname
+ * @param hostname The hostname with no domain part in it.
+ */
+void Logger::print_no_domain_part(const std::string& hostname) const
+{
+    int level = 0;
+    if ( (level <= Loglevel) || ((level <= ExternalWarningLevel) && (!ExternalWarningLog.empty())) )
+    {
+        ostringstream msg;
+        msg << "There is no domain part in the given hostname: " << hostname << endl;
+        log_notice(msg.str(),level);
+    }
+}
index 75117e6..69284b9 100644 (file)
@@ -11,6 +11,7 @@
 #define LOGGER_H
 
 #include <string>
+#include <list>
 
 #include <boost/program_options.hpp>
 #include <boost/shared_ptr.hpp>
@@ -176,6 +177,8 @@ public:
     void print_missing_cmd_proxy_option() const;
 
     void print_missing_conf_proxy_option(const std::string& main_conf_filename) const;
+
+    void print_no_domain_part(const std::string& hostname) const;
 };
 
 #endif