00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <oasys/util/OptParser.h>
00019 #include <oasys/util/StringBuffer.h>
00020 #include "BundleRouter.h"
00021 #include "RouteEntry.h"
00022 #include "contacts/Link.h"
00023 #include "naming/EndpointIDOpt.h"
00024
00025 namespace dtn {
00026
00027
00028 RouteEntry::RouteEntry(const EndpointIDPattern& dest_pattern, Link* link)
00029 : dest_pattern_(dest_pattern),
00030 source_pattern_(EndpointID::WILDCARD_EID()),
00031 bundle_cos_((1 << Bundle::COS_BULK) |
00032 (1 << Bundle::COS_NORMAL) |
00033 (1 << Bundle::COS_EXPEDITED)),
00034 route_priority_(0),
00035 next_hop_(link),
00036 action_(ForwardingInfo::FORWARD_ACTION),
00037 custody_timeout_(),
00038 info_(NULL)
00039 {
00040 route_priority_ = BundleRouter::config_.default_priority_;
00041 }
00042
00043
00044 RouteEntry::~RouteEntry()
00045 {
00046 if (info_)
00047 delete info_;
00048 }
00049
00050
00051 int
00052 RouteEntry::parse_options(int argc, const char** argv, const char** invalidp)
00053 {
00054 int num = custody_timeout_.parse_options(argc, argv, invalidp);
00055 if (num == -1) {
00056 return -1;
00057 }
00058
00059 argc -= num;
00060
00061 oasys::OptParser p;
00062
00063 p.addopt(new EndpointIDOpt("source_eid", &source_pattern_));
00064 p.addopt(new oasys::UIntOpt("route_priority", &route_priority_));
00065 p.addopt(new oasys::UIntOpt("cos_flags", &bundle_cos_));
00066 oasys::EnumOpt::Case fwdopts[] = {
00067 {"forward", ForwardingInfo::FORWARD_ACTION},
00068 {"copy", ForwardingInfo::COPY_ACTION},
00069 {0, 0}
00070 };
00071 p.addopt(new oasys::EnumOpt("action", fwdopts, &action_));
00072
00073 int num2 = p.parse_and_shift(argc, argv, invalidp);
00074 if (num2 == -1) {
00075 return -1;
00076 }
00077
00078 if ((bundle_cos_ == 0) || (bundle_cos_ >= (1 << 3))) {
00079 static const char* s = "invalid cos flags";
00080 invalidp = &s;
00081 return -1;
00082 }
00083
00084 return num + num2;
00085 }
00086
00087
00088 int
00089 RouteEntry::format(char* bp, size_t sz) const
00090 {
00091
00092
00093 return snprintf(bp, sz, "%s -> %s (%s)",
00094 dest_pattern_.c_str(),
00095 next_hop_->nexthop(),
00096 ForwardingInfo::action_to_str(
00097 static_cast<ForwardingInfo::action_t>(action_)));
00098 }
00099
00100
00101 void
00102 RouteEntry::dump_header(oasys::StringBuffer* buf)
00103 {
00104
00105
00106
00107
00108 buf->appendf("%-15s %-10s %3s %-13s %-7s %5s [%-15s]\n"
00109 "%-15s %-10s %3s %-13s %-7s %5s [%-5s %-3s %-5s]\n"
00110 "-----------------------------------"
00111 "-------------------------------------------\n",
00112 "destination",
00113 " source",
00114 "COS",
00115 "link",
00116 " fwd ",
00117 "route",
00118 "custody timeout",
00119 " endpoint",
00120 "endpoint",
00121 "BNE",
00122 "name",
00123 "action",
00124 "prio",
00125 "min",
00126 "pct",
00127 " max");
00128 }
00129
00130
00131 void
00132 RouteEntry::dump(oasys::StringBuffer* buf, EndpointIDVector* long_eids) const
00133 {
00134 size_t len;
00135 if (dest_pattern_.length() <= 15) {
00136 buf->appendf("%-15s ", dest_pattern_.c_str());
00137 } else {
00138 len = buf->appendf("[%zu]", long_eids->size());
00139 buf->appendf("%.*s", 16 - (int)len, " ");
00140 long_eids->push_back(dest_pattern_);
00141 }
00142
00143 if (source_pattern_.length() <= 10) {
00144 buf->appendf("%-10s ", source_pattern_.c_str());
00145 } else {
00146 len = buf->appendf("[%zu]", long_eids->size());
00147 buf->appendf("%.*s", 11 - (int)len, " ");
00148 long_eids->push_back(source_pattern_);
00149 }
00150
00151 buf->appendf("%c%c%c -> %-13.13s %7s %5d [%-5d %3d %5d]\n",
00152 (bundle_cos_ & (1 << Bundle::COS_BULK)) ? '1' : '0',
00153 (bundle_cos_ & (1 << Bundle::COS_NORMAL)) ? '1' : '0',
00154 (bundle_cos_ & (1 << Bundle::COS_EXPEDITED)) ? '1' : '0',
00155 next_hop_->name(),
00156 ForwardingInfo::action_to_str(
00157 static_cast<ForwardingInfo::action_t>(action_)),
00158 route_priority_,
00159 custody_timeout_.min_,
00160 custody_timeout_.lifetime_pct_,
00161 custody_timeout_.max_);
00162 }
00163
00164
00165 void
00166 RouteEntry::serialize(oasys::SerializeAction *a)
00167 {
00168 a->process("dest_pattern", &dest_pattern_);
00169 a->process("source_pattern", &source_pattern_);
00170 a->process("route_priority", &route_priority_);
00171 a->process("action", &action_);
00172 a->process("link", const_cast<std::string *>(&next_hop_->name_str()));
00173 }
00174
00175
00179 struct RoutePriorityGT {
00180 bool operator() (RouteEntry* a, RouteEntry* b) {
00181 if (a->route_priority_ == b->route_priority_)
00182 {
00183 return (a->next_hop_->stats()->bytes_queued_ <
00184 b->next_hop_->stats()->bytes_queued_);
00185 }
00186
00187 return a->route_priority_ > b->route_priority_;
00188 }
00189 };
00190
00191
00192 void
00193 RouteEntryVec::sort_by_priority()
00194 {
00195 std::sort(begin(), end(), RoutePriorityGT());
00196 }
00197
00198 }