00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifdef HAVE_CONFIG_H
00018 # include <dtn-config.h>
00019 #endif
00020
00021 #include "bundling/BundleProtocol.h"
00022 #include "bundling/BundleDaemon.h"
00023 #include <oasys/thread/Lock.h>
00024
00025 #include "prophet/QueuePolicy.h"
00026 #include "ProphetRouter.h"
00027
00028 namespace dtn
00029 {
00030
00031 void prophet_router_shutdown(void*)
00032 {
00033 BundleDaemon::instance()->router()->shutdown();
00034 }
00035
00036 prophet::ProphetParams ProphetRouter::params_;
00037
00038 bool ProphetRouter::is_init_ = false;
00039
00040 ProphetRouter::ProphetRouter()
00041 : BundleRouter("ProphetRouter","prophet"),
00042 core_(NULL), oracle_(NULL),
00043 lock_(new oasys::SpinLock("ProphetRouter"))
00044 {
00045 }
00046
00047 ProphetRouter::~ProphetRouter()
00048 {
00049 delete oracle_;
00050 delete core_;
00051 delete lock_;
00052 }
00053
00054 void
00055 ProphetRouter::initialize()
00056 {
00057 ASSERT( is_init_ == false );
00058
00059
00060
00061 std::string local_eid(BundleDaemon::instance()->local_eid().str());
00062
00063 core_ = new ProphetBundleCore(local_eid,actions_,lock_);
00064 oracle_ = new prophet::Controller(core_,core_->bundles(),¶ms_);
00065
00066
00067 BundleDaemon::instance()->set_rtr_shutdown(
00068 prophet_router_shutdown, (void *) 0);
00069
00070
00071 core_->load_prophet_nodes(oracle_->nodes(),¶ms_);
00072
00073 is_init_ = true;
00074 log_info("ProphetRouter initialization complete");
00075 }
00076
00077 void
00078 ProphetRouter::shutdown()
00079 {
00080 log_info("ProphetRouter shutdown");
00081 oasys::ScopeLock l(lock_, "shutdown");
00082 oracle_->shutdown();
00083 core_->shutdown();
00084 }
00085
00086 void
00087 ProphetRouter::handle_event(BundleEvent* e)
00088 {
00089 dispatch_event(e);
00090 }
00091
00092 void
00093 ProphetRouter::get_routing_state(oasys::StringBuffer* buf)
00094 {
00095 log_info("ProphetRouter get_routing_state");
00096 oasys::ScopeLock l(lock_, "get_routing_state");
00097
00098
00099 buf->appendf("ProphetRouter:\n"
00100 " %zu routes, %zu queued bundles, %zu ACKs, %zu active sessions\n",
00101 oracle_->nodes()->size(),
00102 core_->bundles()->size(),
00103 oracle_->acks()->size(),
00104 oracle_->size());
00105
00106 buf->appendf("Active Sessions\n");
00107 for (prophet::Controller::List::const_iterator i = oracle_->begin();
00108 i != oracle_->end(); i++)
00109 {
00110 buf->appendf(" %4d: %-30s %s timeout %u\n",
00111 (*i)->local_instance(),
00112 (*i)->nexthop()->remote_eid(),
00113 (*i)->state_str(),
00114 (*i)->time_remaining());
00115 }
00116 buf->appendf("Routes\n");
00117 for (prophet::Table::const_iterator i = oracle_->nodes()->begin();
00118 i != oracle_->nodes()->end(); i++)
00119 {
00120 buf->appendf(" %-30s: %.2f %s%s%s %lu s old\n",
00121 i->second->dest_id(), i->second->p_value(),
00122 i->second->relay() ? "R" : " ",
00123 i->second->custody() ? "C" : " ",
00124 i->second->internet_gw() ? "I" : " ",
00125 (time(0) - i->second->age()));
00126 }
00127 buf->appendf("\n R - relay C - custody I - internet gateway \n\n");
00128
00129
00130 buf->appendf("Bundles:\n");
00131 prophet::BundleList bundles = core_->bundles()->get_bundles();
00132 for (prophet::BundleList::iterator i = bundles.begin();
00133 i != bundles.end(); i++)
00134 {
00135 buf->appendf("%s -> %s (%u:%u)\n",
00136 (*i)->source_id().c_str(),
00137 (*i)->destination_id().c_str(),
00138 (*i)->creation_ts(),
00139 (*i)->sequence_num());
00140 }
00141 }
00142
00143 bool
00144 ProphetRouter::accept_bundle(Bundle* bundle, int* errp)
00145 {
00146 log_info("ProphetRouter accept_bundle");
00147
00148
00149 if (!BundleRouter::accept_bundle(bundle,errp))
00150 {
00151 log_debug("BundleRouter rejects *%p",bundle);
00152 return false;
00153 }
00154
00155 BundleRef tmp("accept_bundle");
00156 tmp = bundle;
00157
00158 oasys::ScopeLock l(lock_, "accept_bundle");
00159
00160 const prophet::Bundle* b = core_->get_temp_bundle(tmp);
00161 if (errp != NULL) errp = (int) BundleProtocol::REASON_NO_ADDTL_INFO;
00162
00163 bool ok = oracle_->accept_bundle(b);
00164
00165 delete b;
00166 log_debug("do%saccept bundle *%p", ok ? " " : " not ", bundle);
00167 return ok;
00168 }
00169
00170 void
00171 ProphetRouter::handle_bundle_received(BundleReceivedEvent* e)
00172 {
00173 log_info("ProphetRouter handle_bundle_received");
00174
00175
00176 if (e->source_ == EVENTSRC_STORE)
00177 return;
00178
00179 const prophet::Link* l = NULL;
00180
00181 oasys::ScopeLock sl(lock_, "handle_bundle_received");
00182 if (e->source_ != EVENTSRC_APP)
00183 {
00184
00185
00186
00187 ASSERT(e->link_ != NULL);
00188
00189
00190 core_->add(e->link_);
00191
00192
00193 l = core_->get_link(e->link_.object());
00194
00195 if (l == NULL) return;
00196 }
00197
00198
00199 const prophet::Bundle* b = core_->get_temp_bundle(e->bundleref_);
00200
00201 if (b == NULL)
00202 {
00203 log_err("failed to retrieve prophet handle for *%p",
00204 e->bundleref_.object());
00205 return;
00206 }
00207
00208 core_->bundles_.add(b);
00209
00210
00211 oracle_->handle_bundle_received(b,l);
00212 }
00213
00214 void
00215 ProphetRouter::handle_bundle_delivered(BundleDeliveredEvent* e)
00216 {
00217 log_info("ProphetRouter handle_bundle_delivered");
00218 oasys::ScopeLock l(lock_, "handle_bundle_delivered");
00219
00220 Bundle* bundle = e->bundleref_.object();
00221 if (bundle == NULL) return;
00222
00223
00224 const prophet::Bundle* b = core_->get_bundle(bundle);
00225 if (b == NULL)
00226 {
00227 log_err("Failed to convert *%p to prophet object",bundle);
00228 return;
00229 }
00230
00231 oracle_->ack(b);
00232 }
00233
00234 void
00235 ProphetRouter::handle_bundle_expired(BundleExpiredEvent* e)
00236 {
00237 log_info("ProphetRouter handle_bundle_expired");
00238 oasys::ScopeLock l(lock_, "handle_bundle_expired");
00239
00240 const prophet::Bundle* b = NULL;
00241 Bundle* bundle = e->bundleref_.object();
00242 if (bundle != NULL && ((b = core_->get_bundle(bundle)) != NULL))
00243 {
00244
00245 oracle_->stats()->drop_bundle(b);
00246 }
00247
00248 core_->del(e->bundleref_);
00249 }
00250
00251 void
00252 ProphetRouter::handle_bundle_transmitted(BundleTransmittedEvent* e)
00253 {
00254 const prophet::Bundle* bundle = core_->get_bundle(e->bundleref_.object());
00255 const prophet::Link* link = core_->get_link(e->link_.object());
00256 if (bundle != NULL && link != NULL)
00257 oracle_->handle_bundle_transmitted(bundle,link);
00258 }
00259
00260 void
00261 ProphetRouter::handle_contact_up(ContactUpEvent* e)
00262 {
00263 log_info("ProphetRouter handle_contact_up");
00264 oasys::ScopeLock lk(lock_, "handle_contact_up");
00265
00266 Link* link = e->contact_->link().object();
00267 if (link == NULL) return;
00268
00269
00270 core_->add(e->contact_->link());
00271
00272 const prophet::Link* l = core_->get_link(link);
00273 if (l == NULL) return;
00274
00275 oracle_->new_neighbor(l);
00276 }
00277
00278 void
00279 ProphetRouter::handle_contact_down(ContactDownEvent* e)
00280 {
00281 log_info("ProphetRouter handle_contact_down");
00282 oasys::ScopeLock lk(lock_, "handle_contact_down");
00283
00284 Link* link = e->contact_->link().object();
00285
00286
00287 const prophet::Link* l = NULL;
00288 if (link != NULL &&
00289 (l = core_->get_link(e->contact_->link().object())) != NULL)
00290
00291 oracle_->neighbor_gone(l);
00292
00293 core_->del(e->contact_->link());
00294 }
00295
00296 void
00297 ProphetRouter::handle_link_available(LinkAvailableEvent* e)
00298 {
00299 LinkRef next_hop = e->link_;
00300 ASSERT(next_hop != NULL);
00301 ASSERT(!next_hop->isdeleted());
00302
00303
00304
00305
00306 if (!next_hop->isopen())
00307 {
00308
00309 actions_->open_link(next_hop);
00310 }
00311 }
00312
00313 void
00314 ProphetRouter::set_queue_policy()
00315 {
00316 log_info("ProphetRouter set_queue_policy");
00317 oasys::ScopeLock l(lock_, "set_queue_policy");
00318
00319
00320 oracle_->set_queue_policy();
00321 }
00322
00323 void
00324 ProphetRouter::set_hello_interval()
00325 {
00326 log_info("ProphetRouter set_hello_interval");
00327 oasys::ScopeLock l(lock_, "set_hello_interval");
00328
00329
00330 oracle_->set_hello_interval();
00331 }
00332
00333 void
00334 ProphetRouter::set_max_route()
00335 {
00336 log_info("ProphetRouter set_max_route");
00337 oasys::ScopeLock l(lock_, "set_max_route");
00338
00339
00340 oracle_->set_max_route();
00341 }
00342
00343 };