Commit | Line | Data |
---|---|---|
91fcc471 TJ |
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 | */ | |
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 | 32 | using namespace std; |
f3c09c5a | 33 | using I2n::Logger::LogLevel; |
096b06ef CH |
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; | |
14d14bd7 GMF |
38 | |
39 | //----------------------------------------------------------------------------- | |
40 | // Configuration | |
41 | //----------------------------------------------------------------------------- | |
aa48371a GMF |
42 | |
43 | Configuration::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 | ||
74 | Configuration::~Configuration() | |
75 | { | |
76 | } | |
aa48371a | 77 | |
8ef29e4a GMF |
78 | bool Configuration::get_daemon() const |
79 | { | |
80 | return Daemon; | |
81 | } | |
82 | ||
83 | void Configuration::set_daemon( bool daemon ) | |
529e5587 | 84 | { //lint !e578 |
8ef29e4a GMF |
85 | Daemon = daemon; |
86 | } | |
87 | ||
2c40f493 GMF |
88 | LogLevel Configuration::get_log_level() const |
89 | { | |
90 | return LoggingLevel; | |
91 | } | |
92 | ||
93 | void 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 |
100 | LogOutput Configuration::get_log_output() const |
101 | { | |
102 | return LoggingOutput; | |
103 | } | |
104 | ||
105 | void 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 |
112 | string Configuration::get_log_file() const |
113 | { | |
114 | return LogFileName; | |
115 | } | |
116 | ||
117 | void 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 | 124 | string Configuration::get_config_file_name() const |
aa48371a | 125 | { |
33f408b1 | 126 | return ConfigFileName; |
14d14bd7 | 127 | } |
aa48371a | 128 | |
e15b9466 | 129 | void 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 | 136 | string Configuration::get_nameserver() const |
61e224f8 GMF |
137 | { |
138 | return NameServer; | |
139 | } | |
140 | ||
e15b9466 | 141 | void Configuration::set_nameserver( const string &nameserver ) |
61e224f8 GMF |
142 | { |
143 | NameServer = nameserver; | |
144 | } | |
145 | ||
abb06ac2 GMF |
146 | string Configuration::get_source_network_interface() const |
147 | { | |
148 | return SourceNetworkInterface; | |
149 | } | |
150 | ||
151 | void Configuration::set_source_network_interface( | |
152 | const string &source_network_interface | |
153 | ) | |
154 | { | |
155 | SourceNetworkInterface = source_network_interface; | |
156 | } | |
157 | ||
a341119a | 158 | int Configuration::get_hosts_down_limit() const |
aa48371a | 159 | { |
a341119a | 160 | return HostsDownLimit; |
aa48371a GMF |
161 | } |
162 | ||
a341119a | 163 | void 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 | 170 | int Configuration::get_ping_fail_limit() const |
c5e4bfa1 | 171 | { |
a341119a | 172 | return PingFailLimit; |
c5e4bfa1 GMF |
173 | } |
174 | ||
a341119a | 175 | void 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 |
182 | string Configuration::get_status_notifier_cmd() const |
183 | { | |
184 | return StatusNotifierCmd; | |
185 | } | |
186 | ||
187 | void 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 | 194 | int Configuration::get_link_up_interval_in_sec() const |
fb09230d | 195 | { |
97837af8 | 196 | return LinkUpIntervalInSec; |
fb09230d GMF |
197 | } |
198 | ||
97837af8 CH |
199 | void 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 | 208 | int Configuration::get_link_down_interval_in_sec() const |
1634f2a1 | 209 | { |
97837af8 | 210 | return LinkDownIntervalInSec; |
1634f2a1 GMF |
211 | } |
212 | ||
97837af8 CH |
213 | void 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 |
222 | int Configuration::get_ping_reply_timeout() const |
223 | { | |
224 | return PingReplyTimeout; | |
225 | } | |
226 | void 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 | ||
232 | int Configuration::get_max_address_resolution_attempts() const | |
233 | { | |
234 | return MaxAddressResolutionAttempts; | |
235 | } | |
236 | void 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 | ||
242 | int Configuration::get_resolved_ip_ttl_threshold() const | |
243 | { | |
244 | return ResolvedIpTtlThreshold; | |
245 | } | |
246 | void 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 |
252 | int Configuration::get_min_time_between_resolves() const |
253 | { | |
254 | return MinTimeBetweenResolves; | |
255 | } | |
256 | void 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 |
262 | void 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 | ||
268 | std::string Configuration::get_dns_cache_file() const | |
269 | { | |
270 | return DnsCacheFile; | |
271 | } | |
272 | ||
096b06ef CH |
273 | float Configuration::get_ratio_random_hosts() const |
274 | { | |
275 | return RatioRandomHosts; | |
276 | } | |
277 | ||
278 | void 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 | 284 | HostList Configuration::get_hosts() const |
ad8eb8ab | 285 | { |
8739a651 | 286 | return Hosts; |
ad8eb8ab GMF |
287 | } |
288 | ||
dbe36b16 | 289 | void Configuration::set_hosts( const HostList &hosts_list ) |
ad8eb8ab | 290 | { |
bfec40a6 CH |
291 | Hosts = hosts_list; |
292 | } | |
293 | ||
294 | bool Configuration::get_print_version() | |
295 | { | |
296 | return PrintVersion; | |
297 | } | |
298 | ||
299 | void Configuration::set_print_version( const bool do_print ) | |
300 | { | |
301 | PrintVersion = do_print; | |
ad8eb8ab GMF |
302 | } |
303 | ||
096b06ef CH |
304 | int 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 | */ | |
317 | bool 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 |