02946154383440245aa96a28b400052aedffc278
[bpdyndnsd] / src / service.cpp
1 /** @file
2  * @brief The abstract service class. This class represents all services.
3  *
4  *
5  *
6  * @copyright Intra2net AG
7  * @license GPLv2
8 */
9
10 #include "service.hpp"
11 #include <boost/foreach.hpp>
12
13 using namespace std;
14
15
16 /**
17  * Default Constructor
18  */
19 Service::Service()
20     : Login("NOT SERIALIZED")
21     , Password("NOT SERIALIZED")
22     , ActualIP("0.0.0.0")
23     , UpdateInterval(0)
24     , MaxUpdatesWithinInterval(0)
25     , DNSCacheTTL(0)
26     , Log(new Logger())
27 {
28 }
29
30
31 /**
32  * Default Destructor needed for deserialization.
33  */
34 Service::~Service()
35 {
36 }
37
38
39 /**
40  * Setter for member Protocol.
41  * @param _protocol Value to set Protocol to.
42  */
43 void Service::set_protocol(const string& _protocol)
44 {
45     Protocol = _protocol;
46 }
47
48
49 /**
50  * Getter for memeber Protocol.
51  * @return Value of member Protocol.
52  */
53 string Service::get_protocol() const
54 {
55     return Protocol;
56 }
57
58
59 /**
60  * Setter for member Hostname.
61  * @param _hostname Value to set Hostname to.
62  */
63 void Service::set_hostname(const string& _hostname)
64 {
65     Hostname = _hostname;
66 }
67
68
69 /**
70  * Getter for member Hostname.
71  * @return Value of member Hostname.
72  */
73 string Service::get_hostname() const
74 {
75     return Hostname;
76 }
77
78
79 /**
80  * Setter for member Login.
81  * @param _login Value to set Login to.
82  */
83 void Service::set_login(const string& _login)
84 {
85     Login = _login;
86 }
87
88
89 /**
90  * Getter for member Login.
91  * @return Value of member Login.
92  */
93 string Service::get_login() const
94 {
95     return Login;
96 }
97
98
99 /**
100  * Setter for member Password.
101  * @param _password Value to set Password to.
102  */
103 void Service::set_password(const string& _password)
104 {
105     Password = _password;
106 }
107
108
109 /**
110  * Getter for member Password.
111  * @return Value of member Password.
112  */
113 string Service::get_password() const
114 {
115     return Password;
116 }
117
118
119
120 void Service::set_logger(const Logger::Ptr& _log)
121 {
122     Log = _log;
123 }
124
125
126 /**
127  * Getter for member Log.
128  * @return Shared pointer to Logger object.
129  */
130 Logger::Ptr Service::get_logger() const
131 {
132     return Log;
133 }
134
135
136 void Service::set_last_updates(std::list<time_t> _last_updates)
137 {
138     LastUpdates.clear();
139     BOOST_FOREACH( time_t update_time, _last_updates )
140     {
141         LastUpdates.push_back(update_time);
142     }
143 }
144
145
146 /**
147  * Getter for member Lastupdated.
148  * @return Value of member Lastupdated.
149  */
150 const list<time_t> Service::get_last_updates() const
151 {
152     return LastUpdates;
153 }
154
155
156 /**
157  * Setter for member ActualIP.
158  * @param _actual_ip Value to set ActualIP to.
159  */
160 void Service::set_actual_ip(const std::string& _actual_ip)
161 {
162     ActualIP = _actual_ip;
163 }
164
165
166 /**
167  * Getter for member ActualIP.
168  * @return Value of member ActualIP.
169  */
170 std::string Service::get_actual_ip() const
171 {
172     return ActualIP;
173 }
174
175
176
177 /**
178  * Overloading of comparison operator.
179  * @param other Reference to other Service object.
180  * @return True if they equal, false if not.
181  */
182 bool Service::operator== (const Service& other) const
183 {
184     if ( ( this->Protocol == other.Protocol ) && ( this->Hostname == other.Hostname ) )
185         return true;
186     return false;
187 }
188
189
190 /**
191  * Overloading of disparate operator.
192  * @param other Reference to other Service object.
193  * @return True if they differ, false if they are equal.
194  */
195 bool Service::operator!= (const Service& other) const
196 {
197     return !(*this == other);
198 }
199
200
201 /**
202  * Checks if update will exceed max update interval.
203  * @param current_time Current time.
204  * @return True if update is allowed, false if update would exceed max update interval.
205  */
206 bool Service::update_allowed(const time_t current_time)
207 {
208     list<time_t>::iterator iter;
209     int i=0;
210
211     for (iter = LastUpdates.begin(); (iter != LastUpdates.end()) && ( i < MaxUpdatesWithinInterval ); iter++)
212     {
213         if ( (i == (MaxUpdatesWithinInterval-1)) && ( (*iter + ((time_t)UpdateInterval*60)) >= current_time ) )
214         {
215             Log->print_update_not_allowed(current_time,*iter,MaxUpdatesWithinInterval,get_service_name());
216             return false;
217         }
218         i++;
219     }
220     return true;
221 }
222
223
224 /**
225  * Service update method, common to each service.
226  * @param ip The new ip to set for the hostname.
227  */
228 void Service::update(const string& ip, const time_t current_time)
229 {
230     Log->print_update_service(get_service_name());
231
232     // test if update is permitted by UpdateInterval Status
233     if ( update_allowed(current_time) )
234     {
235         if ( perform_update(ip) == 0 )
236         {
237             // if update was successful, we need to set the Lastupdated and ActualIP base member.
238             set_last_update(current_time);
239             ActualIP = ip;
240             Log->print_update_service_successful(get_service_name());
241         }
242         else
243         {
244             // problem while trying to update service
245             Log->print_update_service_failure(get_service_name());
246         }
247     }
248 }
249
250
251 /**
252 * Sets the given time into the LastUpdates member and deletes expired entries.
253 * @param _timeout Value to set into LastUpdates.
254 */
255 void Service::set_last_update(const time_t current_time)
256 {
257     // Insert value into the list.
258     LastUpdates.push_front(current_time);
259
260     // Check for expired entries:
261
262     // MaxUpdatesWithinInterval given in service config, then use this to check for expired entries.
263     if ( MaxUpdatesWithinInterval > 0 )
264     {
265         // Delete the oldest entry if there are more than MaxUpdatesWithinInterval+1 entries in the list.
266         if (LastUpdates.size() > (MaxUpdatesWithinInterval+1))
267             LastUpdates.pop_back();
268         return;
269     }
270     // UpdateInterval given in service config, then use this to check for expired entries.
271     else if ( UpdateInterval > 0 )
272     {
273         // Delete the oldest entry if it's older than current_time - UpdateInterval(minutes) + 1.
274         if ( (current_time - ((time_t)UpdateInterval*60) + 1) > LastUpdates.back() )
275             LastUpdates.pop_back();
276         return;
277     }
278     // Neither MaxUpdatesWithinInterval nor UpdateInterval are given, so keep fix number of 10 entries.
279     else
280     {
281         if ( LastUpdates.size() > 10 )
282             LastUpdates.pop_back();
283         return;
284     }
285 }
286
287
288 /**
289  * Setter for member Timeout.
290  * @param _timeout Value to set Timeout to.
291  */
292 void Service::set_update_interval(const int _update_interval)
293 {
294     UpdateInterval = _update_interval;
295 }
296
297
298 /**
299  * Getter for member Timeout.
300  * @return Value of Timeout.
301  */
302 int Service::get_update_interval() const
303 {
304     return UpdateInterval;
305 }
306
307
308 /**
309  * Setter for member Max_updates_per_timeout.
310  * @param  _max_updates_per_timeout Value to set Max_updates_per_timeout to.
311  */
312 void Service::set_max_updates_within_interval(const int _max_updates_within_interval)
313 {
314     MaxUpdatesWithinInterval = _max_updates_within_interval;
315 }
316
317
318 /**
319  * Getter for member Max_updates_per_timeout.
320  * @return Value of Max_updates_per_timeout.
321  */
322 int Service::get_max_updates_within_interval() const
323 {
324     return MaxUpdatesWithinInterval;
325 }
326
327
328 /**
329  * Get a unique service identify string
330  * @return A unique service identify string
331  */
332 string Service::get_service_name() const
333 {
334     string service_name;
335
336     service_name.append(Protocol);
337     service_name.append(" ");
338     service_name.append(Hostname);
339
340     return service_name;
341 }
342
343
344 /**
345  * Get member DNSCacheTTL
346  * @return DNSCacheTTL
347  */
348 int Service::get_dns_cache_ttl() const
349 {
350     return DNSCacheTTL;
351 }
352
353
354 /**
355  * Set member DNSCacheTTL
356  * @param _dns_cache_ttl DNSCacheTTL
357  */
358 void Service::set_dns_cache_ttl(const int _dns_cache_ttl)
359 {
360     DNSCacheTTL = _dns_cache_ttl;
361 }