• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

daemon/src/Main.cpp

Go to the documentation of this file.
00001 #include "config.h"
00002 
00003 #include <ibrcommon/data/BLOB.h>
00004 #include <ibrcommon/data/File.h>
00005 #include <ibrcommon/AutoDelete.h>
00006 #include <ibrcommon/net/vinterface.h>
00007 #include <ibrcommon/Logger.h>
00008 #include <ibrcommon/net/LinkManager.h>
00009 #include <ibrdtn/utils/Clock.h>
00010 #include <list>
00011 
00012 #include "core/BundleCore.h"
00013 #include "core/EventSwitch.h"
00014 #include "core/BundleStorage.h"
00015 #include "core/MemoryBundleStorage.h"
00016 #include "core/SimpleBundleStorage.h"
00017 
00018 #include "core/Node.h"
00019 #include "core/EventSwitch.h"
00020 #include "core/GlobalEvent.h"
00021 #include "core/NodeEvent.h"
00022 
00023 #include "routing/BaseRouter.h"
00024 #include "routing/StaticRoutingExtension.h"
00025 #include "routing/NeighborRoutingExtension.h"
00026 #include "routing/epidemic/EpidemicRoutingExtension.h"
00027 #include "routing/flooding/FloodRoutingExtension.h"
00028 #include "routing/RetransmissionExtension.h"
00029 
00030 #include "net/UDPConvergenceLayer.h"
00031 #include "net/TCPConvergenceLayer.h"
00032 
00033 #ifdef HAVE_SQLITE
00034 #include "core/SQLiteBundleStorage.h"
00035 #endif
00036 
00037 #ifdef HAVE_LIBCURL
00038 #include "net/HTTPConvergenceLayer.h"
00039 #endif
00040 
00041 #ifdef HAVE_LOWPAN_SUPPORT
00042 #include "net/LOWPANConvergenceLayer.h"
00043 #endif
00044 
00045 #include "net/IPNDAgent.h"
00046 
00047 #include "ApiServer.h"
00048 #include "Configuration.h"
00049 #include "EchoWorker.h"
00050 #include "Notifier.h"
00051 #include "DevNull.h"
00052 #include "StatisticLogger.h"
00053 #include "Component.h"
00054 
00055 #ifdef WITH_BUNDLE_SECURITY
00056 #include "security/SecurityManager.h"
00057 #include "security/SecurityKeyManager.h"
00058 #endif
00059 
00060 #include <csignal>
00061 #include <sys/types.h>
00062 #include <syslog.h>
00063 #include <set>
00064 
00065 using namespace dtn::core;
00066 using namespace dtn::daemon;
00067 using namespace dtn::utils;
00068 using namespace dtn::net;
00069 
00070 #include "Debugger.h"
00071 
00072 #define UNIT_MB * 1048576
00073 
00078 // logging options
00079 unsigned char logopts = ibrcommon::Logger::LOG_DATETIME | ibrcommon::Logger::LOG_LEVEL;
00080 
00081 // error filter
00082 const unsigned int logerr = ibrcommon::Logger::LOGGER_ERR | ibrcommon::Logger::LOGGER_CRIT;
00083 
00084 // logging filter, everything but debug, err and crit
00085 const unsigned int logstd = ~(ibrcommon::Logger::LOGGER_DEBUG | ibrcommon::Logger::LOGGER_ERR | ibrcommon::Logger::LOGGER_CRIT);
00086 
00087 // syslog filter, everything but DEBUG and NOTICE
00088 const unsigned int logsys = ~(ibrcommon::Logger::LOGGER_DEBUG | ibrcommon::Logger::LOGGER_NOTICE);
00089 
00090 // debug off by default
00091 bool _debug = false;
00092 
00093 // on interruption do this!
00094 void sighandler(int signal)
00095 {
00096         switch (signal)
00097         {
00098         case SIGTERM:
00099         case SIGINT:
00100                 dtn::core::GlobalEvent::raise(dtn::core::GlobalEvent::GLOBAL_SHUTDOWN);
00101                 break;
00102         case SIGUSR1:
00103                 // activate debugging
00104                 // init logger
00105                 ibrcommon::Logger::setVerbosity(99);
00106                 IBRCOMMON_LOGGER(info) << "debug level set to 99" << IBRCOMMON_LOGGER_ENDL;
00107 
00108                 if (!_debug)
00109                 {
00110                         ibrcommon::Logger::addStream(std::cout, ibrcommon::Logger::LOGGER_DEBUG, logopts);
00111                         _debug = true;
00112                 }
00113                 break;
00114         case SIGUSR2:
00115                 // activate debugging
00116                 // init logger
00117                 ibrcommon::Logger::setVerbosity(0);
00118                 IBRCOMMON_LOGGER(info) << "debug level set to 0" << IBRCOMMON_LOGGER_ENDL;
00119                 break;
00120         case SIGHUP:
00121                 // send shutdown signal to unbound threads
00122                 dtn::core::GlobalEvent::raise(dtn::core::GlobalEvent::GLOBAL_RELOAD);
00123                 break;
00124         }
00125 }
00126 
00127 void switchUser(Configuration &config)
00128 {
00129     try {
00130         setuid( config.getUID() );
00131         IBRCOMMON_LOGGER(info) << "Switching UID to " << config.getUID() << IBRCOMMON_LOGGER_ENDL;
00132     } catch (const Configuration::ParameterNotSetException&) {
00133 
00134     }
00135 
00136     try {
00137         setuid( config.getGID() );
00138         IBRCOMMON_LOGGER(info) << "Switching GID to " << config.getGID() << IBRCOMMON_LOGGER_ENDL;
00139     } catch (const Configuration::ParameterNotSetException&) {
00140 
00141     }
00142 }
00143 
00144 void setGlobalVars(Configuration &config)
00145 {
00146     // set the timezone
00147     dtn::utils::Clock::timezone = config.getTimezone();
00148 
00149     // set local eid
00150     dtn::core::BundleCore::local = config.getNodename();
00151     IBRCOMMON_LOGGER(info) << "Local node name: " << config.getNodename() << IBRCOMMON_LOGGER_ENDL;
00152 
00153     try {
00154         // new methods for blobs
00155         ibrcommon::BLOB::tmppath = config.getPath("blob");
00156 
00157         // check if the BLOB path exists
00158         if (ibrcommon::BLOB::tmppath.exists())
00159         {
00160                 if (ibrcommon::BLOB::tmppath.isDirectory())
00161                 {
00162                         IBRCOMMON_LOGGER(info) << "using BLOB path: " << ibrcommon::BLOB::tmppath.getPath() << IBRCOMMON_LOGGER_ENDL;
00163                 }
00164                 else
00165                 {
00166                         IBRCOMMON_LOGGER(warning) << "BLOB path exists, but is not a directory! Fallback to memory based mode." << IBRCOMMON_LOGGER_ENDL;
00167                         ibrcommon::BLOB::tmppath = ibrcommon::File();
00168                 }
00169         }
00170         else
00171         {
00172                 // try to create the BLOB path
00173                 ibrcommon::File::createDirectory(ibrcommon::BLOB::tmppath);
00174 
00175                 if (ibrcommon::BLOB::tmppath.exists())
00176                 {
00177                         IBRCOMMON_LOGGER(info) << "using BLOB path: " << ibrcommon::BLOB::tmppath.getPath() << IBRCOMMON_LOGGER_ENDL;
00178                 }
00179                 else
00180                 {
00181                         IBRCOMMON_LOGGER(warning) << "Could not create BLOB path! Fallback to memory based mode." << IBRCOMMON_LOGGER_ENDL;
00182                         ibrcommon::BLOB::tmppath = ibrcommon::File();
00183                 }
00184         }
00185     } catch (const Configuration::ParameterNotSetException&) {
00186     }
00187 
00188     // set block size limit
00189     dtn::core::BundleCore::blocksizelimit = config.getLimit("blocksize");
00190     if (dtn::core::BundleCore::blocksizelimit > 0)
00191     {
00192         IBRCOMMON_LOGGER(info) << "Block size limited to " << dtn::core::BundleCore::blocksizelimit << " bytes" << IBRCOMMON_LOGGER_ENDL;
00193     }
00194 }
00195 
00196 void createBundleStorage(BundleCore &core, Configuration &conf, std::list< dtn::daemon::Component* > &components)
00197 {
00198         dtn::core::BundleStorage *storage = NULL;
00199 
00200 #ifdef HAVE_SQLITE
00201         if (conf.getStorage() == "sqlite")
00202         {
00203                 try {
00204                         // new methods for blobs
00205                         ibrcommon::File path = conf.getPath("storage");
00206 
00207                         // create workdir if needed
00208                         if (!path.exists())
00209                         {
00210                                 ibrcommon::File::createDirectory(path);
00211                         }
00212 
00213                         IBRCOMMON_LOGGER(info) << "using sqlite bundle storage in " << path.getPath() << IBRCOMMON_LOGGER_ENDL;
00214 
00215                         dtn::core::SQLiteBundleStorage *sbs = new dtn::core::SQLiteBundleStorage(path, conf.getLimit("storage") );
00216 
00217                         components.push_back(sbs);
00218                         storage = sbs;
00219                 } catch (const Configuration::ParameterNotSetException&) {
00220                         IBRCOMMON_LOGGER(error) << "storage for bundles" << IBRCOMMON_LOGGER_ENDL;
00221                         exit(-1);
00222                 }
00223         }
00224 #endif
00225 
00226         if ((conf.getStorage() == "simple") || (conf.getStorage() == "default"))
00227         {
00228                 // default behavior if no bundle storage is set
00229                 try {
00230                         // new methods for blobs
00231                         ibrcommon::File path = conf.getPath("storage");
00232 
00233                         // create workdir if needed
00234                         if (!path.exists())
00235                         {
00236                                 ibrcommon::File::createDirectory(path);
00237                         }
00238 
00239                         IBRCOMMON_LOGGER(info) << "using simple bundle storage in " << path.getPath() << IBRCOMMON_LOGGER_ENDL;
00240 
00241                         dtn::core::SimpleBundleStorage *sbs = new dtn::core::SimpleBundleStorage(path, conf.getLimit("storage"), conf.getLimit("storage_buffer"));
00242 
00243                         components.push_back(sbs);
00244                         storage = sbs;
00245                 } catch (const Configuration::ParameterNotSetException&) {
00246                         IBRCOMMON_LOGGER(info) << "using bundle storage in memory-only mode" << IBRCOMMON_LOGGER_ENDL;
00247 
00248                         dtn::core::MemoryBundleStorage *sbs = new dtn::core::MemoryBundleStorage(conf.getLimit("storage"));
00249                         components.push_back(sbs);
00250                         storage = sbs;
00251                 }
00252         }
00253 
00254         if (storage == NULL)
00255         {
00256                 IBRCOMMON_LOGGER(error) << "bundle storage module \"" << conf.getStorage() << "\" do not exists!" << IBRCOMMON_LOGGER_ENDL;
00257                 exit(-1);
00258         }
00259 
00260         // set the storage in the core
00261         core.setStorage(storage);
00262 }
00263 
00264 void createConvergenceLayers(BundleCore &core, Configuration &conf, std::list< dtn::daemon::Component* > &components, dtn::net::IPNDAgent *ipnd)
00265 {
00266         // get the configuration of the convergence layers
00267         const std::list<Configuration::NetConfig> &nets = conf.getNetwork().getInterfaces();
00268 
00269         // local cl map
00270         std::map<Configuration::NetConfig::NetType, dtn::net::ConvergenceLayer*> _cl_map;
00271 
00272         // create the convergence layers
00273         for (std::list<Configuration::NetConfig>::const_iterator iter = nets.begin(); iter != nets.end(); iter++)
00274         {
00275                 const Configuration::NetConfig &net = (*iter);
00276 
00277                 try {
00278                         switch (net.type)
00279                         {
00280                                 case Configuration::NetConfig::NETWORK_UDP:
00281                                 {
00282                                         try {
00283                                                 UDPConvergenceLayer *udpcl = new UDPConvergenceLayer( net.interface, net.port );
00284                                                 core.addConvergenceLayer(udpcl);
00285                                                 components.push_back(udpcl);
00286                                                 if (ipnd != NULL) ipnd->addService(udpcl);
00287 
00288                                                 IBRCOMMON_LOGGER(info) << "UDP ConvergenceLayer added on " << net.interface.toString() << ":" << net.port << IBRCOMMON_LOGGER_ENDL;
00289                                         } catch (const ibrcommon::Exception &ex) {
00290                                                 IBRCOMMON_LOGGER(error) << "Failed to add UDP ConvergenceLayer on " << net.interface.toString() << ": " << ex.what() << IBRCOMMON_LOGGER_ENDL;
00291                                         }
00292 
00293                                         break;
00294                                 }
00295 
00296                                 case Configuration::NetConfig::NETWORK_TCP:
00297                                 {
00298                                         // look for an earlier instance of
00299                                         std::map<Configuration::NetConfig::NetType, dtn::net::ConvergenceLayer*>::iterator it = _cl_map.find(net.type);
00300 
00301                                         if (it == _cl_map.end())
00302                                         {
00303                                                 try {
00304                                                         TCPConvergenceLayer *tcpcl = new TCPConvergenceLayer();
00305                                                         tcpcl->bind(net.interface, net.port);
00306 
00307                                                         core.addConvergenceLayer(tcpcl);
00308                                                         components.push_back(tcpcl);
00309                                                         if (ipnd != NULL) ipnd->addService(tcpcl);
00310                                                         _cl_map[net.type] = tcpcl;
00311                                                         IBRCOMMON_LOGGER(info) << "TCP ConvergenceLayer added on " << net.interface.toString() << ":" << net.port << IBRCOMMON_LOGGER_ENDL;
00312                                                 } catch (const ibrcommon::Exception &ex) {
00313                                                         IBRCOMMON_LOGGER(error) << "Failed to add TCP ConvergenceLayer on " << net.interface.toString() << ": " << ex.what() << IBRCOMMON_LOGGER_ENDL;
00314                                                 }
00315                                         }
00316                                         else
00317                                         {
00318                                                 ConvergenceLayer *cl = it->second;
00319                                                 TCPConvergenceLayer &tcpcl = dynamic_cast<TCPConvergenceLayer&>(*(cl));
00320                                                 tcpcl.bind(net.interface, net.port);
00321                                         }
00322 
00323                                         break;
00324                                 }
00325 
00326 #ifdef HAVE_LIBCURL
00327                                 case Configuration::NetConfig::NETWORK_HTTP:
00328                                 {
00329                                         try {
00330                                                 HTTPConvergenceLayer *httpcl = new HTTPConvergenceLayer( net.url );
00331                                                 core.addConvergenceLayer(httpcl);
00332                                                 components.push_back(httpcl);
00333 
00334                                                 IBRCOMMON_LOGGER(info) << "HTTP ConvergenceLayer added, Server: " << net.url << IBRCOMMON_LOGGER_ENDL;
00335                                         } catch (const ibrcommon::Exception &ex) {
00336                                                 IBRCOMMON_LOGGER(error) << "Failed to add HTTP ConvergenceLayer, Server: " << net.url << ": " << ex.what() << IBRCOMMON_LOGGER_ENDL;
00337                                         }
00338                                         break;
00339                                 }
00340 #endif
00341 
00342 #ifdef HAVE_LOWPAN_SUPPORT
00343                                 case Configuration::NetConfig::NETWORK_LOWPAN:
00344                                 {
00345                                         try {
00346                                                 LOWPANConvergenceLayer *lowpancl = new LOWPANConvergenceLayer( net.interface, net.port );
00347                                                 core.addConvergenceLayer(lowpancl);
00348                                                 components.push_back(lowpancl);
00349                                                 if (ipnd != NULL) ipnd->addService(lowpancl);
00350 
00351                                                 IBRCOMMON_LOGGER(info) << "LOWPAN ConvergenceLayer added on " << net.interface.toString() << ":" << net.port << IBRCOMMON_LOGGER_ENDL;
00352                                         } catch (const ibrcommon::Exception &ex) {
00353                                                 IBRCOMMON_LOGGER(error) << "Failed to add LOWPAN ConvergenceLayer on " << net.interface.toString() << ": " << ex.what() << IBRCOMMON_LOGGER_ENDL;
00354                                         }
00355 
00356                                         break;
00357                                 }
00358 #endif
00359 
00360                                 default:
00361                                         break;
00362                         }
00363                 } catch (const std::exception &ex) {
00364                         IBRCOMMON_LOGGER(error) << "Error: " << ex.what() << IBRCOMMON_LOGGER_ENDL;
00365                 }
00366         }
00367 }
00368 
00369 int main(int argc, char *argv[])
00370 {
00371         // catch process signals
00372         signal(SIGINT, sighandler);
00373         signal(SIGTERM, sighandler);
00374         signal(SIGHUP, sighandler);
00375         signal(SIGUSR1, sighandler);
00376         signal(SIGUSR2, sighandler);
00377 
00378         // create a configuration
00379         Configuration &conf = Configuration::getInstance();
00380 
00381         // load parameter into the configuration
00382         conf.params(argc, argv);
00383 
00384         // enable timestamps in logging if requested
00385         if (conf.getLogger().display_timestamps())
00386         {
00387                 logopts = (~(ibrcommon::Logger::LOG_DATETIME) & logopts) | ibrcommon::Logger::LOG_TIMESTAMP;
00388         }
00389 
00390         // init syslog
00391         ibrcommon::Logger::enableAsync(); // enable asynchronous logging feature (thread-safe)
00392         ibrcommon::Logger::enableSyslog("ibrdtn-daemon", LOG_PID, LOG_DAEMON, logsys);
00393 
00394         if (!conf.getDebug().quiet())
00395         {
00396                 // add logging to the cout
00397                 ibrcommon::Logger::addStream(std::cout, logstd, logopts);
00398 
00399                 // add logging to the cerr
00400                 ibrcommon::Logger::addStream(std::cerr, logerr, logopts);
00401         }
00402 
00403         // greeting
00404         IBRCOMMON_LOGGER(info) << "IBR-DTN daemon " << conf.version() << IBRCOMMON_LOGGER_ENDL;
00405 
00406         // activate debugging
00407         if (conf.getDebug().enabled() && !conf.getDebug().quiet())
00408         {
00409                 // init logger
00410                 ibrcommon::Logger::setVerbosity(conf.getDebug().level());
00411 
00412                 IBRCOMMON_LOGGER(info) << "debug level set to " << conf.getDebug().level() << IBRCOMMON_LOGGER_ENDL;
00413 
00414                 ibrcommon::Logger::addStream(std::cout, ibrcommon::Logger::LOGGER_DEBUG, logopts);
00415 
00416                 _debug = true;
00417         }
00418 
00419         // load the configuration file
00420         conf.load();
00421 
00422         // switch the user is requested
00423         switchUser(conf);
00424 
00425         // set global vars
00426         setGlobalVars(conf);
00427 
00428 #ifdef WITH_BUNDLE_SECURITY
00429         const dtn::daemon::Configuration::Security &sec = conf.getSecurity();
00430 
00431         if (sec.enabled())
00432         {
00433                 // initialize the key manager for the security extensions
00434                 dtn::security::SecurityKeyManager::getInstance().initialize( sec.getPath(), sec.getCA(), sec.getKey() );
00435         }
00436 #endif
00437 
00438         // list of components
00439         std::list< dtn::daemon::Component* > components;
00440 
00441         // create a notifier if configured
00442         try {
00443                 components.push_back( new dtn::daemon::Notifier( conf.getNotifyCommand() ) );
00444         } catch (const Configuration::ParameterNotSetException&) {
00445 
00446         }
00447 
00448         // create the bundle core object
00449         BundleCore &core = BundleCore::getInstance();
00450 
00451         // create the event switch object
00452         dtn::core::EventSwitch &esw = dtn::core::EventSwitch::getInstance();
00453 
00454         // create a storage for bundles
00455         createBundleStorage(core, conf, components);
00456 
00457         // initialize the DiscoveryAgent
00458         dtn::net::IPNDAgent *ipnd = NULL;
00459 
00460         if (conf.getDiscovery().enabled())
00461         {
00462                 // get the discovery port
00463                 int disco_port = conf.getDiscovery().port();
00464 
00465                 try {
00466                         ipnd = new dtn::net::IPNDAgent( disco_port, conf.getDiscovery().address() );
00467                 } catch (const Configuration::ParameterNotFoundException&) {
00468                         ipnd = new dtn::net::IPNDAgent( disco_port, ibrcommon::vaddress(ibrcommon::vaddress::VADDRESS_INET, "255.255.255.255") );
00469                 }
00470 
00471                 // collect all interfaces of convergence layer instances
00472                 std::set<ibrcommon::vinterface> interfaces;
00473 
00474                 const std::list<Configuration::NetConfig> &nets = conf.getNetwork().getInterfaces();
00475                 for (std::list<Configuration::NetConfig>::const_iterator iter = nets.begin(); iter != nets.end(); iter++)
00476                 {
00477                         const Configuration::NetConfig &net = (*iter);
00478                         interfaces.insert(net.interface);
00479                 }
00480 
00481                 for (std::set<ibrcommon::vinterface>::const_iterator iter = interfaces.begin(); iter != interfaces.end(); iter++)
00482                 {
00483                         // add interfaces to discovery
00484                         ipnd->bind(*iter);
00485                 }
00486 
00487                 components.push_back(ipnd);
00488         }
00489         else
00490         {
00491                 IBRCOMMON_LOGGER(info) << "Discovery disabled" << IBRCOMMON_LOGGER_ENDL;
00492         }
00493 
00494         // create the base router
00495         dtn::routing::BaseRouter *router = new dtn::routing::BaseRouter(core.getStorage());
00496 
00497         // add routing extensions
00498         switch (conf.getNetwork().getRoutingExtension())
00499         {
00500         case Configuration::FLOOD_ROUTING:
00501         {
00502                 IBRCOMMON_LOGGER(info) << "Using flooding routing extensions" << IBRCOMMON_LOGGER_ENDL;
00503                 dtn::routing::FloodRoutingExtension *flooding = new dtn::routing::FloodRoutingExtension();
00504                 router->addExtension( flooding );
00505                 break;
00506         }
00507 
00508         case Configuration::EPIDEMIC_ROUTING:
00509         {
00510                 IBRCOMMON_LOGGER(info) << "Using epidemic routing extensions" << IBRCOMMON_LOGGER_ENDL;
00511                 router->addExtension( new dtn::routing::EpidemicRoutingExtension() );
00512                 break;
00513         }
00514 
00515         default:
00516                 IBRCOMMON_LOGGER(info) << "Using default routing extensions" << IBRCOMMON_LOGGER_ENDL;
00517                 break;
00518         }
00519 
00520         // add standard routing modules
00521         router->addExtension( new dtn::routing::StaticRoutingExtension( conf.getNetwork().getStaticRoutes() ) );
00522         router->addExtension( new dtn::routing::NeighborRoutingExtension() );
00523         router->addExtension( new dtn::routing::RetransmissionExtension() );
00524 
00525         components.push_back(router);
00526 
00527         // enable or disable forwarding of bundles
00528         if (conf.getNetwork().doForwarding())
00529         {
00530                 IBRCOMMON_LOGGER(info) << "Forwarding of bundles enabled." << IBRCOMMON_LOGGER_ENDL;
00531                 BundleCore::forwarding = true;
00532         }
00533         else
00534         {
00535                 IBRCOMMON_LOGGER(info) << "Forwarding of bundles disabled." << IBRCOMMON_LOGGER_ENDL;
00536                 BundleCore::forwarding = false;
00537         }
00538 
00539         // enable netlink manager (watchdog for network interfaces)
00540         ibrcommon::LinkManager::initialize();
00541 
00542         try {
00543                 // initialize all convergence layers
00544                 createConvergenceLayers(core, conf, components, ipnd);
00545         } catch (const std::exception&) {
00546                 return -1;
00547         }
00548 
00549         if (conf.doAPI())
00550         {
00551                 try {
00552                         ibrcommon::File socket = conf.getAPISocket();
00553 
00554                         try {
00555                                 // use unix domain sockets for API
00556                                 components.push_back( new ApiServer(socket) );
00557                                 IBRCOMMON_LOGGER(info) << "API initialized using unix domain socket: " << socket.getPath() << IBRCOMMON_LOGGER_ENDL;
00558                         } catch (const ibrcommon::vsocket_exception&) {
00559                                 IBRCOMMON_LOGGER(error) << "Unable to bind to unix domain socket " << socket.getPath() << ". API not initialized!" << IBRCOMMON_LOGGER_ENDL;
00560                                 exit(-1);
00561                         }
00562 
00563                 } catch (const Configuration::ParameterNotSetException&) {
00564                         Configuration::NetConfig lo = conf.getAPIInterface();
00565 
00566                         try {
00567                                 // instance a API server, first create a socket
00568                                 components.push_back( new ApiServer(lo.interface, lo.port) );
00569                                 IBRCOMMON_LOGGER(info) << "API initialized using tcp socket: " << lo.interface.toString() << ":" << lo.port << IBRCOMMON_LOGGER_ENDL;
00570                         } catch (const ibrcommon::vsocket_exception&) {
00571                                 IBRCOMMON_LOGGER(error) << "Unable to bind to " << lo.interface.toString() << ":" << lo.port << ". API not initialized!" << IBRCOMMON_LOGGER_ENDL;
00572                                 exit(-1);
00573                         }
00574                 }
00575         }
00576         else
00577         {
00578                 IBRCOMMON_LOGGER(info) << "API disabled" << IBRCOMMON_LOGGER_ENDL;
00579         }
00580 
00581         // create a statistic logger if configured
00582         if (conf.getStatistic().enabled())
00583         {
00584                 try {
00585                         if (conf.getStatistic().type() == "stdout")
00586                         {
00587                                 components.push_back( new StatisticLogger( dtn::daemon::StatisticLogger::LOGGER_STDOUT, conf.getStatistic().interval() ) );
00588                         }
00589                         else if (conf.getStatistic().type() == "syslog")
00590                         {
00591                                 components.push_back( new StatisticLogger( dtn::daemon::StatisticLogger::LOGGER_SYSLOG, conf.getStatistic().interval() ) );
00592                         }
00593                         else if (conf.getStatistic().type() == "plain")
00594                         {
00595                                 components.push_back( new StatisticLogger( dtn::daemon::StatisticLogger::LOGGER_FILE_PLAIN, conf.getStatistic().interval(), conf.getStatistic().logfile() ) );
00596                         }
00597                         else if (conf.getStatistic().type() == "csv")
00598                         {
00599                                 components.push_back( new StatisticLogger( dtn::daemon::StatisticLogger::LOGGER_FILE_CSV, conf.getStatistic().interval(), conf.getStatistic().logfile() ) );
00600                         }
00601                         else if (conf.getStatistic().type() == "stat")
00602                         {
00603                                 components.push_back( new StatisticLogger( dtn::daemon::StatisticLogger::LOGGER_FILE_STAT, conf.getStatistic().interval(), conf.getStatistic().logfile() ) );
00604                         }
00605                         else if (conf.getStatistic().type() == "udp")
00606                         {
00607                                 components.push_back( new StatisticLogger( dtn::daemon::StatisticLogger::LOGGER_UDP, conf.getStatistic().interval(), conf.getStatistic().address(), conf.getStatistic().port() ) );
00608                         }
00609                 } catch (const Configuration::ParameterNotSetException&) {
00610                         IBRCOMMON_LOGGER(error) << "StatisticLogger: Parameter statistic_file is not set! Fallback to stdout logging." << IBRCOMMON_LOGGER_ENDL;
00611                         components.push_back( new StatisticLogger( dtn::daemon::StatisticLogger::LOGGER_STDOUT, conf.getStatistic().interval() ) );
00612                 }
00613         }
00614 
00615         // initialize core component
00616         core.initialize();
00617 
00618         // initialize the event switch
00619         esw.initialize();
00620 
00624         for (std::list< dtn::daemon::Component* >::iterator iter = components.begin(); iter != components.end(); iter++ )
00625         {
00626                 IBRCOMMON_LOGGER_DEBUG(20) << "Initialize component " << (*iter)->getName() << IBRCOMMON_LOGGER_ENDL;
00627                 (*iter)->initialize();
00628         }
00629 
00630         // run core component
00631         core.startup();
00632 
00636         for (std::list< dtn::daemon::Component* >::iterator iter = components.begin(); iter != components.end(); iter++ )
00637         {
00638                 IBRCOMMON_LOGGER_DEBUG(20) << "Startup component " << (*iter)->getName() << IBRCOMMON_LOGGER_ENDL;
00639                 (*iter)->startup();
00640         }
00641 
00642         // Debugger
00643         Debugger debugger;
00644 
00645         // add echo module
00646         EchoWorker echo;
00647 
00648         // add DevNull module
00649         DevNull devnull;
00650 
00651         // announce static nodes, create a list of static nodes
00652         list<Node> static_nodes = conf.getNetwork().getStaticNodes();
00653 
00654         for (list<Node>::iterator iter = static_nodes.begin(); iter != static_nodes.end(); iter++)
00655         {
00656                 core.addConnection(*iter);
00657         }
00658 
00659         // run the event switch loop forever
00660         esw.loop();
00661 
00662         IBRCOMMON_LOGGER(info) << "shutdown dtn node" << IBRCOMMON_LOGGER_ENDL;
00663 
00664         // send shutdown signal to unbound threads
00665         dtn::core::GlobalEvent::raise(dtn::core::GlobalEvent::GLOBAL_SHUTDOWN);
00666 
00670         for (std::list< dtn::daemon::Component* >::iterator iter = components.begin(); iter != components.end(); iter++ )
00671         {
00672                 IBRCOMMON_LOGGER_DEBUG(20) << "Terminate component " << (*iter)->getName() << IBRCOMMON_LOGGER_ENDL;
00673                 (*iter)->terminate();
00674         }
00675 
00676         // terminate event switch component
00677         esw.terminate();
00678 
00679         // terminate core component
00680         core.terminate();
00681 
00682         // delete all components
00683         for (std::list< dtn::daemon::Component* >::iterator iter = components.begin(); iter != components.end(); iter++ )
00684         {
00685                 delete (*iter);
00686         }
00687 
00688         // stop the asynchronous logger
00689         ibrcommon::Logger::stop();
00690 
00691         return 0;
00692 };

Generated on Thu Mar 10 2011 15:44:03 for IBR-DTNSuite by  doxygen 1.7.1