|
IBR-DTNSuite 0.6
|
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 "net/ConnectionEvent.h" 00016 #include "routing/QueueBundleEvent.h" 00017 #include "routing/RequeueBundleEvent.h" 00018 #include "core/BundleStorage.h" 00019 #include "core/BundleGeneratedEvent.h" 00020 #include "core/BundleExpiredEvent.h" 00021 #include "core/BundleEvent.h" 00022 #include "core/NodeEvent.h" 00023 #include "core/TimeEvent.h" 00024 00025 #include <ibrcommon/Logger.h> 00026 #include <ibrcommon/thread/MutexLock.h> 00027 00028 #ifdef WITH_BUNDLE_SECURITY 00029 #include "security/SecurityManager.h" 00030 #endif 00031 00032 namespace dtn 00033 { 00034 namespace routing 00035 { 00036 BaseRouter *BaseRouter::Extension::_router = NULL; 00037 00041 BaseRouter::ThreadedExtension::ThreadedExtension() 00042 { } 00043 00044 BaseRouter::ThreadedExtension::~ThreadedExtension() 00045 { 00046 join(); 00047 } 00048 00052 BaseRouter::Extension::Extension() 00053 { } 00054 00055 BaseRouter::Extension::~Extension() 00056 { } 00057 00058 BaseRouter& BaseRouter::Extension::operator*() 00059 { 00060 return *_router; 00061 } 00062 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 bindEvent(dtn::net::ConnectionEvent::className); 00143 00144 for (std::list<BaseRouter::Extension*>::iterator iter = _extensions.begin(); iter != _extensions.end(); iter++) 00145 { 00146 ThreadedExtension *thread = dynamic_cast<ThreadedExtension*>(*iter); 00147 00148 if (thread != NULL) 00149 { 00150 try { 00151 // run the thread 00152 thread->start(); 00153 } catch (const ibrcommon::ThreadException &ex) { 00154 IBRCOMMON_LOGGER(error) << "failed to start component in BaseRouter\n" << ex.what() << IBRCOMMON_LOGGER_ENDL; 00155 } 00156 } 00157 } 00158 } 00159 00160 void BaseRouter::componentDown() 00161 { 00162 unbindEvent(dtn::net::TransferAbortedEvent::className); 00163 unbindEvent(dtn::net::TransferCompletedEvent::className); 00164 unbindEvent(dtn::net::BundleReceivedEvent::className); 00165 unbindEvent(dtn::routing::QueueBundleEvent::className); 00166 unbindEvent(dtn::routing::RequeueBundleEvent::className); 00167 unbindEvent(dtn::core::NodeEvent::className); 00168 unbindEvent(dtn::core::BundleExpiredEvent::className); 00169 unbindEvent(dtn::core::TimeEvent::className); 00170 unbindEvent(dtn::core::BundleGeneratedEvent::className); 00171 unbindEvent(dtn::net::ConnectionEvent::className); 00172 00173 // delete all extensions 00174 for (std::list<BaseRouter::Extension*>::iterator iter = _extensions.begin(); iter != _extensions.end(); iter++) 00175 { 00176 ThreadedExtension *thread = dynamic_cast<ThreadedExtension*>(*iter); 00177 00178 if (thread != NULL) 00179 { 00180 try { 00181 // run the thread 00182 thread->stop(); 00183 } catch (const ibrcommon::ThreadException &ex) { 00184 IBRCOMMON_LOGGER(error) << "failed to stop component in BaseRouter\n" << ex.what() << IBRCOMMON_LOGGER_ENDL; 00185 } 00186 } 00187 00188 delete (*iter); 00189 } 00190 } 00191 00195 void BaseRouter::raiseEvent(const dtn::core::Event *evt) 00196 { 00197 // If a new neighbor comes available, send him a request for the summary vector 00198 // If a neighbor went away we can free the stored database 00199 try { 00200 const dtn::core::NodeEvent &event = dynamic_cast<const dtn::core::NodeEvent&>(*evt); 00201 00202 if (event.getAction() == NODE_AVAILABLE) 00203 { 00204 ibrcommon::MutexLock l(_neighbor_database); 00205 _neighbor_database.create( event.getNode().getEID() ); 00206 } 00207 else if (event.getAction() == NODE_UNAVAILABLE) 00208 { 00209 ibrcommon::MutexLock l(_neighbor_database); 00210 _neighbor_database.reset( event.getNode().getEID() ); 00211 } 00212 } catch (const std::bad_cast&) { }; 00213 00214 try { 00215 const dtn::net::TransferCompletedEvent &event = dynamic_cast<const dtn::net::TransferCompletedEvent&>(*evt); 00216 00217 // if a tranfer is completed, then release the transfer resource of the peer 00218 try { 00219 // lock the list of neighbors 00220 ibrcommon::MutexLock l(_neighbor_database); 00221 NeighborDatabase::NeighborEntry &entry = _neighbor_database.get(event.getPeer()); 00222 entry.releaseTransfer(event.getBundle()); 00223 00224 // add the bundle to the summary vector of the neighbor 00225 _neighbor_database.addBundle(event.getPeer(), event.getBundle()); 00226 } catch (const NeighborDatabase::NeighborNotAvailableException&) { }; 00227 00228 } catch (const std::bad_cast&) { }; 00229 00230 try { 00231 const dtn::net::TransferAbortedEvent &event = dynamic_cast<const dtn::net::TransferAbortedEvent&>(*evt); 00232 00233 // if a tranfer is aborted, then release the transfer resource of the peer 00234 try { 00235 // lock the list of neighbors 00236 ibrcommon::MutexLock l(_neighbor_database); 00237 NeighborDatabase::NeighborEntry &entry = _neighbor_database.get(event.getPeer()); 00238 entry.releaseTransfer(event.getBundleID()); 00239 00240 if (event.reason == dtn::net::TransferAbortedEvent::REASON_REFUSED) 00241 { 00242 const dtn::data::MetaBundle meta = _storage.get(event.getBundleID()); 00243 00244 // add the transferred bundle to the bloomfilter of the receiver 00245 _neighbor_database.addBundle(event.getPeer(), meta); 00246 } 00247 } catch (const NeighborDatabase::NeighborNotAvailableException&) { }; 00248 } catch (const std::bad_cast&) { }; 00249 00250 try { 00251 const dtn::net::BundleReceivedEvent &received = dynamic_cast<const dtn::net::BundleReceivedEvent&>(*evt); 00252 00253 // drop bundles to the NULL-destination 00254 if (received.bundle._destination == EID("dtn:null")) return; 00255 00256 // Store incoming bundles into the storage 00257 try { 00258 if (received.fromlocal) 00259 { 00260 // store the bundle into a storage module 00261 _storage.store(received.bundle); 00262 00263 // set the bundle as known 00264 setKnown(received.bundle); 00265 00266 // raise the queued event to notify all receivers about the new bundle 00267 QueueBundleEvent::raise(received.bundle, received.peer); 00268 } 00269 // if the bundle is not known 00270 else if (!isKnown(received.bundle)) 00271 { 00272 #ifdef WITH_BUNDLE_SECURITY 00273 // security methods modifies the bundle, thus we need a copy of it 00274 dtn::data::Bundle bundle = received.bundle; 00275 00276 // lets see if signatures and hashes are correct and remove them if possible 00277 dtn::security::SecurityManager::getInstance().verify(bundle); 00278 00279 // prevent loops 00280 { 00281 ibrcommon::MutexLock l(_neighbor_database); 00282 00283 // add the bundle to the summary vector of the neighbor 00284 _neighbor_database.addBundle(received.peer, received.bundle); 00285 } 00286 00287 // store the bundle into a storage module 00288 _storage.store(bundle); 00289 #else 00290 // store the bundle into a storage module 00291 _storage.store(received.bundle); 00292 #endif 00293 // set the bundle as known 00294 setKnown(received.bundle); 00295 00296 // raise the queued event to notify all receivers about the new bundle 00297 QueueBundleEvent::raise(received.bundle, received.peer); 00298 } 00299 00300 // finally create a bundle received event 00301 dtn::core::BundleEvent::raise(received.bundle, dtn::core::BUNDLE_RECEIVED); 00302 #ifdef WITH_BUNDLE_SECURITY 00303 } catch (const dtn::security::SecurityManager::VerificationFailedException &ex) { 00304 IBRCOMMON_LOGGER(notice) << "Security checks failed, bundle will be dropped: " << received.bundle.toString() << IBRCOMMON_LOGGER_ENDL; 00305 #endif 00306 } catch (const ibrcommon::IOException &ex) { 00307 IBRCOMMON_LOGGER(notice) << "Unable to store bundle " << received.bundle.toString() << IBRCOMMON_LOGGER_ENDL; 00308 } catch (const dtn::core::BundleStorage::StorageSizeExeededException &ex) { 00309 IBRCOMMON_LOGGER(notice) << "No space left for bundle " << received.bundle.toString() << IBRCOMMON_LOGGER_ENDL; 00310 } 00311 00312 return; 00313 } catch (const std::bad_cast&) { 00314 } 00315 00316 try { 00317 const dtn::core::BundleGeneratedEvent &generated = dynamic_cast<const dtn::core::BundleGeneratedEvent&>(*evt); 00318 00319 // set the bundle as known 00320 setKnown(generated.bundle); 00321 00322 // Store incoming bundles into the storage 00323 try { 00324 // store the bundle into a storage module 00325 _storage.store(generated.bundle); 00326 00327 // raise the queued event to notify all receivers about the new bundle 00328 QueueBundleEvent::raise(generated.bundle, dtn::core::BundleCore::local); 00329 } catch (const ibrcommon::IOException &ex) { 00330 IBRCOMMON_LOGGER(notice) << "Unable to store bundle " << generated.bundle.toString() << IBRCOMMON_LOGGER_ENDL; 00331 } catch (const dtn::core::BundleStorage::StorageSizeExeededException &ex) { 00332 IBRCOMMON_LOGGER(notice) << "No space left for bundle " << generated.bundle.toString() << IBRCOMMON_LOGGER_ENDL; 00333 } 00334 00335 return; 00336 } catch (const std::bad_cast&) { 00337 } 00338 00339 try { 00340 const dtn::core::TimeEvent &time = dynamic_cast<const dtn::core::TimeEvent&>(*evt); 00341 { 00342 ibrcommon::MutexLock l(_known_bundles_lock); 00343 _known_bundles.expire(time.getTimestamp()); 00344 } 00345 00346 { 00347 ibrcommon::MutexLock l(_neighbor_database); 00348 _neighbor_database.expire(time.getTimestamp()); 00349 } 00350 } catch (const std::bad_cast&) { 00351 } 00352 00353 // notify all underlying extensions 00354 for (std::list<BaseRouter::Extension*>::iterator iter = _extensions.begin(); iter != _extensions.end(); iter++) 00355 { 00356 (*iter)->notify(evt); 00357 } 00358 } 00359 00365 dtn::data::Bundle BaseRouter::getBundle(const dtn::data::BundleID &id) 00366 { 00367 return _storage.get(id); 00368 } 00369 00370 dtn::core::BundleStorage& BaseRouter::getStorage() 00371 { 00372 return _storage; 00373 } 00374 00375 void BaseRouter::setKnown(const dtn::data::MetaBundle &meta) 00376 { 00377 ibrcommon::MutexLock l(_known_bundles_lock); 00378 return _known_bundles.add(meta); 00379 } 00380 00381 // set the bundle as known 00382 bool BaseRouter::isKnown(const dtn::data::BundleID &id) 00383 { 00384 ibrcommon::MutexLock l(_known_bundles_lock); 00385 return _known_bundles.contains(id); 00386 } 00387 00388 const SummaryVector BaseRouter::getSummaryVector() 00389 { 00390 ibrcommon::MutexLock l(_known_bundles_lock); 00391 return _known_bundles.getSummaryVector(); 00392 } 00393 00394 const std::string BaseRouter::getName() const 00395 { 00396 return "BaseRouter"; 00397 } 00398 00399 NeighborDatabase& BaseRouter::getNeighborDB() 00400 { 00401 return _neighbor_database; 00402 } 00403 } 00404 }