⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dsdvroutetable.cc

📁 COPE the first practical network coding scheme which is developped on click
💻 CC
📖 第 1 页 / 共 4 页
字号:
/* * dsdvroutetable.{cc,hh} -- DSDV routing element * Douglas S. J. De Couto * * Copyright (c) 2002 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, subject to the conditions * listed in the Click LICENSE file. These conditions include: you must * preserve this copyright notice, and you cannot mention the copyright * holders in advertising related to the Software without their permission. * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This * notice is a summary of the Click LICENSE file; the license in that file is * legally binding. */#include <click/config.h>#include <stddef.h>#include <click/confparse.hh>#include <click/error.hh>#include <clicknet/ether.h>#include <clicknet/ip.h>#include <click/standard/scheduleinfo.hh>#include <click/router.hh>#include <click/element.hh>#include <click/glue.hh>#include <click/straccum.hh>#include <click/packet_anno.hh>#include <elements/grid/dsdvroutetable.hh>#include <elements/grid/linkstat.hh>#include <elements/grid/gridgatewayinfo.hh>#include <elements/grid/timeutils.hh>#include <elements/wifi/txfeedbackstats.hh>CLICK_DECLS#define DBG  0#define DBG2 0#define DBG3 0#define FULL_DUMP_ON_TRIG_UPDATE 0#define max(a, b) ((a) > (b) ? (a) : (b))#define min(a, b) ((a) < (b) ? (a) : (b))#define dsdv_assert(e) ((e) ? (void) 0 : dsdv_assert_(__FILE__, __LINE__, #e))boolDSDVRouteTable::get_one_entry(const IPAddress &dest_ip, RouteEntry &entry){  RTEntry r;  bool res = lookup_route(dest_ip, r);  if (res)    entry = r;  return res;}boolDSDVRouteTable::lookup_route(const IPAddress &dest_ip, RTEntry &entry) {#if ENABLE_PAUSE  if (_paused) {    RTEntry *r =_snapshot_rtes.findp(dest_ip);    if (r == 0)      return false;#if USE_OLD_SEQ    if (use_old_route(dest_ip, _snapshot_jiffies))      r = _snapshot_old_rtes.findp(dest_ip);#endif    entry = *r;    return true;  }#endif  RTEntry *r = _rtes.findp(dest_ip);  if (r == 0)    return false;#if USE_OLD_SEQ  if (use_old_route(dest_ip, dsdv_jiffies()))    r = _old_rtes.findp(dest_ip);#endif  entry = *r;  return true;  }voidDSDVRouteTable::get_all_entries(Vector<RouteEntry> &vec){#if ENABLE_PAUSE  if (_paused) {    for (RTIter iter = _snapshot_rtes.begin(); iter; iter++) {      const RTEntry &rte = iter.value();#if USE_OLD_SEQ      if (use_old_route(rte.dest_ip, _snapshot_jiffies))	vec.push_back(_snapshot_old_rtes[rte.dest_ip]);      else	vec.push_back(rte);#else      vec.push_back(rte);#endif    return;    }  }#endif#if USE_OLD_SEQ  unsigned jiff = dsdv_jiffies();#endif  for (RTIter iter = _rtes.begin(); iter; iter++) {    const RTEntry &rte = iter.value();#if USE_OLD_SEQ    if (use_old_route(rte.dest_ip, jiff))      vec.push_back(_old_rtes[rte.dest_ip]);    else      vec.push_back(rte);#else    vec.push_back(rte);#endif  }}unsignedDSDVRouteTable::get_number_direct_neigbors(){  Vector<RouteEntry> v;    // delegate to avoid repeating all the pause/old seq logic  get_all_entries(v);  // assume all direct neighbors are one-hop neighbors, and count  // those instead  int num_nbrs = 0;  for (int i = 0; i < v.size(); i++)    if (v[i].num_hops() == 1 && v[i].good())      num_nbrs++;  return num_nbrs;}#if USE_OLD_SEQboolDSDVRouteTable::use_old_route(const IPAddress &dst, unsigned jiff){  if (!_use_old_route)    return false;  RTEntry *real = _rtes.findp(dst);  RTEntry *old = _old_rtes.findp(dst);#if ENABLE_PAUSE  if (_paused) {    real = _snapshot_rtes.findp(dst);    old = _snapshot_old_rtes.findp(dst);  }#endif#if USE_GOOD_NEW_ROUTES  // never use an old route if the new one is better  if (_use_good_new_route && real && old && metric_preferable(*real, *old))    return false;#endif  return    (real && real->good() &&             // if real route is bad, don't use good but old route     old && old->good() &&               // if old route is bad, don't use it     real->advertise_ok_jiffies > jiff); // if ok to advertise real route, don't use old route}#endifDSDVRouteTable::DSDVRouteTable() :   GridGenericRouteTable(1, 1),#if SEQ_METRIC  _use_seq_metric(false),#endif  _gw_info(0), _metric(0), _log(0),  _seq_no(0), _mtu(2000), _bcast_count(0),  _max_hops(3), _alpha(88), _wst0(6000),  _last_periodic_update(0),  _last_triggered_update(0),   _ignore_invalid_routes(false),  _hello_timer(static_hello_hook, this),  _log_dump_timer(static_log_dump_hook, this),  _verbose(true){}DSDVRouteTable::~DSDVRouteTable(){  for (TMIter i = _expire_timers.begin(); i; i++) {    if (i.value()->scheduled())      i.value()->unschedule();    delete i.value();  }  for (TMIter i = _trigger_timers.begin(); i; i++) {    if (i.value()->scheduled())      i.value()->unschedule();    delete i.value();  }  for (HMIter i = _expire_hooks.begin(); i; i++)     delete i.value();  for (HMIter i = _trigger_hooks.begin(); i; i++)     delete i.value();}void *DSDVRouteTable::cast(const char *n){  if (strcmp(n, "DSDVRouteTable") == 0)    return (DSDVRouteTable *) this;  else if (strcmp(n, "GridGenericRouteTable") == 0)    return (GridGenericRouteTable *) this;  else    return 0;}intDSDVRouteTable::configure(Vector<String> &conf, ErrorHandler *errh){  String logfile;  int res = cp_va_parse(conf, this, errh,			cpUnsigned, "entry timeout (msec)", &_timeout,			cpUnsigned, "route broadcast period (msec)", &_period,			cpUnsigned, "route broadcast jitter (msec)", &_jitter,			cpUnsigned, "minimum triggered update period (msec)", &_min_triggered_update_period,			cpEthernetAddress, "source Ethernet address", &_eth,			cpIPAddress, "source IP address", &_ip,			cpKeywords,			"VERBOSE", cpBool, "verbose warnings and messages?", &_verbose,			"GW", cpElement, "GridGatewayInfo element", &_gw_info,			"MAX_HOPS", cpUnsigned, "max hops", &_max_hops,			"METRIC", cpElement, "GridGenericMetric element", &_metric,			"LOG", cpElement, "GridGenericLogger element", &_log,			"WST0", cpUnsigned, "initial weight settling time, wst0 (msec)", &_wst0,			"ALPHA", cpUnsigned, "alpha parameter for settling time computation, in percent (0 <= ALPHA <= 100)", &_alpha,			"SEQ0", cpUnsigned, "initial sequence number (must be even)", &_seq_no,			"MTU", cpUnsigned, "interface MTU", &_mtu,			"IGNORE_INVALID_ROUTES", cpBool, "ignore routes with invalid metrics?", &_ignore_invalid_routes,#if SEQ_METRIC			"USE_SEQ_METRIC", cpBool, "use `dsdv_seqs' metric?", &_use_seq_metric,#endif			cpEnd);  if (res < 0)    return res;  if (_seq_no & 1)     return errh->error("initial sequence number must be even");  if (_timeout == 0)    return errh->error("timeout interval must be greater than 0");  if (_period == 0)    return errh->error("period must be greater than 0");  // _jitter is allowed to be 0  if (_jitter > _period)    return errh->error("jitter is bigger than period");  if (_max_hops == 0)    return errh->error("max hops must be greater than 0");  if (_alpha > 100)     return errh->error("alpha must be between 0 and 100 inclusive");  if (_mtu < sizeof(click_ether) + sizeof(grid_hdr) + sizeof(grid_hello))     return errh->error("mtu is too small to send a route ads");  if (_log && _log->cast("GridGenericLogger") == 0)     return errh->error("LOG element is not a GridGenericLogger");  if (_gw_info && _gw_info->cast("GridGatewayInfo") == 0)    return errh->error("GW element is not a GridGatewayInfo");  if (_metric && _metric->cast("GridGenericMetric") == 0)    return errh->error("METRIC element is not a GridGenericMetric");  if (_gw_info == 0 && _verbose)    errh->warning("No GridGatewayInfo element specified, will default to not advertising as gateway");  if (_metric == 0 && _verbose)    errh->warning("No metric elements specified, will default to minimum hop-count");#if SEQ_METRIC  if (_metric && _use_seq_metric)    errh->warning("USE_SEQ_METRIC has been specified, the specified METRIC element will be ignored");#endif  return res;}intDSDVRouteTable::initialize(ErrorHandler *){  _hello_timer.initialize(this);  _hello_timer.schedule_after_ms(_period);  _log_dump_timer.initialize(this);  _log_dump_timer.schedule_after_ms(_log_dump_period);   check_invariants();#if ENABLE_PAUSE  _paused = false;#endif#if USE_OLD_SEQ  _use_old_route = false;#if USE_GOOD_NEW_ROUTES  _use_good_new_route = false;#endif#endif#if ENABLE_SEEN  _use_seen = false;#endif  return 0;}boolDSDVRouteTable::current_gateway(RouteEntry &gw){  RTEntry best;  bool found_gateway = false;  Vector<IPAddress> gw_addrs;  RTIter i = _rtes.begin();#if ENABLE_PAUSE  if (_paused)    i = _snapshot_rtes.begin();#endif    for ( ; i; i++) {    if (i.value().is_gateway)       gw_addrs.push_back(i.value().dest_ip);  }  for (Vector<IPAddress>::const_iterator i = gw_addrs.begin(); i != gw_addrs.end(); i++) {    RTEntry r;    bool res = lookup_route(*i, r);    dsdv_assert(res);    if (r.is_gateway && r.good() && (!found_gateway || metric_preferable(r, best))) {      best = r;      found_gateway = true;    }  }  if (found_gateway) {    gw = best;  }   return found_gateway;}voidDSDVRouteTable::insert_route(const RTEntry &r, const GridGenericLogger::reason_t why){  check_invariants();  r.check();    dsdv_assert(!_ignore_invalid_routes || r.metric.good());    RTEntry *old_r = _rtes.findp(r.dest_ip);    // invariant check: running timers exist for all current good  // routes.  no timers or bogus timer entries exist for bad routes.  // hook objects exist for each timer.  Timer **old = _expire_timers.findp(r.dest_ip);  HookPair **oldhp = _expire_hooks.findp(r.dest_ip);  if (old_r && old_r->good())    dsdv_assert(old && *old && (*old)->scheduled() && oldhp && *oldhp);  else {     dsdv_assert(old == 0);    dsdv_assert(oldhp == 0);  }  // get rid of old expire timer  if (old) {    (*old)->unschedule();    delete *old;    delete *oldhp;    _expire_timers.remove(r.dest_ip);    _expire_hooks.remove(r.dest_ip);  }    // Note: ns dsdv only schedules a timeout for the sender of each  // route ad, relying on the next-hop expiry logic to get all routes  // via that next hop.  However, that won't work for general metrics,  // so we install a timeout for *every* newly installed good route.  if (r.good()) {    HookPair *hp = new HookPair(this, r.dest_ip);    Timer *t = new Timer(static_expire_hook, (void *) hp);    t->initialize(this);    t->schedule_after_ms(min(r.ttl, _timeout));        _expire_timers.insert(r.dest_ip, t);    _expire_hooks.insert(r.dest_ip, hp);  }#if USE_OLD_SEQ  // if we are getting new seqno, save route for old seqno  if (old_r && old_r->seq_no() < r.seq_no())     _old_rtes.insert(r.dest_ip, *old_r);#endif  _rtes.insert(r.dest_ip, r);  // note, we don't change any pending triggered update for this  // updated dest.  ... but shouldn't we postpone it?  -- shouldn't  // matter if timer fires too early, since the advertise_ok_jiffies  // should tell us it's too early.  if (_log)    _log->log_added_route(why, make_generic_rte(r), (unsigned int) r.wst);  check_invariants();}voidDSDVRouteTable::expire_hook(const IPAddress &ip){  check_invariants(&ip);  // invariant check:  // 1. route to expire should exist  RTEntry *r = _rtes.findp(ip);  dsdv_assert(r != 0);    // 2. route to expire should be good  dsdv_assert(r->good() && (r->seq_no() & 1) == 0);    // 3. the expire timer for this dest should exist, but should not be  // running.  Timer **old = _expire_timers.findp(ip);  HookPair **oldhp = _expire_hooks.findp(ip);  dsdv_assert(old && *old && !(*old)->scheduled() && oldhp && *oldhp);  if (_log) {    _log->log_start_expire_handler(Timestamp::now());    _log->log_expired_route(GridGenericLogger::TIMEOUT, ip);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -