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

📄 dsragent.cc

📁 NS2的dsr-ocean仿真代码,对学习研究NS2的人非常有研究价值
💻 CC
📖 第 1 页 / 共 5 页
字号:
  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::access(p.pkt);  hdr_sr *srh =  hdr_sr::access(p.pkt);  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::access(p.pkt);  iph->saddr() = Address::instance().create_ipaddr(p.src.addr, RT_PORT);  iph->sport() = RT_PORT;  iph->daddr() = Address::instance().create_ipaddr(p.dest.addr, RT_PORT);  iph->dport() = RT_PORT;  iph->ttl() = 255;  srh = hdr_sr::access(p.pkt);  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::access(p.pkt);  cmnh->ptype() = PT_DSR;  cmnh->size() = IP_HDR_LEN;  if (verbose_srr)    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)     // 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::access(p.pkt);  hdr_cmn *cmnh = hdr_cmn::access(p.pkt);  assert(srh->valid());  assert(cmnh->size() > 0);  ID dest;  if (diff_subnet(p.dest,net_id)) {  dest = ID(node_->base_stn(),::IP);  p.dest = dest;  }  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_info.name(cmnh->ptype()), p.route.dump());	}    }  p.route.fillSR(srh);  // set direction of pkt to DOWN , i.e downward  cmnh->direction() = hdr_cmn::DOWN;  // let's see if we can snag this packet for flow state... ych 5/2/01  if (dsragent_enable_flowstate &&      p.src == net_id && !srh->route_request() && !srh->cur_addr() &&      // can't yet decode flow errors and route errors/replies together      // so don't tempt the system... ych 5/7/01      !srh->route_error() && !srh->route_reply()) {    hdr_ip *iph =  hdr_ip::access(p.pkt);    int flowidx;    u_int16_t flowid, default_flowid;    double now = Scheduler::instance().clock();    // hmmm, let's see if we can save us some overhead...    if (dsragent_prefer_default_flow &&	flow_table.defaultFlow(p.src.addr, p.dest.addr, flowid) &&	-1 != (flowidx = flow_table.find(p.src.addr, p.dest.addr, flowid)) &&	flow_table[flowidx].timeout >= now &&	(!dsragent_prefer_shorter_over_default || 	  flow_table[flowidx].sourceRoute.length() <= p.route.length()) &&	!(p.route == flow_table[flowidx].sourceRoute)) {      p.route = flow_table[flowidx].sourceRoute;      p.route.fillSR(srh);    }    flowidx = flow_table.find(p.src.addr, p.dest.addr, p.route);    if (flowidx == -1 || flow_table[flowidx].timeout < now) {      // I guess we don't know about this flow; allocate it.      flow_table.cleanup();      flowid = flow_table.generateNextFlowId(p.dest.addr, true);      flowidx = flow_table.createEntry(p.src.addr, p.dest.addr, flowid);      assert(flowidx != -1);      // fill out the table      flow_table[flowidx].count = 1;      flow_table[flowidx].lastAdvRt = Scheduler::instance().clock();      flow_table[flowidx].timeout = now + default_flow_timeout;      flow_table[flowidx].hopCount = 0;      flow_table[flowidx].expectedTTL = iph->ttl();      flow_table[flowidx].allowDefault = true;      flow_table[flowidx].sourceRoute = p.route;      flow_table[flowidx].nextHop = srh->get_next_addr();      assert(srh->get_next_type() == ::IP);      // fix up the srh for the timeout      srh->flow_timeout() = 1;      srh->flow_timeout_time() = default_flow_timeout;      srh->cur_addr() = srh->cur_addr() + 1;    } else if (flow_table[flowidx].count <= END_TO_END_COUNT ||		flow_table[flowidx].lastAdvRt < 		   (Scheduler::instance().clock() - min_adv_interval)) {      // I've got it, but maybe someone else doesn't      if (flow_table[flowidx].expectedTTL != iph->ttl())	flow_table[flowidx].allowDefault = false;      flow_table[flowidx].count++;      flow_table[flowidx].lastAdvRt = Scheduler::instance().clock();      srh->flow_timeout() = 1;      if (dsragent_always_reestablish)	srh->flow_timeout_time() = default_flow_timeout;      else	srh->flow_timeout_time() = (int)(flow_table[flowidx].timeout - now);      srh->cur_addr() = srh->cur_addr() + 1;    } else {      // flow is established end to end      assert (flow_table[flowidx].sourceRoute == p.route);      srh->flow_timeout() = srh->cur_addr() = srh->num_addrs() = 0;    }    if (dsragent_always_reestablish) {      // XXX see major problems detailed above (search for dsragent_always_re..)      flow_table[flowidx].timeout = now + default_flow_timeout;    }    cmnh->next_hop() = flow_table[flowidx].nextHop;    cmnh->addr_type() = ::IP;    if (flow_table.defaultFlow(p.src.addr, p.dest.addr, default_flowid) &&	flow_table[flowidx].flowId == default_flowid &&	!srh->num_addrs() && iph->ttl() == flow_table[flowidx].expectedTTL &&	flow_table[flowidx].allowDefault) {      // we can go without anything... woo hoo!      assert(!srh->flow_header());    } else {      srh->flow_header() = 1;      srh->flow_id() = flow_table[flowidx].flowId;      srh->hopCount() = 1;    }    trace("SF%ss %.9f _%s_ %d [%s -> %s] %d(%d) to %d %s", 	srh->num_addrs() ? "EST" : "",	Scheduler::instance().clock(), net_id.dump(), cmnh->uid(),	p.src.dump(), p.dest.dump(), flow_table[flowidx].flowId,	srh->flow_header(), flow_table[flowidx].nextHop,	srh->num_addrs() ? srh->dump() : "");    cmnh->size() += srh->size();    cmnh->xmit_failure_ = srh->num_addrs() ? XmitFailureCallback : 					     XmitFlowFailureCallback;    cmnh->xmit_failure_data_ = (void *) this;    assert(!srh->num_addrs() || srh->flow_timeout());  } else {    // old non-flowstate stuff...    assert(p.src != net_id || !srh->flow_header());    cmnh->size() += srh->size();    if (srh->route_request())      { // broadcast forward        cmnh->xmit_failure_ = 0;        cmnh->next_hop() = MAC_BROADCAST;        cmnh->addr_type() = NS_AF_ILINK;      }    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;      } /* route_request() */  } /* can snag for path state */  /* put route errors at the head of the ifq somehow? -dam 4/13/98 */  // make sure we aren't cycling packets  #ifdef notdef  if (ifq->prq_length() > 25)	  trace("SIFQ %.5f _%s_ len %d",		Scheduler::instance().clock(),		net_id.dump(), ifq->prq_length());#endif#ifdef NEW_IFQ_LOGIC  /*   *  If the interface queue is full, there's no sense in sending   *  the packet.  Drop it and generate a Route Error?   */  /* question for the author: this seems rife with congestion/infinite loop   * possibilities. you're responding to an ifq full by sending a rt err.   * sounds like the source quench problem. ych 5/5/01   */  if(ifq->prq_isfull(p.pkt)) {	  xmitFailed(p.pkt, DROP_IFQ_QFULL);	  p.pkt = 0;	  return;  }#endif /* NEW_IFQ_LOGIC */  // ych debugging  assert(!srh->flow_header() || !srh->num_addrs() || srh->flow_timeout());  // 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();#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::access(rrp.pkt);  hdr_ip *iph = hdr_ip::access(rrp.pkt);  hdr_cmn *cmh =  hdr_cmn::access(rrp.pkt);  //iph->daddr() = p.dest.getNSAddr_t();  iph->daddr() = Address::instance().create_ipaddr(p.dest.getNSAddr_t(),RT_PORT);  iph->dport() = RT_PORT;  //iph->saddr() = net_id.getNSAddr_t();  iph->saddr() = Address::instance().create_ipaddr(net_id.getNSAddr_t(),RT_PORT);  iph->sport() = RT_PORT;  cmnh->ptype() = PT_DSR;  cmnh->size() = size_;  cmnh->num_forwards() = 0;#endif  /* make the route request packet */  SRPacket rrp;  rrp.dest = p.dest;  rrp.src = net_id;  rrp.pkt = allocpkt();  hdr_sr *srh = hdr_sr::access(rrp.pkt);   hdr_ip *iph = hdr_ip::access(rrp.pkt);  hdr_cmn *cmnh =  hdr_cmn::access(rrp.pkt);    iph->daddr() = Address::instance().create_ipaddr(p.dest.getNSAddr_t(),RT_PORT);  iph->dport() = RT_PORT;  iph->saddr() = Address::instance().create_ipaddr(net_id.getNSAddr_t(),RT_PORT);  iph->sport() = RT_PORT;  cmnh->ptype() = PT_DSR;  cmnh->size() = size_ + IP_HDR_LEN; // add in IP header  cmnh->num_forwards() = 0;    srh->init();  if (BackOffTest(e, time)) {	  // it's time to start another route request cycle#ifdef NEW_SALVAGE_LOGIC	  if(p.src != net_id) {		  assert(dsr_salvage_max_requests > 0);		  assert(p.pkt);		  if(e->rt_reqs_outstanding > dsr_salvage_max_requests) {			  drop(p.pkt, DROP_RTR_NO_ROUTE);			  p.pkt = 0;			  // dump the route request packet we made up			  Packet::free(rrp.pkt);			  rrp.pkt = 0;			  return;		  }	  }#endif /* NEW_SALVAGE_LOGIC */	  if (dsragent_ring_zero_search) {		  // do a ring zero search		  e->last_type = LIMIT0;		  sendOutRtReq(rrp, 0);	  } else {		  // do a propagating route request right now		  e->last_type = UNLIMIT;		  sendOutRtReq(rrp, MAX_SR_LEN);	  }	  e->last_arp = time;  }  else if (LIMIT0 == e->last_type &&#ifdef NEW_SALVAGE_LOGIC	      (dsr_salvage_allow_propagating || p.src == net_id) &&#endif	   (time - e->last_arp) > arp_timeout) {	  // try propagating rt req since we haven't heard back	  // from limited one

⌨️ 快捷键说明

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