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

Generated on Thu Nov 11 2010 09:49:47 for IBR-DTNSuite by  doxygen 1.7.1