Go to the documentation of this file.00001
00002
00003
00004
00005
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
00071 ibrcommon::MutexLock l(_router->getNeighborDB());
00072
00073
00074 NeighborDatabase::NeighborEntry &entry = _router->getNeighborDB().get(destination);
00075
00076
00077 transferTo(entry, id);
00078 }
00079
00080 void BaseRouter::Extension::transferTo(NeighborDatabase::NeighborEntry &entry, const dtn::data::BundleID &id)
00081 {
00082
00083 entry.acquireTransfer(id);
00084
00085
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
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
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
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
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
00196
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
00216 try {
00217
00218 ibrcommon::MutexLock l(_neighbor_database);
00219 NeighborDatabase::NeighborEntry &entry = _neighbor_database.get(event.getPeer());
00220 entry.releaseTransfer(event.getBundle());
00221
00222
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
00232 try {
00233
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
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
00252 if (received.bundle._destination == EID("dtn:null")) return;
00253
00254
00255 try {
00256 if (received.fromlocal)
00257 {
00258
00259 _storage.store(received.bundle);
00260
00261
00262 setKnown(received.bundle);
00263
00264
00265 QueueBundleEvent::raise(received.bundle, received.peer);
00266 }
00267
00268 else if (!isKnown(received.bundle))
00269 {
00270 #ifdef WITH_BUNDLE_SECURITY
00271
00272 dtn::data::Bundle bundle = received.bundle;
00273
00274
00275 dtn::security::SecurityManager::getInstance().verify(bundle);
00276
00277
00278 {
00279 ibrcommon::MutexLock l(_neighbor_database);
00280
00281
00282 _neighbor_database.addBundle(received.peer, received.bundle);
00283 }
00284
00285
00286 _storage.store(bundle);
00287 #else
00288
00289 _storage.store(received.bundle);
00290 #endif
00291
00292 setKnown(received.bundle);
00293
00294
00295 QueueBundleEvent::raise(received.bundle, received.peer);
00296 }
00297
00298
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
00318 setKnown(generated.bundle);
00319
00320
00321 try {
00322
00323 _storage.store(generated.bundle);
00324
00325
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
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
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 }