IBR-DTNSuite  0.8
daemon/src/Configuration.cpp
Go to the documentation of this file.
00001 #include "config.h"
00002 #include "Configuration.h"
00003 #include "net/DiscoveryAnnouncement.h"
00004 #include "net/DiscoveryAnnouncement.h"
00005 #include "core/Node.h"
00006 
00007 #include <ibrdtn/utils/Utils.h>
00008 #include <ibrdtn/utils/Clock.h>
00009 
00010 #include <ibrcommon/net/vinterface.h>
00011 #include <ibrcommon/Logger.h>
00012 
00013 #include <getopt.h>
00014 #include <unistd.h>
00015 
00016 #ifdef __DEVELOPMENT_ASSERTIONS__
00017 #include <cassert>
00018 #endif
00019 
00020 using namespace dtn::net;
00021 using namespace dtn::core;
00022 using namespace dtn::utils;
00023 using namespace ibrcommon;
00024 
00025 namespace dtn
00026 {
00027         namespace daemon
00028         {
00029                 Configuration::NetConfig::NetConfig(std::string n, NetType t, const std::string &u, bool d)
00030                  : name(n), type(t), url(u), mtu(0), port(0), discovery(d)
00031                 {
00032                 }
00033 
00034                 Configuration::NetConfig::NetConfig(std::string n, NetType t, const ibrcommon::vinterface &i, int p, bool d)
00035                  : name(n), type(t), interface(i), port(p), discovery(d)
00036                 {
00037                 }
00038 
00039                 Configuration::NetConfig::NetConfig(std::string n, NetType t, const ibrcommon::vaddress &a, int p, bool d)
00040                  : name(n), type(t), interface(), address(a), port(p), discovery(d)
00041                 {
00042                 }
00043 
00044                 Configuration::NetConfig::NetConfig(std::string n, NetType t, int p, bool d)
00045                  : name(n), type(t), interface(), port(p), discovery(d)
00046                 {
00047                 }
00048 
00049                 Configuration::NetConfig::~NetConfig()
00050                 {
00051                 }
00052 
00053                 std::string Configuration::version()
00054                 {
00055                         std::stringstream ss;
00056                         ss << PACKAGE_VERSION;
00057                 #ifdef SVN_REVISION
00058                         ss << " (build " << SVN_REVISION << ")";
00059                 #endif
00060 
00061                         return ss.str();
00062                 }
00063 
00064                 Configuration::Configuration()
00065                  : _filename("config.ini"), _doapi(true)
00066                 {
00067                 }
00068 
00069                 Configuration::~Configuration()
00070                 {}
00071 
00072                 Configuration::Discovery::Discovery()
00073                  : _enabled(true), _timeout(5) {};
00074 
00075                 Configuration::Statistic::Statistic() {};
00076 
00077                 Configuration::Debug::Debug()
00078                  : _enabled(false), _quiet(false), _level(0) {};
00079 
00080                 Configuration::Logger::Logger()
00081                  : _quiet(false), _options(0), _timestamps(false) {};
00082 
00083                 Configuration::Network::Network()
00084                  : _routing("default"), _forwarding(true), _tcp_nodelay(true), _tcp_chunksize(4096), _default_net("lo"), _use_default_net(false), _auto_connect(0), _fragmentation(false)
00085                 {};
00086 
00087                 Configuration::Security::Security()
00088                  : _enabled(false), _tlsEnabled(false), _tlsRequired(false)
00089                 {};
00090 
00091                 Configuration::Daemon::Daemon()
00092                  : _daemonize(false), _kill(false), _threads(0)
00093                 {};
00094 
00095                 Configuration::TimeSync::TimeSync()
00096                  : _reference(true), _sync(false), _discovery(false), _qot_tick(0)
00097                 {};
00098 
00099                 Configuration::DHT::DHT()
00100                  : _enabled(true), _port(0), _ipv4(true), _ipv6(true), _blacklist(true),
00101                         _minRating(1), _allowNeighbourToAnnounceMe(true), _allowNeighbourAnnouncement(true),
00102                         _ignoreDHTNeighbourInformations(false)
00103                 {};
00104 
00105                 Configuration::Discovery::~Discovery() {};
00106                 Configuration::Statistic::~Statistic() {};
00107                 Configuration::Debug::~Debug() {};
00108                 Configuration::Logger::~Logger() {};
00109                 Configuration::Network::~Network() {};
00110                 Configuration::Daemon::~Daemon() {};
00111                 Configuration::TimeSync::~TimeSync() {};
00112                 Configuration::DHT::~DHT() {};
00113 
00114                 const Configuration::Discovery& Configuration::getDiscovery() const
00115                 {
00116                         return _disco;
00117                 }
00118 
00119                 const Configuration::Statistic& Configuration::getStatistic() const
00120                 {
00121                         return _stats;
00122                 }
00123 
00124                 const Configuration::Debug& Configuration::getDebug() const
00125                 {
00126                         return _debug;
00127                 }
00128 
00129                 const Configuration::Logger& Configuration::getLogger() const
00130                 {
00131                         return _logger;
00132                 }
00133 
00134                 const Configuration::Network& Configuration::getNetwork() const
00135                 {
00136                         return _network;
00137                 }
00138 
00139                 const Configuration::Security& Configuration::getSecurity() const
00140                 {
00141                         return _security;
00142                 }
00143 
00144                 const Configuration::Daemon& Configuration::getDaemon() const
00145                 {
00146                         return _daemon;
00147                 }
00148 
00149                 const Configuration::TimeSync& Configuration::getTimeSync() const
00150                 {
00151                         return _timesync;
00152                 }
00153 
00154                 const Configuration::DHT& Configuration::getDHT() const
00155                 {
00156                         return _dht;
00157                 }
00158 
00159                 Configuration& Configuration::getInstance()
00160                 {
00161                         static Configuration conf;
00162                         return conf;
00163                 }
00164 
00165                 void Configuration::params(int argc, char *argv[])
00166                 {
00167                         int c;
00168                         int doapi = _doapi;
00169                         int disco = _disco._enabled;
00170                         int badclock = dtn::utils::Clock::badclock;
00171                         int timestamp = _logger._timestamps;
00172 
00173                         while (1)
00174                         {
00175                                 static struct option long_options[] =
00176                                 {
00177                                                 /* These options set a flag. */
00178                                                 {"noapi", no_argument, &doapi, 0},
00179                                                 {"nodiscovery", no_argument, &disco, 0},
00180                                                 {"badclock", no_argument, &badclock, 1},
00181                                                 {"timestamp", no_argument, &timestamp, 1},
00182 
00183                                                 /* These options don't set a flag. We distinguish them by their indices. */
00184                                                 {"help", no_argument, 0, 'h'},
00185 #ifdef HAVE_LIBDAEMON
00186                                                 {"daemon", no_argument, 0, 'D'},
00187                                                 {"kill", no_argument, 0, 'k'},
00188                                                 {"pidfile", required_argument, 0, 'p'},
00189 #endif
00190 
00191                                                 {"quiet", no_argument, 0, 'q'},
00192                                                 {"version", no_argument, 0, 'v'},
00193                                                 {"interface", required_argument, 0, 'i'},
00194                                                 {"configuration", required_argument, 0, 'c'},
00195                                                 {"debug", required_argument, 0, 'd'},
00196                                                 {0, 0, 0, 0}
00197                                 };
00198 
00199                                 /* getopt_long stores the option index here. */
00200                                 int option_index = 0;
00201 
00202 #ifdef HAVE_LIBDAEMON
00203                                 c = getopt_long (argc, argv, "qhDkp:vi:c:d:t:",
00204                                                 long_options, &option_index);
00205 #else
00206                                 c = getopt_long (argc, argv, "qhvi:c:d:t:",
00207                                                 long_options, &option_index);
00208 #endif
00209 
00210                                 /* Detect the end of the options. */
00211                                 if (c == -1)
00212                                         break;
00213 
00214                                 switch (c)
00215                                 {
00216                                 case 0:
00217                                         /* If this option set a flag, do nothing else now. */
00218                                         if (long_options[option_index].flag != 0)
00219                                                 break;
00220                                         printf ("option %s", long_options[option_index].name);
00221                                         if (optarg)
00222                                                 printf (" with arg %s", optarg);
00223                                         printf ("\n");
00224                                         break;
00225 
00226                                 case 'h':
00227                                         std::cout << "IBR-DTN version: " << version() << std::endl;
00228                                         std::cout << "Syntax: dtnd [options]"  << std::endl;
00229                                         std::cout << " -h|--help       display this text" << std::endl;
00230                                         std::cout << " -c <file>       set a configuration file" << std::endl;
00231 #ifdef HAVE_LIBDAEMON
00232                                         std::cout << " -D              daemonize the process" << std::endl;
00233                                         std::cout << " -k              stop the running daemon" << std::endl;
00234                                         std::cout << " -p <file>       store the pid in this pidfile" << std::endl;
00235 #endif
00236                                         std::cout << " -i <interface>  interface to bind on (e.g. eth0)" << std::endl;
00237                                         std::cout << " -d <level>      enable debugging and set a verbose level" << std::endl;
00238                                         std::cout << " -q              enables the quiet mode (no logging to the console)" << std::endl;
00239                                         std::cout << " -t <threads>    specify a number of threads for parallel event processing" << std::endl;
00240                                         std::cout << " --noapi         disable API module" << std::endl;
00241                                         std::cout << " --nodiscovery   disable discovery module" << std::endl;
00242                                         std::cout << " --badclock      assume a bad clock on the system (use AgeBlock)" << std::endl;
00243                                         std::cout << " --timestamp     enables timestamps for logging instead of datetime values" << std::endl;
00244                                         exit(0);
00245                                         break;
00246 
00247                                 case 'v':
00248                                         std::cout << "IBR-DTN version: " << version() << std::endl;
00249                                         exit(0);
00250                                         break;
00251 
00252                                 case 'q':
00253                                         _debug._quiet = true;
00254                                         break;
00255 
00256                                 case 'c':
00257                                         _filename = optarg;
00258                                         break;
00259 
00260                                 case 'i':
00261                                         _network._default_net = ibrcommon::vinterface(optarg);
00262                                         _network._use_default_net = true;
00263                                         break;
00264 
00265                                 case 'd':
00266                                         _debug._enabled = true;
00267                                         _debug._level = atoi(optarg);
00268                                         break;
00269 
00270                                 case 'D':
00271                                         _daemon._daemonize = true;
00272                                         _debug._quiet = true;
00273                                         break;
00274 
00275                                 case 'k':
00276                                         _daemon._daemonize = true;
00277                                         _daemon._kill = true;
00278                                         break;
00279 
00280                                 case 'p':
00281                                         _daemon._pidfile = std::string(optarg);
00282                                         break;
00283 
00284                                 case 't':
00285                                         _daemon._threads = atoi(optarg);
00286                                         break;
00287 
00288                                 case '?':
00289                                         /* getopt_long already printed an error message. */
00290                                         break;
00291 
00292                                 default:
00293                                         abort();
00294                                         break;
00295                                 }
00296                         }
00297 
00298                         _doapi = doapi;
00299                         _disco._enabled = disco;
00300                         dtn::utils::Clock::badclock = badclock;
00301                         _logger._timestamps = timestamp;
00302                 }
00303 
00304                 void Configuration::load()
00305                 {
00306                         load(_filename);
00307                 }
00308 
00309                 void Configuration::load(string filename)
00310                 {
00311                         try {
00312                                 // load main configuration
00313                                 _conf = ibrcommon::ConfigFile(filename);
00314                                 _filename = filename;
00315 
00316                                 IBRCOMMON_LOGGER(info) << "Configuration: " << filename << IBRCOMMON_LOGGER_ENDL;
00317                         } catch (const ibrcommon::ConfigFile::file_not_found&) {
00318                                 IBRCOMMON_LOGGER(info) << "Using default settings. Call with --help for options." << IBRCOMMON_LOGGER_ENDL;
00319                                 _conf = ConfigFile();
00320 
00321                                 // set the default user to nobody
00322                                 _conf.add<std::string>("user", "nobody");
00323                         }
00324 
00325                         // load all configuration extensions
00326                         _disco.load(_conf);
00327                         _stats.load(_conf);
00328                         _debug.load(_conf);
00329                         _logger.load(_conf);
00330                         _network.load(_conf);
00331                         _security.load(_conf);
00332                         _timesync.load(_conf);
00333                         _dht.load(_conf);
00334                 }
00335 
00336                 void Configuration::Discovery::load(const ibrcommon::ConfigFile &conf)
00337                 {
00338                         _timeout = conf.read<unsigned int>("discovery_timeout", 5);
00339                 }
00340 
00341                 void Configuration::Statistic::load(const ibrcommon::ConfigFile&)
00342                 {
00343                 }
00344 
00345                 void Configuration::Logger::load(const ibrcommon::ConfigFile &conf)
00346                 {
00347                         try {
00348                                 _logfile = conf.read<std::string>("logfile");
00349                         } catch (const ibrcommon::ConfigFile::key_not_found&) {
00350                         }
00351                 }
00352 
00353                 void Configuration::Debug::load(const ibrcommon::ConfigFile&)
00354                 {
00355                 }
00356 
00357                 void Configuration::Daemon::load(const ibrcommon::ConfigFile&)
00358                 {
00359                 }
00360 
00361                 void Configuration::TimeSync::load(const ibrcommon::ConfigFile &conf)
00362                 {
00363                         try {
00364                                 _reference = (conf.read<std::string>("time_reference") == "yes");
00365                         } catch (const ibrcommon::ConfigFile::key_not_found&) { };
00366 
00367                         try {
00368                                 _sync = (conf.read<std::string>("time_sync_on_discovery") == "yes");
00369                         } catch (const ibrcommon::ConfigFile::key_not_found&) { };
00370 
00371                         try {
00372                                 _discovery = (conf.read<std::string>("time_discovery_announcements") == "yes");
00373                         } catch (const ibrcommon::ConfigFile::key_not_found&) { };
00374 
00375                         _qot_tick = conf.read<int>("time_qot_tick", 0);
00376                         _sigma = conf.read<float>("time_sigma", 1.001);
00377                         _sync_level = conf.read<float>("time_sync_level", 0.15);
00378 
00379                         // enable the clock modify feature
00380                         dtn::utils::Clock::modify_clock = (conf.read<std::string>("time_set_clock", "no") == "yes");
00381                 }
00382                 
00383                 void Configuration::DHT::load(const ibrcommon::ConfigFile &conf)
00384                 {
00385                         _enabled = (conf.read<std::string> ("dht_enabled", "no") == "yes");
00386                         _port = conf.read<int> ("dht_port", 9999);
00387                         _id = conf.read<string> ("dht_id", "");
00388                         _blacklist = (conf.read<std::string> ("dht_blacklist", "yes") == "yes");
00389                         _selfannounce = (conf.read<std::string> ("dht_self_announce", "yes") == "yes");
00390                         _dnsbootstrapping = (conf.read<std::string> ("dht_bootstrapping", "yes") == "yes");
00391                         string list = conf.read<string> ("dht_bootstrapping_domains", "");
00392                         _bootstrappingdomains = dtn::utils::Utils::tokenize(" ", list);
00393                         list = conf.read<string> ("dht_bootstrapping_ips", "");
00394                         _bootstrappingips = dtn::utils::Utils::tokenize(";", list);
00395                         _ipv4bind = conf.read<string> ("dht_bind_ipv4", "");
00396                         _ipv6bind = conf.read<string> ("dht_bind_ipv6", "");
00397                         _nodesFilePath = conf.read<string> ("dht_nodes_file", "");
00398                         _ipv4 = (conf.read<std::string> ("dht_enable_ipv4", "yes") == "yes");
00399                         _ipv6 = (conf.read<std::string> ("dht_enable_ipv6", "yes") == "yes");
00400                         _minRating = conf.read<int> ("dht_min_rating", 1);
00401                         _allowNeighbourToAnnounceMe = (conf.read<std::string> ("dht_allow_neighbours_to_announce_me", "yes") == "yes");
00402                         _allowNeighbourAnnouncement = (conf.read<std::string> ("dht_allow_neighbour_announcement", "yes") == "yes");
00403                         _ignoreDHTNeighbourInformations = (conf.read<std::string> ("dht_ignore_neighbour_informations", "no") == "yes");
00404                         
00405                         if (_minRating < 0)     _minRating = 0;
00406                 }
00407 
00408                 bool Configuration::Debug::quiet() const
00409                 {
00410                         return _quiet;
00411                 }
00412 
00413                 bool Configuration::Debug::enabled() const
00414                 {
00415                         return _enabled;
00416                 }
00417 
00418                 int Configuration::Debug::level() const
00419                 {
00420                         return _level;
00421                 }
00422 
00423                 std::string Configuration::getNodename()
00424                 {
00425                         try {
00426                                 return _conf.read<string>("local_uri");
00427                         } catch (const ibrcommon::ConfigFile::key_not_found&) {
00428                                 char *hostname_array = new char[64];
00429                                 if ( gethostname(hostname_array, 64) != 0 )
00430                                 {
00431                                         // error
00432                                         delete[] hostname_array;
00433                                         return "local";
00434                                 }
00435 
00436                                 string hostname(hostname_array);
00437                                 delete[] hostname_array;
00438 
00439                                 stringstream ss;
00440                                 ss << "dtn://" << hostname;
00441                                 ss >> hostname;
00442 
00443                                 return hostname;
00444                         }
00445                 }
00446 
00447                 const std::list<Configuration::NetConfig>& Configuration::Network::getInterfaces() const
00448                 {
00449                         return _interfaces;
00450                 }
00451 
00452                 const ibrcommon::vaddress Configuration::Discovery::address() const throw (ParameterNotFoundException)
00453                 {
00454                         try {
00455                                 return ibrcommon::vaddress( ibrcommon::vaddress::VADDRESS_INET,
00456                                                 Configuration::getInstance()._conf.read<string>("discovery_address"));
00457                         } catch (const ConfigFile::key_not_found&) {
00458                                 throw ParameterNotFoundException();
00459                         }
00460                 }
00461 
00462                 int Configuration::Discovery::port() const
00463                 {
00464                         return Configuration::getInstance()._conf.read<int>("discovery_port", 4551);
00465                 }
00466 
00467                 unsigned int Configuration::Discovery::timeout() const
00468                 {
00469                         return _timeout;
00470                 }
00471 
00472                 Configuration::NetConfig Configuration::getAPIInterface()
00473                 {
00474                         size_t port = 4550;
00475                         std::string interface_name = "lo";
00476 
00477                         try {
00478                                 port = _conf.read<size_t>("api_port");
00479                         } catch (const ConfigFile::key_not_found&) { };
00480 
00481                         try {
00482                                 interface_name = _conf.read<std::string>("api_interface");
00483                         } catch (const ConfigFile::key_not_found&) { };
00484 
00485                         if (interface_name == "any")
00486                         {
00487                                 return Configuration::NetConfig("api", Configuration::NetConfig::NETWORK_TCP, ibrcommon::vinterface(), port);
00488                         }
00489 
00490                         return Configuration::NetConfig("api", Configuration::NetConfig::NETWORK_TCP, ibrcommon::vinterface(interface_name), port);
00491                 }
00492 
00493                 ibrcommon::File Configuration::getAPISocket()
00494                 {
00495                         try {
00496                                 return ibrcommon::File(_conf.read<std::string>("api_socket"));
00497                         } catch (const ConfigFile::key_not_found&) {
00498                                 throw ParameterNotSetException();
00499                         }
00500 
00501                         throw ParameterNotSetException();
00502                 }
00503 
00504                 std::string Configuration::getStorage() const
00505                 {
00506                         return _conf.read<std::string>("storage", "default");
00507                 }
00508 
00509                 void Configuration::Network::load(const ibrcommon::ConfigFile &conf)
00510                 {
00514                         _static_routes.clear();
00515 
00516                         string key = "route1";
00517                         unsigned int keynumber = 1;
00518 
00519                         while (conf.keyExists( key ))
00520                         {
00521                                 vector<string> route = dtn::utils::Utils::tokenize(" ", conf.read<string>(key, "dtn:none dtn:none"));
00522                                 _static_routes.insert( pair<std::string, std::string>( route.front(), route.back() ) );
00523 
00524                                 keynumber++;
00525                                 stringstream ss; ss << "route" << keynumber; ss >> key;
00526                         }
00527 
00531                         // read the node count
00532                         int count = 1;
00533 
00534                         // initial prefix
00535                         std::string prefix = "static1_";
00536 
00537                         while ( conf.keyExists(prefix + "uri") )
00538                         {
00539                                 const dtn::data::EID node_eid( conf.read<std::string>(prefix + "uri", "dtn:none") );
00540 
00541                                 // create a address URI
00542                                 std::stringstream ss;
00543                                 ss << "ip=" << conf.read<std::string>(prefix + "address", "127.0.0.1") << ";port=" << conf.read<unsigned int>(prefix + "port", 4556) << ";";
00544 
00545                                 dtn::core::Node::Protocol p = Node::CONN_UNDEFINED;
00546 
00547                                 const std::string protocol = conf.read<std::string>(prefix + "proto", "tcp");
00548                                 if (protocol == "tcp") p = Node::CONN_TCPIP;
00549                                 if (protocol == "udp") p = Node::CONN_UDPIP;
00550                                 if (protocol == "lowpan") p = Node::CONN_LOWPAN;
00551                                 if (protocol == "zigbee") p = Node::CONN_LOWPAN; //Legacy: Stay compatible with older config files
00552                                 if (protocol == "bluetooth") p = Node::CONN_BLUETOOTH;
00553                                 if (protocol == "http") p = Node::CONN_HTTP;
00554                                 if (protocol == "file") p = Node::CONN_FILE;
00555                                 if (protocol == "dgram:udp") p = Node::CONN_DGRAM_UDP;
00556                                 if (protocol == "dgram:ethernet") p = Node::CONN_DGRAM_ETHERNET;
00557                                 if (protocol == "dgram:lowpan") p = Node::CONN_DGRAM_LOWPAN;
00558 
00559                                 bool node_exists = false;
00560 
00561                                 // get node
00562                                 for (std::list<Node>::iterator iter = _nodes.begin(); iter != _nodes.end(); iter++)
00563                                 {
00564                                         dtn::core::Node &n = (*iter);
00565 
00566                                         if (n.getEID() == node_eid)
00567                                         {
00568                                                 n.add( dtn::core::Node::URI( dtn::core::Node::NODE_STATIC, p, ss.str(), 0, 10 ) );
00569                                                 n.setConnectImmediately( conf.read<std::string>(prefix + "immediately", "no") == "yes" );
00570                                                 node_exists = true;
00571                                                 break;
00572                                         }
00573                                 }
00574 
00575                                 if (!node_exists)
00576                                 {
00577                                         Node n(node_eid);
00578                                         n.add( dtn::core::Node::URI( dtn::core::Node::NODE_STATIC, p, ss.str(), 0, 10 ) );
00579                                         n.setConnectImmediately( conf.read<std::string>(prefix + "immediately", "no") == "yes" );
00580                                         _nodes.push_back(n);
00581                                 }
00582 
00583                                 count++;
00584 
00585                                 std::stringstream prefix_stream;
00586                                 prefix_stream << "static" << count << "_";
00587                                 prefix = prefix_stream.str();
00588                         }
00589 
00593                         _routing = conf.read<string>("routing", "default");
00594 
00595                         if(_routing == "prophet"){
00596                                 /* read prophet parameters */
00597                                 _prophet_config.p_encounter_max = conf.read<float>("prophet_p_encounter_max", 0.7);
00598                                 if(_prophet_config.p_encounter_max > 1 || _prophet_config.p_encounter_max <= 0)
00599                                         _prophet_config.p_encounter_max = 0.7;
00600                                 _prophet_config.p_encounter_first = conf.read<float>("prophet_p_encounter_first", 0.5);
00601                                 if(_prophet_config.p_encounter_first > 1 || _prophet_config.p_encounter_first <= 0)
00602                                         _prophet_config.p_encounter_first = 0.5;
00603                                 _prophet_config.p_first_threshold = conf.read<float>("prophet_p_first_threshold", 0.1);
00604                                 if(_prophet_config.p_first_threshold < 0 || _prophet_config.p_first_threshold >= _prophet_config.p_encounter_first)
00605                                         _prophet_config.p_first_threshold = 0; //disable first threshold on misconfiguration
00606                                 _prophet_config.beta = conf.read<float>("prophet_beta", 0.9);
00607                                 if(_prophet_config.beta < 0 || _prophet_config.beta > 1)
00608                                         _prophet_config.beta = 0.9;
00609                                 _prophet_config.gamma = conf.read<float>("prophet_gamma", 0.999);
00610                                 if(_prophet_config.gamma <= 0 || _prophet_config.gamma > 1)
00611                                         _prophet_config.gamma = 0.999;
00612                                 _prophet_config.delta = conf.read<float>("prophet_delta", 0.01);
00613                                 if(_prophet_config.delta < 0 || _prophet_config.delta > 1)
00614                                         _prophet_config.delta = 0.01;
00615                                 _prophet_config.time_unit = conf.read<ibrcommon::Timer::time_t>("prophet_time_unit", 1);
00616                                 if(_prophet_config.time_unit < 1)
00617                                         _prophet_config.time_unit = 1;
00618                                 _prophet_config.i_typ = conf.read<ibrcommon::Timer::time_t>("prophet_i_typ", 300);
00619                                 if(_prophet_config.i_typ < 1)
00620                                         _prophet_config.i_typ = 1;
00621                                 _prophet_config.next_exchange_timeout = conf.read<ibrcommon::Timer::time_t>("prophet_next_exchange_timeout", 60);
00622                                 _prophet_config.forwarding_strategy = conf.read<std::string>("prophet_forwarding_strategy", "GRTR");
00623                                 _prophet_config.gtmx_nf_max = conf.read<unsigned int>("prophet_gtmx_nf_max", 30);
00624                         }
00625 
00629                         _forwarding = (conf.read<std::string>("routing_forwarding", "yes") == "yes");
00630 
00634                         _interfaces.clear();
00635 
00636                         if (_use_default_net)
00637                         {
00638                                 _interfaces.push_back( Configuration::NetConfig("default", Configuration::NetConfig::NETWORK_TCP, _default_net, 4556) );
00639                         }
00640                         else try
00641                         {
00642                                 vector<string> nets = dtn::utils::Utils::tokenize(" ", conf.read<string>("net_interfaces") );
00643                                 for (vector<string>::const_iterator iter = nets.begin(); iter != nets.end(); iter++)
00644                                 {
00645                                         std::string netname = (*iter);
00646 
00647                                         std::string key_type = "net_" + netname + "_type";
00648                                         std::string key_port = "net_" + netname + "_port";
00649                                         std::string key_interface = "net_" + netname + "_interface";
00650                                         std::string key_address = "net_" + netname + "_address";
00651                                         std::string key_discovery = "net_" + netname + "_discovery";
00652                                         std::string key_path = "net_" + netname + "_path";
00653                                         std::string key_mtu = "net_" + netname + "_mtu";
00654 
00655                                         std::string type_name = conf.read<string>(key_type, "tcp");
00656                                         Configuration::NetConfig::NetType type = Configuration::NetConfig::NETWORK_UNKNOWN;
00657 
00658                                         if (type_name == "tcp") type = Configuration::NetConfig::NETWORK_TCP;
00659                                         if (type_name == "udp") type = Configuration::NetConfig::NETWORK_UDP;
00660                                         if (type_name == "http") type = Configuration::NetConfig::NETWORK_HTTP;
00661                                         if (type_name == "lowpan") type = Configuration::NetConfig::NETWORK_LOWPAN;
00662                                         if (type_name == "file") type = Configuration::NetConfig::NETWORK_FILE;
00663                                         if (type_name == "dgram:udp") type = Configuration::NetConfig::NETWORK_DGRAM_UDP;
00664                                         if (type_name == "dgram:lowpan") type = Configuration::NetConfig::NETWORK_DGRAM_LOWPAN;
00665                                         if (type_name == "dgram:ethernet") type = Configuration::NetConfig::NETWORK_DGRAM_ETHERNET;
00666 
00667                                         switch (type)
00668                                         {
00669                                                 case Configuration::NetConfig::NETWORK_HTTP:
00670                                                 {
00671                                                         Configuration::NetConfig nc(netname, type,
00672                                                                         conf.read<std::string>(key_address, "http://localhost/"),
00673                                                                         conf.read<std::string>(key_discovery, "yes") == "no");
00674 
00675                                                         _interfaces.push_back(nc);
00676                                                         break;
00677                                                 }
00678 
00679                                                 case Configuration::NetConfig::NETWORK_FILE:
00680                                                 {
00681                                                         Configuration::NetConfig nc(netname, type,
00682                                                                         conf.read<std::string>(key_path, ""),
00683                                                                         conf.read<std::string>(key_discovery, "yes") == "no");
00684 
00685                                                         _interfaces.push_back(nc);
00686                                                         break;
00687                                                 }
00688 
00689                                                 default:
00690                                                 {
00691                                                         int port = conf.read<int>(key_port, 4556);
00692                                                         bool discovery = (conf.read<std::string>(key_discovery, "yes") == "yes");
00693                                                         int mtu = conf.read<int>(key_mtu, 1280);
00694 
00695                                                         try {
00696                                                                 ibrcommon::vinterface interface(conf.read<std::string>(key_interface));
00697                                                                 Configuration::NetConfig nc(netname, type, interface, port, discovery);
00698                                                                 nc.mtu = mtu;
00699                                                                 _interfaces.push_back(nc);
00700                                                         } catch (const ConfigFile::key_not_found&) {
00701                                                                 ibrcommon::vaddress addr;
00702                                                                 Configuration::NetConfig nc(netname, type, addr, port, discovery);
00703                                                                 nc.mtu = mtu;
00704                                                                 _interfaces.push_back(nc);
00705                                                         }
00706 
00707                                                         break;
00708                                                 }
00709                                         }
00710                                 }
00711                         } catch (const ConfigFile::key_not_found&) {
00712                                 // stop the one network is not found.
00713                         }
00714 
00718                         _tcp_nodelay = (conf.read<std::string>("tcp_nodelay", "yes") == "yes");
00719                         _tcp_chunksize = conf.read<unsigned int>("tcp_chunksize", 4096);
00720                         _tcp_idle_timeout = conf.read<unsigned int>("tcp_idle_timeout", 0);
00721 
00725                         _dynamic_rebind = (conf.read<std::string>("net_rebind", "no") == "yes");
00726 
00730                         _auto_connect = conf.read<size_t>("net_autoconnect", 0);
00731 
00735                         _fragmentation = (conf.read<std::string>("fragmentation", "no") == "yes");
00736                 }
00737 
00738                 const std::multimap<std::string, std::string>& Configuration::Network::getStaticRoutes() const
00739                 {
00740                         return _static_routes;
00741                 }
00742 
00743                 const std::list<Node>& Configuration::Network::getStaticNodes() const
00744                 {
00745                         return _nodes;
00746                 }
00747 
00748                 int Configuration::getTimezone()
00749                 {
00750                         return _conf.read<int>( "timezone", 0 );
00751                 }
00752 
00753                 ibrcommon::File Configuration::getPath(string name)
00754                 {
00755                         stringstream ss;
00756                         ss << name << "_path";
00757                         string key; ss >> key;
00758 
00759                         try {
00760                                 return ibrcommon::File(_conf.read<string>(key));
00761                         } catch (const ConfigFile::key_not_found&) {
00762                                 throw ParameterNotSetException();
00763                         }
00764                 }
00765 
00766                 const std::string Configuration::getUser() const
00767                 {
00768                         try {
00769                                 return _conf.read<std::string>("user");
00770                         } catch (const ConfigFile::key_not_found&) {
00771                                 throw ParameterNotSetException();
00772                         }
00773                 }
00774 
00775                 unsigned int Configuration::getUID() const
00776                 {
00777                         try {
00778                                 return _conf.read<unsigned int>("uid");
00779                         } catch (const ConfigFile::key_not_found&) {
00780                                 throw ParameterNotSetException();
00781                         }
00782                 }
00783 
00784                 unsigned int Configuration::getGID() const
00785                 {
00786                         try {
00787                                 return _conf.read<unsigned int>("gid");
00788                         } catch (const ConfigFile::key_not_found&) {
00789                                 throw ParameterNotSetException();
00790                         }
00791                 }
00792 
00793 
00794                 bool Configuration::Discovery::enabled() const
00795                 {
00796                         return _enabled;
00797                 }
00798 
00799                 bool Configuration::Discovery::announce() const
00800                 {
00801                         return (Configuration::getInstance()._conf.read<int>("discovery_announce", 1) == 1);
00802                 }
00803 
00804                 bool Configuration::Discovery::shortbeacon() const
00805                 {
00806                         return (Configuration::getInstance()._conf.read<int>("discovery_short", 0) == 1);
00807                 }
00808 
00809                 char Configuration::Discovery::version() const
00810                 {
00811                         return Configuration::getInstance()._conf.read<int>("discovery_version", 2);
00812                 }
00813 
00814                 bool Configuration::doAPI()
00815                 {
00816                         return _doapi;
00817                 }
00818 
00819                 string Configuration::getNotifyCommand()
00820                 {
00821                         try {
00822                                 return _conf.read<string>("notify_cmd");
00823                         } catch (const ConfigFile::key_not_found&) {
00824                                 throw ParameterNotSetException();
00825                         }
00826                 }
00827 
00828                 Configuration::RoutingExtension Configuration::Network::getRoutingExtension() const
00829                 {
00830                         if ( _routing == "epidemic" ) return EPIDEMIC_ROUTING;
00831                         if ( _routing == "flooding" ) return FLOOD_ROUTING;
00832                         if ( _routing == "prophet" ) return PROPHET_ROUTING;
00833                         return DEFAULT_ROUTING;
00834                 }
00835 
00836 
00837                 bool Configuration::Network::doForwarding() const
00838                 {
00839                         return _forwarding;
00840                 }
00841 
00842                 bool Configuration::Network::doFragmentation() const
00843                 {
00844                         return _fragmentation;
00845                 }
00846 
00847                 bool Configuration::Network::getTCPOptionNoDelay() const
00848                 {
00849                         return _tcp_nodelay;
00850                 }
00851 
00852                 size_t Configuration::Network::getTCPChunkSize() const
00853                 {
00854                         return _tcp_chunksize;
00855                 }
00856 
00857                 size_t Configuration::Network::getTCPIdleTimeout() const
00858                 {
00859                         return _tcp_idle_timeout;
00860                 }
00861 
00862                 bool Configuration::Network::doDynamicRebind() const
00863                 {
00864                         return _dynamic_rebind;
00865                 }
00866 
00867                 size_t Configuration::Network::getAutoConnect() const
00868                 {
00869                         return _auto_connect;
00870                 }
00871 
00872                 Configuration::Network::ProphetConfig Configuration::Network::getProphetConfig() const
00873                 {
00874                         return _prophet_config;
00875                 }
00876 
00877 
00878                 bool Configuration::Statistic::enabled() const
00879                 {
00880                         return Configuration::getInstance()._conf.keyExists("statistic_type");
00881                 }
00882 
00883                 ibrcommon::File Configuration::Statistic::logfile() const throw (ParameterNotSetException)
00884                 {
00885                         try {
00886                                 return ibrcommon::File(Configuration::getInstance()._conf.read<std::string>("statistic_file"));
00887                         } catch (const ConfigFile::key_not_found&) {
00888                                 throw ParameterNotSetException();
00889                         }
00890                 }
00891 
00892                 std::string Configuration::Statistic::type() const
00893                 {
00894                         return Configuration::getInstance()._conf.read<std::string>("statistic_type", "stdout");
00895                 }
00896 
00897                 unsigned int Configuration::Statistic::interval() const
00898                 {
00899                         return Configuration::getInstance()._conf.read<unsigned int>("statistic_interval", 300);
00900                 }
00901 
00902                 std::string Configuration::Statistic::address() const
00903                 {
00904                         return Configuration::getInstance()._conf.read<std::string>("statistic_address", "127.0.0.1");
00905                 }
00906 
00907                 unsigned int Configuration::Statistic::port() const
00908                 {
00909                         return Configuration::getInstance()._conf.read<unsigned int>("statistic_port", 1234);
00910                 }
00911 
00912                 size_t Configuration::getLimit(std::string suffix)
00913                 {
00914                         std::string unparsed = _conf.read<std::string>("limit_" + suffix, "0");
00915 
00916                         std::stringstream ss(unparsed);
00917 
00918                         float value; ss >> value;
00919                         char multiplier = 0; ss >> multiplier;
00920 
00921                         switch (multiplier)
00922                         {
00923                         default:
00924                                 return (size_t)value;
00925                                 break;
00926 
00927                         case 'G':
00928                                 return (size_t)(value * 1000000000);
00929                                 break;
00930 
00931                         case 'M':
00932                                 return (size_t)(value * 1000000);
00933                                 break;
00934 
00935                         case 'K':
00936                                 return (size_t)(value * 1000);
00937                                 break;
00938                         }
00939 
00940                         return 0;
00941                 }
00942 
00943                 void Configuration::Security::load(const ibrcommon::ConfigFile &conf)
00944                 {
00945                         bool withTLS = false;
00946 #ifdef WITH_TLS
00947                         withTLS = true;
00948                         /* enable TLS if the certificate path, a certificate and the private key was given */
00949                         bool activateTLS = true;
00950 
00951                         // load public key file
00952                         try {
00953                                 _cert = conf.read<std::string>("security_certificate");
00954 
00955                                 if (!_cert.exists())
00956                                 {
00957                                         IBRCOMMON_LOGGER(warning) << "Certificate file " << _cert.getPath() << " does not exists!" << IBRCOMMON_LOGGER_ENDL;
00958                                         activateTLS = false;
00959                                 }
00960                         } catch (const ibrcommon::ConfigFile::key_not_found&) {
00961                                 activateTLS = false;
00962                         }
00963 
00964                         // load KEY file
00965                         try {
00966                                 _key = conf.read<std::string>("security_key");
00967 
00968                                 if (!_key.exists())
00969                                 {
00970                                         IBRCOMMON_LOGGER(warning) << "KEY file " << _key.getPath() << " does not exists!" << IBRCOMMON_LOGGER_ENDL;
00971                                         activateTLS = false;
00972                                 }
00973                         } catch (const ibrcommon::ConfigFile::key_not_found&) {
00974                                 activateTLS = false;
00975                         }
00976 
00977                         // read trustedCAPath
00978                         try{
00979                                 _trustedCAPath = conf.read<std::string>("security_trusted_ca_path");
00980                                 if(!_trustedCAPath.isDirectory()){
00981                                         IBRCOMMON_LOGGER(warning) << "Trusted CA Path " << _trustedCAPath.getPath() << " does not exists or is no directory!" << IBRCOMMON_LOGGER_ENDL;
00982                                         activateTLS = false;
00983                                 }
00984                         } catch (const ibrcommon::ConfigFile::key_not_found&) {
00985                                 activateTLS = false;
00986                         }
00987 
00988                         // read if encryption should be disabled
00989                         _disableEncryption = (conf.read<std::string>("security_tls_disable_encryption", "no") == "yes");
00990 
00991                         if (activateTLS)
00992                         {
00993                                 _tlsEnabled = true;
00994 
00995                                 /* read if TLS is required */
00996                                 _tlsRequired = (conf.read<std::string>("security_tls_required", "no") == "yes");
00997 
00998                                 /* If the clock is not in sync, SSL will fail. Accept plain connection when the clock is not sync'ed. */
00999                                 _tlsOptionalOnBadClock = (conf.read<std::string>("security_tls_fallback_badclock", "no") == "yes");
01000                         }
01001 #endif
01002 
01003 #ifdef WITH_BUNDLE_SECURITY
01004                         // enable security if the security path is set
01005                         try {
01006                                 _path = conf.read<std::string>("security_path");
01007 
01008                                 if (!_path.exists())
01009                                 {
01010                                         ibrcommon::File::createDirectory(_path);
01011                                 }
01012 
01013                                 _enabled = true;
01014                         } catch (const ibrcommon::ConfigFile::key_not_found&) {
01015                                 return;
01016                         }
01017 
01018                         // load level
01019                         _level = Level(conf.read<int>("security_level", 0));
01020 
01021                         if ( !withTLS )
01022                         {
01023                                 /* if TLS is enabled, the Certificate file and the key have been read earlier */
01024                                 // load CA file
01025                                 try {
01026                                         _cert = conf.read<std::string>("security_certificate");
01027 
01028                                         if (!_cert.exists())
01029                                         {
01030                                                 IBRCOMMON_LOGGER(warning) << "Certificate file " << _cert.getPath() << " does not exists!" << IBRCOMMON_LOGGER_ENDL;
01031                                         }
01032                                 } catch (const ibrcommon::ConfigFile::key_not_found&) { }
01033 
01034                                 // load KEY file
01035                                 try {
01036                                         _key = conf.read<std::string>("security_key");
01037 
01038                                         if (!_key.exists())
01039                                         {
01040                                                 IBRCOMMON_LOGGER(warning) << "KEY file " << _key.getPath() << " does not exists!" << IBRCOMMON_LOGGER_ENDL;
01041                                         }
01042                                 } catch (const ibrcommon::ConfigFile::key_not_found&) { }
01043                         }
01044 
01045                         // load KEY file
01046                         try {
01047                                 _bab_default_key = conf.read<std::string>("security_bab_default_key");
01048 
01049                                 if (!_bab_default_key.exists())
01050                                 {
01051                                         IBRCOMMON_LOGGER(warning) << "KEY file " << _bab_default_key.getPath() << " does not exists!" << IBRCOMMON_LOGGER_ENDL;
01052                                 }
01053                         } catch (const ibrcommon::ConfigFile::key_not_found&) {
01054                         }
01055 #endif
01056                 };
01057 
01058                 Configuration::Security::~Security() {};
01059 
01060                 bool Configuration::Security::enabled() const
01061                 {
01062                         return _enabled;
01063                 }
01064 
01065                 bool Configuration::Security::doTLS() const
01066                 {
01067                         return _tlsEnabled;
01068                 }
01069 
01070                 bool Configuration::Security::TLSRequired() const
01071                 {
01072                         // TLS is only required, if the clock is in sync
01073                         if ((dtn::utils::Clock::quality == 0) && _tlsOptionalOnBadClock) return false;
01074                         return _tlsRequired;
01075                 }
01076 
01077 #ifdef WITH_BUNDLE_SECURITY
01078                 const ibrcommon::File& Configuration::Security::getPath() const
01079                 {
01080                         return _path;
01081                 }
01082 
01083                 Configuration::Security::Level Configuration::Security::getLevel() const
01084                 {
01085                         return _level;
01086                 }
01087 
01088                 const ibrcommon::File& Configuration::Security::getBABDefaultKey() const
01089                 {
01090                         return _bab_default_key;
01091                 }
01092 #endif
01093 #if defined WITH_BUNDLE_SECURITY || defined WITH_TLS
01094                 const ibrcommon::File& Configuration::Security::getCertificate() const
01095                 {
01096                         return _cert;
01097                 }
01098 
01099                 const ibrcommon::File& Configuration::Security::getKey() const
01100                 {
01101                         return _key;
01102                 }
01103 #endif
01104 #ifdef WITH_TLS
01105                 const ibrcommon::File& Configuration::Security::getTrustedCAPath() const
01106                 {
01107                         return _trustedCAPath;
01108                 }
01109 
01110                 bool Configuration::Security::TLSEncryptionDisabled() const
01111                 {
01112                         return _disableEncryption;
01113                 }
01114 #endif
01115 
01116                 bool Configuration::Logger::quiet() const
01117                 {
01118                         return _quiet;
01119                 }
01120 
01121                 const ibrcommon::File& Configuration::Logger::getLogfile() const
01122                 {
01123                         if (_logfile.getPath() == "") throw Configuration::ParameterNotSetException();
01124                         return _logfile;
01125                 }
01126 
01127                 bool Configuration::Logger::display_timestamps() const
01128                 {
01129                         return _timestamps;
01130                 }
01131 
01132                 unsigned int Configuration::Logger::options() const
01133                 {
01134                         return _options;
01135                 }
01136 
01137                 std::ostream& Configuration::Logger::output() const
01138                 {
01139                         return std::cout;
01140                 }
01141 
01142                 bool Configuration::Daemon::daemonize() const
01143                 {
01144                         return _daemonize;
01145                 }
01146 
01147                 bool Configuration::Daemon::kill_daemon() const
01148                 {
01149                         return _kill;
01150                 }
01151 
01152                 size_t Configuration::Daemon::getThreads() const
01153                 {
01154                         return _threads;
01155                 }
01156 
01157                 const ibrcommon::File& Configuration::Daemon::getPidFile() const
01158                 {
01159                         if (_pidfile == ibrcommon::File()) throw ParameterNotSetException();
01160                         return _pidfile;
01161                 }
01162 
01163                 bool Configuration::TimeSync::hasReference() const
01164                 {
01165                         return _reference;
01166                 }
01167 
01168                 bool Configuration::TimeSync::syncOnDiscovery() const
01169                 {
01170                         return _sync;
01171                 }
01172 
01173                 bool Configuration::TimeSync::sendDiscoveryAnnouncements() const
01174                 {
01175                         return _discovery;
01176                 }
01177 
01178                 int Configuration::TimeSync::getQualityOfTimeTick() const
01179                 {
01180                         return _qot_tick;
01181                 }
01182 
01183                 float Configuration::TimeSync::getSigma() const
01184                 {
01185                         return _sigma;
01186                 }
01187 
01188                 float Configuration::TimeSync::getSyncLevel() const
01189                 {
01190                         return _sync_level;
01191                 }
01192 
01193                 bool Configuration::DHT::enabled() const
01194                 {
01195                         return _enabled;
01196                 }
01197 
01198                 bool Configuration::DHT::randomPort() const
01199                 {
01200                         return _port == 0;
01201                 }
01202 
01203                 unsigned int Configuration::DHT::getPort() const
01204                 {
01205                         return _port;
01206                 }
01207 
01208                 string Configuration::DHT::getID() const
01209                 {
01210                         return _id;
01211                 }
01212 
01213                 bool Configuration::DHT::randomID() const
01214                 {
01215                         return _id == "";
01216                 }
01217 
01218                 bool Configuration::DHT::isDNSBootstrappingEnabled() const
01219                 {
01220                         return _dnsbootstrapping;
01221                 }
01222 
01223                 std::vector<string> Configuration::DHT::getDNSBootstrappingNames() const
01224                 {
01225                         return _bootstrappingdomains;
01226                 }
01227 
01228                 bool Configuration::DHT::isIPBootstrappingEnabled() const
01229                 {
01230                         return _bootstrappingips.size() > 0;
01231                 }
01232 
01233                 std::vector<string> Configuration::DHT::getIPBootstrappingIPs() const
01234                 {
01235                         return _bootstrappingips;
01236                 }
01237 
01238                 string Configuration::DHT::getIPv4Binding() const
01239                 {
01240                         return _ipv4bind;
01241                 }
01242                 string Configuration::DHT::getIPv6Binding() const
01243                 {
01244                         return _ipv6bind;
01245                 }
01246 
01247                 string Configuration::DHT::getPathToNodeFiles() const
01248                 {
01249                         return _nodesFilePath;
01250                 }
01251 
01252                 bool Configuration::DHT::isIPv4Enabled() const
01253                 {
01254                         return _ipv4;
01255                 }
01256 
01257                 bool Configuration::DHT::isIPv6Enabled() const
01258                 {
01259                         return _ipv6;
01260                 }
01261 
01262                 bool Configuration::DHT::isSelfAnnouncingEnabled() const
01263                 {
01264                         return _selfannounce;
01265                 }
01266 
01267                 int Configuration::DHT::getMinimumRating() const
01268                 {
01269                         return _minRating;
01270                 }
01271 
01272                 bool Configuration::DHT::isNeighbourAnnouncementEnabled() const
01273                 {
01274                         return _allowNeighbourAnnouncement;
01275                 }
01276 
01277                 bool Configuration::DHT::isNeighbourAllowedToAnnounceMe() const
01278                 {
01279                         return _allowNeighbourToAnnounceMe;
01280                 }
01281 
01282                 bool Configuration::DHT::isBlacklistEnabled() const
01283                 {
01284                         return _blacklist;
01285                 }
01286                 
01287                 bool Configuration::DHT::ignoreDHTNeighbourInformations() const
01288                 {
01289                         return _ignoreDHTNeighbourInformations;
01290                 }
01291         }
01292 }