From: Bjoern Sikora Date: Mon, 7 Sep 2009 14:33:34 +0000 (+0200) Subject: Refactoring: Class renaming. All service implementaion classes should start with... X-Git-Tag: v1.1~195 X-Git-Url: http://developer.intra2net.com/git/?a=commitdiff_plain;h=089a715249ba8d42f4184394a86c1a95373e57ba;p=bpdyndnsd Refactoring: Class renaming. All service implementaion classes should start with service_. --- diff --git a/src/config.cpp b/src/config.cpp index 34674ab..db8095b 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -9,13 +9,13 @@ #include "config.h" -#include "dhs.h" -#include "ods.h" -#include "dyndns.h" -#include "dyns.h" -#include "easydns.h" -#include "tzo.h" -#include "zoneedit.h" +#include "service_dhs.h" +#include "service_ods.h" +#include "service_dyndns.h" +#include "service_dyns.h" +#include "service_easydns.h" +#include "service_tzo.h" +#include "service_zoneedit.h" #include #include @@ -263,37 +263,37 @@ Service::Ptr Config::create_service(const string &protocol,const string &hostnam if(protocol == "dhs") { - Service::Ptr service_dhs(new DHS(protocol,hostname,login,password,Log,update_interval,max_updates_within_interval,dns_cache_ttl,Proxy,ProxyPort)); + Service::Ptr service_dhs(new SERVICE_DHS(protocol,hostname,login,password,Log,update_interval,max_updates_within_interval,dns_cache_ttl,Proxy,ProxyPort)); return service_dhs; } else if(protocol == "ods") { - Service::Ptr service_ods(new ODS(protocol,hostname,login,password,Log,update_interval,max_updates_within_interval,dns_cache_ttl)); + Service::Ptr service_ods(new SERVICE_ODS(protocol,hostname,login,password,Log,update_interval,max_updates_within_interval,dns_cache_ttl)); return service_ods; } else if(protocol == "dyndns") { - Service::Ptr service_dyndns(new DYNDNS(protocol,hostname,login,password,Log,update_interval,max_updates_within_interval,dns_cache_ttl,Proxy,ProxyPort)); + Service::Ptr service_dyndns(new SERVICE_DYNDNS(protocol,hostname,login,password,Log,update_interval,max_updates_within_interval,dns_cache_ttl,Proxy,ProxyPort)); return service_dyndns; } else if(protocol == "dyns") { - Service::Ptr service_dyns(new DYNS(protocol,hostname,login,password,Log,update_interval,max_updates_within_interval,dns_cache_ttl,Proxy,ProxyPort)); + Service::Ptr service_dyns(new SERVICE_DYNS(protocol,hostname,login,password,Log,update_interval,max_updates_within_interval,dns_cache_ttl,Proxy,ProxyPort)); return service_dyns; } else if(protocol == "easydns") { - Service::Ptr service_easydns(new EASYDNS(protocol,hostname,login,password,Log,update_interval,max_updates_within_interval,dns_cache_ttl,Proxy,ProxyPort)); + Service::Ptr service_easydns(new SERVICE_EASYDNS(protocol,hostname,login,password,Log,update_interval,max_updates_within_interval,dns_cache_ttl,Proxy,ProxyPort)); return service_easydns; } else if(protocol == "tzo") { - Service::Ptr service_tzo(new TZO(protocol,hostname,login,password,Log,update_interval,max_updates_within_interval,dns_cache_ttl,Proxy,ProxyPort)); + Service::Ptr service_tzo(new SERVICE_TZO(protocol,hostname,login,password,Log,update_interval,max_updates_within_interval,dns_cache_ttl,Proxy,ProxyPort)); return service_tzo; } else if(protocol == "zoneedit") { - Service::Ptr service_zoneedit(new ZONEEDIT(protocol,hostname,login,password,Log,update_interval,max_updates_within_interval,dns_cache_ttl,Proxy,ProxyPort)); + Service::Ptr service_zoneedit(new SERVICE_ZONEEDIT(protocol,hostname,login,password,Log,update_interval,max_updates_within_interval,dns_cache_ttl,Proxy,ProxyPort)); return service_zoneedit; } else diff --git a/src/main.cpp b/src/main.cpp index a60787d..a7b9719 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -37,13 +37,13 @@ #include "httphelper.cpp" #include "serializeservicecontainer.cpp" -#include "dyndns.cpp" -#include "dyns.cpp" -#include "ods.cpp" -#include "dhs.cpp" -#include "easydns.cpp" -#include "tzo.cpp" -#include "zoneedit.cpp" +#include "service_dyndns.cpp" +#include "service_dyns.cpp" +#include "service_ods.cpp" +#include "service_dhs.cpp" +#include "service_easydns.cpp" +#include "service_tzo.cpp" +#include "service_zoneedit.cpp" using namespace std; diff --git a/src/service_dhs.cpp b/src/service_dhs.cpp new file mode 100644 index 0000000..f70ccfa --- /dev/null +++ b/src/service_dhs.cpp @@ -0,0 +1,173 @@ +/** @file + * @brief DHS Service class implementation. This class represents the DHS service. + * + * + * + * @copyright Intra2net AG + * @license GPLv2 +*/ + +#include "service_dhs.h" + +#include +#include +#include + +namespace ba = boost::algorithm; + +using namespace std; + + +/** + * Default Constructor, needed for object serialization. + */ +SERVICE_DHS::SERVICE_DHS() +{ +} + + +/** + * Constructor. + * @param _hostname The hostname to update + * @param _login The login name. + * @param _password The corresponding password. + */ +SERVICE_DHS::SERVICE_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(15); // use default protocol value + else + set_update_interval(_update_interval); + + if ( _max_updates_within_interval == -1 ) + 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(7200); + else + set_dns_cache_ttl(_dns_cache_ttl); + + set_protocol(_protocol); + set_hostname(_hostname); + set_login(_login); + set_password(_password); + set_logger(_logger); + + // create http helper class + 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()); + + BaseUrl = assemble_base_url(host_domain_part.front(),host_domain_part.back()); +} + + +/** + * Default destructor + */ +SERVICE_DHS::~SERVICE_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 SERVICE_DHS::assemble_base_url(const string& hostname, const string& domain_part) const +{ + string base_url; + + 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="); + + 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 SERVICE_DHS::separate_domain_and_host_part(const string& fqdn) const +{ + list splitted; + ba::split(splitted,fqdn,boost::is_any_of(".")); + + 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; +} + + +/** + * Performs the Service update. + * @param ip IP Address to set. + * @return 0 if all is fine, -1 otherwise. + */ +int SERVICE_DHS::perform_update(const std::string& ip) +{ + int ret_val = -1; + + string url = BaseUrl; + url.append(ip); + + // Perform curl operation on given url. + long http_status_code = HTTPHelp->http_get(url); + + get_logger()->print_http_status_code(url,http_status_code); + + // Check the status code for protocol errors. + if ( http_status_code == 200 ) + { + // TODO: Account related errors should be handled here! + ret_val = 0; + } + else if ( http_status_code == 401 ) + get_logger()->print_http_not_authorized(url,get_login(),get_password()); + else + get_logger()->print_update_failure(url,http_status_code); + + return ret_val; +} + + +/** + * Serialize function needed by boost/serialization to define which members should be stored as the object state. + * @param ar Archive + * @param version Version + */ +template +void SERVICE_DHS::serialize(Archive & ar, const unsigned int version) +{ + ar & boost::serialization::base_object(*this); +} diff --git a/src/service_dhs.h b/src/service_dhs.h new file mode 100644 index 0000000..1d05898 --- /dev/null +++ b/src/service_dhs.h @@ -0,0 +1,52 @@ +/** @file + * @brief DHS Service class header. This class represents the DHS service. + * + * + * + * @copyright Intra2net AG + * @license GPLv2 +*/ + +#ifndef SERVICE_DHS_H +#define SERVICE_DHS_H + +#include + +#include "service.h" +#include "logger.h" + +#include +#include +#include + +class SERVICE_DHS : public Service +{ + +private: + + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int version); + + std::string BaseUrl; + + HTTPHelper::Ptr HTTPHelp; + + 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; + + SERVICE_DHS(); + + SERVICE_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, const std::string& proxy, const int proxy_port); + + ~SERVICE_DHS(); + + int perform_update(const std::string& ip); +}; + +#endif diff --git a/src/service_dyndns.cpp b/src/service_dyndns.cpp new file mode 100644 index 0000000..f16940e --- /dev/null +++ b/src/service_dyndns.cpp @@ -0,0 +1,140 @@ +/** @file + * @brief DYNDNS Service class implementation. This class represents the DYNDNS service. + * + * + * + * @copyright Intra2net AG + * @license GPLv2 +*/ + +#include "service_dyndns.h" + +#include +#include + +using namespace std; + + +/** + * Default Constructor, needed for object serialization. + */ +SERVICE_DYNDNS::SERVICE_DYNDNS() +{ +} + + +/** + * Constructor. + * @param _hostname The hostname to update + * @param _login The login name. + * @param _password The corresponding password. + */ +SERVICE_DYNDNS::SERVICE_DYNDNS(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 + else + set_update_interval(_update_interval); + + if ( _max_updates_within_interval == -1 ) + set_max_updates_within_interval(0); + else + set_max_updates_within_interval(_max_updates_within_interval); + + if ( _dns_cache_ttl == -1 ) + set_dns_cache_ttl(60); + else + set_dns_cache_ttl(_dns_cache_ttl); + + set_protocol(_protocol); + set_hostname(_hostname); + set_login(_login); + set_password(_password); + set_logger(_logger); + + // create http helper class + HTTPHelper::Ptr _http_help(new HTTPHelper(_logger,_proxy,_proxy_port,_login,_password)); + HTTPHelp = _http_help; + _http_help.reset(); + + BaseUrl = assemble_base_url(get_hostname()); +} + + +/** + * Default destructor + */ +SERVICE_DYNDNS::~SERVICE_DYNDNS() +{ +} + + +/** + * Assemble the dyndns update url from the given fqhn + * @param hostname The fqhn hostname to update IP for. + * @return The assembled update url without IP. + */ +string SERVICE_DYNDNS::assemble_base_url(const string& fqhn) const +{ + string base_url; + + base_url = "https://members.dyndns.org"; + base_url.append("/nic/update?hostname="); + base_url.append(fqhn); + base_url.append("&wildcard=NOCHG&mx=NOCHG&backmx=NOCHG&myip="); + + return base_url; +} + + +/** + * Performs the Service update. + * @param ip IP Address to set. + * @return 0 if all is fine, -1 otherwise. + */ +int SERVICE_DYNDNS::perform_update(const std::string& ip) +{ + int ret_val = -1; + + // the result string if update was successful + string good = "good "; + good.append(ip); + + string url = BaseUrl; + url.append(ip); + + // Perform curl operation on given url + long http_status_code = HTTPHelp->http_get(url); + + get_logger()->print_http_status_code(url,http_status_code); + + // HTTP operation completed successful. + // Now we have to parse the data received by curl, + // cause http status code is not significant for dyndns update errors + if ( http_status_code == 200 ) + { + // Get the received http data. + string curl_data = HTTPHelp->get_curl_data(); + + if ( curl_data == good ) + ret_val = 0; + else if ( curl_data == "badauth" ) + get_logger()->print_http_not_authorized(url,get_login(),get_password()); + else + get_logger()->print_update_failure(url, curl_data); + } + + return ret_val; +} + + +/** + * Serialize function needed by boost/serialization to define which members should be stored as the object state. + * @param ar Archive + * @param version Version + */ +template +void SERVICE_DYNDNS::serialize(Archive & ar, const unsigned int version) +{ + ar & boost::serialization::base_object(*this); +} diff --git a/src/service_dyndns.h b/src/service_dyndns.h new file mode 100644 index 0000000..35b8568 --- /dev/null +++ b/src/service_dyndns.h @@ -0,0 +1,51 @@ +/** @file + * @brief DYNDNS Service class header. This class represents the DYNDNS service. + * + * + * + * @copyright Intra2net AG + * @license GPLv2 +*/ + +#ifndef SERVICE_DYNDNS_H +#define SERVICE_DYNDNS_H + +#include + +#include "service.h" +#include "logger.h" + +#include +#include +#include + +class SERVICE_DYNDNS : public Service +{ + +private: + + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int version); + + std::string BaseUrl; + + HTTPHelper::Ptr HTTPHelp; + + std::string assemble_base_url(const std::string& fqhn) const; + +public: + + typedef boost::shared_ptr Ptr; + + SERVICE_DYNDNS(); + + SERVICE_DYNDNS(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, const std::string& proxy, const int proxy_port); + + ~SERVICE_DYNDNS(); + + int perform_update(const std::string& ip); + +}; + +#endif diff --git a/src/service_dyns.cpp b/src/service_dyns.cpp new file mode 100644 index 0000000..975ea2a --- /dev/null +++ b/src/service_dyns.cpp @@ -0,0 +1,158 @@ +/** @file + * @brief DYNS Service class implementation. This class represents the DYNS service. + * + * + * + * @copyright Intra2net AG + * @license GPLv2 +*/ + +#include "service_dyns.h" + +#include +#include +#include + +namespace ba = boost::algorithm; + +using namespace std; + + +/** + * Default Constructor, needed for object serialization. + */ +SERVICE_DYNS::SERVICE_DYNS() +{ +} + + +/** + * Constructor. + * @param _hostname The hostname to update + * @param _login The login name. + * @param _password The corresponding password. + */ +SERVICE_DYNS::SERVICE_DYNS(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(5); // use default protocol value + else + set_update_interval(_update_interval); + + if ( _max_updates_within_interval == -1 ) + set_max_updates_within_interval(1); + else + set_max_updates_within_interval(_max_updates_within_interval); + + if ( _dns_cache_ttl == -1 ) + set_dns_cache_ttl(300); + else + set_dns_cache_ttl(_dns_cache_ttl); + + set_protocol(_protocol); + set_hostname(_hostname); + set_login(_login); + set_password(_password); + set_logger(_logger); + + // create http helper class + HTTPHelper::Ptr _http_help(new HTTPHelper(_logger,_proxy,_proxy_port)); + HTTPHelp = _http_help; + _http_help.reset(); + + BaseUrl = assemble_base_url(get_hostname(),get_login(),get_password()); +} + + +/** + * Default destructor + */ +SERVICE_DYNS::~SERVICE_DYNS() +{ +} + + +/** + * Assemble the dyns update url from the given fqhn + * @param hostname The fqhn hostname to update IP for. + * @param username The username to use. + * @param hostname The password to use. + * @return The assembled update url without IP. + */ +string SERVICE_DYNS::assemble_base_url(const string& fqhn, const string& username, const string& password) const +{ + string base_url; + + base_url = "http://www.dyns.net"; + base_url.append("/postscript011.php?username="); + base_url.append(username); + base_url.append("&password="); + base_url.append(password); + base_url.append("&host="); + base_url.append(fqhn); + base_url.append("&ip="); + + return base_url; +} + + +/** + * Performs the Service update. + * @param ip IP Address to set. + * @return 0 if all is fine, -1 otherwise. + */ +int SERVICE_DYNS::perform_update(const std::string& ip) +{ + int ret_val = -1; + + string url = BaseUrl; + url.append(ip); + + long http_status_code = HTTPHelp->http_get(url); + + get_logger()->print_http_status_code(url,http_status_code); + + // HTTP operation completed successful. + // Now we have to parse the data received by curl, + // cause http status code is not significant for dyns update errors + if ( http_status_code == 200 ) + { + // Get the received http data and parse the status code. + string curl_data = HTTPHelp->get_curl_data(); + string status_code = parse_status_code(curl_data); + + if ( status_code == "200" ) + ret_val = 0; + else if ( status_code == "401" ) + get_logger()->print_http_not_authorized(url,get_login(),get_password()); + else + get_logger()->print_update_failure(url,curl_data); + } + + return ret_val; +} + + +/** + * Get the status code from the returned http data + * @param data The returned http data. + * @return The status code. + */ +string SERVICE_DYNS::parse_status_code(const string& data) const +{ + list tokens; + ba::split(tokens,data,boost::is_any_of(" ")); + return tokens.front(); +} + + +/** + * Serialize function needed by boost/serialization to define which members should be stored as the object state. + * @param ar Archive + * @param version Version + */ +template +void SERVICE_DYNS::serialize(Archive & ar, const unsigned int version) +{ + ar & boost::serialization::base_object(*this); +} diff --git a/src/service_dyns.h b/src/service_dyns.h new file mode 100644 index 0000000..36a3783 --- /dev/null +++ b/src/service_dyns.h @@ -0,0 +1,52 @@ +/** @file + * @brief DYNS Service class header. This class represents the DYNS service. + * + * + * + * @copyright Intra2net AG + * @license GPLv2 +*/ + +#ifndef SERVICE_DYNS_H +#define SERVICE_DYNS_H + +#include + +#include "service.h" +#include "logger.h" + +#include +#include +#include + +class SERVICE_DYNS : public Service +{ + +private: + + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int version); + + std::string BaseUrl; + + HTTPHelper::Ptr HTTPHelp; + + std::string assemble_base_url(const std::string& fqhn, const std::string& username, const std::string& password) const; + + std::string parse_status_code(const std::string& data) const; + +public: + + typedef boost::shared_ptr Ptr; + + SERVICE_DYNS(); + + SERVICE_DYNS(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, const std::string& proxy, const int proxy_port); + + ~SERVICE_DYNS(); + + int perform_update(const std::string& ip); +}; + +#endif diff --git a/src/service_easydns.cpp b/src/service_easydns.cpp new file mode 100644 index 0000000..ad33c85 --- /dev/null +++ b/src/service_easydns.cpp @@ -0,0 +1,224 @@ +/** @file + * @brief EASYDNS Service class implementation. This class represents the EASYDNS service. + * + * + * + * @copyright Intra2net AG + * @license GPLv2 +*/ + +#include "service_easydns.h" + +#include +#include +#include + +namespace ba = boost::algorithm; + +using namespace std; + + +/** + * Default Constructor, needed for object serialization. + */ +SERVICE_EASYDNS::SERVICE_EASYDNS() +{ +} + + +/** + * Constructor. + * @param _hostname The hostname to update + * @param _login The login name. + * @param _password The corresponding password. + */ +SERVICE_EASYDNS::SERVICE_EASYDNS(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(10); // use default protocol value + else + set_update_interval(_update_interval); + + if ( _max_updates_within_interval == -1 ) + set_max_updates_within_interval(1); + else + set_max_updates_within_interval(_max_updates_within_interval); + + if ( _dns_cache_ttl == -1 ) + set_dns_cache_ttl(1200); + else + set_dns_cache_ttl(_dns_cache_ttl); + + set_protocol(_protocol); + set_hostname(_hostname); + set_login(_login); + set_password(_password); + set_logger(_logger); + + // create http helper class + 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()); + + string two_level_tld = get_two_level_tld(host_domain_part.back()); + if ( !two_level_tld.empty() ) + BaseUrl = assemble_base_url(get_hostname(),two_level_tld); + else + BaseUrl = assemble_base_url(get_hostname(),""); +} + + +/** + * Default destructor + */ +SERVICE_EASYDNS::~SERVICE_EASYDNS() +{ +} + + +/** + * Tries to extract the two_level domain part if there is one + * @param domain_part The complete domain part. + * @return Two_level_domain part if there is one or "" if not so. + */ +string SERVICE_EASYDNS::get_two_level_tld(const string& domain_part) const +{ + // TODO: There is a list with all two level TLD's, use it + + // split the domain_part + list domain_tokens; + ba::split(domain_tokens,domain_part,boost::is_any_of(".")); + + domain_tokens.pop_front(); + + if ( domain_tokens.size() > 1 ) + { + string two_level_tld = domain_tokens.front(); + domain_tokens.pop_front(); + + BOOST_FOREACH(string domain_part, domain_tokens) + { + two_level_tld.append("."); + two_level_tld.append(domain_part); + } + + return two_level_tld; + } + else + { + return ""; + } +} + + +/** + * Assemble the easydns 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 SERVICE_EASYDNS::assemble_base_url(const string& hostname, const string& two_level_tld) const +{ + string base_url; + if ( !two_level_tld.empty() ) + { + base_url = "https://members.easydns.com"; + base_url.append("/dyn/dyndns.php?hostname="); + base_url.append(hostname); + base_url.append("&tld="); + base_url.append(two_level_tld); + base_url.append("&myip="); + } + else + { + base_url = "https://members.easydns.com"; + base_url.append("/dyn/dyndns.php?hostname="); + base_url.append(hostname); + base_url.append("&myip="); + } + 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 SERVICE_EASYDNS::separate_domain_and_host_part(const string& fqdn) const +{ + list splitted; + ba::split(splitted,fqdn,boost::is_any_of(".")); + + 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; +} + + +/** + * Performs the Service update. + * @param ip IP Address to set. + * @return 0 if all is fine, -1 otherwise. + */ +int SERVICE_EASYDNS::perform_update(const std::string& ip) +{ + int ret_val = -1; + + string url = BaseUrl; + url.append(ip); + + long http_status_code = HTTPHelp->http_get(url); + + get_logger()->print_http_status_code(url,http_status_code); + + // HTTP operation completed successful. + // Now we have to parse the data received by curl, + // cause http status code is not significant for easydns update errors + if ( http_status_code == 200 ) + { + // Get the received http data. + string curl_data = HTTPHelp->get_curl_data(); + + if ( curl_data == "NOERROR" ) + ret_val = 0; + else if ( curl_data == "NOACCESS" ) + get_logger()->print_http_not_authorized(url,get_login(),get_password()); + else + get_logger()->print_update_failure(url, curl_data); + } + + return ret_val; +} + + +/** + * Serialize function needed by boost/serialization to define which members should be stored as the object state. + * @param ar Archive + * @param version Version + */ +template +void SERVICE_EASYDNS::serialize(Archive & ar, const unsigned int version) +{ + ar & boost::serialization::base_object(*this); +} diff --git a/src/service_easydns.h b/src/service_easydns.h new file mode 100644 index 0000000..dffb5b1 --- /dev/null +++ b/src/service_easydns.h @@ -0,0 +1,55 @@ +/** @file + * @brief EASYDNS Service class header. This class represents the EASYDNS service. + * + * + * + * @copyright Intra2net AG + * @license GPLv2 +*/ + +#ifndef SERVICE_EASYDNS_H +#define SERVICE_EASYDNS_H + +#include + +#include "service.h" +#include "logger.h" + +#include +#include +#include + +class SERVICE_EASYDNS : public Service +{ + +private: + + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int version); + + std::string BaseUrl; + + HTTPHelper::Ptr HTTPHelp; + + std::list separate_domain_and_host_part(const std::string& str) const; + + std::string assemble_base_url(const std::string& hostname, const std::string& two_level_tld) const; + + std::string get_two_level_tld(const std::string& domain_part) const; + +public: + + typedef boost::shared_ptr Ptr; + + SERVICE_EASYDNS(); + + SERVICE_EASYDNS(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, const std::string& proxy, const int proxy_port); + + ~SERVICE_EASYDNS(); + + int perform_update(const std::string& ip); + +}; + +#endif diff --git a/src/service_ods.cpp b/src/service_ods.cpp new file mode 100644 index 0000000..6d33566 --- /dev/null +++ b/src/service_ods.cpp @@ -0,0 +1,84 @@ +/** @file + * @brief ODS Service class implementation. This class represents the ODS service. + * + * + * + * @copyright Intra2net AG + * @license GPLv2 +*/ + +#include "service_ods.h" + +#include + +using namespace std; + + +/** + * Default Constructor, needed for object serialization. + */ +SERVICE_ODS::SERVICE_ODS() +{ +} + + +/** + * Constructor. + * @param _hostname The hostname to update + * @param _login The login name. + * @param _password The corresponding password. + */ +SERVICE_ODS::SERVICE_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 + else + set_update_interval(_update_interval); + + if ( _max_updates_within_interval == -1 ) + 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); + else + set_dns_cache_ttl(_dns_cache_ttl); + + set_protocol(_protocol); + set_hostname(_hostname); + set_login(_login); + set_password(_password); + set_logger(_logger); +} + + +/** + * Default destructor. + */ +SERVICE_ODS::~SERVICE_ODS() +{ +} + + +/** + * Performs the Service update. + * @param ip IP Address to set. + * @return 0 if all is fine, -1 otherwise. + */ +int SERVICE_ODS::perform_update(const std::string& ip) +{ + return 0; +} + + +/** + * Serialize function needed by boost/serialization to define which members should be stored as the object state. + * @param ar Archive + * @param version Version + */ +template +void SERVICE_ODS::serialize(Archive & ar, const unsigned int version) +{ + ar & boost::serialization::base_object(*this); +} diff --git a/src/service_ods.h b/src/service_ods.h new file mode 100644 index 0000000..4eb55e1 --- /dev/null +++ b/src/service_ods.h @@ -0,0 +1,44 @@ +/** @file + * @brief ODS Service class header. This class represents the ODS service. + * + * + * + * @copyright Intra2net AG + * @license GPLv2 +*/ + +#ifndef SERVICE_ODS_H +#define SERVICE_ODS_H + +#include + +#include "service.h" +#include "logger.h" + +#include +#include + + +class SERVICE_ODS : public Service +{ + +private: + + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int version); + +public: + + typedef boost::shared_ptr Ptr; + + SERVICE_ODS(); + + SERVICE_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); + + ~SERVICE_ODS(); + + int perform_update(const std::string& ip); +}; + +#endif diff --git a/src/service_tzo.cpp b/src/service_tzo.cpp new file mode 100644 index 0000000..5282d0b --- /dev/null +++ b/src/service_tzo.cpp @@ -0,0 +1,158 @@ +/** @file + * @brief TZO Service class implementation. This class represents the TZO service. + * + * + * + * @copyright Intra2net AG + * @license GPLv2 +*/ + +#include "service_tzo.h" + +#include +#include +#include + +namespace ba = boost::algorithm; + +using namespace std; + + +/** + * Default Constructor, needed for object serialization. + */ +SERVICE_TZO::SERVICE_TZO() +{ +} + + +/** + * Constructor. + * @param _hostname The hostname to update + * @param _login The login name. + * @param _password The corresponding password. + */ +SERVICE_TZO::SERVICE_TZO(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 + else + set_update_interval(_update_interval); + + if ( _max_updates_within_interval == -1 ) + set_max_updates_within_interval(0); + else + set_max_updates_within_interval(_max_updates_within_interval); + + if ( _dns_cache_ttl == -1 ) + set_dns_cache_ttl(60); + else + set_dns_cache_ttl(_dns_cache_ttl); + + set_protocol(_protocol); + set_hostname(_hostname); + set_login(_login); + set_password(_password); + set_logger(_logger); + + // create http helper class + HTTPHelper::Ptr _http_help(new HTTPHelper(_logger,_proxy,_proxy_port)); + HTTPHelp = _http_help; + _http_help.reset(); + + BaseUrl = assemble_base_url(get_hostname(),get_login(),get_password()); +} + + +/** + * Default destructor + */ +SERVICE_TZO::~SERVICE_TZO() +{ +} + + +/** + * Assemble the dyns update url from the given fqhn + * @param hostname The fqhn hostname to update IP for. + * @param username The username to use. + * @param hostname The password to use. + * @return The assembled update url without IP. + */ +string SERVICE_TZO::assemble_base_url(const string& fqhn, const string& username, const string& password) const +{ + string base_url; + + base_url = "http://rh.tzo.com"; + base_url.append("/webclient/tzoperl.html?system=tzodns&info=1&tzoname="); + base_url.append(fqhn); + base_url.append("&email="); + base_url.append(username); + base_url.append("&tzokey="); + base_url.append(password); + base_url.append("&ipaddress="); + + return base_url; +} + + +/** + * Performs the Service update. + * @param ip IP Address to set. + * @return 0 if all is fine, -1 otherwise. + */ +int SERVICE_TZO::perform_update(const std::string& ip) +{ + int ret_val = -1; + + string url = BaseUrl; + url.append(ip); + + long http_status_code = HTTPHelp->http_get(url); + + get_logger()->print_http_status_code(url,http_status_code); + + // HTTP operation completed successful. + // Now we have to parse the data received by curl, + // cause http status code is not significant for dyns update errors + if ( http_status_code == 200 ) + { + // Get the received http data and parse the status code. + string curl_data = HTTPHelp->get_curl_data(); + string status_code = parse_status_code(curl_data); + + if ( status_code == "200" ) + ret_val = 0; + else if ( status_code == "401" ) + get_logger()->print_http_not_authorized(url,get_login(),get_password()); + else + get_logger()->print_update_failure(url,curl_data); + } + + return ret_val; +} + + +/** + * Get the status code from the returned http data + * @param data The returned http data. + * @return The status code. + */ +string SERVICE_TZO::parse_status_code(const string& data) const +{ + list tokens; + ba::split(tokens,data,boost::is_any_of(" ")); + return tokens.front(); +} + + +/** + * Serialize function needed by boost/serialization to define which members should be stored as the object state. + * @param ar Archive + * @param version Version + */ +template +void SERVICE_TZO::serialize(Archive & ar, const unsigned int version) +{ + ar & boost::serialization::base_object(*this); +} diff --git a/src/service_tzo.h b/src/service_tzo.h new file mode 100644 index 0000000..6a0fb9f --- /dev/null +++ b/src/service_tzo.h @@ -0,0 +1,52 @@ +/** @file + * @brief TZO Service class header. This class represents the TZO service. + * + * + * + * @copyright Intra2net AG + * @license GPLv2 +*/ + +#ifndef SERVICE_TZO_H +#define SERVICE_TZO_H + +#include + +#include "service.h" +#include "logger.h" + +#include +#include +#include + +class SERVICE_TZO : public Service +{ + +private: + + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int version); + + std::string BaseUrl; + + HTTPHelper::Ptr HTTPHelp; + + std::string assemble_base_url(const std::string& fqhn, const std::string& username, const std::string& password) const; + + std::string parse_status_code(const std::string& data) const; + +public: + + typedef boost::shared_ptr Ptr; + + SERVICE_TZO(); + + SERVICE_TZO(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, const std::string& proxy, const int proxy_port); + + ~SERVICE_TZO(); + + int perform_update(const std::string& ip); +}; + +#endif diff --git a/src/service_zoneedit.cpp b/src/service_zoneedit.cpp new file mode 100644 index 0000000..0e3afd7 --- /dev/null +++ b/src/service_zoneedit.cpp @@ -0,0 +1,154 @@ +/** @file + * @brief ZONEEDIT Service class implementation. This class represents the ZONEEDIT service. + * + * + * + * @copyright Intra2net AG + * @license GPLv2 +*/ + +#include "service_zoneedit.h" + +#include +#include +#include + +namespace ba = boost::algorithm; + +using namespace std; + + +/** + * Default Constructor, needed for object serialization. + */ +SERVICE_ZONEEDIT::SERVICE_ZONEEDIT() +{ +} + + +/** + * Constructor. + * @param _hostname The hostname to update + * @param _login The login name. + * @param _password The corresponding password. + */ +SERVICE_ZONEEDIT::SERVICE_ZONEEDIT(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 + else + set_update_interval(_update_interval); + + if ( _max_updates_within_interval == -1 ) + set_max_updates_within_interval(0); + else + set_max_updates_within_interval(_max_updates_within_interval); + + if ( _dns_cache_ttl == -1 ) + set_dns_cache_ttl(60); + else + set_dns_cache_ttl(_dns_cache_ttl); + + set_protocol(_protocol); + set_hostname(_hostname); + set_login(_login); + set_password(_password); + set_logger(_logger); + + // create http helper class + HTTPHelper::Ptr _http_help(new HTTPHelper(_logger,_proxy,_proxy_port)); + HTTPHelp = _http_help; + _http_help.reset(); + + BaseUrl = assemble_base_url(get_hostname()); +} + + +/** + * Default destructor + */ +SERVICE_ZONEEDIT::~SERVICE_ZONEEDIT() +{ +} + + +/** + * Assemble the zoneedit update url from the given fqhn + * @param hostname The fqhn hostname to update IP for. + * @return The assembled update url without IP. + */ +string SERVICE_ZONEEDIT::assemble_base_url(const string& fqhn) const +{ + string base_url; + + base_url = "http://dynamic.zoneedit.com"; + base_url.append("/auth/dynamic.html?host="); + base_url.append(fqhn); + base_url.append("&dnsto="); + + return base_url; +} + + +/** + * Performs the Service update. + * @param ip IP Address to set. + * @return 0 if all is fine, -1 otherwise. + */ +int SERVICE_ZONEEDIT::perform_update(const std::string& ip) +{ + int ret_val = -1; + + string url = BaseUrl; + url.append(ip); + + long http_status_code = HTTPHelp->http_get(url); + + get_logger()->print_http_status_code(url,http_status_code); + + // HTTP operation completed successful. + // Now we have to parse the data received by curl, + // cause http status code is not significant for dyns update errors + if ( http_status_code == 200 ) + { + // Get the received http data and parse the status code. + string curl_data = HTTPHelp->get_curl_data(); + string status_code = parse_status_code(curl_data); + + if ( status_code == "200" ) + ret_val = 0; + else + get_logger()->print_update_failure(url,curl_data); + } + else if ( http_status_code == 401 ) + get_logger()->print_http_not_authorized(url,get_login(),get_password()); + else + get_logger()->print_update_failure(url,http_status_code); + + return ret_val; +} + + +/** + * Get the status code from the returned http data + * @param data The returned http data. + * @return The status code. + */ +string SERVICE_ZONEEDIT::parse_status_code(const string& data) const +{ + list tokens; + ba::split(tokens,data,boost::is_any_of(" ")); + return tokens.front(); +} + + +/** + * Serialize function needed by boost/serialization to define which members should be stored as the object state. + * @param ar Archive + * @param version Version + */ +template +void SERVICE_ZONEEDIT::serialize(Archive & ar, const unsigned int version) +{ + ar & boost::serialization::base_object(*this); +} diff --git a/src/service_zoneedit.h b/src/service_zoneedit.h new file mode 100644 index 0000000..3899e37 --- /dev/null +++ b/src/service_zoneedit.h @@ -0,0 +1,52 @@ +/** @file + * @brief ZONEEDIT Service class header. This class represents the ZONEEDIT service. + * + * + * + * @copyright Intra2net AG + * @license GPLv2 +*/ + +#ifndef SERVICE_ZONEEDIT_H +#define SERVICE_ZONEEDIT_H + +#include + +#include "service.h" +#include "logger.h" + +#include +#include +#include + +class SERVICE_ZONEEDIT : public Service +{ + +private: + + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int version); + + std::string BaseUrl; + + HTTPHelper::Ptr HTTPHelp; + + std::string assemble_base_url(const std::string& fqhn) const; + + std::string parse_status_code(const std::string& data) const; + +public: + + typedef boost::shared_ptr Ptr; + + SERVICE_ZONEEDIT(); + + SERVICE_ZONEEDIT(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, const std::string& proxy, const int proxy_port); + + ~SERVICE_ZONEEDIT(); + + int perform_update(const std::string& ip); +}; + +#endif diff --git a/src/updater.cpp b/src/updater.cpp index c7e6fe0..46ad502 100644 --- a/src/updater.cpp +++ b/src/updater.cpp @@ -10,25 +10,25 @@ #include "updater.h" #include "serviceholder.h" -#include "dhs.h" -#include "ods.h" -#include "dyndns.h" -#include "dyns.h" -#include "easydns.h" -#include "tzo.h" -#include "zoneedit.h" +#include "service_dhs.h" +#include "service_ods.h" +#include "service_dyndns.h" +#include "service_dyns.h" +#include "service_easydns.h" +#include "service_tzo.h" +#include "service_zoneedit.h" #include // Following boost macros are needed for serialization of derived classes through a base class pointer (Service *). -BOOST_CLASS_EXPORT_GUID(ODS, "ODS") -BOOST_CLASS_EXPORT_GUID(DHS, "DHS") -BOOST_CLASS_EXPORT_GUID(DYNS, "DYNS") -BOOST_CLASS_EXPORT_GUID(DYNDNS, "DYNDNS") -BOOST_CLASS_EXPORT_GUID(EASYDNS, "EASYDNS") -BOOST_CLASS_EXPORT_GUID(TZO, "TZO") -BOOST_CLASS_EXPORT_GUID(ZONEEDIT, "ZONEEDIT") +BOOST_CLASS_EXPORT_GUID(SERVICE_ODS, "SERVICE_ODS") +BOOST_CLASS_EXPORT_GUID(SERVICE_DHS, "SERVICE_DHS") +BOOST_CLASS_EXPORT_GUID(SERVICE_DYNS, "SERVICE_DYNS") +BOOST_CLASS_EXPORT_GUID(SERVICE_DYNDNS, "SERVICE_DYNDNS") +BOOST_CLASS_EXPORT_GUID(SERVICE_EASYDNS, "SERVICE_EASYDNS") +BOOST_CLASS_EXPORT_GUID(SERVICE_TZO, "SERVICE_TZO") +BOOST_CLASS_EXPORT_GUID(SERVICE_ZONEEDIT, "SERVICE_ZONEEDIT") namespace fs = boost::filesystem;