Fix 'occurred' typo
[bpdyndnsd] / src / service_easydns.cpp
CommitLineData
089a7152
BS
1/** @file
2 * @brief EASYDNS Service class implementation. This class represents the EASYDNS service.
3 *
4 *
5 *
6 * @copyright Intra2net AG
7 * @license GPLv2
8*/
9
4de6a9b8
BS
10#include "service_easydns.hpp"
11#include "util.hpp"
089a7152
BS
12
13#include <time.h>
14#include <boost/foreach.hpp>
15#include <boost/algorithm/string.hpp>
16
17namespace ba = boost::algorithm;
18
19using namespace std;
20
21
22/**
23 * Default Constructor, needed for object serialization.
24 */
629d8110 25ServiceEasydns::ServiceEasydns()
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 36ServiceEasydns::ServiceEasydns(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)
5b52ac67 39 set_update_interval(12); // use default protocol value
089a7152
BS
40 else
41 set_update_interval(_update_interval);
42
43 if ( _max_updates_within_interval == -1 )
44 set_max_updates_within_interval(1);
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(1200);
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
ce70569b 65 HTTPHelp = HTTPHelper::Ptr(new HTTPHelper(_logger,_proxy,_proxy_port,_login,_password));
31af6a2e 66
089a7152
BS
67 // extract domain part from hostname
68 list<string> host_domain_part = separate_domain_and_host_part(get_hostname());
69
70 string two_level_tld = get_two_level_tld(host_domain_part.back());
71 if ( !two_level_tld.empty() )
72 BaseUrl = assemble_base_url(get_hostname(),two_level_tld);
73 else
74 BaseUrl = assemble_base_url(get_hostname(),"");
75}
76
77
78/**
79 * Default destructor
80 */
629d8110 81ServiceEasydns::~ServiceEasydns()
089a7152
BS
82{
83}
84
85
86/**
87 * Tries to extract the two_level domain part if there is one
88 * @param domain_part The complete domain part.
89 * @return Two_level_domain part if there is one or "" if not so.
90 */
629d8110 91string ServiceEasydns::get_two_level_tld(const string& domain_part) const
089a7152 92{
089a7152
BS
93 // split the domain_part
94 list<string> domain_tokens;
95 ba::split(domain_tokens,domain_part,boost::is_any_of("."));
96
97 domain_tokens.pop_front();
98
99 if ( domain_tokens.size() > 1 )
100 {
101 string two_level_tld = domain_tokens.front();
102 domain_tokens.pop_front();
103
104 BOOST_FOREACH(string domain_part, domain_tokens)
105 {
106 two_level_tld.append(".");
107 two_level_tld.append(domain_part);
108 }
109
110 return two_level_tld;
111 }
112 else
113 {
114 return "";
115 }
116}
117
118
119/**
120 * Assemble the easydns update url from the given hostname and domain part
121 * @param hostname The hostname to update IP for.
122 * @param domain_part The domain_part in which the hostname is located.
123 * @return The assembled update url without IP.
124 */
629d8110 125string ServiceEasydns::assemble_base_url(const string& hostname, const string& two_level_tld) const
089a7152
BS
126{
127 string base_url;
128 if ( !two_level_tld.empty() )
129 {
130 base_url = "https://members.easydns.com";
131 base_url.append("/dyn/dyndns.php?hostname=");
132 base_url.append(hostname);
133 base_url.append("&tld=");
134 base_url.append(two_level_tld);
135 base_url.append("&myip=");
136 }
137 else
138 {
139 base_url = "https://members.easydns.com";
140 base_url.append("/dyn/dyndns.php?hostname=");
141 base_url.append(hostname);
142 base_url.append("&myip=");
143 }
144 return base_url;
145}
146
147
148/**
149 * Separates the hostname from the domain part.
150 * @param fqdn Hostname with domain part.
151 * @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.
152 */
629d8110 153list<string> ServiceEasydns::separate_domain_and_host_part(const string& fqdn) const
089a7152
BS
154{
155 list<string> splitted;
156 ba::split(splitted,fqdn,boost::is_any_of("."));
157
158 if ( splitted.size() > 1 )
159 {
160 string host = splitted.front();
161 splitted.pop_front();
162
163 string domain = splitted.front();
164 splitted.pop_front();
165
166 BOOST_FOREACH(string domain_part, splitted)
167 {
168 domain.append(".");
169 domain.append(domain_part);
170 }
171
172 splitted.clear();
173 splitted.push_back(host);
174 splitted.push_back(domain);
175 }
176
177 return splitted;
178}
179
180
181/**
182 * Performs the Service update.
183 * @param ip IP Address to set.
184 * @return 0 if all is fine, -1 otherwise.
185 */
d008afbe 186Service::UpdateErrorCode ServiceEasydns::perform_update(const std::string& ip)
089a7152 187{
089a7152
BS
188 string url = BaseUrl;
189 url.append(ip);
190
08a5a621 191 if ( HTTPHelp->is_initialized() )
089a7152 192 {
31af6a2e 193 long http_status_code = HTTPHelp->http_get(url);
089a7152 194
31af6a2e
BS
195 get_logger()->print_http_status_code(url,http_status_code);
196
197 // HTTP operation completed successful.
198 // Now we have to parse the data received by curl,
199 // cause http status code is not significant for easydns update errors
200 if ( http_status_code == 200 )
a78b44b5 201 {
31af6a2e
BS
202 // Get the received http data.
203 string curl_data = HTTPHelp->get_curl_data();
204 string status_code = Util::parse_status_code(curl_data,"\n");
205
206 if ( status_code == "NOERROR" )
207 {
d008afbe 208 return UpdateOk;
31af6a2e
BS
209 }
210 else if ( status_code == "NOACCESS" )
211 {
212 get_logger()->print_service_not_authorized(url,get_login(),get_password());
7335d7a7 213 return NotAuth;
31af6a2e
BS
214 }
215 else
216 {
217 get_logger()->print_update_failure(url, curl_data);
7335d7a7 218 return UpdateError;
31af6a2e 219 }
a78b44b5 220 }
089a7152 221 else
a78b44b5 222 {
31af6a2e 223 get_logger()->print_update_failure(url,http_status_code);
a78b44b5
BS
224 }
225 }
226 else
227 {
e8787e2e 228 get_logger()->print_httphelper_not_initialized();
e417b034 229 HTTPHelp->re_initialize();
089a7152 230 }
d008afbe
TJ
231
232 return GenericError;
089a7152 233}