From 2dd2db3edff4b6db95bc7b48b8d62e87255eedbb Mon Sep 17 00:00:00 2001 From: Bjoern Sikora Date: Wed, 2 Sep 2009 12:01:17 +0200 Subject: [PATCH] Firt shot on DHS Protocol implementation. At this point only Error handling is missing. --- src/dhs.cpp | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++-- src/dhs.h | 10 ++++- src/httphelper.cpp | 17 +++++++- src/httphelper.h | 12 +++--- src/logger.cpp | 17 ++++++++ src/logger.h | 3 + 6 files changed, 162 insertions(+), 13 deletions(-) diff --git a/src/dhs.cpp b/src/dhs.cpp index 49bd832..dd3fc80 100644 --- a/src/dhs.cpp +++ b/src/dhs.cpp @@ -10,6 +10,7 @@ #include "dhs.h" #include +#include 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 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 DHS::separate_domain_and_host_part(const string& fqdn) const +{ + list 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 DHS::split(const string& str,const string& delimiters) const +{ + list 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; } diff --git a/src/dhs.h b/src/dhs.h index 54c85c2..54e818b 100644 --- a/src/dhs.h +++ b/src/dhs.h @@ -17,7 +17,7 @@ #include #include - +#include class DHS : public Service { @@ -28,8 +28,16 @@ private: template void serialize(Archive & ar, const unsigned int version); + std::string BaseUrl; + HTTPHelper::Ptr HTTPHelp; + std::list split(const std::string& str,const std::string& delimiters) const; + + std::list 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 Ptr; diff --git a/src/httphelper.cpp b/src/httphelper.cpp index 927f2b3..2b4b3ac 100644 --- a/src/httphelper.cpp +++ b/src/httphelper.cpp @@ -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 diff --git a/src/httphelper.h b/src/httphelper.h index 67c894f..b5cb9d2 100644 --- a/src/httphelper.h +++ b/src/httphelper.h @@ -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 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 diff --git a/src/logger.cpp b/src/logger.cpp index 61d0cb0..d0ad8d2 100644 --- a/src/logger.cpp +++ b/src/logger.cpp @@ -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); + } +} diff --git a/src/logger.h b/src/logger.h index 75117e6..69284b9 100644 --- a/src/logger.h +++ b/src/logger.h @@ -11,6 +11,7 @@ #define LOGGER_H #include +#include #include #include @@ -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 -- 1.7.1