IBR-DTNSuite 0.6

daemon/src/routing/BaseRouter.cpp

Go to the documentation of this file.
00001 /*
00002  * BaseRouter.cpp
00003  *
00004  *  Created on: 15.02.2010
00005  *      Author: morgenro
00006  */
00007 
00008 #include "config.h"
00009 #include "routing/BaseRouter.h"
00010 #include "core/BundleCore.h"
00011 
00012 #include "net/TransferAbortedEvent.h"
00013 #include "net/TransferCompletedEvent.h"
00014 #include "net/BundleReceivedEvent.h"
00015 #include "routing/QueueBundleEvent.h"
00016 #include "routing/RequeueBundleEvent.h"
00017 #include "core/BundleStorage.h"
00018 #include "core/BundleGeneratedEvent.h"
00019 #include "core/BundleExpiredEvent.h"
00020 #include "core/BundleEvent.h"
00021 #include "core/NodeEvent.h"
00022 #include "core/TimeEvent.h"
00023 
00024 #include <ibrcommon/Logger.h>
00025 #include <ibrcommon/thread/MutexLock.h>
00026 
00027 #ifdef WITH_BUNDLE_SECURITY
00028 #include "security/SecurityManager.h"
00029 #endif
00030 
00031 namespace dtn
00032 {
00033         namespace routing
00034         {
00035                 BaseRouter *BaseRouter::Extension::_router = NULL;
00036 
00040                 BaseRouter::ThreadedExtension::ThreadedExtension()
00041                 { }
00042 
00043                 BaseRouter::ThreadedExtension::~ThreadedExtension()
00044                 {
00045                         join();
00046                 }
00047 
00051                 BaseRouter::Extension::Extension()
00052                 { }
00053 
00054                 BaseRouter::Extension::~Extension()
00055                 { }
00056 
00057                 BaseRouter& BaseRouter::Extension::operator*()
00058                 {
00059                         return *_router;
00060                 }
00061 
00068                 void BaseRouter::Extension::transferTo(const dtn::data::EID &destination, const dtn::data::BundleID &id)
00069                 {
00070                         // lock the list of neighbors
00071                         ibrcommon::MutexLock l(_router->getNeighborDB());
00072 
00073                         // get the neighbor entry for the next hop
00074                         NeighborDatabase::NeighborEntry &entry = _router->getNeighborDB().get(destination);
00075 
00076                         // transfer bundle to the neighbor
00077                         transferTo(entry, id);
00078                 }
00079 
00080                 void BaseRouter::Extension::transferTo(NeighborDatabase::NeighborEntry &entry, const dtn::data::BundleID &id)
00081                 {
00082                         // acquire the transfer of this bundle, could throw already in transit or no resource left exception
00083                         entry.acquireTransfer(id);
00084 
00085                         // transfer the bundle to the next hop
00086                         dtn::core::BundleCore::getInstance().transferTo(entry.eid, id);
00087                 }
00088 
00092                 BaseRouter::Endpoint::Endpoint()
00093                 { }
00094 
00095                 BaseRouter::Endpoint::~Endpoint()
00096                 { }
00097 
00101                 BaseRouter::VirtualEndpoint::VirtualEndpoint(dtn::data::EID name)
00102                  : _client(NULL), _name(name)
00103                 { }
00104 
00105                 BaseRouter::VirtualEndpoint::~VirtualEndpoint()
00106                 { }
00107 
00111                 BaseRouter::BaseRouter(dtn::core::BundleStorage &storage)
00112                  : _storage(storage)
00113                 {
00114                         // register myself for all extensions
00115                         Extension::_router = this;
00116                 }
00117 
00118                 BaseRouter::~BaseRouter()
00119                 {
00120                 }
00121 
00126                 void BaseRouter::addExtension(BaseRouter::Extension *extension)
00127                 {
00128                         _extensions.push_back(extension);
00129                 }
00130 
00131                 void BaseRouter::componentUp()
00132                 {
00133                         bindEvent(dtn::net::TransferAbortedEvent::className);
00134                         bindEvent(dtn::net::TransferCompletedEvent::className);
00135                         bindEvent(dtn::net::BundleReceivedEvent::className);
00136                         bindEvent(dtn::routing::QueueBundleEvent::className);
00137                         bindEvent(dtn::routing::RequeueBundleEvent::className);
00138                         bindEvent(dtn::core::NodeEvent::className);
00139                         bindEvent(dtn::core::BundleExpiredEvent::className);
00140                         bindEvent(dtn::core::TimeEvent::className);
00141                         bindEvent(dtn::core::BundleGeneratedEvent::className);
00142 
00143                         for (std::list<BaseRouter::Extension*>::iterator iter = _extensions.begin(); iter != _extensions.end(); iter++)
00144                         {
00145                                 ThreadedExtension *thread = dynamic_cast<ThreadedExtension*>(*iter);
00146 
00147                                 if (thread != NULL)
00148                                 {
00149                                         try {
00150                                                 // run the thread
00151                                                 thread->start();
00152                                         } catch (const ibrcommon::ThreadException &ex) {
00153                                                 IBRCOMMON_LOGGER(error) << "failed to start component in BaseRouter\n" << ex.what() << IBRCOMMON_LOGGER_ENDL;
00154                                         }
00155                                 }
00156                         }
00157                 }
00158 
00159                 void BaseRouter::componentDown()
00160                 {
00161                         unbindEvent(dtn::net::TransferAbortedEvent::className);
00162                         unbindEvent(dtn::net::TransferCompletedEvent::className);
00163                         unbindEvent(dtn::net::BundleReceivedEvent::className);
00164                         unbindEvent(dtn::routing::QueueBundleEvent::className);
00165                         unbindEvent(dtn::routing::RequeueBundleEvent::className);
00166                         unbindEvent(dtn::core::NodeEvent::className);
00167                         unbindEvent(dtn::core::BundleExpiredEvent::className);
00168                         unbindEvent(dtn::core::TimeEvent::className);
00169                         unbindEvent(dtn::core::BundleGeneratedEvent::className);
00170 
00171                         // delete all extensions
00172                         for (std::list<BaseRouter::Extension*>::iterator iter = _extensions.begin(); iter != _extensions.end(); iter++)
00173                         {
00174                                 ThreadedExtension *thread = dynamic_cast<ThreadedExtension*>(*iter);
00175 
00176                                 if (thread != NULL)
00177                                 {
00178                                         try {
00179                                                 // run the thread
00180                                                 thread->stop();
00181                                         } catch (const ibrcommon::ThreadException &ex) {
00182                                                 IBRCOMMON_LOGGER(error) << "failed to stop component in BaseRouter\n" << ex.what() << IBRCOMMON_LOGGER_ENDL;
00183                                         }
00184                                 }
00185 
00186                                 delete (*iter);
00187                         }
00188                 }
00189 
00193                 void BaseRouter::raiseEvent(const dtn::core::Event *evt)
00194                 {
00195                         // If a new neighbor comes available, send him a request for the summary vector
00196                         // If a neighbor went away we can free the stored database
00197                         try {
00198                                 const dtn::core::NodeEvent &event = dynamic_cast<const dtn::core::NodeEvent&>(*evt);
00199 
00200                                 if (event.getAction() == NODE_AVAILABLE)
00201                                 {
00202                                         ibrcommon::MutexLock l(_neighbor_database);
00203                                         _neighbor_database.create( event.getNode().getEID() );
00204                                 }
00205                                 else if (event.getAction() == NODE_UNAVAILABLE)
00206                                 {
00207                                         ibrcommon::MutexLock l(_neighbor_database);
00208                                         _neighbor_database.reset( event.getNode().getEID() );
00209                                 }
00210                         } catch (const std::bad_cast&) { };
00211 
00212                         try {
00213                                 const dtn::net::TransferCompletedEvent &event = dynamic_cast<const dtn::net::TransferCompletedEvent&>(*evt);
00214 
00215                                 // if a tranfer is completed, then release the transfer resource of the peer
00216                                 try {
00217                                         // lock the list of neighbors
00218                                         ibrcommon::MutexLock l(_neighbor_database);
00219                                         NeighborDatabase::NeighborEntry &entry = _neighbor_database.get(event.getPeer());
00220                                         entry.releaseTransfer(event.getBundle());
00221 
00222                                         // add the bundle to the summary vector of the neighbor
00223                                         _neighbor_database.addBundle(event.getPeer(), event.getBundle());
00224                                 } catch (const NeighborDatabase::NeighborNotAvailableException&) { };
00225 
00226                         } catch (const std::bad_cast&) { };
00227 
00228                         try {
00229                                 const dtn::net::TransferAbortedEvent &event = dynamic_cast<const dtn::net::TransferAbortedEvent&>(*evt);
00230 
00231                                 // if a tranfer is aborted, then release the transfer resource of the peer
00232                                 try {
00233                                         // lock the list of neighbors
00234                                         ibrcommon::MutexLock l(_neighbor_database);
00235                                         NeighborDatabase::NeighborEntry &entry = _neighbor_database.get(event.getPeer());
00236                                         entry.releaseTransfer(event.getBundleID());
00237 
00238                                         if (event.reason == dtn::net::TransferAbortedEvent::REASON_REFUSED)
00239                                         {
00240                                                 const dtn::data::MetaBundle meta = _storage.get(event.getBundleID());
00241 
00242                                                 // add the transferred bundle to the bloomfilter of the receiver
00243                                                 _neighbor_database.addBundle(event.getPeer(), meta);
00244                                         }
00245                                 } catch (const NeighborDatabase::NeighborNotAvailableException&) { };
00246                         } catch (const std::bad_cast&) { };
00247 
00248                         try {
00249                                 const dtn::net::BundleReceivedEvent &received = dynamic_cast<const dtn::net::BundleReceivedEvent&>(*evt);
00250 
00251                                 // drop bundles to the NULL-destination
00252                                 if (received.bundle._destination == EID("dtn:null")) return;
00253 
00254                                 // Store incoming bundles into the storage
00255                                 try {
00256                                         if (received.fromlocal)
00257                                         {
00258                                                 // store the bundle into a storage module
00259                                                 _storage.store(received.bundle);
00260 
00261                                                 // set the bundle as known
00262                                                 setKnown(received.bundle);
00263 
00264                                                 // raise the queued event to notify all receivers about the new bundle
00265                                                 QueueBundleEvent::raise(received.bundle, received.peer);
00266                                         }
00267                                         // if the bundle is not known
00268                                         else if (!isKnown(received.bundle))
00269                                         {
00270 #ifdef WITH_BUNDLE_SECURITY
00271                                                 // security methods modifies the bundle, thus we need a copy of it
00272                                                 dtn::data::Bundle bundle = received.bundle;
00273 
00274                                                 // lets see if signatures and hashes are correct and remove them if possible
00275                                                 dtn::security::SecurityManager::getInstance().verify(bundle);
00276 
00277                                                 // prevent loops
00278                                                 {
00279                                                         ibrcommon::MutexLock l(_neighbor_database);
00280 
00281                                                         // add the bundle to the summary vector of the neighbor
00282                                                         _neighbor_database.addBundle(received.peer, received.bundle);
00283                                                 }
00284 
00285                                                 // store the bundle into a storage module
00286                                                 _storage.store(bundle);
00287 #else
00288                                                 // store the bundle into a storage module
00289                                                 _storage.store(received.bundle);
00290 #endif
00291                                                 // set the bundle as known
00292                                                 setKnown(received.bundle);
00293 
00294                                                 // raise the queued event to notify all receivers about the new bundle
00295                                                 QueueBundleEvent::raise(received.bundle, received.peer);
00296                                         }
00297 
00298                                         // finally create a bundle received event
00299                                         dtn::core::BundleEvent::raise(received.bundle, dtn::core::BUNDLE_RECEIVED);
00300 #ifdef WITH_BUNDLE_SECURITY
00301                                 } catch (const dtn::security::SecurityManager::VerificationFailedException &ex) {
00302                                         IBRCOMMON_LOGGER(notice) << "Security checks failed, bundle will be dropped: " << received.bundle.toString() << IBRCOMMON_LOGGER_ENDL;
00303 #endif
00304                                 } catch (const ibrcommon::IOException &ex) {
00305                                         IBRCOMMON_LOGGER(notice) << "Unable to store bundle " << received.bundle.toString() << IBRCOMMON_LOGGER_ENDL;
00306                                 } catch (const dtn::core::BundleStorage::StorageSizeExeededException &ex) {
00307                                         IBRCOMMON_LOGGER(notice) << "No space left for bundle " << received.bundle.toString() << IBRCOMMON_LOGGER_ENDL;
00308                                 }
00309 
00310                                 return;
00311                         } catch (const std::bad_cast&) {
00312                         }
00313 
00314                         try {
00315                                 const dtn::core::BundleGeneratedEvent &generated = dynamic_cast<const dtn::core::BundleGeneratedEvent&>(*evt);
00316                                 
00317                                 // set the bundle as known
00318                                 setKnown(generated.bundle);
00319 
00320                                 // Store incoming bundles into the storage
00321                                 try {
00322                                         // store the bundle into a storage module
00323                                         _storage.store(generated.bundle);
00324 
00325                                         // raise the queued event to notify all receivers about the new bundle
00326                                         QueueBundleEvent::raise(generated.bundle, dtn::core::BundleCore::local);
00327                                 } catch (const ibrcommon::IOException &ex) {
00328                                         IBRCOMMON_LOGGER(notice) << "Unable to store bundle " << generated.bundle.toString() << IBRCOMMON_LOGGER_ENDL;
00329                                 } catch (const dtn::core::BundleStorage::StorageSizeExeededException &ex) {
00330                                         IBRCOMMON_LOGGER(notice) << "No space left for bundle " << generated.bundle.toString() << IBRCOMMON_LOGGER_ENDL;
00331                                 }
00332 
00333                                 return;
00334                         } catch (const std::bad_cast&) {
00335                         }
00336 
00337                         try {
00338                                 const dtn::core::TimeEvent &time = dynamic_cast<const dtn::core::TimeEvent&>(*evt);
00339                                 {
00340                                         ibrcommon::MutexLock l(_known_bundles_lock);
00341                                         _known_bundles.expire(time.getTimestamp());
00342                                 }
00343 
00344                                 {
00345                                         ibrcommon::MutexLock l(_neighbor_database);
00346                                         _neighbor_database.expire(time.getTimestamp());
00347                                 }
00348                         } catch (const std::bad_cast&) {
00349                         }
00350 
00351                         // notify all underlying extensions
00352                         for (std::list<BaseRouter::Extension*>::iterator iter = _extensions.begin(); iter != _extensions.end(); iter++)
00353                         {
00354                                 (*iter)->notify(evt);
00355                         }
00356                 }
00357 
00363                 dtn::data::Bundle BaseRouter::getBundle(const dtn::data::BundleID &id)
00364                 {
00365                         return _storage.get(id);
00366                 }
00367 
00368                 dtn::core::BundleStorage& BaseRouter::getStorage()
00369                 {
00370                         return _storage;
00371                 }
00372 
00373                 void BaseRouter::setKnown(const dtn::data::MetaBundle &meta)
00374                 {
00375                         ibrcommon::MutexLock l(_known_bundles_lock);
00376                         return _known_bundles.add(meta);
00377                 }
00378 
00379                 // set the bundle as known
00380                 bool BaseRouter::isKnown(const dtn::data::BundleID &id)
00381                 {
00382                         ibrcommon::MutexLock l(_known_bundles_lock);
00383                         return _known_bundles.contains(id);
00384                 }
00385 
00386                 const SummaryVector BaseRouter::getSummaryVector()
00387                 {
00388                         ibrcommon::MutexLock l(_known_bundles_lock);
00389                         return _known_bundles.getSummaryVector();
00390                 }
00391 
00392                 const std::string BaseRouter::getName() const
00393                 {
00394                         return "BaseRouter";
00395                 }
00396 
00397                 NeighborDatabase& BaseRouter::getNeighborDB()
00398                 {
00399                         return _neighbor_database;
00400                 }
00401         }
00402 }