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

📄 srquerier.cc

📁 COPE the first practical network coding scheme which is developped on click
💻 CC
字号:
/* * SRQuerier.{cc,hh} -- DSR implementation * John Bicket * * Copyright (c) 1999-2001 Massachussrcrs 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 "srquerier.hh"#include <click/ipaddress.hh>#include <click/confparse.hh>#include <click/error.hh>#include <click/glue.hh>#include "linkmetric.hh"#include <click/straccum.hh>#include <clicknet/ether.h>#include "srpacket.hh"#include "srforwarder.hh"CLICK_DECLSSRQuerier::SRQuerier()  :  Element(1,2),     _en(),     _sr_forwarder(0),     _link_table(0){  // Pick a starting sequence number that we have not used before.  struct timeval tv;  click_gettimeofday(&tv);  _seq = tv.tv_usec;  _query_wait = Timestamp(5, 0);  static unsigned char bcast_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };  _bcast = EtherAddress(bcast_addr);}SRQuerier::~SRQuerier(){}intSRQuerier::configure (Vector<String> &conf, ErrorHandler *errh){  int ret;  _debug = false;  _route_dampening = true;  _time_before_switch_sec = 10;  ret = cp_va_parse(conf, this, errh,                    cpKeywords,		    "ETH", cpEtherAddress, "EtherAddress", &_en,		    "SR", cpElement, "SRForwarder element", &_sr_forwarder,		    "LT", cpElement, "LinkTable element", &_link_table,		    /* below not required */		    "DEBUG", cpBool, "Debug", &_debug,		    "ROUTE_DAMPENING", cpBool, "Enable Route Dampening", &_route_dampening,		    "TIME_BEFORE_SWITCH", cpUnsigned, "", &_time_before_switch_sec,                    cpEnd);  if (!_en)     return errh->error("ETH not specified");  if (!_link_table)     return errh->error("LT not specified");  if (!_sr_forwarder)     return errh->error("SR not specified");  if (_sr_forwarder->cast("SRForwarder") == 0)     return errh->error("SRQuerier element is not a SRQuerier");  if (_link_table->cast("LinkTable") == 0)     return errh->error("LinkTable element is not a LinkTable");  return ret;}intSRQuerier::initialize (ErrorHandler *){  return 0;}voidSRQuerier::send_query(IPAddress dst){  DstInfo *nfo = _queries.findp(dst);  if (!nfo) {    _queries.insert(dst, DstInfo(dst));    nfo = _queries.findp(dst);  }  nfo->_last_query.set_now();  nfo->_count++;  WritablePacket *p = Packet::make((unsigned)0);  p->set_dst_ip_anno(dst);  output(1).push(p);}voidSRQuerier::push(int, Packet *p_in){  bool sent_packet = false;  IPAddress dst = p_in->dst_ip_anno();    if (!dst) {    click_chatter("%{element}: got invalid dst %s\n",		  this,		  dst.s().cc());    p_in->kill();    return;  }  sr_assert(dst);  Path best = _link_table->best_route(dst, true);  bool best_valid = _link_table->valid_route(best);  int best_metric = _link_table->get_route_metric(best);    bool do_query = false;  DstInfo *q = _queries.findp(dst);  if (!q) {    DstInfo foo = DstInfo(dst);    _queries.insert(dst, foo);    q = _queries.findp(dst);    q->_best_metric = 0;    do_query = true;  }  sr_assert(q);  if (best_valid) {    if (!q->_p.size()) {      q->_p = best;      q->_last_switch = q->_first_selected = Timestamp::now();    }    bool current_path_valid = _link_table->valid_route(q->_p);    int current_path_metric = _link_table->get_route_metric(q->_p);        Timestamp now = Timestamp::now();    Timestamp expire = q->_last_switch + Timestamp(_time_before_switch_sec, 0);        if (!_route_dampening ||	!current_path_valid || 	current_path_metric > 100 + best_metric ||	expire < now) {      if (q->_p != best) {	q->_first_selected = now;      }      q->_p = best;      q->_last_switch = now;    }    p_in = _sr_forwarder->encap(p_in, q->_p, 0);    if (p_in) {      output(0).push(p_in);    }    sent_packet = true;  } else {    /* no valid route, don't send. */    click_chatter("%{element} :: %s no valid route to %s\n",		  this,		  __func__,		  dst.s().cc());    p_in->kill();  }    if (!best_valid) {    do_query = true;  } else {      if (!q->_best_metric) {      q->_best_metric = best_metric;    }        if (q->_best_metric < best_metric) {      q->_best_metric = best_metric;    }        if (sent_packet && 	q->_best_metric * 2 < best_metric) {      /*        * send another query if the route got crappy       */      q->_best_metric = best_metric;      do_query = true;    }  }    if (do_query) {    Timestamp expire = q->_last_query + _query_wait;    if (expire < Timestamp::now()) {      send_query(dst);    }  }  return;    }enum {H_DEBUG, H_PATH_CACHE, H_RESET, H_QUERIES, H_QUERY};static String read_param(Element *e, void *thunk){  SRQuerier *td = (SRQuerier *)e;    switch ((uintptr_t) thunk) {      case H_DEBUG:	return String(td->_debug) + "\n";    case H_QUERIES: {        StringAccum sa;	Timestamp now = Timestamp::now();	for (SRQuerier::DstTable::const_iterator iter = td->_queries.begin(); iter; iter++) {	  SRQuerier::DstInfo dst = iter.value();	  sa << dst._ip;	  sa << " query_count " << dst._count;	  sa << " best_metric " << dst._best_metric;	  sa << " last_query_ago " << now - dst._last_query;	  sa << " first_selected_ago " << now - dst._first_selected;	  sa << " last_switch_ago " << now - dst._last_switch;	  int current_path_metric = td->_link_table->get_route_metric(dst._p);	  sa << " current_path_metric " << current_path_metric;	  sa << " [ ";	  sa << path_to_string(dst._p);	  sa << " ]";	  Path best = td->_link_table->best_route(dst._ip, true);	  int best_metric = td->_link_table->get_route_metric(best);	  sa << " best_metric " << best_metric;	  sa << " best_route [ ";	  sa << path_to_string(best);	  sa << " ]";	  sa << "\n";	}	return sa.take_string();    }    default:      return String();    }}static int write_param(const String &in_s, Element *e, void *vparam,		      ErrorHandler *errh){  SRQuerier *f = (SRQuerier *)e;  String s = cp_uncomment(in_s);  switch((int)vparam) {  case H_DEBUG: {    //debug    bool debug;    if (!cp_bool(s, &debug))       return errh->error("debug parameter must be boolean");    f->_debug = debug;    break;  }  case H_QUERY: {    //    IPAddress dst;    if (!cp_ip_address(s, &dst))       return errh->error("query parameter must be IPAddress");    f->send_query(dst);    break;  }  case H_RESET:    f->_queries.clear();    break;  }  return 0;}voidSRQuerier::add_handlers(){  add_read_handler("queries", read_param, (void *) H_QUERIES);  add_read_handler("debug", read_param, (void *) H_DEBUG);  add_write_handler("debug", write_param, (void *) H_DEBUG);  add_write_handler("reset", write_param, (void *) H_RESET);  add_write_handler("query", write_param, (void *) H_QUERY);}// generate Vector template instance#include <click/vector.cc>#include <click/hashmap.cc>#include <click/dequeue.cc>#if EXPLICIT_TEMPLATE_INSTANCEStemplate class Vector<SRQuerier::IPAddress>;template class DEQueue<SRQuerier::Seen>;#endifCLICK_ENDDECLSEXPORT_ELEMENT(SRQuerier)

⌨️ 快捷键说明

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