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

📄 dsragent.cc

📁 CBRP协议(移动adhoc中基于分簇的路由协议)ns2下的源码
💻 CC
📖 第 1 页 / 共 4 页
字号:
    { // this must be an outgoing packet, it doesn't have a SR header on it      srh->init();		 // give packet an SR header now      cmh->size() += IP_HDR_LEN; // add on IP header size      if (verbose)	trace("S %.9f _%s_ originating %s -> %s",	      Scheduler::instance().clock(), net_id.dump(), p.src.dump(), 	      p.dest.dump());      handlePktWithoutSR(p, false);      goto done;    }  else if (p.dest == net_id || p.dest == IP_broadcast)    { // this packet is intended for us      handlePacketReceipt(p);      goto done;    }        // should we check to see if it's an error packet we're handling  // and if so call processBrokenRouteError to snoop  if (dsragent_snoop_forwarded_errors && srh->route_error())    {      processBrokenRouteError(p);    }  if (srh->route_request())    { // propagate a route_request that's not for us      handleRouteRequest(p);    }  else    { // we're not the intended final recpt, but we're a hop      handleForwarding(p);    }done:  assert(p.pkt == 0);  p.pkt = 0;  return;}/*===========================================================================  handlers for each class of packet---------------------------------------------------------------------------*/voidDSRAgent::handlePktWithoutSR(SRPacket& p, bool retry)  /* obtain a source route to p's destination and send it off.     this should be a retry if the packet is already in the sendbuffer */{  hdr_sr *srh =  (hdr_sr*)p.pkt->access(off_sr_);  assert(srh->valid());  if (p.dest == net_id)    { // it doesn't need a source route, 'cause it's for us      handlePacketReceipt(p);      return;    }  if (route_cache->findRoute(p.dest, p.route, 1))    { // we've got a route...      if (verbose)	trace("S$hit %.5f _%s_ %s -> %s %s",	      Scheduler::instance().clock(), net_id.dump(),	      p.src.dump(), p.dest.dump(), p.route.dump());            sendOutPacketWithRoute(p, true);      return;    } // end if we have a route  else    { // we don't have a route...      if (verbose) 	trace("S$miss %.5f _%s_ %s -> %s", 	      Scheduler::instance().clock(), net_id.dump(), 	      net_id.dump(), p.dest.dump());      getRouteForPacket(p, retry);      return;    } // end of we don't have a route}voidDSRAgent::handlePacketReceipt(SRPacket& p)  /* Handle a packet destined to us */{  hdr_sr *srh =  (hdr_sr*)p.pkt->access(off_sr_);  if (srh->route_reply())    { // we got a route_reply piggybacked on a route_request      // accept the new source route before we do anything else      // (we'll send off any packet's we have queued and waiting)      acceptRouteReply(p);    }    if (srh->route_request())    {      if (dsragent_reply_only_to_first_rtreq  && ignoreRouteRequestp(p)) 	{ //we only respond to the first route request	  // we receive from a host 	  Packet::free(p.pkt);     // drop silently	  p.pkt = 0;	  return;	}      else	{ // we're going to process this request now, so record the req_num	  request_table.insert(p.src, p.src, srh->rtreq_seq());	  returnSrcRouteToRequestor(p);	}    }  if (srh->route_error())    { // register the dead route            processBrokenRouteError(p);    }  /* give the data in the packet to our higher layer (our port dmuxer, most    likely) */  assert(p.dest == net_id || p.dest == MAC_id);  target_->recv(p.pkt, (Handler*)0);  p.pkt = 0;}voidDSRAgent::handleForwarding(SRPacket &p)  /* forward packet on to next host in source route,   snooping as appropriate */{  hdr_sr *srh =  (hdr_sr*)p.pkt->access(off_sr_);  hdr_cmn *cmh =  (hdr_cmn*)p.pkt->access(off_cmn_);  trace("SF %.9f _%s_ --- %d [%s -> %s] %s", 	Scheduler::instance().clock(), net_id.dump(), cmh->uid(),	p.src.dump(), p.dest.dump(), srh->dump());  // first make sure we are the ``current'' host along the source route.  // if we're not, the previous node set up the source route incorrectly.  assert(p.route[p.route.index()] == net_id	 || p.route[p.route.index()] == MAC_id);  if (p.route.index() >= p.route.length())    {      fprintf(stderr,"dfu: ran off the end of a source route\n");      trace("SDFU:  ran off the end of a source route\n");      drop(p.pkt, DROP_RTR_ROUTE_LOOP);      p.pkt = 0;      // maybe we should send this packet back as an error...      return;    }  // if there's a source route, maybe we should snoop it too  if (dsragent_snoop_source_routes)    route_cache->noticeRouteUsed(p.route, Scheduler::instance().clock(), 				 net_id);  // sendOutPacketWithRoute will add in the size of the src hdr, so  // we have to subtract it out here  struct hdr_cmn *ch = HDR_CMN(p.pkt);  ch->size() -= srh->size();  // now forward the packet...  sendOutPacketWithRoute(p, false);}voidDSRAgent::handleRouteRequest(SRPacket &p)  /* process a route request that isn't targeted at us */{  hdr_sr *srh =  (hdr_sr*)p.pkt->access(off_sr_);  assert (srh->route_request());  if (ignoreRouteRequestp(p))     {      if (verbose_srr)         trace("SRR %.5f _%s_ dropped %s #%d (ignored)",              Scheduler::instance().clock(), net_id.dump(), p.src.dump(),              srh->rtreq_seq());      Packet::free(p.pkt);  // pkt is a route request we've already processed      p.pkt = 0;      return; // drop silently    }  // we're going to process this request now, so record the req_num  request_table.insert(p.src, p.src, srh->rtreq_seq());  /*  - if it's a Ring 0 search, check the rt$ for a reply and use it if     possible.  There's not much point in doing Ring 0 search if you're      not going to check the cache.  See the comment about turning off all     reply from cache behavior near the definition of d_r_f_c_o_p (if your      workload had really good spatial locality, it might still make      sense 'cause your target is probably sitting next to you)      - if reply from cache is on, check the cache and reply if possible      - otherwise, just propagate if possible. */  if ((srh->max_propagation() == 0 || dsragent_reply_from_cache_on_propagating)      && replyFromRouteCache(p))    return;			// all done  // does the orginator want us to propagate?  if (p.route.length() > srh->max_propagation())    { 	// no propagation      if (verbose_srr)         trace("SRR %.5f _%s_ dropped %s #%d (prop limit exceeded)",              Scheduler::instance().clock(), net_id.dump(), p.src.dump(),              srh->rtreq_seq());      Packet::free(p.pkt); // pkt isn't for us, and isn't data carrying      p.pkt = 0;      return;		    }  // can we propagate?  if (p.route.full())    { 	// no propagation      trace("SRR %.5f _%s_ dropped %s #%d (SR full)",            Scheduler::instance().clock(), net_id.dump(), p.src.dump(),	    srh->rtreq_seq());      /* pkt is a rt req, even if data carrying, we don't want to log 	 the drop using drop() since many nodes could be dropping the 	 packet in this fashion */      Packet::free(p.pkt);      p.pkt = 0;      return;		    }  // add ourselves to the source route  p.route.appendToPath(net_id);  if (verbose_srr)    trace("SRR %.5f _%s_ rebroadcast %s #%d ->%s %s",          Scheduler::instance().clock(), net_id.dump(), p.src.dump(),          srh->rtreq_seq(), p.dest.dump(), p.route.dump());  sendOutPacketWithRoute(p, false);  return;      }/*===========================================================================  Helpers---------------------------------------------------------------------------*/boolDSRAgent::ignoreRouteRequestp(SRPacket &p)// should we ignore this route request?{  hdr_sr *srh =  (hdr_sr*)p.pkt->access(off_sr_);  if (request_table.get(p.src) >= srh->rtreq_seq())    { // we've already processed a copy of this reqest so      // we should drop the request silently      return true;    }  if (p.route.member(net_id,MAC_id))    { // we're already on the route, drop silently      return true;    }  if (p.route.full())    { // there won't be room for us to put our address into      // the route      // so drop silently - sigh, so close, and yet so far...      // Note that since we don't record the req_id of this message yet,      // we'll process the request if it gets to us on a shorter path      return true;    }  return false;}boolDSRAgent::replyFromRouteCache(SRPacket &p)  /* - see if can reply to this route request from our cache     if so, do it and return true, otherwise, return false      - frees or hands off p iff returns true */{  Path rest_of_route;  Path complete_route = p.route;  /* we shouldn't yet be on on the pkt's current source route */  assert(!p.route.member(net_id, MAC_id));  // do we have a cached route the target?  /* XXX what if we have more than 1?  (and one is legal for reply from     cache and one isn't?) 1/28/97 -dam */  if (!route_cache->findRoute(p.dest, rest_of_route, 0))    { // no route => we're done      return false;    }  /* but we should be on on the remainder of the route (and should be at   the start of the route */  assert(rest_of_route[0] == net_id || rest_of_route[0] == MAC_id);  if (rest_of_route.length() + p.route.length() > MAX_SR_LEN)    return false; // too long to work with...  // add our suggested completion to the route so far  complete_route.appendPath(rest_of_route);  // call compressPath to remove any double backs  ::compressPath(complete_route);  if (!complete_route.member(net_id, MAC_id))    { // we're not on the suggested route, so we can't return it      return false;    }  // if there is any other information piggybacked into the  // route request pkt, we need to forward it on to the dst  hdr_cmn *cmh =  (hdr_cmn*)p.pkt->access(off_cmn_);  hdr_sr *srh =  (hdr_sr*)p.pkt->access(off_sr_);  int request_seqnum = srh->rtreq_seq();    if (PT_DSR != cmh->ptype()	// there's data      || srh->route_reply()      || (srh->route_error() && 	  srh->down_links()[srh->num_route_errors()-1].tell_addr 	  != GRAT_ROUTE_ERROR))    { // must forward the packet on      SRPacket p_copy = p;      p.pkt = 0;      srh->route_request() = 0;      p_copy.route = complete_route;      p_copy.route.setIterator(p.route.length());      assert(p.route[p.route.index()] == net_id);            if (verbose) trace("Sdebug %.9f _%s_ splitting %s to %s",                         Scheduler::instance().clock(), net_id.dump(),                         p.route.dump(), p_copy.route.dump());      sendOutPacketWithRoute(p_copy,false);    }  else     {      Packet::free(p.pkt);  // free the rcvd rt req before making rt reply      p.pkt = 0;    }  // make up and send out a route reply  p.route.appendToPath(net_id);  p.route.reverseInPlace();  route_cache->addRoute(p.route, Scheduler::instance().clock(), net_id);  p.dest = p.src;  p.src = net_id;  p.pkt = allocpkt();  hdr_ip *iph =  (hdr_ip*)p.pkt->access(off_ip_);  iph->src() = p.src.addr;  iph->sport() = RT_PORT;  iph->dst() = p.dest.addr;  iph->dport() = RT_PORT;  iph->ttl() = 255;  srh = (hdr_sr*)p.pkt->access(off_sr_);  srh->init();  for (int i = 0 ; i < complete_route.length() ; i++)    complete_route[i].fillSRAddr(srh->reply_addrs()[i]);  srh->route_reply_len() = complete_route.length();  srh->route_reply() = 1;  // propagate the request sequence number in the reply for analysis purposes  srh->rtreq_seq() = request_seqnum;  hdr_cmn *cmnh =  (hdr_cmn*)p.pkt->access(off_cmn_);  cmnh->ptype() = PT_DSR;  cmnh->size() = IP_HDR_LEN;  trace("SRR %.9f _%s_ cache-reply-sent %s -> %s #%d (len %d) %s",	Scheduler::instance().clock(), net_id.dump(),	p.src.dump(), p.dest.dump(), request_seqnum, complete_route.length(),	complete_route.dump());  sendOutPacketWithRoute(p, true);  return true;}voidDSRAgent::sendOutPacketWithRoute(SRPacket& p, bool fresh, Time delay = 0.0)     // take packet and send it out, packet must a have a route in it     // return value is not very meaningful     // if fresh is true then reset the path before using it, if fresh     //  is false then our caller wants us use a path with the index     //  set as it currently is{  hdr_sr *srh =  (hdr_sr*)p.pkt->access(off_sr_);  hdr_cmn *cmnh = (hdr_cmn*)p.pkt->access(off_cmn_);  assert(srh->valid());  assert(cmnh->size() > 0);  if (p.dest == net_id)    { // it doesn't need to go on the wire, 'cause it's for us      recv(p.pkt, (Handler *) 0);      p.pkt = 0;      return;    }  if (fresh)    {      p.route.resetIterator();      if (verbose && !srh->route_request())	{	  trace("SO %.9f _%s_ originating %s %s", 		Scheduler::instance().clock(), 		net_id.dump(), packet_names[cmnh->ptype()], p.route.dump());	}    }  p.route.fillSR(srh);  cmnh->size() += srh->size();  if (srh->route_request())    { // broadcast forward      cmnh->xmit_failure_ = 0;      cmnh->next_hop() = MAC_BROADCAST;      cmnh->addr_type() = AF_LINK;    }  else    { // forward according to source route      cmnh->xmit_failure_ = XmitFailureCallback;      cmnh->xmit_failure_data_ = (void *) this;      cmnh->next_hop() = srh->get_next_addr();      cmnh->addr_type() = srh->get_next_type();      srh->cur_addr() = srh->cur_addr() + 1;    }  /* put route errors at the head of the ifq somehow? -dam 4/13/98 */  // make sure we aren't cycling packets  assert(p.pkt->incoming == 0); // this is an outgoing packet  if (ifq->length() > 25)    trace("SIFQ %.5f _%s_ len %d",          Scheduler::instance().clock(), net_id.dump(), ifq->length());  // off it goes!  if (srh->route_request())    { // route requests need to be jittered a bit      Scheduler::instance().schedule(ll, p.pkt, 				     Random::uniform(RREQ_JITTER) + delay);    }  else    { // no jitter required       Scheduler::instance().schedule(ll, p.pkt, delay);    }  p.pkt = NULL; /* packet sent off */}voidDSRAgent::getRouteForPacket(SRPacket &p, bool retry)  /* try to obtain a route for packet     pkt is freed or handed off as needed, unless retry == true     in which case it is not touched */{  // since we'll commonly be only one hop away, we should  // arp first before route discovery as an optimization...  Entry *e = request_table.getEntry(p.dest);  Time time = Scheduler::instance().clock();    /* for now, no piggybacking at all, queue all pkts */  if (!retry)     {      stickPacketInSendBuffer(p);      p.pkt = 0; // pkt is handled for now (it's in sendbuffer)    }#if 0  /* pre 4/13/98 logic -dam removed b/c it seemed more complicated than     needed since we're not doing piggybacking and we're returning     route replies via a reversed route (the copy in this code is     critical if we need to piggyback route replies on the route request to     discover the return path) */  /* make the route request packet */  SRPacket rrp = p;  rrp.pkt = p.pkt->copy();  hdr_sr *srh =  (hdr_sr*)rrp.pkt->access(off_sr_);  hdr_ip *iph =  (hdr_ip*)rrp.pkt->access(off_ip_);

⌨️ 快捷键说明

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