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

📄 dsragent.cc

📁 CBRP协议(移动adhoc中基于分簇的路由协议)ns2下的源码
💻 CC
📖 第 1 页 / 共 4 页
字号:
/*    dsragent.cc   requires a radio model such that sendPacket returns true   iff the packet is recieved by the destination node.   $Id: dsragent.cc,v 1.47 1998/08/06 20:43:42 dmaltz Exp $*/extern "C" {#include <assert.h>#include <math.h>#include <stdio.h>#include <signal.h>#include <float.h>}#include <object.h>#include <agent.h>#include <trace.h>#include <packet.h>#include <scheduler.h>#include <random.h>#include <cmu/mac.h>#include <cmu/ll.h>#include <cmu/cmu-trace.h>#include "path.h"#include "srpacket.h"#include "routecache.h"#include "requesttable.h"#include "dsragent.h"/*==============================================================  Declarations and global defintions------------------------------------------------------------*/static const int verbose = 0;static const int verbose_srr = 0;DSRAgent_List DSRAgent::agthead = { 0 };Time arp_timeout = 30.0e-3;	// (sec) arp request timeoutTime rt_rq_period = 0.5;	// (sec) length of one backoff periodTime rt_rq_max_period = 10.0;	// (sec) maximum time between rt reqs#if 0/* used in route reply holdoffs, which are currently disabled -dam 5/98 */static const int tapped_pkts = 0;Time rt_rep_holdoff_period = 3.0e-3; // secs (about 2*process_time)// to determine how long to sit on our rt reply we pick a number// U(O.0,rt_rep_holdoff_period) + (our route length-1)*rt_rep_holdoff#endif 0Time grat_hold_down_time = 1.0;	// (sec) min time between grat replies for				// same routeTime max_err_hold = 1.0;        // (sec) // maximum time between when we recv a route error told to us, and when we// transmit a propagating route request that can carry that data.  used to// keep us from propagating stale route error data/*************** selectors ******************/bool dsragent_snoop_forwarded_errors = true;// give errors we forward to our cache?bool dsragent_snoop_source_routes = true;// should we snoop on any source routes we see?bool dsragent_reply_only_to_first_rtreq = false;// should we only respond to the first route request we receive from a host?bool dsragent_propagate_last_error = true;// should we take the data from the last route error msg sent to us// and propagate it around on the next propagating route request we do?// this is aka grat route error propagationbool dsragent_send_grat_replies = true;// should we send gratuitous replies to effect route shortening?bool dsragent_salvage_with_cache = true;// should we consult our cache for a route if we get a xmitfailure// and salvage the packet using the route if possiblebool dsragent_use_tap = true;// should we listen to a promiscuous tap?bool dsragent_reply_from_cache_on_propagating = true;// should we consult the route cache before propagating rt req's and// answer if possible?bool dsragent_ring_zero_search = true;// should we send a non-propagating route request as the first action// in each route discovery action?// NOTE: to completely turn off replying from cache, you should// set both dsragent_ring_zero_search and // dsragent_reply_from_cache_on_propagating to falsebool dsragent_dont_salvage_bad_replies = true;// if we have an xmit failure on a packet, and the packet contains a // route reply, should we scan the reply to see if contains the dead link?// if it does, we won't salvage the packet unless there's something aside// from a reply in it (in which case we salvage, but cut out the rt reply)bool dsragent_require_bi_routes = true;// do we need to have bidirectional source routes? // [XXX this flag doesn't control all the behaviors and code that assume// bidirectional links -dam 5/14/98]#if 0bool lsnode_holdoff_rt_reply = true;// if we have a cached route to reply to route_request with, should we// hold off and not send it for a while?bool lsnode_require_use = true;// do we require ourselves to hear a route requestor use a route// before we withold our route, or is merely hearing another (better)// route reply enough?#endif/*Our strategy is as follows: - it's only worth discovering bidirectional routes, since all data paths will have to have to be bidirectional for 802.11 ACKs to work - reply to all route requests for us that we recv (not just the first one) but reply to them by reversing the route and unicasting.  don't do a route request (since that will end up returning the requestor lots of routes that are potentially unidirectional). By reversing the discovered  route for the route reply, only routes that are bidirectional will make it back the original requestor - once a packet goes into the sendbuffer, it can't be piggybacked on a  route request.  the code assumes that the only thing that removes packets from the send buff is the StickPktIn routine, or the route reply arrives routine*//*===========================================================================  SendBuf management and helpers---------------------------------------------------------------------------*/voidSendBufferTimer::expire(Event *e) {   a_->sendBufferCheck();   resched(BUFFER_CHECK + BUFFER_CHECK * (double) ((int) e>>5 & 0xff) / 256.0);}voidDSRAgent::dropSendBuff(SRPacket &p)  // log p as being dropped by the sendbuffer in DSR agent{  trace("Ssb %.5f _%s_ dropped %s -> %s", Scheduler::instance().clock(), 	net_id.dump(), p.src.dump(), p.dest.dump());  drop(p.pkt, DROP_RTR_QTIMEOUT);  p.pkt = 0;  p.route.reset();}voidDSRAgent::stickPacketInSendBuffer(SRPacket& p){  Time min = DBL_MAX;  int min_index = 0;  int c;  if (verbose)    trace("Sdebug %.5f _%s_ stuck into send buff %s -> %s",	  Scheduler::instance().clock(), 	  net_id.dump(), p.src.dump(), p.dest.dump());  for (c = 0 ; c < SEND_BUF_SIZE ; c ++)    if (send_buf[c].p.pkt == NULL)      {	send_buf[c].t = Scheduler::instance().clock();	send_buf[c].p = p;	return;      }    else if (send_buf[c].t < min)      {	min = send_buf[c].t;	min_index = c;      }    // kill somebody  dropSendBuff(send_buf[min_index].p);  send_buf[min_index].t = Scheduler::instance().clock();  send_buf[min_index].p = p;}voidDSRAgent::sendBufferCheck()  // see if any packets in send buffer need route requests sent out  // for them, or need to be expired{ // this is called about once a second.  run everybody through the  // get route for pkt routine to see if it's time to do another   // route request or what not  int c;  for (c  = 0 ; c <SEND_BUF_SIZE ; c++)    {      if (send_buf[c].p.pkt == NULL) continue;      if (Scheduler::instance().clock() - send_buf[c].t > SEND_TIMEOUT)	{	  	  dropSendBuff(send_buf[c].p);	  send_buf[c].p.pkt = 0;	  continue;	}#ifdef DEBUG      trace("Sdebug %.5f _%s_ checking for route for dst %s",	    Scheduler::instance().clock(), net_id.dump(), 	    send_buf[c].p.dest.dump());#endif      handlePktWithoutSR(send_buf[c].p, true);#ifdef DEBUG      if (send_buf[c].p.pkt == NULL) 	trace("Sdebug %.5f _%s_ sendbuf pkt to %s liberated by handlePktWOSR",	    Scheduler::instance().clock(), net_id.dump(), 	    send_buf[c].p.dest.dump());#endif    }}/*==============================================================  Route Request backoff------------------------------------------------------------*/static boolBackOffTest(Entry *e, Time time)// look at the entry and decide if we can send another route// request or not.  update entry as well{  Time next = ((Time) (0x1<<(e->rt_reqs_outstanding*2))) * rt_rq_period;  if (next > rt_rq_max_period) next = rt_rq_max_period;  if (next + e->last_rt_req > time) return false;  // don't let rt_reqs_outstanding overflow next on the LogicalShiftsLeft's  if (e->rt_reqs_outstanding < 15) e->rt_reqs_outstanding++;  e->last_rt_req = time;  return true;}/*===========================================================================  DSRAgent OTcl linkage---------------------------------------------------------------------------*/static class DSRAgentClass : public TclClass {public:  DSRAgentClass() : TclClass("Agent/DSRAgent") {}  TclObject* create(int, const char*const*) {    return (new DSRAgent);  }} class_DSRAgent;/*===========================================================================  DSRAgent methods---------------------------------------------------------------------------*/DSRAgent::DSRAgent(): request_table(128), route_cache(NULL), Agent(PT_DSR),  send_buf_timer(this){  int c;  route_request_num = 1;  route_cache = makeRouteCache();  for (c = 0 ; c < RTREP_HOLDOFF_SIZE ; c++)    rtrep_holdoff[c].requested_dest = invalid_addr;  num_heldoff_rt_replies = 0;  target_ = 0;  logtarget = 0;  grat_hold_victim = 0;  for (c = 0; c < RTREP_HOLDOFF_SIZE ; c++)    grat_hold[c].p.reset();  bind("off_SR_", &off_sr_);  bind("off_ll_", &off_ll_);  bind("off_mac_", &off_mac_);  bind("off_ip_", &off_ip_);  //Jinyang initiate stat countes  tapped_pkts = 0;  total_pkts = 0;  LIST_INSERT_HEAD(&agthead, this, link);  route_error_held = false;  }DSRAgent::~DSRAgent(){  fprintf(stderr,"DFU: Don't do this! I haven't figured out ~DSRAgent\n");  exit(-1);}voidDSRAgent::Terminate(){	int c;	for (c  = 0 ; c < SEND_BUF_SIZE ; c++) {		if (send_buf[c].p.pkt) {			drop(send_buf[c].p.pkt, DROP_END_OF_SIMULATION);			send_buf[c].p.pkt = 0;		}	}}//Jinyang a helper function for me to print out stats at sim endvoidDSRAgent::simend(){  printf("%d\n", tapped_pkts);  printf("%d\n\n", total_pkts);}  voidDSRAgent::testinit(){  struct hdr_sr hsr;    if (net_id == ID(1,::IP))    {      printf("adding route to 1\n");      hsr.init();      hsr.append_addr( 1, AF_INET );      hsr.append_addr( 2, AF_INET );      hsr.append_addr( 3, AF_INET );      hsr.append_addr( 4, AF_INET );            route_cache->addRoute(Path(hsr.addrs, hsr.num_addrs()), 0.0, ID(1,::IP));    }    if (net_id == ID(3,::IP))    {      printf("adding route to 3\n");      hsr.init();      hsr.append_addr( 3, AF_INET );      hsr.append_addr( 2, AF_INET );      hsr.append_addr( 1, AF_INET );            route_cache->addRoute(Path(hsr.addrs, hsr.num_addrs()), 0.0, ID(3,::IP));    }}intDSRAgent::command(int argc, const char*const* argv){  TclObject *obj;    if (argc == 2)     {        if (strcasecmp(argv[1], "simend") == 0)	{	  simend();	  return TCL_OK;	}      if (strcasecmp(argv[1], "testinit") == 0)	{	  testinit();	  return TCL_OK;	}      if (strcasecmp(argv[1], "reset") == 0)	{	  Terminate();	  return Agent::command(argc, argv);	}      if (strcasecmp(argv[1], "check-cache") == 0)	{	  return route_cache->command(argc, argv);	}      if (strcasecmp(argv[1], "startdsr") == 0)	{	  if (ID(1,::IP) == net_id) 	    { // log the configuration parameters of the dsragent  trace("Sconfig %.5f tap: %s snoop: rts? %s errs? %s",		    Scheduler::instance().clock(),		    dsragent_use_tap ? "on" : "off",		    dsragent_snoop_source_routes ? "on" : "off",		    dsragent_snoop_forwarded_errors ? "on" : "off");  trace("Sconfig %.5f salvage: %s !bd replies? %s",		    Scheduler::instance().clock(),		    dsragent_salvage_with_cache ? "on" : "off",		    dsragent_dont_salvage_bad_replies ? "on" : "off");  trace("Sconfig %.5f grat error: %s grat reply: %s",	            Scheduler::instance().clock(),	            dsragent_propagate_last_error ? "on" : "off",	            dsragent_send_grat_replies ? "on" : "off");  trace("Sconfig %.5f $reply for props: %s ring 0 search: %s",	            Scheduler::instance().clock(),	            dsragent_reply_from_cache_on_propagating ? "on" : "off",	            dsragent_ring_zero_search ? "on" : "off");	    }	  // cheap source of jitter	  send_buf_timer.sched(BUFFER_CHECK 			       + BUFFER_CHECK * Random::uniform(1.0));	            return route_cache->command(argc,argv);	}    }  else if(argc == 3)     {      if (strcasecmp(argv[1], "ip-addr") == 0) 	{	 net_id = ID(atoi(argv[2]), ::IP);	 route_cache->net_id = net_id;	 return TCL_OK;	}       else if(strcasecmp(argv[1], "mac-addr") == 0) 	{	  MAC_id = ID(atoi(argv[2]), ::MAC);	  route_cache->MAC_id = MAC_id;	  return TCL_OK;	}            if( (obj = TclObject::lookup(argv[2])) == 0) 	{	  fprintf(stderr, "DSRAgent: %s lookup of %s failed\n", argv[1],		  argv[2]);	  return TCL_ERROR;	}      if (strcasecmp(argv[1], "log-target") == 0) 	{	  logtarget = (Trace*) obj;	  return route_cache->command(argc, argv);	}      else if (strcasecmp(argv[1], "install-tap") == 0) 	{	  Mac *m = (Mac*) obj;	  m->installTap(this);	  return TCL_OK;	}    }  else if (argc == 4)    {      if (strcasecmp(argv[1], "add-ll") == 0) 	{	  if( (obj = TclObject::lookup(argv[2])) == 0) {	    fprintf(stderr, "DSRAgent: %s lookup of %s failed\n", argv[1],		    argv[2]);	    return TCL_ERROR;	  }	  ll = (NsObject*) obj;	  if( (obj = TclObject::lookup(argv[3])) == 0) {	    fprintf(stderr, "DSRAgent: %s lookup of %s failed\n", argv[1],		    argv[3]);	    return TCL_ERROR;	  }	  ifq = (PriQueue *) obj;	  return TCL_OK;	}    }  return Agent::command(argc, argv);}voidDSRAgent::recv(Packet* packet, Handler*)  /* handle packets with a MAC destination address of this host, or     the MAC broadcast addr */{  hdr_sr *srh =  (hdr_sr*)packet->access(off_sr_);  hdr_ip *iph =  (hdr_ip*)packet->access(off_ip_);  hdr_cmn *cmh =  (hdr_cmn*)packet->access(off_cmn_);  assert(cmh->size() >= 0);    //Jinyang -count the total number of packets processed at network layer  total_pkts++;  SRPacket p(packet, srh);  p.dest = ID(iph->dst(),::IP);  p.src = ID(iph->src(),::IP);  assert(logtarget != 0);  if (!srh->valid())

⌨️ 快捷键说明

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