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 ), |
33f408b1 | 47 | ConfigFileName( "" ), |
abb06ac2 | 48 | SourceNetworkInterface( "" ), |
61e224f8 | 49 | NameServer( "" ), |
a341119a GMF |
50 | HostsDownLimit( 0 ), |
51 | MinHostsDownLimit( 0 ), | |
52 | MaxHostsDownLimit( 50 ), | |
53 | PingFailLimit( 0 ), | |
54 | MinPingFailLimit( 0 ), | |
55 | MaxPingFailLimit( 100 ), | |
d52d036a | 56 | StatusNotifierCmd( "" ), |
4d6ab0f3 | 57 | LinkUpIntervalInMin( 0 ), |
1634f2a1 | 58 | LinkDownIntervalInMin( 0 ), |
4d6ab0f3 GMF |
59 | MinStableLinkIntervalInMin( 0 ), |
60 | MaxStableLinkIntervalInMin( 60 ), | |
079d19ab CH |
61 | PingReplyTimeout( 30 ), |
62 | MaxAddressResolutionAttempts( 10 ), | |
63 | ResolvedIpTtlThreshold( 10 ), | |
a901aed6 | 64 | DnsCacheFile(""), |
096b06ef CH |
65 | Hosts(), |
66 | RatioRandomHosts( 1.0f ), | |
bfec40a6 | 67 | PrintVersion( false ), |
096b06ef | 68 | RandomNumberGenerator( boost::numeric_cast<unsigned int>(time(0)) ) |
ced28dc7 GMF |
69 | { |
70 | } | |
71 | ||
72 | Configuration::~Configuration() | |
73 | { | |
74 | } | |
aa48371a | 75 | |
8ef29e4a GMF |
76 | bool Configuration::get_daemon() const |
77 | { | |
78 | return Daemon; | |
79 | } | |
80 | ||
81 | void Configuration::set_daemon( bool daemon ) | |
529e5587 | 82 | { //lint !e578 |
8ef29e4a GMF |
83 | Daemon = daemon; |
84 | } | |
85 | ||
2c40f493 GMF |
86 | LogLevel Configuration::get_log_level() const |
87 | { | |
88 | return LoggingLevel; | |
89 | } | |
90 | ||
91 | void Configuration::set_log_level( const LogLevel &log_level ) | |
92 | { | |
f3c09c5a | 93 | BOOST_ASSERT( (LogLevel::Emergency <= log_level) && (log_level <= LogLevel::Debug) ); |
2c40f493 GMF |
94 | |
95 | this->LoggingLevel = log_level; | |
96 | } | |
97 | ||
5ba17410 GMF |
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 | ||
14d14bd7 | 110 | string Configuration::get_config_file_name() const |
aa48371a | 111 | { |
33f408b1 | 112 | return ConfigFileName; |
14d14bd7 | 113 | } |
aa48371a | 114 | |
e15b9466 | 115 | void Configuration::set_config_file_name( const string &config_file_name ) |
14d14bd7 | 116 | { |
8c3f445c GMF |
117 | BOOST_ASSERT( !config_file_name.empty() ); |
118 | ||
33f408b1 | 119 | this->ConfigFileName = config_file_name; |
aa48371a GMF |
120 | } |
121 | ||
e15b9466 | 122 | string Configuration::get_nameserver() const |
61e224f8 GMF |
123 | { |
124 | return NameServer; | |
125 | } | |
126 | ||
e15b9466 | 127 | void Configuration::set_nameserver( const string &nameserver ) |
61e224f8 GMF |
128 | { |
129 | NameServer = nameserver; | |
130 | } | |
131 | ||
abb06ac2 GMF |
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 | ||
a341119a | 144 | int Configuration::get_hosts_down_limit() const |
aa48371a | 145 | { |
a341119a | 146 | return HostsDownLimit; |
aa48371a GMF |
147 | } |
148 | ||
a341119a | 149 | void Configuration::set_hosts_down_limit( const int hosts_down_limit ) |
aa48371a | 150 | { |
f75a2748 | 151 | BOOST_ASSERT( ( MinHostsDownLimit <= hosts_down_limit ) && ( hosts_down_limit <= MaxHostsDownLimit ) ); |
8c3f445c | 152 | |
a341119a | 153 | this->HostsDownLimit = hosts_down_limit; |
aa48371a | 154 | } |
ad8eb8ab | 155 | |
a341119a | 156 | int Configuration::get_ping_fail_limit() const |
c5e4bfa1 | 157 | { |
a341119a | 158 | return PingFailLimit; |
c5e4bfa1 GMF |
159 | } |
160 | ||
a341119a | 161 | void Configuration::set_ping_fail_limit( const int ping_fail_limit ) |
c5e4bfa1 | 162 | { |
f75a2748 GMF |
163 | BOOST_ASSERT( ( MinPingFailLimit <= ping_fail_limit ) && ( ping_fail_limit <= MaxPingFailLimit ) ); |
164 | ||
a341119a | 165 | PingFailLimit = ping_fail_limit; |
c5e4bfa1 GMF |
166 | } |
167 | ||
d52d036a GMF |
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 | ||
4d6ab0f3 | 180 | int Configuration::get_link_up_interval_in_min() const |
fb09230d | 181 | { |
4d6ab0f3 | 182 | return LinkUpIntervalInMin; |
fb09230d GMF |
183 | } |
184 | ||
7028b80b GMF |
185 | void Configuration::set_link_up_interval_in_min( |
186 | const int link_up_interval_in_min | |
187 | ) | |
fb09230d | 188 | { |
4d6ab0f3 | 189 | BOOST_ASSERT( ( MinStableLinkIntervalInMin <= link_up_interval_in_min ) && ( link_up_interval_in_min <= MaxStableLinkIntervalInMin ) ); |
f75a2748 | 190 | |
4d6ab0f3 | 191 | LinkUpIntervalInMin = link_up_interval_in_min; |
fb09230d GMF |
192 | } |
193 | ||
1634f2a1 GMF |
194 | int Configuration::get_link_down_interval_in_min() const |
195 | { | |
196 | return LinkDownIntervalInMin; | |
197 | } | |
198 | ||
7028b80b GMF |
199 | void Configuration::set_link_down_interval_in_min( |
200 | const int link_down_interval_in_min | |
201 | ) | |
1634f2a1 GMF |
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 | ||
079d19ab CH |
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 | { | |
fd62d09f | 234 | BOOST_ASSERT(resolved_ip_ttl_threshold >= 0 ); |
079d19ab CH |
235 | ResolvedIpTtlThreshold = resolved_ip_ttl_threshold; |
236 | } | |
237 | ||
a901aed6 CH |
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 | ||
096b06ef CH |
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) ); | |
bfec40a6 | 257 | RatioRandomHosts = ratio; |
096b06ef CH |
258 | } |
259 | ||
dbe36b16 | 260 | HostList Configuration::get_hosts() const |
ad8eb8ab | 261 | { |
8739a651 | 262 | return Hosts; |
ad8eb8ab GMF |
263 | } |
264 | ||
dbe36b16 | 265 | void Configuration::set_hosts( const HostList &hosts_list ) |
ad8eb8ab | 266 | { |
bfec40a6 CH |
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; | |
ad8eb8ab GMF |
278 | } |
279 | ||
096b06ef CH |
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 |