Introduced HTTPHelper class to easily perform HTTP operations within services.
[bpdyndnsd] / src / updater.cpp
CommitLineData
b1be615b
BS
1/** @file
2 * @brief The updater class implementation. This class implements the updater logic.
3 *
4 *
5 *
6 * @copyright Intra2net AG
7 * @license GPLv2
8*/
9
4545a371
BS
10#include "updater.h"
11
e0080b78
BS
12#include "serviceholder.h"
13#include "dhs.h"
14#include "ods.h"
15
88a594e8
BS
16#include <boost/foreach.hpp>
17
e0080b78
BS
18
19// Following boost macros are needed for serialization of derived classes through a base class pointer (Service *).
20BOOST_CLASS_EXPORT_GUID(ODS, "ODS")
21BOOST_CLASS_EXPORT_GUID(DHS, "DHS")
22
23namespace fs = boost::filesystem;
24
8bca3c5d 25using namespace std;
527536b3 26
b1be615b
BS
27/**
28 * Default constructor which initializes the member Conf.
29 */
4545a371 30Updater::Updater()
019dc0d9 31 : IPHelp(new IPHelper)
4545a371 32{
2e956a36 33 // Initialize program wide Logger, at this point we don't know where to log and with which loglevel.
88a594e8 34 Logger::Ptr _log(new Logger);
254bbf53 35 Log = _log;
0665b239 36 _log.reset();
4545a371 37
e0080b78
BS
38 // initialize Serviceholder
39 Serviceholder::Ptr _serviceholder(new Serviceholder(Log));
40 ServiceHolder = _serviceholder;
41 _serviceholder.reset();
42
254bbf53 43 // initialize Config
e0080b78 44 Config::Ptr _config(new Config(Log,ServiceHolder));
254bbf53 45 Conf = _config;
0665b239 46 _config.reset();
4545a371
BS
47}
48
527536b3 49
b1be615b
BS
50/**
51 * Default destructor.
52 */
4545a371
BS
53Updater::~Updater()
54{
55}
56
527536b3 57
efbde536
BS
58
59/**
60 * Load config and initialize helper classes.
61 * @param argc Number of arguments in array
62 * @param argv Array with cmd options
63 */
64int Updater::load_config(int argc, char *argv[])
65{
66 // load the cmd options
67 if ( init_config_from_cmd(argc,argv) != 0 )
68 return -1;
69
70 // load the config and service files
71 if ( init_config_from_files() != 0 )
72 return -1;
73
74 // init all helper classes
75 if ( init_helper_classes() != 0 )
76 return -1;
77
78 return 0;
79}
80
81
82/**
83 * Reloading the config. Delete all Service objects and then init new Service objects from config files.
84 */
85int Updater::reload_config()
86{
87 // serialize all service objects
88 if ( ServiceHolder->serialize_services() != 0 )
89 return -1;
90
91 // delete all service objects
92 ServiceHolder->delete_services();
93
94 // delete the actual Variables_map, perhaps with old cmd options which would overwrite new config file options.
95 Conf->delete_variables_map();
96
97 // load only config files
98 if ( init_config_from_files() != 0 )
99 return -1;
100
101 // init all helper classes
102 if ( init_helper_classes() != 0 )
103 return -1;
104
105 return 0;
106}
107
108
b1be615b 109/**
254bbf53
BS
110 * Parse the command line arguments and initialize corresponding options.
111 * @param argc Number command line arguments.
112 * @param argv[] Array with arguments.
113 * @return 0 if cmd options successfully parsed, 1 if usage or version.
38060291 114 */
254bbf53 115int Updater::init_config_from_cmd(int argc, char *argv[])
38060291
BS
116{
117 // Load the command line parameters
efbde536 118 if( Conf->parse_cmd_line( argc, argv, HTTPHelp) != 0)
667c672c 119 return -1;
38060291 120
59c8d63c
BS
121 // If we have loaded the cmd options we need to init the log facility immediately in case debugging is enabled from cmd.
122 init_log_facility();
123
254bbf53
BS
124 // successful parsed
125 Log->print_cmd_parsed();
38060291
BS
126 return 0;
127}
128
129
130/**
254bbf53
BS
131 * Load the main config and the service definition files in config path.
132 * @return 0 if all is fine,
b1be615b 133 */
254bbf53 134int Updater::init_config_from_files()
4545a371 135{
254bbf53 136 // Load the main and service config files in config path
efbde536 137 if ( Conf->load_config_from_files(HTTPHelp) != 0 )
667c672c 138 return -1;
4545a371 139
59c8d63c
BS
140 // Re-init log facility, perhaps new config file options for logger are set.
141 // These config file options will only overwrite the cmd options if the SIGHUP (reload config) is caught.
142 init_log_facility();
143
27baf279 144 // Here we are. All Service Objects should be initialized, so it is time to deserialize the old service objects and compare them.
e0080b78 145 if ( ServiceHolder->deserialize_services() != 0 )
667c672c 146 return -1;
27baf279 147
254bbf53 148 // successful loaded
667c672c 149 Log->print_conf_files_parsed();
254bbf53 150 return 0;
4545a371
BS
151}
152
527536b3 153
b1be615b 154/**
efbde536
BS
155 * Init all Helper classes
156 * @return
3434b35f 157 */
efbde536 158int Updater::init_helper_classes()
3434b35f 159{
efbde536
BS
160 // Initialize IPHelper
161 if ( init_ip_helper() != 0 )
162 return -1;
3434b35f 163
efbde536
BS
164 // Initialize HTTPHelper
165 if ( init_http_helper() != 0 )
166 return -1;
3434b35f 167
efbde536 168 return 0;
3434b35f
BS
169}
170
171
172/**
0665b239
BS
173 * Init the IPHelp member with needed values.
174 * @return 0 if all is fine, -1 otherwise.
175 */
176int Updater::init_ip_helper()
177{
019dc0d9 178 // initialize IPHelper
4eb87664 179 IPHelper::Ptr _iphelp(new IPHelper(Log,Conf->get_webcheck_ip_url(),Conf->get_webcheck_ip_url_alt(),Conf->get_enable_ipv6(),Conf->get_proxy(),Conf->get_proxy_port()));
019dc0d9
BS
180 IPHelp = _iphelp;
181 _iphelp.reset();
0665b239
BS
182
183 return 0;
184}
185
186
187/**
efbde536
BS
188 * Init the IPHelp member with needed values.
189 * @return 0 if all is fine, -1 otherwise.
c5675c01 190 */
efbde536 191int Updater::init_http_helper()
c5675c01 192{
efbde536
BS
193 // initialize IPHelper
194 HTTPHelper::Ptr _httphelp(new HTTPHelper(Log,Conf->get_proxy(),Conf->get_proxy_port()));
195 HTTPHelp = _httphelp;
196 _httphelp.reset();
27baf279 197
efbde536
BS
198 return 0;
199}
8bca3c5d 200
8bca3c5d 201
efbde536
BS
202/**
203 * Getter for member Config.
204 * @return Member Config.
205 */
206Config::Ptr Updater::get_config() const
207{
208 return Conf;
209}
667c672c 210
efbde536
BS
211
212/**
213 * Getter for member Logger.
214 * @return Member Logger.
215 */
216Logger::Ptr Updater::get_logger() const
217{
218 return Log;
8bca3c5d
BS
219}
220
221
2bc1878a
BS
222/**
223 * Initialize the logging facility with loglevel and syslog.
224 */
8bca3c5d
BS
225void Updater::init_log_facility()
226{
cbbdeb6c 227 Log->set_log_facility(Conf->get_loglevel(),Conf->get_syslog(),Conf->get_external_warning_log(),Conf->get_external_warning_level());
8bca3c5d 228 Log->print_init_log_facility();
c5675c01
BS
229}
230
231
232/**
b1be615b
BS
233 * Update all configured services.
234 */
4545a371
BS
235void Updater::update_services()
236{
e0080b78 237 list<Service::Ptr> services = ServiceHolder->get_services();
4545a371 238
0665b239 239 string ip = IPHelp->get_actual_ip();
4545a371 240
3c0cd271 241 if ( !ip.empty() )
4545a371 242 {
3c0cd271
BS
243 BOOST_FOREACH(Service::Ptr &service, services )
244 {
c3dea5dc
BS
245 string dns_recheck_ip = ip;
246 int current_time = time(NULL);
247
248 int lastupdated = 0;
249 if ( service->get_last_updates()->size() > 0 )
250 lastupdated = service->get_last_updates()->front();
251
4eb87664 252 // If the dns cache ttl is expired, then get the actual ip of the dns record (this should be the IP in the last update)
c3dea5dc 253 if ( (lastupdated != 0) && ((lastupdated + service->get_dns_cache_ttl()) < current_time) )
0541cd71
BS
254 {
255 Log->print_recheck_dns_entry(service->get_hostname(),lastupdated,service->get_dns_cache_ttl(),current_time);
256 string _dns_recheck_ip = IPHelp->dns_query(service->get_hostname());
257 Log->print_cached_dns_entry(service->get_hostname(), _dns_recheck_ip, service->get_actual_ip());
258 if (!_dns_recheck_ip.empty())
259 dns_recheck_ip = _dns_recheck_ip;
260 }
c3dea5dc 261
4eb87664
BS
262 // In case the local hosts IP (ip) differ from the IP set in the last update (actual_ip) or
263 // the IP of the dns record (dns_recheck_ip) differs from the IP of the local host (ip)
264 // then perform an update. This implies that the update is not performed if actual_ip == dns_recheck_ip.
c3dea5dc
BS
265 if ( (service->get_actual_ip() != ip) || (dns_recheck_ip != ip) )
266 service->update(ip,current_time);
3c0cd271 267 }
4545a371 268 }
b1be615b 269}
e0080b78
BS
270
271
272/**
273 * Getter for member ServiceHolder.
274 * @return ServiceHolder
275 */
276Serviceholder::Ptr Updater::get_service_holder() const
277{
278 return ServiceHolder;
279}