Fix 'occurred' typo
[bpdyndnsd] / src / service_dhs.cpp
CommitLineData
089a7152
BS
1/** @file
2 * @brief DHS Service class implementation. This class represents the DHS service.
3 *
4 *
5 *
6 * @copyright Intra2net AG
7 * @license GPLv2
8*/
9
4de6a9b8 10#include "service_dhs.hpp"
089a7152
BS
11
12#include <time.h>
13#include <boost/foreach.hpp>
14#include <boost/algorithm/string.hpp>
113a03a9 15#include <boost/regex.hpp>
089a7152
BS
16
17namespace ba = boost::algorithm;
18
19using namespace std;
20
21
22/**
23 * Default Constructor, needed for object serialization.
24 */
629d8110 25ServiceDhs::ServiceDhs()
089a7152
BS
26{
27}
28
29
30/**
31 * Constructor.
32 * @param _hostname The hostname to update
33 * @param _login The login name.
34 * @param _password The corresponding password.
35 */
4553e833 36ServiceDhs::ServiceDhs(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 _max_equal_updates_in_succession, const int _dns_cache_ttl, const string& _proxy, const int _proxy_port)
089a7152
BS
37{
38 if ( _update_interval == -1 ) // If _update_interval is default po::option_desc (not specified via config)
39 set_update_interval(15); // use default protocol value
40 else
41 set_update_interval(_update_interval);
42
43 if ( _max_updates_within_interval == -1 )
44 set_max_updates_within_interval(3);
45 else
46 set_max_updates_within_interval(_max_updates_within_interval);
47
4553e833
BS
48 if ( _max_equal_updates_in_succession == -1 )
49 set_max_equal_updates_in_succession(2);
50 else
51 set_max_equal_updates_in_succession(_max_equal_updates_in_succession);
52
089a7152
BS
53 if ( _dns_cache_ttl == -1 )
54 set_dns_cache_ttl(7200);
55 else
56 set_dns_cache_ttl(_dns_cache_ttl);
57
58 set_protocol(_protocol);
59 set_hostname(_hostname);
60 set_login(_login);
61 set_password(_password);
62 set_logger(_logger);
63
64 // create http helper class
c3c84086 65 HTTPHelp = HTTPHelper::Ptr(new HTTPHelper(_logger,_proxy,_proxy_port,_login,_password));
089a7152
BS
66
67 // extract domain part from hostname
68 list<string> host_domain_part = separate_domain_and_host_part(get_hostname());
69
08a5a621 70 BaseUrl = assemble_base_url(host_domain_part.front(),host_domain_part.back()); /*lint !e864 */
089a7152
BS
71}
72
73
74/**
75 * Default destructor
76 */
629d8110 77ServiceDhs::~ServiceDhs()
089a7152
BS
78{
79}
80
81
82/**
83 * Assemble the dhs update url from the given hostname and domain part
84 * @param hostname The hostname to update IP for.
85 * @param domain_part The domain_part in which the hostname is located.
86 * @return The assembled update url without IP.
87 */
629d8110 88string ServiceDhs::assemble_base_url(const string& hostname, const string& domain_part) const
089a7152
BS
89{
90 string base_url;
91
92 base_url = "http://members.dhs.org";
93 base_url.append("/nic/hosts?hostscmd=edit&hostscmdstage=2&type=4&domain=");
94 base_url.append(domain_part);
95 base_url.append("&hostname=");
96 base_url.append(hostname);
97 base_url.append("&updatetype=Online&ip=");
98
99 return base_url;
100}
101
102
103/**
104 * Separates the hostname from the domain part.
105 * @param fqdn Hostname with domain part.
106 * @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.
107 */
629d8110 108list<string> ServiceDhs::separate_domain_and_host_part(const string& fqdn) const
089a7152
BS
109{
110 list<string> splitted;
111 ba::split(splitted,fqdn,boost::is_any_of("."));
112
113 if ( splitted.size() > 1 )
114 {
115 string host = splitted.front();
116 splitted.pop_front();
117
118 string domain = splitted.front();
119 splitted.pop_front();
120
121 BOOST_FOREACH(string domain_part, splitted)
122 {
123 domain.append(".");
124 domain.append(domain_part);
125 }
126
127 splitted.clear();
128 splitted.push_back(host);
129 splitted.push_back(domain);
130 }
131
132 return splitted;
133}
134
135
136/**
137 * Performs the Service update.
138 * @param ip IP Address to set.
139 * @return 0 if all is fine, -1 otherwise.
140 */
d008afbe 141Service::UpdateErrorCode ServiceDhs::perform_update(const std::string& ip)
089a7152 142{
089a7152
BS
143 string url = BaseUrl;
144 url.append(ip);
145
08a5a621 146 if ( HTTPHelp->is_initialized() )
089a7152 147 {
31af6a2e
BS
148 // Perform curl operation on given url.
149 long http_status_code = HTTPHelp->http_get(url);
113a03a9 150
31af6a2e
BS
151 get_logger()->print_http_status_code(url,http_status_code);
152
153 // Check the status code for protocol errors.
154 if ( http_status_code == 200 )
155 {
156 // Get the received http data.
157 string curl_data = HTTPHelp->get_curl_data();
158
159 // Search for the following string in the received http data
160 boost::regex expr_done("Updating ip on .*: done");
161 if ( boost::regex_search(curl_data,expr_done) )
162 {
163 // Update successful
d008afbe 164 return UpdateOk;
31af6a2e
BS
165 }
166 else
167 {
168 get_logger()->print_update_failure(url,curl_data);
7335d7a7 169 return UpdateError;
31af6a2e
BS
170 }
171 }
172 else if ( http_status_code == 401 )
113a03a9 173 {
31af6a2e 174 get_logger()->print_service_not_authorized(url,get_login(),get_password());
7335d7a7 175 return NotAuth;
113a03a9
BS
176 }
177 else
178 {
31af6a2e 179 get_logger()->print_update_failure(url,http_status_code);
113a03a9 180 }
089a7152 181 }
089a7152 182 else
a78b44b5 183 {
e8787e2e 184 get_logger()->print_httphelper_not_initialized();
e417b034 185 HTTPHelp->re_initialize();
a78b44b5 186 }
d008afbe
TJ
187
188 return GenericError;
089a7152 189}