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