Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008 #include "routing/StaticRoutingExtension.h"
00009 #include "routing/QueueBundleEvent.h"
00010 #include "net/TransferAbortedEvent.h"
00011 #include "net/TransferCompletedEvent.h"
00012 #include "routing/RequeueBundleEvent.h"
00013 #include "core/NodeEvent.h"
00014 #include "core/SimpleBundleStorage.h"
00015
00016 #include <ibrcommon/Logger.h>
00017 #include <ibrcommon/AutoDelete.h>
00018
00019 #include <typeinfo>
00020
00021 namespace dtn
00022 {
00023 namespace routing
00024 {
00025 StaticRoutingExtension::StaticRoutingExtension(const std::list<StaticRoutingExtension::StaticRoute> &routes)
00026 : _routes(routes)
00027 {
00028 }
00029
00030 StaticRoutingExtension::~StaticRoutingExtension()
00031 {
00032 stop();
00033 join();
00034 }
00035
00036 void StaticRoutingExtension::stopExtension()
00037 {
00038 _taskqueue.abort();
00039 }
00040
00041 bool StaticRoutingExtension::__cancellation()
00042 {
00043 _taskqueue.abort();
00044 return true;
00045 }
00046
00047 void StaticRoutingExtension::run()
00048 {
00049 class BundleFilter : public dtn::core::BundleStorage::BundleFilterCallback
00050 {
00051 public:
00052 BundleFilter(const NeighborDatabase::NeighborEntry &entry, const std::list<StaticRoutingExtension::StaticRoute> &routes)
00053 : _entry(entry), _routes(routes)
00054 {};
00055
00056 virtual ~BundleFilter() {};
00057
00058 virtual size_t limit() const { return 10; };
00059
00060 virtual bool shouldAdd(const dtn::data::MetaBundle &meta) const
00061 {
00062
00063 const dtn::data::EID dest = meta.destination.getNodeEID();
00064 if (_blacklist.find(dest) != _blacklist.end())
00065 {
00066 return false;
00067 }
00068
00069
00070 if (_entry.has(meta))
00071 {
00072 return false;
00073 }
00074
00075
00076 for (std::list<StaticRoutingExtension::StaticRoute>::const_iterator iter = _routes.begin();
00077 iter != _routes.end(); iter++)
00078 {
00079 const StaticRoutingExtension::StaticRoute &route = (*iter);
00080
00081 if (route.match(meta.destination))
00082 {
00083 return true;
00084 }
00085 }
00086
00087 return false;
00088 };
00089
00090 void blacklist(const dtn::data::EID& id)
00091 {
00092 _blacklist.insert(id);
00093 };
00094
00095 private:
00096 std::set<dtn::data::EID> _blacklist;
00097 const NeighborDatabase::NeighborEntry &_entry;
00098 const std::list<StaticRoutingExtension::StaticRoute> _routes;
00099 };
00100
00101 dtn::core::BundleStorage &storage = (**this).getStorage();
00102
00103 while (true)
00104 {
00105 NeighborDatabase &db = (**this).getNeighborDB();
00106
00107 try {
00108 Task *t = _taskqueue.getnpop(true);
00109 ibrcommon::AutoDelete<Task> killer(t);
00110
00111 IBRCOMMON_LOGGER_DEBUG(5) << "processing static routing task " << t->toString() << IBRCOMMON_LOGGER_ENDL;
00112
00113 try {
00114 SearchNextBundleTask &task = dynamic_cast<SearchNextBundleTask&>(*t);
00115
00116 std::list<StaticRoutingExtension::StaticRoute> routes;
00117
00118
00119 for (std::list<StaticRoutingExtension::StaticRoute>::const_iterator iter = _routes.begin();
00120 iter != _routes.end(); iter++)
00121 {
00122 const StaticRoutingExtension::StaticRoute &route = (*iter);
00123 if (route.getDestination() == task.eid)
00124 {
00125
00126 routes.push_back(route);
00127 }
00128 }
00129
00130 if (routes.size() > 0)
00131 {
00132
00133 ibrcommon::MutexLock l(db);
00134 NeighborDatabase::NeighborEntry &entry = db.get(task.eid);
00135
00136
00137 BundleFilter filter(entry, routes);
00138
00139
00140 IBRCOMMON_LOGGER_DEBUG(40) << "search some bundles not known by " << task.eid.getString() << IBRCOMMON_LOGGER_ENDL;
00141
00142
00143 filter.blacklist(task.eid);
00144
00145
00146 const std::list<dtn::data::MetaBundle> list = storage.get(filter);
00147
00148
00149 for (std::list<dtn::data::MetaBundle>::const_iterator iter = list.begin(); iter != list.end(); iter++)
00150 {
00151 try {
00152
00153 transferTo(entry, *iter);
00154 } catch (const NeighborDatabase::AlreadyInTransitException&) { };
00155 }
00156 }
00157 } catch (const NeighborDatabase::NoMoreTransfersAvailable&) {
00158 } catch (const NeighborDatabase::NeighborNotAvailableException&) {
00159 } catch (const std::bad_cast&) { };
00160
00161 try {
00162 const ProcessBundleTask &task = dynamic_cast<ProcessBundleTask&>(*t);
00163
00164
00165 for (std::list<StaticRoutingExtension::StaticRoute>::const_iterator iter = _routes.begin();
00166 iter != _routes.end(); iter++)
00167 {
00168 const StaticRoutingExtension::StaticRoute &route = (*iter);
00169 try {
00170 if (route.match(task.bundle.destination))
00171 {
00172 ibrcommon::MutexLock l(db);
00173 NeighborDatabase::NeighborEntry &n = db.get(route.getDestination());
00174
00175
00176 transferTo(n, task.bundle);
00177 }
00178 } catch (const NeighborDatabase::NeighborNotAvailableException&) {
00179
00180 } catch (const NeighborDatabase::NoMoreTransfersAvailable&) {
00181 } catch (const NeighborDatabase::AlreadyInTransitException&) { };
00182 }
00183 } catch (const std::bad_cast&) { };
00184
00185 } catch (const std::exception &ex) {
00186 IBRCOMMON_LOGGER_DEBUG(20) << "static routing failed: " << ex.what() << IBRCOMMON_LOGGER_ENDL;
00187 return;
00188 }
00189
00190 yield();
00191 }
00192 }
00193
00194 void StaticRoutingExtension::notify(const dtn::core::Event *evt)
00195 {
00196 try {
00197 const QueueBundleEvent &queued = dynamic_cast<const QueueBundleEvent&>(*evt);
00198 _taskqueue.push( new ProcessBundleTask(queued.bundle, queued.origin) );
00199 return;
00200 } catch (const std::bad_cast&) { };
00201
00202 try {
00203 const dtn::core::NodeEvent &nodeevent = dynamic_cast<const dtn::core::NodeEvent&>(*evt);
00204 const dtn::core::Node &n = nodeevent.getNode();
00205
00206 if (nodeevent.getAction() == NODE_AVAILABLE)
00207 {
00208 _taskqueue.push( new SearchNextBundleTask(n.getEID()) );
00209 }
00210 return;
00211 } catch (const std::bad_cast&) { };
00212
00213
00214 try {
00215 const dtn::net::TransferAbortedEvent &aborted = dynamic_cast<const dtn::net::TransferAbortedEvent&>(*evt);
00216 _taskqueue.push( new SearchNextBundleTask(aborted.getPeer()) );
00217 return;
00218 } catch (const std::bad_cast&) { };
00219
00220
00221 try {
00222 const dtn::net::TransferCompletedEvent &completed = dynamic_cast<const dtn::net::TransferCompletedEvent&>(*evt);
00223 _taskqueue.push( new SearchNextBundleTask(completed.getPeer()) );
00224 return;
00225 } catch (const std::bad_cast&) { };
00226 }
00227
00228 StaticRoutingExtension::StaticRoute::StaticRoute(const std::string ®ex, const std::string &dest)
00229 : _dest(dest), _regex_str(regex), _invalid(false)
00230 {
00231 if ( regcomp(&_regex, regex.c_str(), 0) )
00232 {
00233 IBRCOMMON_LOGGER(error) << "Could not compile regex: " << regex << IBRCOMMON_LOGGER_ENDL;
00234 _invalid = true;
00235 }
00236 }
00237
00238 StaticRoutingExtension::StaticRoute::~StaticRoute()
00239 {
00240 if (!_invalid)
00241 regfree(&_regex);
00242 }
00243
00244 StaticRoutingExtension::StaticRoute::StaticRoute(const StaticRoutingExtension::StaticRoute &obj)
00245 : _dest(obj._dest), _regex_str(obj._regex_str), _invalid(obj._invalid)
00246 {
00247 if ( regcomp(&_regex, _regex_str.c_str(), 0) )
00248 {
00249 _invalid = true;
00250 }
00251 }
00252
00253 StaticRoutingExtension::StaticRoute& StaticRoutingExtension::StaticRoute::operator=(const StaticRoutingExtension::StaticRoute &obj)
00254 {
00255 if (!_invalid)
00256 {
00257 regfree(&_regex);
00258 }
00259
00260 _dest = obj._dest;
00261 _regex_str = obj._regex_str;
00262 _invalid = obj._invalid;
00263
00264 if (!_invalid)
00265 {
00266 if ( regcomp(&_regex, obj._regex_str.c_str(), 0) )
00267 {
00268 IBRCOMMON_LOGGER(error) << "Could not compile regex: " << _regex_str << IBRCOMMON_LOGGER_ENDL;
00269 _invalid = true;
00270 }
00271 }
00272
00273 return *this;
00274 }
00275
00276 bool StaticRoutingExtension::StaticRoute::match(const dtn::data::EID &eid) const
00277 {
00278 if (_invalid) return false;
00279
00280 const std::string dest = eid.getString();
00281
00282
00283 int reti = regexec(&_regex, dest.c_str(), 0, NULL, 0);
00284
00285 if( !reti )
00286 {
00287
00288 return true;
00289 }
00290 else if( reti == REG_NOMATCH )
00291 {
00292
00293 return false;
00294 }
00295 else
00296 {
00297 char msgbuf[100];
00298 regerror(reti, &_regex, msgbuf, sizeof(msgbuf));
00299 IBRCOMMON_LOGGER(error) << "Regex match failed: " << std::string(msgbuf) << IBRCOMMON_LOGGER_ENDL;
00300 return false;
00301 }
00302 }
00303
00304 const dtn::data::EID& StaticRoutingExtension::StaticRoute::getDestination() const
00305 {
00306 return _dest;
00307 }
00308
00309
00310
00311 StaticRoutingExtension::SearchNextBundleTask::SearchNextBundleTask(const dtn::data::EID &e)
00312 : eid(e)
00313 { }
00314
00315 StaticRoutingExtension::SearchNextBundleTask::~SearchNextBundleTask()
00316 { }
00317
00318 std::string StaticRoutingExtension::SearchNextBundleTask::toString()
00319 {
00320 return "SearchNextBundleTask: " + eid.getString();
00321 }
00322
00323
00324
00325 StaticRoutingExtension::ProcessBundleTask::ProcessBundleTask(const dtn::data::MetaBundle &meta, const dtn::data::EID &o)
00326 : bundle(meta), origin(o)
00327 { }
00328
00329 StaticRoutingExtension::ProcessBundleTask::~ProcessBundleTask()
00330 { }
00331
00332 std::string StaticRoutingExtension::ProcessBundleTask::toString()
00333 {
00334 return "ProcessBundleTask: " + bundle.toString();
00335 }
00336 }
00337 }