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