|
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 "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 }