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 <stdlib.h>
00022
00023 #include "BundleRouter.h"
00024 #include "bundling/BundleDaemon.h"
00025 #include "bundling/BundleActions.h"
00026 #include "bundling/BundleList.h"
00027 #include "storage/BundleStore.h"
00028
00029 #include "StaticBundleRouter.h"
00030 #include "FloodBundleRouter.h"
00031 #include "ProphetRouter.h"
00032 #include "DTLSRRouter.h"
00033 #include "ExternalRouter.h"
00034 #include "TcaRouter.h"
00035
00036 namespace dtn {
00037
00038
00039 BundleRouter::Config::Config()
00040 : type_("static"),
00041 add_nexthop_routes_(true),
00042 open_discovered_links_(true),
00043 default_priority_(0),
00044 max_route_to_chain_(10),
00045 storage_quota_(0),
00046 subscription_timeout_(600)
00047 {}
00048
00049 BundleRouter::Config BundleRouter::config_;
00050
00051
00052 BundleRouter*
00053 BundleRouter::create_router(const char* type)
00054 {
00055 if (strcmp(type, "static") == 0) {
00056 return new StaticBundleRouter();
00057 }
00058 else if (strcmp(type, "prophet") == 0) {
00059 return new ProphetRouter();
00060 }
00061 else if (strcmp(type, "flood") == 0) {
00062 return new FloodBundleRouter();
00063 }
00064 else if (strcmp(type, "dtlsr") == 0) {
00065 return new DTLSRRouter();
00066 }
00067 else if (!strcmp(type, "tca_router")) {
00068 return new TcaRouter(TcaRouter::TCA_ROUTER);
00069 }
00070 else if (!strcmp(type, "tca_gateway")) {
00071 return new TcaRouter(TcaRouter::TCA_GATEWAY);
00072 }
00073 #if defined(XERCES_C_ENABLED) && defined(EXTERNAL_DP_ENABLED)
00074 else if (strcmp(type, "external") == 0) {
00075 return new ExternalRouter();
00076 }
00077 #endif
00078 else {
00079 PANIC("unknown type %s for router", type);
00080 }
00081 }
00082
00083
00084 BundleRouter::BundleRouter(const char* classname, const std::string& name)
00085 : BundleEventHandler(classname, "/dtn/route"),
00086 name_(name)
00087 {
00088 logpathf("/dtn/route/%s", name.c_str());
00089
00090 actions_ = BundleDaemon::instance()->actions();
00091
00092
00093 pending_bundles_ = BundleDaemon::instance()->pending_bundles();
00094 custody_bundles_ = BundleDaemon::instance()->custody_bundles();
00095 }
00096
00097
00098 bool
00099 BundleRouter::should_fwd(const Bundle* bundle, const LinkRef& link,
00100 ForwardingInfo::action_t action)
00101 {
00102 ForwardingInfo info;
00103 bool found = bundle->fwdlog()->get_latest_entry(link, &info);
00104
00105 if (found) {
00106 ASSERT(info.state() != ForwardingInfo::NONE);
00107 } else {
00108 ASSERT(info.state() == ForwardingInfo::NONE);
00109 }
00110
00111
00112
00113 if (info.state() == ForwardingInfo::TRANSMITTED ||
00114 info.state() == ForwardingInfo::QUEUED)
00115 {
00116 log_debug("should_fwd bundle %d: "
00117 "skip %s due to forwarding log entry %s",
00118 bundle->bundleid(), link->name(),
00119 ForwardingInfo::state_to_str(info.state()));
00120 return false;
00121 }
00122
00123
00124
00125 if (link->remote_eid() != EndpointID::NULL_EID())
00126 {
00127 size_t count = bundle->fwdlog()->get_count(
00128 link->remote_eid(),
00129 ForwardingInfo::TRANSMITTED | ForwardingInfo::QUEUED);
00130
00131 if (count > 0)
00132 {
00133 log_debug("should_fwd bundle %d: "
00134 "skip %s since already sent or queued %zu times for remote eid %s",
00135 bundle->bundleid(), link->name(),
00136 count, link->remote_eid().c_str());
00137 return false;
00138 }
00139
00140
00141
00142
00143 count = bundle->fwdlog()->get_count(
00144 link->remote_eid(),
00145 ForwardingInfo::SUPPRESSED);
00146
00147 if (count > 0)
00148 {
00149 log_debug("should_fwd bundle %d: "
00150 "skip %s since transmission suppressed to remote eid %s",
00151 bundle->bundleid(), link->name(),
00152 link->remote_eid().c_str());
00153 return false;
00154 }
00155 }
00156
00157
00158
00159
00160 if (bundle->singleton_dest() && action == ForwardingInfo::FORWARD_ACTION)
00161 {
00162 size_t count = bundle->fwdlog()->get_count(
00163 ForwardingInfo::TRANSMITTED |
00164 ForwardingInfo::QUEUED,
00165 action);
00166
00167 if (count > 0) {
00168 log_debug("should_fwd bundle %d: "
00169 "skip %s since already transmitted or queued (count %zu)",
00170 bundle->bundleid(), link->name(), count);
00171 return false;
00172 } else {
00173 log_debug("should_fwd bundle %d: "
00174 "link %s ok since transmission count=%zu",
00175 bundle->bundleid(), link->name(), count);
00176 }
00177 }
00178
00179
00180 log_debug("should_fwd bundle %d: "
00181 "match %s: forwarding log entry %s",
00182 bundle->bundleid(), link->name(),
00183 ForwardingInfo::state_to_str(info.state()));
00184
00185 return true;
00186 }
00187
00188
00189 void
00190 BundleRouter::initialize()
00191 {
00192 }
00193
00194
00195 BundleRouter::~BundleRouter()
00196 {
00197 }
00198
00199
00200 bool
00201 BundleRouter::accept_bundle(Bundle* bundle, int* errp)
00202 {
00203
00204
00205
00206 BundleStore* bs = BundleStore::instance();
00207 if (bs->payload_quota() != 0 &&
00208 (bs->total_size() + bundle->payload().length() > bs->payload_quota()))
00209 {
00210 log_info("accept_bundle: rejecting bundle *%p since "
00211 "cur size %llu + bundle size %zu > quota %llu",
00212 bundle, U64FMT(bs->total_size()), bundle->payload().length(),
00213 U64FMT(bs->payload_quota()));
00214 *errp = BundleProtocol::REASON_DEPLETED_STORAGE;
00215 return false;
00216 }
00217
00218 *errp = 0;
00219 return true;
00220 }
00221
00222
00223 bool
00224 BundleRouter::can_delete_bundle(const BundleRef& bundle)
00225 {
00226 size_t num_mappings = bundle->num_mappings();
00227 if (num_mappings > 1) {
00228 log_debug("can_delete_bundle(*%p): not deleting because "
00229 "bundle has %zu list mappings",
00230 bundle.object(), num_mappings);
00231 return false;
00232 }
00233
00234 return true;
00235 }
00236
00237
00238 void
00239 BundleRouter::delete_bundle(const BundleRef& bundle)
00240 {
00241 (void)bundle;
00242 }
00243
00244
00245 void
00246 BundleRouter::tcl_dump_state(oasys::StringBuffer* buf)
00247 {
00248 buf->append("{}");
00249 }
00250
00251
00252 void
00253 BundleRouter::recompute_routes()
00254 {
00255 }
00256
00257
00258 void
00259 BundleRouter::shutdown()
00260 {
00261 }
00262
00263 }