IBR-DTNSuite
0.8
|
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, ×tamp, 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 }