IBR-DTNSuite  0.12
Configuration.cpp
Go to the documentation of this file.
1 /*
2  * Configuration.cpp
3  *
4  * Copyright (C) 2011 IBR, TU Braunschweig
5  *
6  * Written-by: Johannes Morgenroth <morgenroth@ibr.cs.tu-bs.de>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21 
22 #include "config.h"
23 #include "Configuration.h"
24 #include "net/DiscoveryBeacon.h"
25 #include "net/DiscoveryBeacon.h"
26 #include "core/Node.h"
27 
28 #include <ibrdtn/utils/Utils.h>
29 #include <ibrdtn/utils/Clock.h>
30 
32 #include <ibrcommon/Logger.h>
34 
35 #ifdef __WIN32__
37 #include <windows.h>
38 
39 #endif
40 
41 #include <getopt.h>
42 #include <unistd.h>
43 
44 #ifdef __DEVELOPMENT_ASSERTIONS__
45 #include <cassert>
46 #endif
47 
48 using namespace dtn::net;
49 using namespace dtn::core;
50 using namespace dtn::utils;
51 using namespace ibrcommon;
52 
53 namespace dtn
54 {
55  namespace daemon
56  {
57  Configuration::NetConfig::NetConfig(const std::string &n, NetType t)
58  : name(n), type(t), iface(ibrcommon::vinterface::ANY), mtu(0), port(0)
59  {
60  }
61 
63  {
64  }
65 
66  std::string Configuration::version() const
67  {
68  std::stringstream ss;
69  ss << PACKAGE_VERSION;
70  #ifdef BUILD_NUMBER
71  ss << " (build " << BUILD_NUMBER << ")";
72  #endif
73 
74  return ss.str();
75  }
76 
77  Configuration::Configuration()
78  : _filename("config.ini"), _doapi(true)
79  {
80  }
81 
82  Configuration::~Configuration()
83  {}
84 
86  : _enabled(true), _timeout(5), _crosslayer(false) {}
87 
89  : _enabled(false), _quiet(false), _level(0) {}
90 
92  : _quiet(false), _options(0), _timestamps(false), _verbose(false) {}
93 
95  : _routing("default"), _forwarding(true), _prefer_direct(true), _tcp_nodelay(true), _tcp_chunksize(4096), _tcp_idle_timeout(0), _default_net("lo"), _use_default_net(false), _auto_connect(0), _fragmentation(false), _scheduling(false), _link_request_interval(5000)
96  {}
97 
99  : _enabled(false), _tlsEnabled(false), _tlsRequired(false), _tlsOptionalOnBadClock(false), _level(SECURITY_LEVEL_NONE), _disableEncryption(false)
100  {}
101 
103  : _daemonize(false), _kill(false), _threads(0)
104  {}
105 
107  : _reference(true), _sync(false), _discovery(false), _sigma(1.001f), _psi(0.8f), _sync_level(0.10f)
108  {}
109 
111  : _enabled(true), _port(0), _dnsbootstrapping(true), _ipv4(true), _ipv6(true), _blacklist(true), _selfannounce(true),
112  _minRating(1), _allowNeighbourToAnnounceMe(true), _allowNeighbourAnnouncement(true),
113  _ignoreDHTNeighbourInformations(false)
114  {}
115 
117  : _ctrl_path(""), _enabled(false)
118  {}
119 
121  : _smtpPort(25), _smtpUseTLS(false), _smtpUseSSL(false), _smtpNeedAuth(false), _smtpInterval(60), _smtpConnectionTimeout(-1), _smtpKeepAliveTimeout(30),
122  _imapPort(143), _imapUseTLS(false), _imapUseSSL(false), _imapInterval(60), _imapConnectionTimeout(-1), _imapPurgeMail(false),
123  _availableTime(1800), _returningMailsCheck(3)
124  {}
125 
135 
137  {
138  return _disco;
139  }
140 
142  {
143  return _debug;
144  }
145 
147  {
148  return _logger;
149  }
150 
152  {
153  return _network;
154  }
155 
157  {
158  return _security;
159  }
160 
162  {
163  return _daemon;
164  }
165 
167  {
168  return _timesync;
169  }
170 
172  {
173  return _dht;
174  }
175 
177  {
178  return _p2p;
179  }
180 
182  {
183  return _email;
184  }
185 
187  {
188  static Configuration conf;
189 
190  // reset configuration
191  if (reset) conf = Configuration();
192 
193  return conf;
194  }
195 
196  void Configuration::params(int argc, char *argv[])
197  {
198  int c;
199  int doapi = _doapi;
200  int disco = _disco._enabled;
201  int timestamp = _logger._timestamps;
202  int showversion = 0;
203 
204  // set number of threads to the number of available cpus
205  _daemon._threads = static_cast<dtn::data::Size>(ibrcommon::Thread::getNumberOfProcessors());
206 
207  while (1)
208  {
209  static struct option long_options[] =
210  {
211  /* These options set a flag. */
212  {"noapi", no_argument, &doapi, 0},
213  {"nodiscovery", no_argument, &disco, 0},
214  {"timestamp", no_argument, &timestamp, 1},
215  {"version", no_argument, &showversion, 1},
216 
217  /* These options don't set a flag. We distinguish them by their indices. */
218  {"help", no_argument, 0, 'h'},
219 #ifdef HAVE_LIBDAEMON
220  {"daemon", no_argument, 0, 'D'},
221  {"kill", no_argument, 0, 'k'},
222  {"pidfile", required_argument, 0, 'p'},
223 #endif
224 
225  {"quiet", no_argument, 0, 'q'},
226  {"interface", required_argument, 0, 'i'},
227  {"configuration", required_argument, 0, 'c'},
228  {"debug", required_argument, 0, 'd'},
229 #ifdef __WIN32__
230  {"interfaces", no_argument, 0, 'I'},
231 #endif
232  {0, 0, 0, 0}
233  };
234 
235  /* getopt_long stores the option index here. */
236  int option_index = 0;
237 
238 #ifdef HAVE_LIBDAEMON
239  c = getopt_long (argc, argv, "qhDkp:vi:c:d:t:",
240  long_options, &option_index);
241 #else
242  c = getopt_long (argc, argv, "qhvi:c:d:t:",
243  long_options, &option_index);
244 #endif
245 
246  /* Detect the end of the options. */
247  if (c == -1)
248  break;
249 
250  switch (c)
251  {
252  case 0:
253  /* If this option set a flag, do nothing else now. */
254  if (long_options[option_index].flag != 0)
255  break;
256  printf ("option %s", long_options[option_index].name);
257  if (optarg)
258  printf (" with arg %s", optarg);
259  printf ("\n");
260  break;
261 
262  case 'h':
263  std::cout << "IBR-DTN version: " << version() << std::endl;
264  std::cout << "Syntax: dtnd [options]" << std::endl;
265  std::cout << " -h|--help display this text" << std::endl;
266  std::cout << " -c <file> set a configuration file" << std::endl;
267 #ifdef HAVE_LIBDAEMON
268  std::cout << " -D daemonize the process" << std::endl;
269  std::cout << " -k stop the running daemon" << std::endl;
270  std::cout << " -p <file> store the pid in this pidfile" << std::endl;
271 #endif
272  std::cout << " -i <interface> interface to bind on (e.g. eth0)" << std::endl;
273  std::cout << " -d <level> enable debugging and set a verbose level" << std::endl;
274  std::cout << " -q enables the quiet mode (no logging to the console)" << std::endl;
275  std::cout << " -t <threads> specify a number of threads for parallel event processing" << std::endl;
276  std::cout << " -v be verbose - show NOTICE log messages" << std::endl;
277  std::cout << " --version show version and exit" << std::endl;
278  std::cout << " --noapi disable API module" << std::endl;
279  std::cout << " --nodiscovery disable discovery module" << std::endl;
280  std::cout << " --timestamp enables timestamps for logging instead of datetime values" << std::endl;
281 #ifdef __WIN32__
282  std::cout << " --interfaces list all available interfaces" << std::endl;
283 #endif
284  exit(0);
285  break;
286 
287  case 'v':
288  _logger._verbose = true;
289  break;
290 
291  case 'q':
292  _debug._quiet = true;
293  break;
294 
295  case 'c':
296  _filename = optarg;
297  break;
298 
299  case 'i':
300  _network._default_net = ibrcommon::vinterface(optarg);
301  _network._use_default_net = true;
302  break;
303 
304  case 'd':
305  _debug._enabled = true;
306  _debug._level = atoi(optarg);
307  break;
308 
309  case 'D':
310  _daemon._daemonize = true;
311  _debug._quiet = true;
312  break;
313 
314  case 'k':
315  _daemon._daemonize = true;
316  _daemon._kill = true;
317  break;
318 
319  case 'p':
320  _daemon._pidfile = std::string(optarg);
321  break;
322 
323  case 't':
324  _daemon._threads = atoi(optarg);
325  break;
326 
327 #ifdef __WIN32__
328  case 'I':
329  {
331  try {
333 
334  std::set<ibrcommon::vinterface> ifs = wlm.getInterfaces();
335 
336  std::cout << "Available interfaces:" << std::endl;
337 
338  for (std::set<ibrcommon::vinterface>::const_iterator it = ifs.begin(); it != ifs.end(); ++it)
339  {
340  const ibrcommon::vinterface &iface = (*it);
341  std::cout << iface.toString() << '\t';
342  std::wcout << iface.getFriendlyName() << std::endl;
343  }
344  } catch (const std::bad_cast&) {
345  }
346  exit(0);
347  break;
348  }
349 #endif
350 
351  case '?':
352  /* getopt_long already printed an error message. */
353  break;
354 
355  default:
356  abort();
357  break;
358  }
359  }
360 
361  if (showversion == 1) {
362  std::cout << "IBR-DTN version: " << version() << std::endl;
363  exit(0);
364  }
365 
366  _doapi = doapi;
367  _disco._enabled = disco;
368  _logger._timestamps = timestamp;
369  }
370 
371  void Configuration::load(bool quiet)
372  {
373  load(_filename, quiet);
374  }
375 
376  void Configuration::load(const std::string &filename, bool quiet)
377  {
378  try {
379  // load main configuration
380  _conf = ibrcommon::ConfigFile(filename);
381  _filename = filename;
382 
383  if (!quiet) IBRCOMMON_LOGGER_TAG("Configuration", info) << "Configuration: " << filename << IBRCOMMON_LOGGER_ENDL;
384  } catch (const ibrcommon::ConfigFile::file_not_found&) {
385  if (!quiet) IBRCOMMON_LOGGER_TAG("Configuration", info) << "Using default settings. Call with --help for options." << IBRCOMMON_LOGGER_ENDL;
386  _conf = ConfigFile();
387 
388  // set the default user to nobody
389  _conf.add<std::string>("user", "nobody");
390  }
391 
392  // load all configuration extensions
393  _disco.load(_conf);
394  _debug.load(_conf);
395  _logger.load(_conf);
396  _network.load(_conf);
397  _security.load(_conf);
398  _timesync.load(_conf);
399  _dht.load(_conf);
400  _p2p.load(_conf);
401  _email.load(_conf);
402  }
403 
405  {
406  _timeout = conf.read<unsigned int>("discovery_timeout", 5);
407  _crosslayer = (conf.read<std::string>("discovery_crosslayer", "no") == "yes");
408  }
409 
411  {
412  try {
413  _logfile = conf.read<std::string>("logfile");
414  } catch (const ibrcommon::ConfigFile::key_not_found&) {
415  }
416  }
417 
419  {
420  }
421 
423  {
424  }
425 
427  {
428  try {
429  _reference = (conf.read<std::string>("time_reference") == "yes");
430  } catch (const ibrcommon::ConfigFile::key_not_found&) { };
431 
432  try {
433  _sync = (conf.read<std::string>("time_synchronize") == "yes");
434  } catch (const ibrcommon::ConfigFile::key_not_found&) { };
435 
436  try {
437  _discovery = (conf.read<std::string>("time_discovery_announcements") == "yes");
438  } catch (const ibrcommon::ConfigFile::key_not_found&) { };
439 
440  _sigma = conf.read<float>("time_sigma", 1.001f);
441  _psi = conf.read<float>("time_psi", 0.9f);
442  _sync_level = conf.read<float>("time_sync_level", 0.15f);
443 
444  // enable the clock modify feature
445  dtn::utils::Clock::setModifyClock(conf.read<std::string>("time_set_clock", "no") == "yes");
446  }
447 
449  {
450  _enabled = (conf.read<std::string> ("dht_enabled", "no") == "yes");
451  _port = conf.read<int> ("dht_port", 9999);
452  _id = conf.read<string> ("dht_id", "");
453  _blacklist = (conf.read<std::string> ("dht_blacklist", "yes") == "yes");
454  _selfannounce = (conf.read<std::string> ("dht_self_announce", "yes") == "yes");
455  _dnsbootstrapping = (conf.read<std::string> ("dht_bootstrapping", "yes") == "yes");
456  string list = conf.read<string> ("dht_bootstrapping_domains", "");
457  _bootstrappingdomains = dtn::utils::Utils::tokenize(" ", list);
458  list = conf.read<string> ("dht_bootstrapping_ips", "");
459  _bootstrappingips = dtn::utils::Utils::tokenize(";", list);
460  _ipv4bind = conf.read<string> ("dht_bind_ipv4", "");
461  _ipv6bind = conf.read<string> ("dht_bind_ipv6", "");
462  _nodesFilePath = conf.read<string> ("dht_nodes_file", "");
463  _ipv4 = (conf.read<std::string> ("dht_enable_ipv4", "yes") == "yes");
464  _ipv6 = (conf.read<std::string> ("dht_enable_ipv6", "yes") == "yes");
465  _minRating = conf.read<int> ("dht_min_rating", 1);
466  _allowNeighbourToAnnounceMe = (conf.read<std::string> ("dht_allow_neighbours_to_announce_me", "yes") == "yes");
467  _allowNeighbourAnnouncement = (conf.read<std::string> ("dht_allow_neighbour_announcement", "yes") == "yes");
468  _ignoreDHTNeighbourInformations = (conf.read<std::string> ("dht_ignore_neighbour_informations", "no") == "yes");
469 
470  if (_minRating < 0) _minRating = 0;
471  }
472 
474  {
475  try {
476  _ctrl_path = conf.read<std::string>("p2p_ctrlpath");
477  _enabled = true;
478  } catch (const ibrcommon::ConfigFile::key_not_found&) {
479  // do nothing here...
480  _enabled = false;
481  }
482  }
483 
485  {
486  std::string tmp;
487  _address = conf.read<std::string> ("email_address", "root@localhost");
488  _smtpServer = conf.read<std::string> ("email_smtp_server", "localhost");
489  _smtpPort = conf.read<int> ("email_smtp_port", 25);
490  _smtpUsername = conf.read<std::string> ("email_smtp_username", "root");
491  _smtpPassword = conf.read<std::string> ("email_smtp_password", "");
492  _smtpInterval = conf.read<size_t> ("email_smtp_submit_interval", 60);
493  _smtpConnectionTimeout = conf.read<size_t> ("email_smtp_connection_timeout", -1);
494  _smtpKeepAliveTimeout = conf.read<size_t> ("email_smtp_keep_alive", 30);
495  _smtpNeedAuth = (conf.read<std::string> ("email_smtp_need_authentication", "no") == "yes");
496  _smtpUseTLS = (conf.read<std::string> ("email_smtp_socket_type", "") == "tls");
497  _smtpUseSSL = (conf.read<std::string> ("email_smtp_socket_type", "") == "ssl");
498  _imapServer = conf.read<std::string> ("email_imap_server", "localhost");
499  _imapPort = conf.read<int> ("email_imap_port", 143);
500  _imapUsername = conf.read<std::string> ("email_imap_username", _smtpUsername);
501  _imapPassword = conf.read<std::string> ("email_imap_password", _smtpPassword);
502  tmp = conf.read<string> ("email_imap_folder", "");
503  _imapFolder = dtn::utils::Utils::tokenize("/", tmp);
504  _imapInterval = conf.read<size_t> ("email_imap_lookup_interval", 60);
505  _imapConnectionTimeout = conf.read<size_t> ("email_imap_connection_timeout", -1);
506  _imapUseTLS = (conf.read<std::string> ("email_imap_socket_type", "") == "tls");
507  _imapUseSSL = (conf.read<std::string> ("email_imap_socket_type", "") == "ssl");
508  _imapPurgeMail = (conf.read<std::string> ("email_imap_purge_mail", "no") == "yes");
509  tmp = conf.read<string> ("email_certs_ca", "");
510  _tlsCACerts = dtn::utils::Utils::tokenize(",", tmp);
511  tmp = conf.read<string> ("email_certs_user", "");
512  _tlsUserCerts = dtn::utils::Utils::tokenize(",", tmp);
513  _availableTime = conf.read<size_t> ("email_node_available_time", 1800);
514  _returningMailsCheck = conf.read<size_t> ("email_returning_mails_checks", 3);
515  }
516 
518  {
519  return _quiet;
520  }
521 
523  {
524  return _enabled;
525  }
526 
528  {
529  return _level;
530  }
531 
532  std::string Configuration::getNodename() const
533  {
534  try {
535  return _conf.read<string>("local_uri");
536  } catch (const ibrcommon::ConfigFile::key_not_found&) {
537  std::vector<char> hostname_array(255);
538  if ( gethostname(&hostname_array[0], hostname_array.size()) != 0 )
539  {
540 #ifdef __WIN32__
541  // read hostname from registry
542  bool success = false;
543  HKEY hKey = 0;
544  DWORD dwType = REG_SZ;
545  DWORD dwBufSize = hostname_array.size();
546 
547  const char* subkey = "System\\CurrentControlSet\\Control\\ComputerName\\ActiveComputerName";
548  const char* win9x_subkey = "System\\CurrentControlSet\\Control\\ComputerName\\ComputerName";
549 
550  if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, subkey, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
551  {
552  if ( RegQueryValueEx(hKey, "ComputerName", NULL, &dwType, (BYTE*)&hostname_array[0], &dwBufSize) == ERROR_SUCCESS )
553  {
554  success = true;
555  }
556 
557  RegCloseKey(hKey);
558  }
559 
560  if (!success) {
561  if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, win9x_subkey, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
562  {
563  if ( RegQueryValueEx(hKey, "ComputerName", NULL, &dwType, (BYTE*)&hostname_array[0], &dwBufSize) == ERROR_SUCCESS )
564  {
565  success = true;
566  }
567 
568  RegCloseKey(hKey);
569  }
570  }
571 
572  if (!success) {
573  // not hostname available
574  return "dtn://local";
575  }
576 #endif
577  }
578 
579  return "dtn://" + std::string(&hostname_array[0]);
580  }
581  return "dtn://noname";
582  }
583 
584  const std::list<Configuration::NetConfig>& Configuration::Network::getInterfaces() const
585  {
586  return _interfaces;
587  }
588 
589  const std::set<ibrcommon::vaddress> Configuration::Discovery::address() const throw (ParameterNotFoundException)
590  {
591  std::set<ibrcommon::vaddress> ret;
592 
593  try {
594  std::string address_str = Configuration::getInstance()._conf.read<string>("discovery_address");
595  std::vector<std::string> addresses = dtn::utils::Utils::tokenize(" ", address_str);
596 
597  for (std::vector<std::string>::iterator iter = addresses.begin(); iter != addresses.end(); ++iter) {
598  ret.insert( ibrcommon::vaddress(*iter, port(), AF_UNSPEC) );
599  }
600  } catch (const ConfigFile::key_not_found&) {
601  throw ParameterNotFoundException();
602  }
603 
604  return ret;
605  }
606 
608  {
609  return Configuration::getInstance()._conf.read<int>("discovery_port", 4551);
610  }
611 
613  {
614  return _timeout;
615  }
616 
618  {
619  return _crosslayer;
620  }
621 
623  {
625 
626  nc.port = _conf.read<int>("api_port", 4550);
627 
628  try {
629  const std::string interface_name = _conf.read<std::string>("api_interface");
630 
631  if (interface_name != "any")
632  {
633  nc.iface = ibrcommon::vinterface(interface_name);
634  }
635  } catch (const ConfigFile::key_not_found&) {
637  }
638 
639  return nc;
640  }
641 
643  {
644  try {
645  return ibrcommon::File(_conf.read<std::string>("api_socket"));
646  } catch (const ConfigFile::key_not_found&) {
647  throw ParameterNotSetException();
648  }
649 
650  throw ParameterNotSetException();
651  }
652 
653  std::string Configuration::getStorage() const
654  {
655  return _conf.read<std::string>("storage", "default");
656  }
657 
659  {
660  return _conf.read<std::string>("use_persistent_bundlesets", "no") == "yes";
661  }
662 
664  {
668  _static_routes.clear();
669 
670  string key = "route1";
671  unsigned int keynumber = 1;
672 
673  while (conf.keyExists( key ))
674  {
675  vector<string> route = dtn::utils::Utils::tokenize(" ", conf.read<string>(key, "dtn:none dtn:none"));
676  _static_routes.insert( pair<std::string, std::string>( route.front(), route.back() ) );
677 
678  keynumber++;
679  stringstream ss; ss << "route" << keynumber; ss >> key;
680  }
681 
685  // read the node count
686  int count = 1;
687 
688  // initial prefix
689  std::string prefix = "static1_";
690 
691  while ( conf.keyExists(prefix + "uri") )
692  {
693  const dtn::data::EID node_eid( conf.read<std::string>(prefix + "uri", "dtn:none") );
694 
695  // create a address URI
696  std::stringstream ss;
697  ss << "ip=" << conf.read<std::string>(prefix + "address", "127.0.0.1") << ";port=" << conf.read<unsigned int>(prefix + "port", 4556) << ";";
698 
699  dtn::core::Node::Protocol p = Node::CONN_UNDEFINED;
700 
701  const std::string protocol = conf.read<std::string>(prefix + "proto", "tcp");
702  if (protocol == "tcp") p = Node::CONN_TCPIP;
703  if (protocol == "udp") p = Node::CONN_UDPIP;
704  if (protocol == "lowpan") p = Node::CONN_LOWPAN;
705  if (protocol == "zigbee") p = Node::CONN_LOWPAN; //Legacy: Stay compatible with older config files
706  if (protocol == "bluetooth") p = Node::CONN_BLUETOOTH;
707  if (protocol == "http") p = Node::CONN_HTTP;
708  if (protocol == "file") p = Node::CONN_FILE;
709  if (protocol == "dgram:udp") p = Node::CONN_DGRAM_UDP;
710  if (protocol == "dgram:ethernet") p = Node::CONN_DGRAM_ETHERNET;
711  if (protocol == "dgram:lowpan") p = Node::CONN_DGRAM_LOWPAN;
712  if (protocol == "email") {
713  p = Node::CONN_EMAIL;
714  ss.clear();
715  ss << "email=" << conf.read<std::string>(prefix + "email", "root@localhost") << ";";
716  }
717 
718  bool node_exists = false;
719 
720  dtn::core::Node::Type t = (conf.read<std::string>(prefix + "global", "no") == "yes") ?
722 
723  // get node
724  for (std::list<Node>::iterator iter = _nodes.begin(); iter != _nodes.end(); ++iter)
725  {
726  dtn::core::Node &n = (*iter);
727 
728  if (n.getEID() == node_eid)
729  {
730  n.add( dtn::core::Node::URI( t, p, ss.str(), 0, 10 ) );
731  n.setConnectImmediately( conf.read<std::string>(prefix + "immediately", "no") == "yes" );
732  node_exists = true;
733  break;
734  }
735  }
736 
737  if (!node_exists)
738  {
739  Node n(node_eid);
740  n.add( dtn::core::Node::URI( t, p, ss.str(), 0, 10 ) );
741  n.setConnectImmediately( conf.read<std::string>(prefix + "immediately", "no") == "yes" );
742  _nodes.push_back(n);
743  }
744 
745  count++;
746 
747  std::stringstream prefix_stream;
748  prefix_stream << "static" << count << "_";
749  prefix = prefix_stream.str();
750  }
751 
755  _routing = conf.read<string>("routing", "default");
756 
757  if(_routing == "prophet"){
758  /* read prophet parameters */
759  _prophet_config.p_encounter_max = conf.read<float>("prophet_p_encounter_max", 0.7f);
760  if(_prophet_config.p_encounter_max > 1 || _prophet_config.p_encounter_max <= 0)
761  _prophet_config.p_encounter_max = 0.7f;
762  _prophet_config.p_encounter_first = conf.read<float>("prophet_p_encounter_first", 0.5f);
763  if(_prophet_config.p_encounter_first > 1 || _prophet_config.p_encounter_first <= 0)
764  _prophet_config.p_encounter_first = 0.5f;
765  _prophet_config.p_first_threshold = conf.read<float>("prophet_p_first_threshold", 0.1f);
766  if(_prophet_config.p_first_threshold < 0 || _prophet_config.p_first_threshold >= _prophet_config.p_encounter_first)
767  _prophet_config.p_first_threshold = 0; //disable first threshold on misconfiguration
768  _prophet_config.beta = conf.read<float>("prophet_beta", 0.9f);
769  if(_prophet_config.beta < 0 || _prophet_config.beta > 1)
770  _prophet_config.beta = 0.9f;
771  _prophet_config.gamma = conf.read<float>("prophet_gamma", 0.999f);
772  if(_prophet_config.gamma <= 0 || _prophet_config.gamma > 1)
773  _prophet_config.gamma = 0.999f;
774  _prophet_config.delta = conf.read<float>("prophet_delta", 0.01f);
775  if(_prophet_config.delta < 0 || _prophet_config.delta > 1)
776  _prophet_config.delta = 0.01f;
777  _prophet_config.time_unit = conf.read<ibrcommon::Timer::time_t>("prophet_time_unit", 1);
778  if(_prophet_config.time_unit < 1)
779  _prophet_config.time_unit = 1;
780  _prophet_config.i_typ = conf.read<ibrcommon::Timer::time_t>("prophet_i_typ", 300);
781  if(_prophet_config.i_typ < 1)
782  _prophet_config.i_typ = 1;
783  _prophet_config.next_exchange_timeout = conf.read<ibrcommon::Timer::time_t>("prophet_next_exchange_timeout", 60);
784  _prophet_config.forwarding_strategy = conf.read<std::string>("prophet_forwarding_strategy", "GRTR");
785  _prophet_config.gtmx_nf_max = conf.read<unsigned int>("prophet_gtmx_nf_max", 30);
786  }
787 
791  _forwarding = (conf.read<std::string>("routing_forwarding", "yes") == "yes");
792 
796  _prefer_direct = (conf.read<std::string>("routing_prefer_direct", "yes") == "yes");
797 
801  _interfaces.clear();
802 
803  if (_use_default_net)
804  {
805  // create a new netconfig object
807 
808  // set default interface
809  nc.iface = ibrcommon::vinterface(_default_net);
810 
811  // set default port
812  nc.port = 4556;
813 
814  // add to interfaces list
815  _interfaces.push_back( nc );
816  }
817  else try
818  {
819  vector<string> nets = dtn::utils::Utils::tokenize(" ", conf.read<string>("net_interfaces") );
820  for (vector<string>::const_iterator iter = nets.begin(); iter != nets.end(); ++iter)
821  {
822  const std::string &netname = (*iter);
823 
824  const std::string key_type = "net_" + netname + "_type";
825  const std::string key_port = "net_" + netname + "_port";
826  const std::string key_interface = "net_" + netname + "_interface";
827  const std::string key_address = "net_" + netname + "_address";
828  const std::string key_path = "net_" + netname + "_path";
829  const std::string key_mtu = "net_" + netname + "_mtu";
830 
831  const std::string type_name = conf.read<string>(key_type, "tcp");
833 
834  if (type_name == "tcp") type = Configuration::NetConfig::NETWORK_TCP;
835  if (type_name == "udp") type = Configuration::NetConfig::NETWORK_UDP;
836  if (type_name == "http") type = Configuration::NetConfig::NETWORK_HTTP;
837  if (type_name == "lowpan") type = Configuration::NetConfig::NETWORK_LOWPAN;
838  if (type_name == "file") type = Configuration::NetConfig::NETWORK_FILE;
839  if (type_name == "dgram:udp") type = Configuration::NetConfig::NETWORK_DGRAM_UDP;
840  if (type_name == "dgram:lowpan") type = Configuration::NetConfig::NETWORK_DGRAM_LOWPAN;
841  if (type_name == "dgram:ethernet") type = Configuration::NetConfig::NETWORK_DGRAM_ETHERNET;
842  if (type_name == "email") type = Configuration::NetConfig::NETWORK_EMAIL;
843 
844  // create a new netconfig object
845  Configuration::NetConfig nc(netname, type);
846 
847  switch (type)
848  {
850  {
851  nc.url = conf.read<std::string>(key_address, "http://localhost/");
852  break;
853  }
854 
856  {
857  nc.url = conf.read<std::string>(key_path, "");
858  break;
859  }
860 
861  default:
862  {
863  nc.port = conf.read<int>(key_port, 4556);
864  nc.mtu = conf.read<int>(key_mtu, 1280);
865 
866  try {
867  nc.iface = ibrcommon::vinterface(conf.read<std::string>(key_interface));
868  } catch (const ConfigFile::key_not_found&) {
869  // no interface assigned
870  }
871 
872  break;
873  }
874  }
875 
876  // add to interfaces list
877  _interfaces.push_back(nc);
878  }
879  } catch (const ConfigFile::key_not_found&) {
880  // stop the one network is not found.
881  }
882 
886  _tcp_nodelay = (conf.read<std::string>("tcp_nodelay", "yes") == "yes");
887  _tcp_chunksize = conf.read<unsigned int>("tcp_chunksize", 4096);
888  _tcp_idle_timeout = conf.read<unsigned int>("tcp_idle_timeout", 0);
889 
893  _auto_connect = conf.read<dtn::data::Timeout>("net_autoconnect", 0);
894 
898  _fragmentation = (conf.read<std::string>("fragmentation", "yes") == "yes");
899 
903  try {
904  std::vector<string> inets = dtn::utils::Utils::tokenize(" ", conf.read<string>("net_internet") );
905  for (std::vector<string>::const_iterator iter = inets.begin(); iter != inets.end(); ++iter)
906  {
907  ibrcommon::vinterface inet_dev(*iter);
908  _internet_devices.insert(inet_dev);
909  }
910  } catch (const ibrcommon::ConfigFile::key_not_found&) { };
911 
915  _scheduling = (conf.read<std::string>("scheduling", "no") == "yes");
916 
920  _link_request_interval = conf.read<dtn::data::Timeout>("link_request_interval",5000);
921  }
922 
923  const std::multimap<std::string, std::string>& Configuration::Network::getStaticRoutes() const
924  {
925  return _static_routes;
926  }
927 
928  const std::list<Node>& Configuration::Network::getStaticNodes() const
929  {
930  return _nodes;
931  }
932 
934  {
935  stringstream ss;
936  ss << name << "_path";
937  string key; ss >> key;
938 
939  try {
940  return ibrcommon::File(_conf.read<string>(key));
941  } catch (const ConfigFile::key_not_found&) { }
942 
943  throw ParameterNotSetException();
944  }
945 
947  {
948  return _enabled;
949  }
950 
952  {
953  return (Configuration::getInstance()._conf.read<int>("discovery_announce", 1) == 1);
954  }
955 
957  {
958  return (Configuration::getInstance()._conf.read<int>("discovery_short", 0) == 1);
959  }
960 
962  {
963  return Configuration::getInstance()._conf.read<int>("discovery_version", 2);
964  }
965 
966  bool Configuration::doAPI() const
967  {
968  return _doapi;
969  }
970 
972  {
973  if ( _routing == "none" ) return NO_ROUTING;
974  if ( _routing == "epidemic" ) return EPIDEMIC_ROUTING;
975  if ( _routing == "flooding" ) return FLOOD_ROUTING;
976  if ( _routing == "prophet" ) return PROPHET_ROUTING;
977  return DEFAULT_ROUTING;
978  }
979 
980 
982  {
983  return _forwarding;
984  }
985 
987  {
988  return _prefer_direct;
989  }
990 
992  {
993  return _fragmentation;
994  }
995 
997  {
998  return _scheduling;
999  }
1000 
1002  {
1003  return _tcp_nodelay;
1004  }
1005 
1007  {
1008  return _tcp_chunksize;
1009  }
1010 
1012  {
1013  return _tcp_idle_timeout;
1014  }
1015 
1017  {
1018  return _auto_connect;
1019  }
1020 
1022  {
1023  return _prophet_config;
1024  }
1025 
1026  std::set<ibrcommon::vinterface> Configuration::Network::getInternetDevices() const
1027  {
1028  return _internet_devices;
1029  }
1030 
1032  {
1033  return _link_request_interval;
1034  }
1035 
1036  dtn::data::Size Configuration::getLimit(const std::string &suffix) const
1037  {
1038  std::string unparsed = _conf.read<std::string>("limit_" + suffix, "0");
1039 
1040  std::stringstream ss(unparsed);
1041 
1042  float value; ss >> value;
1043  char multiplier = 0; ss >> multiplier;
1044 
1045  switch (multiplier)
1046  {
1047  default:
1048  return static_cast<dtn::data::Size>(value);
1049  break;
1050 
1051  case 'G':
1052  return static_cast<dtn::data::Size>(value * 1000000000);
1053  break;
1054 
1055  case 'M':
1056  return static_cast<dtn::data::Size>(value * 1000000);
1057  break;
1058 
1059  case 'K':
1060  return static_cast<dtn::data::Size>(value * 1000);
1061  break;
1062  }
1063 
1064  return 0;
1065  }
1066 
1068  {
1069  bool withTLS = false;
1070 #ifdef WITH_TLS
1071  withTLS = true;
1072  /* enable TLS if the certificate path, a certificate and the private key was given */
1073  bool activateTLS = true;
1074 
1075  // load public key file
1076  try {
1077  _cert = conf.read<std::string>("security_certificate");
1078 
1079  if (!_cert.exists())
1080  {
1081  IBRCOMMON_LOGGER_TAG("Configuration", warning) << "Certificate file " << _cert.getPath() << " does not exists!" << IBRCOMMON_LOGGER_ENDL;
1082  activateTLS = false;
1083  }
1084  } catch (const ibrcommon::ConfigFile::key_not_found&) {
1085  activateTLS = false;
1086  }
1087 
1088  // load KEY file
1089  try {
1090  _key = conf.read<std::string>("security_key");
1091 
1092  if (!_key.exists())
1093  {
1094  IBRCOMMON_LOGGER_TAG("Configuration", warning) << "KEY file " << _key.getPath() << " does not exists!" << IBRCOMMON_LOGGER_ENDL;
1095  activateTLS = false;
1096  }
1097  } catch (const ibrcommon::ConfigFile::key_not_found&) {
1098  activateTLS = false;
1099  }
1100 
1101  // read trustedCAPath
1102  try{
1103  _trustedCAPath = conf.read<std::string>("security_trusted_ca_path");
1104  if(!_trustedCAPath.isDirectory()){
1105  IBRCOMMON_LOGGER_TAG("Configuration", warning) << "Trusted CA Path " << _trustedCAPath.getPath() << " does not exists or is no directory!" << IBRCOMMON_LOGGER_ENDL;
1106  activateTLS = false;
1107  }
1108  } catch (const ibrcommon::ConfigFile::key_not_found&) {
1109  activateTLS = false;
1110  }
1111 
1112  // read if encryption should be disabled
1113  _disableEncryption = (conf.read<std::string>("security_tls_disable_encryption", "no") == "yes");
1114 
1115  if (activateTLS)
1116  {
1117  _tlsEnabled = true;
1118 
1119  /* read if TLS is required */
1120  _tlsRequired = (conf.read<std::string>("security_tls_required", "no") == "yes");
1121 
1122  /* If the clock is not in sync, SSL will fail. Accept plain connection when the clock is not sync'ed. */
1123  _tlsOptionalOnBadClock = (conf.read<std::string>("security_tls_fallback_badclock", "no") == "yes");
1124  }
1125 #endif
1126 
1127 #ifdef WITH_BUNDLE_SECURITY
1128  // enable security if the security path is set
1129  try {
1130  _path = conf.read<std::string>("security_path");
1131 
1132  if (!_path.exists())
1133  {
1135  }
1136 
1137  _enabled = true;
1138  } catch (const ibrcommon::ConfigFile::key_not_found&) {
1139  return;
1140  }
1141 
1142  // load level
1143  _level = Level(conf.read<int>("security_level", 0));
1144 
1145  if ( !withTLS )
1146  {
1147  /* if TLS is enabled, the Certificate file and the key have been read earlier */
1148  // load CA file
1149  try {
1150  _cert = conf.read<std::string>("security_certificate");
1151 
1152  if (!_cert.exists())
1153  {
1154  IBRCOMMON_LOGGER_TAG("Configuration", warning) << "Certificate file " << _cert.getPath() << " does not exists!" << IBRCOMMON_LOGGER_ENDL;
1155  }
1156  } catch (const ibrcommon::ConfigFile::key_not_found&) { }
1157 
1158  // load KEY file
1159  try {
1160  _key = conf.read<std::string>("security_key");
1161 
1162  if (!_key.exists())
1163  {
1164  IBRCOMMON_LOGGER_TAG("Configuration", warning) << "KEY file " << _key.getPath() << " does not exists!" << IBRCOMMON_LOGGER_ENDL;
1165  }
1166  } catch (const ibrcommon::ConfigFile::key_not_found&) { }
1167  }
1168 
1169  // load KEY file
1170  try {
1171  _bab_default_key = conf.read<std::string>("security_bab_default_key");
1172 
1173  if (!_bab_default_key.exists())
1174  {
1175  IBRCOMMON_LOGGER_TAG("Configuration", warning) << "KEY file " << _bab_default_key.getPath() << " does not exists!" << IBRCOMMON_LOGGER_ENDL;
1176  }
1177  } catch (const ibrcommon::ConfigFile::key_not_found&) {
1178  }
1179 #endif
1180  }
1181 
1183 
1185  {
1186  return _enabled;
1187  }
1188 
1190  {
1191  return _tlsEnabled;
1192  }
1193 
1195  {
1196  // TLS is only required, if the clock is in sync
1197  if ((dtn::utils::Clock::getRating() == 0) && _tlsOptionalOnBadClock) return false;
1198  return _tlsRequired;
1199  }
1200 
1202  {
1203  return _path;
1204  }
1205 
1207  {
1208  return _level;
1209  }
1210 
1212  {
1213  return _bab_default_key;
1214  }
1215 
1217  {
1218  return _cert;
1219  }
1220 
1222  {
1223  return _key;
1224  }
1225 
1227  {
1228  return _trustedCAPath;
1229  }
1230 
1232  {
1233  return _disableEncryption;
1234  }
1235 
1237  {
1238  return _quiet;
1239  }
1240 
1242  {
1243  if (_logfile.getPath() == "") throw Configuration::ParameterNotSetException();
1244  return _logfile;
1245  }
1246 
1248  {
1249  return _verbose;
1250  }
1251 
1253  {
1254  return _timestamps;
1255  }
1256 
1257  unsigned int Configuration::Logger::options() const
1258  {
1259  return _options;
1260  }
1261 
1262  std::ostream& Configuration::Logger::output() const
1263  {
1264  return std::cout;
1265  }
1266 
1268  {
1269  return _daemonize;
1270  }
1271 
1273  {
1274  return _kill;
1275  }
1276 
1278  {
1279  return _threads;
1280  }
1281 
1283  {
1284  if (_pidfile == ibrcommon::File()) throw ParameterNotSetException();
1285  return _pidfile;
1286  }
1287 
1289  {
1290  return _reference;
1291  }
1292 
1294  {
1295  return _sync;
1296  }
1297 
1299  {
1300  return _discovery;
1301  }
1302 
1304  {
1305  return _sigma;
1306  }
1307 
1309  {
1310  return _psi;
1311  }
1312 
1314  {
1315  return _sync_level;
1316  }
1317 
1319  {
1320  return _enabled;
1321  }
1322 
1324  {
1325  return _port == 0;
1326  }
1327 
1328  unsigned int Configuration::DHT::getPort() const
1329  {
1330  return _port;
1331  }
1332 
1334  {
1335  return _id;
1336  }
1337 
1339  {
1340  return _id == "";
1341  }
1342 
1344  {
1345  return _dnsbootstrapping;
1346  }
1347 
1349  {
1350  return _bootstrappingdomains;
1351  }
1352 
1354  {
1355  return !_bootstrappingips.empty();
1356  }
1357 
1358  std::vector<string> Configuration::DHT::getIPBootstrappingIPs() const
1359  {
1360  return _bootstrappingips;
1361  }
1362 
1364  {
1365  return _ipv4bind;
1366  }
1368  {
1369  return _ipv6bind;
1370  }
1371 
1373  {
1374  return _nodesFilePath;
1375  }
1376 
1378  {
1379  return _ipv4;
1380  }
1381 
1383  {
1384  return _ipv6;
1385  }
1386 
1388  {
1389  return _selfannounce;
1390  }
1391 
1393  {
1394  return _minRating;
1395  }
1396 
1398  {
1399  return _allowNeighbourAnnouncement;
1400  }
1401 
1403  {
1404  return _allowNeighbourToAnnounceMe;
1405  }
1406 
1408  {
1409  return _blacklist;
1410  }
1411 
1413  {
1414  return _ignoreDHTNeighbourInformations;
1415  }
1416 
1418  {
1419  return _enabled;
1420  }
1421 
1422  const std::string Configuration::P2P::getCtrlPath() const
1423  {
1424  return _ctrl_path;
1425  }
1426 
1428  {
1429  return _address;
1430  }
1431 
1433  {
1434  return _smtpServer;
1435  }
1436 
1438  {
1439  return _smtpPort;
1440  }
1441 
1443  {
1444  return _smtpUsername;
1445  }
1446 
1448  {
1449  return _smtpPassword;
1450  }
1451 
1453  {
1454  return _smtpInterval;
1455  }
1456 
1458  {
1459  return _smtpConnectionTimeout;
1460  }
1462  {
1463  return _smtpKeepAliveTimeout * 1000;
1464  }
1465 
1467  {
1468  return _smtpNeedAuth;
1469  }
1470 
1472  {
1473  return _smtpUseTLS;
1474  }
1475 
1477  {
1478  return _smtpUseSSL;
1479  }
1480 
1482  {
1483  return _imapServer;
1484  }
1485 
1487  {
1488  return _imapPort;
1489  }
1490 
1492  {
1493  return _imapUsername;
1494  }
1495 
1497  {
1498  return _imapPassword;
1499  }
1500 
1501  std::vector<std::string> Configuration::EMail::getImapFolder() const
1502  {
1503  return _imapFolder;
1504  }
1505 
1507  {
1508  return _imapInterval;
1509  }
1510 
1512  {
1513  return _imapConnectionTimeout;
1514  }
1515 
1517  {
1518  return _imapUseTLS;
1519  }
1520 
1522  {
1523  return _imapUseSSL;
1524  }
1525 
1527  {
1528  return _imapPurgeMail;
1529  }
1530 
1531  std::vector<std::string> Configuration::EMail::getTlsCACerts() const
1532  {
1533  return _tlsCACerts;
1534  }
1535 
1536  std::vector<std::string> Configuration::EMail::getTlsUserCerts() const
1537  {
1538  return _tlsUserCerts;
1539  }
1540 
1542  {
1543  return _availableTime;
1544  }
1545 
1547  {
1548  return _returningMailsCheck;
1549  }
1550  }
1551 }