Update pingcheck to work with cmake 3.28
[pingcheck] / src / config / configuration.cpp
CommitLineData
91fcc471
TJ
1/*
2The software in this package is distributed under the GNU General
3Public License version 2 (with a special exception described below).
4
5A copy of GNU General Public License (GPL) is included in this distribution,
6in the file COPYING.GPL.
7
8As a special exception, if other files instantiate templates or use macros
9or inline functions from this file, or you compile this file and link it
10with other works to produce a work based on this file, this file
11does not by itself cause the resulting work to be covered
12by the GNU General Public License.
13
14However the source code for this file must still be made available
15in accordance with section (3) of the GNU General Public License.
16
17This exception does not invalidate any other reasons why a work based
18on this file might be covered by the GNU General Public License.
19*/
9c55ecd3 20#include "config/configuration.h"
8c3f445c 21
096b06ef
CH
22#include <set>
23#include <ctime> // for seeding random number generator
096b06ef
CH
24#include <boost/math/special_functions/round.hpp>
25#include <boost/numeric/conversion/cast.hpp>
26#include <boost/foreach.hpp>
27#include <boost/random/uniform_int.hpp>
28#include <boost/random/variate_generator.hpp>
ced28dc7 29
780b0bca
CH
30#include "boost_assert_handler.h"
31
aa48371a 32using namespace std;
f3c09c5a 33using I2n::Logger::LogLevel;
096b06ef
CH
34using I2n::Logger::GlobalLogger;
35
36typedef boost::uniform_int<> rand_dist_type;
37typedef boost::variate_generator<rand_gen_type&, rand_dist_type> rand_var_type;
14d14bd7
GMF
38
39//-----------------------------------------------------------------------------
40// Configuration
41//-----------------------------------------------------------------------------
aa48371a
GMF
42
43Configuration::Configuration() :
8ef29e4a 44 Daemon( false ),
f3c09c5a 45 LoggingLevel( LogLevel::Error ),
5ba17410 46 LoggingOutput( LogOutput_SYSLOG ),
fda777ea 47 LogFileName( "" ),
33f408b1 48 ConfigFileName( "" ),
abb06ac2 49 SourceNetworkInterface( "" ),
61e224f8 50 NameServer( "" ),
a341119a
GMF
51 HostsDownLimit( 0 ),
52 MinHostsDownLimit( 0 ),
53 MaxHostsDownLimit( 50 ),
54 PingFailLimit( 0 ),
55 MinPingFailLimit( 0 ),
56 MaxPingFailLimit( 100 ),
d52d036a 57 StatusNotifierCmd( "" ),
97837af8
CH
58 LinkUpIntervalInSec( 0 ),
59 LinkDownIntervalInSec( 0 ),
60 MinStableLinkIntervalInSec( 0 ),
61 MaxStableLinkIntervalInSec( 3600 ),
079d19ab
CH
62 PingReplyTimeout( 30 ),
63 MaxAddressResolutionAttempts( 10 ),
64 ResolvedIpTtlThreshold( 10 ),
f833126b 65 MinTimeBetweenResolves( 10 ),
a901aed6 66 DnsCacheFile(""),
096b06ef
CH
67 Hosts(),
68 RatioRandomHosts( 1.0f ),
bfec40a6 69 PrintVersion( false ),
096b06ef 70 RandomNumberGenerator( boost::numeric_cast<unsigned int>(time(0)) )
ced28dc7
GMF
71{
72}
73
74Configuration::~Configuration()
75{
76}
aa48371a 77
8ef29e4a
GMF
78bool Configuration::get_daemon() const
79{
80 return Daemon;
81}
82
83void Configuration::set_daemon( bool daemon )
529e5587 84{ //lint !e578
8ef29e4a
GMF
85 Daemon = daemon;
86}
87
2c40f493
GMF
88LogLevel Configuration::get_log_level() const
89{
90 return LoggingLevel;
91}
92
93void Configuration::set_log_level( const LogLevel &log_level )
94{
f3c09c5a 95 BOOST_ASSERT( (LogLevel::Emergency <= log_level) && (log_level <= LogLevel::Debug) );
2c40f493
GMF
96
97 this->LoggingLevel = log_level;
98}
99
5ba17410
GMF
100LogOutput Configuration::get_log_output() const
101{
102 return LoggingOutput;
103}
104
105void Configuration::set_log_output( const LogOutput &log_output )
106{
107 BOOST_ASSERT( (LogOutput_First <= log_output) && (log_output <= LogOutput_Last) );
108
109 this->LoggingOutput = log_output;
110}
111
fda777ea
CH
112string Configuration::get_log_file() const
113{
114 return LogFileName;
115}
116
117void Configuration::set_log_file( const std::string &log_file )
118{
119 BOOST_ASSERT( !log_file.empty() );
120
121 this->LogFileName = log_file;
122}
123
14d14bd7 124string Configuration::get_config_file_name() const
aa48371a 125{
33f408b1 126 return ConfigFileName;
14d14bd7 127}
aa48371a 128
e15b9466 129void Configuration::set_config_file_name( const string &config_file_name )
14d14bd7 130{
8c3f445c
GMF
131 BOOST_ASSERT( !config_file_name.empty() );
132
33f408b1 133 this->ConfigFileName = config_file_name;
aa48371a
GMF
134}
135
e15b9466 136string Configuration::get_nameserver() const
61e224f8
GMF
137{
138 return NameServer;
139}
140
e15b9466 141void Configuration::set_nameserver( const string &nameserver )
61e224f8
GMF
142{
143 NameServer = nameserver;
144}
145
abb06ac2
GMF
146string Configuration::get_source_network_interface() const
147{
148 return SourceNetworkInterface;
149}
150
151void Configuration::set_source_network_interface(
152 const string &source_network_interface
153)
154{
155 SourceNetworkInterface = source_network_interface;
156}
157
a341119a 158int Configuration::get_hosts_down_limit() const
aa48371a 159{
a341119a 160 return HostsDownLimit;
aa48371a
GMF
161}
162
a341119a 163void Configuration::set_hosts_down_limit( const int hosts_down_limit )
aa48371a 164{
f75a2748 165 BOOST_ASSERT( ( MinHostsDownLimit <= hosts_down_limit ) && ( hosts_down_limit <= MaxHostsDownLimit ) );
8c3f445c 166
a341119a 167 this->HostsDownLimit = hosts_down_limit;
aa48371a 168}
ad8eb8ab 169
a341119a 170int Configuration::get_ping_fail_limit() const
c5e4bfa1 171{
a341119a 172 return PingFailLimit;
c5e4bfa1
GMF
173}
174
a341119a 175void Configuration::set_ping_fail_limit( const int ping_fail_limit )
c5e4bfa1 176{
f75a2748
GMF
177 BOOST_ASSERT( ( MinPingFailLimit <= ping_fail_limit ) && ( ping_fail_limit <= MaxPingFailLimit ) );
178
a341119a 179 PingFailLimit = ping_fail_limit;
c5e4bfa1
GMF
180}
181
d52d036a
GMF
182string Configuration::get_status_notifier_cmd() const
183{
184 return StatusNotifierCmd;
185}
186
187void Configuration::set_status_notifier_cmd( const string &status_notifier_cmd )
188{
189 BOOST_ASSERT( !status_notifier_cmd.empty() );
190
191 StatusNotifierCmd = status_notifier_cmd;
192}
193
97837af8 194int Configuration::get_link_up_interval_in_sec() const
fb09230d 195{
97837af8 196 return LinkUpIntervalInSec;
fb09230d
GMF
197}
198
97837af8
CH
199void Configuration::set_link_up_interval_in_sec(
200 const int link_up_interval_in_sec
7028b80b 201)
fb09230d 202{
97837af8 203 BOOST_ASSERT( ( MinStableLinkIntervalInSec <= link_up_interval_in_sec ) && ( link_up_interval_in_sec <= MaxStableLinkIntervalInSec ) );
f75a2748 204
97837af8 205 LinkUpIntervalInSec = link_up_interval_in_sec;
fb09230d
GMF
206}
207
97837af8 208int Configuration::get_link_down_interval_in_sec() const
1634f2a1 209{
97837af8 210 return LinkDownIntervalInSec;
1634f2a1
GMF
211}
212
97837af8
CH
213void Configuration::set_link_down_interval_in_sec(
214 const int link_down_interval_in_sec
7028b80b 215)
1634f2a1 216{
97837af8 217 BOOST_ASSERT( ( MinStableLinkIntervalInSec <= link_down_interval_in_sec ) && ( link_down_interval_in_sec <= MaxStableLinkIntervalInSec ) );
1634f2a1 218
97837af8 219 LinkDownIntervalInSec = link_down_interval_in_sec;
1634f2a1
GMF
220}
221
079d19ab
CH
222int Configuration::get_ping_reply_timeout() const
223{
224 return PingReplyTimeout;
225}
226void Configuration::set_ping_reply_timeout( const int ping_reply_timeout )
227{
228 BOOST_ASSERT(ping_reply_timeout > 0 );
229 PingReplyTimeout = ping_reply_timeout;
230}
231
232int Configuration::get_max_address_resolution_attempts() const
233{
234 return MaxAddressResolutionAttempts;
235}
236void Configuration::set_max_address_resolution_attempts( const int max_address_resolution_attempts )
237{
238 BOOST_ASSERT(max_address_resolution_attempts > 0 );
239 MaxAddressResolutionAttempts = max_address_resolution_attempts;
240}
241
242int Configuration::get_resolved_ip_ttl_threshold() const
243{
244 return ResolvedIpTtlThreshold;
245}
246void Configuration::set_resolved_ip_ttl_threshold( const int resolved_ip_ttl_threshold )
247{
fd62d09f 248 BOOST_ASSERT(resolved_ip_ttl_threshold >= 0 );
079d19ab
CH
249 ResolvedIpTtlThreshold = resolved_ip_ttl_threshold;
250}
251
f833126b
CH
252int Configuration::get_min_time_between_resolves() const
253{
254 return MinTimeBetweenResolves;
255}
256void Configuration::set_min_time_between_resolves( const int min_time_between_resolves )
257{
258 BOOST_ASSERT(min_time_between_resolves >= 0 );
259 MinTimeBetweenResolves = min_time_between_resolves;
260}
261
a901aed6
CH
262void Configuration::set_dns_cache_file( const std::string &dns_cache_file)
263{
264 BOOST_ASSERT( !dns_cache_file.empty() );
265 DnsCacheFile = dns_cache_file;
266}
267
268std::string Configuration::get_dns_cache_file() const
269{
270 return DnsCacheFile;
271}
272
096b06ef
CH
273float Configuration::get_ratio_random_hosts() const
274{
275 return RatioRandomHosts;
276}
277
278void Configuration::set_ratio_random_hosts( const float ratio )
279{
280 BOOST_ASSERT( (ratio > 0.0f) && (ratio <= 1.0f) );
bfec40a6 281 RatioRandomHosts = ratio;
096b06ef
CH
282}
283
dbe36b16 284HostList Configuration::get_hosts() const
ad8eb8ab 285{
8739a651 286 return Hosts;
ad8eb8ab
GMF
287}
288
dbe36b16 289void Configuration::set_hosts( const HostList &hosts_list )
ad8eb8ab 290{
bfec40a6
CH
291 Hosts = hosts_list;
292}
293
294bool Configuration::get_print_version()
295{
296 return PrintVersion;
297}
298
299void Configuration::set_print_version( const bool do_print )
300{
301 PrintVersion = do_print;
ad8eb8ab
GMF
302}
303
096b06ef
CH
304int Configuration::get_random_number(const int lowest, const int highest)
305{
306 rand_dist_type random_distribution(lowest, highest);
307 rand_var_type random_variate(RandomNumberGenerator, random_distribution);
308 return random_variate();
309}
310
311/**
312 * @brief select RatioRandomHosts of the hosts at random.
313 * changes internal list of hosts
314 * @returns false if could not randomize (e.g. only 1 host
315 * available or ratio=1)
316 */
317bool Configuration::randomize_hosts()
318{
319 // need this a few times
320 unsigned int n_hosts = Hosts.size();
321 float n_hosts_float = boost::numeric_cast<float>(n_hosts);
322
323 // check if RatioRandomHosts == 1
324 if ((1. - RatioRandomHosts) < 0.5/n_hosts_float)
325 return false;
326
327 // determine number of hosts to keep
328 unsigned int n_wanted = boost::math::iround(n_hosts_float * RatioRandomHosts);
329 if (n_wanted == 0)
330 n_wanted = 1; // want at least 1 host
331 if (n_wanted == n_hosts) // e.g. always the case if only 1 host given
332 return false;
333
334 GlobalLogger.info() << "randomizing hosts: keeping "
335 << n_wanted << " from overall " << n_hosts;
336
337 BOOST_ASSERT(n_wanted <= n_hosts); // just to be sure
338
339 // create new set of hosts (more efficient than removal from std::vector Hosts)
340 std::set<HostItem> new_hosts;
341 int take_idx;
342
343 // add hosts at random until size is good
344 rand_dist_type random_distribution(0, n_hosts-1);
345 rand_var_type random_variate(RandomNumberGenerator, random_distribution);
346 while (new_hosts.size() < n_wanted)
347 {
348 take_idx = random_variate();
349 new_hosts.insert( Hosts[take_idx] ); // does nothing if host is already in there
350 }
351
352 // convert from set to list
353 HostList new_list;
354 BOOST_FOREACH(HostItem host, new_hosts)
355 new_list.push_back(host);
356
357 this->Hosts = new_list;
358
359 return true;
360}
361