dsragent.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:90k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * dsragent.cc
  3.  * Copyright (C) 2000 by the University of Southern California
  4.  * $Id: dsragent.cc,v 1.37 2006/03/10 12:25:28 mahrenho Exp $
  5.  *
  6.  * This program is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU General Public License,
  8.  * version 2, as published by the Free Software Foundation.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License along
  16.  * with this program; if not, write to the Free Software Foundation, Inc.,
  17.  * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  18.  *
  19.  *
  20.  * The copyright of this module includes the following
  21.  * linking-with-specific-other-licenses addition:
  22.  *
  23.  * In addition, as a special exception, the copyright holders of
  24.  * this module give you permission to combine (via static or
  25.  * dynamic linking) this module with free software programs or
  26.  * libraries that are released under the GNU LGPL and with code
  27.  * included in the standard release of ns-2 under the Apache 2.0
  28.  * license or under otherwise-compatible licenses with advertising
  29.  * requirements (or modified versions of such code, with unchanged
  30.  * license).  You may copy and distribute such a system following the
  31.  * terms of the GNU GPL for this module and the licenses of the
  32.  * other code concerned, provided that you include the source code of
  33.  * that other code when and as the GNU GPL requires distribution of
  34.  * source code.
  35.  *
  36.  * Note that people who make modified versions of this module
  37.  * are not obligated to grant this special exception for their
  38.  * modified versions; it is their choice whether to do so.  The GNU
  39.  * General Public License gives permission to release a modified
  40.  * version without this exception; this exception also makes it
  41.  * possible to release a modified version which carries forward this
  42.  * exception.
  43.  *
  44.  */
  45. //
  46. // Other copyrights might apply to parts of this software and are so
  47. // noted when applicable.
  48. //
  49. /* 
  50.    dsragent.cc
  51.    requires a radio model such that sendPacket returns true
  52.    iff the packet is recieved by the destination node.
  53.    
  54.    Ported from CMU/Monarch's code, appropriate copyright applies.  
  55. */
  56. extern "C" {
  57. #include <assert.h>
  58. #include <math.h>
  59. #include <stdio.h>
  60. #include <signal.h>
  61. #include <float.h>
  62. }
  63. #include <object.h>
  64. #include <agent.h>
  65. #include <trace.h>
  66. #include <packet.h>
  67. #include <scheduler.h>
  68. #include <random.h>
  69. #include <mac.h>
  70. #include <ll.h>
  71. #include <cmu-trace.h>
  72. #include "path.h"
  73. #include "srpacket.h"
  74. #include "routecache.h"
  75. #include "requesttable.h"
  76. #include "dsragent.h"
  77. /*==============================================================
  78.   Declarations and global defintions
  79. ------------------------------------------------------------*/
  80. // #define NEW_IFQ_LOGIC
  81. // #define NEW_REQUEST_LOGIC
  82. #define NEW_SALVAGE_LOGIC
  83. #ifdef NEW_SALVAGE_LOGIC
  84. /*
  85.  *  Maximum number of times that a packet may be salvaged.
  86.  */
  87. static int dsr_salvage_max_attempts = 15;
  88. /*
  89.  *  Maximum number of Route Requests that can be sent for a salvaged
  90.  *  packets that was originated at another node.
  91.  */
  92. static int dsr_salvage_max_requests = 1;
  93. /*
  94.  *  May an intermediate node send a propagating Route Request for
  95.  *  a salvaged packet that was originated elsewhere.
  96.  */
  97. static bool dsr_salvage_allow_propagating = 0;
  98. #endif
  99. /* couple of flowstate constants... */
  100. static const bool dsragent_enable_flowstate = true;
  101. static const bool dsragent_prefer_default_flow = true;
  102. static const bool dsragent_prefer_shorter_over_default = true;
  103. static const bool dsragent_always_reestablish = true;
  104. static const int min_adv_interval = 5;
  105. static const int default_flow_timeout = 60;
  106. //#define DSRFLOW_VERBOSE
  107. static const int verbose = 0;
  108. static const int verbose_srr = 0;
  109. static const int verbose_ssalv = 1;
  110. DSRAgent_List DSRAgent::agthead = { 0 };
  111. Time arp_timeout = 30.0e-3; // (sec) arp request timeout
  112. Time rt_rq_period = 0.5; // (sec) length of one backoff period
  113. Time rt_rq_max_period = 10.0; // (sec) maximum time between rt reqs
  114. Time send_timeout = SEND_TIMEOUT; // (sec) how long a packet can live in sendbuf
  115. #if 0
  116. /* used in route reply holdoffs, which are currently disabled -dam 5/98 */
  117. Time rt_rep_holdoff_period = 3.0e-3; // secs (about 2*process_time)
  118. // to determine how long to sit on our rt reply we pick a number
  119. // U(O.0,rt_rep_holdoff_period) + (our route length-1)*rt_rep_holdoff
  120. #endif //0
  121. Time grat_hold_down_time = 1.0; // (sec) min time between grat replies for
  122. // same route
  123. Time max_err_hold = 1.0;        // (sec) 
  124. // maximum time between when we recv a route error told to us, and when we
  125. // transmit a propagating route request that can carry that data.  used to
  126. // keep us from propagating stale route error data
  127. /*************** selectors ******************/
  128. bool dsragent_snoop_forwarded_errors = true;
  129. // give errors we forward to our cache?
  130. bool dsragent_snoop_source_routes = true;
  131. // should we snoop on any source routes we see?
  132. bool dsragent_reply_only_to_first_rtreq = false;
  133. // should we only respond to the first route request we receive from a host?
  134. bool dsragent_propagate_last_error = true;
  135. // should we take the data from the last route error msg sent to us
  136. // and propagate it around on the next propagating route request we do?
  137. // this is aka grat route error propagation
  138. bool dsragent_send_grat_replies = true;
  139. // should we send gratuitous replies to effect route shortening?
  140. bool dsragent_salvage_with_cache = true;
  141. // should we consult our cache for a route if we get a xmitfailure
  142. // and salvage the packet using the route if possible
  143. bool dsragent_use_tap = true;
  144. // should we listen to a promiscuous tap?
  145. bool dsragent_reply_from_cache_on_propagating = true;
  146. // should we consult the route cache before propagating rt req's and
  147. // answer if possible?
  148. bool dsragent_ring_zero_search = true;
  149. // should we send a non-propagating route request as the first action
  150. // in each route discovery action?
  151. // NOTE: to completely turn off replying from cache, you should
  152. // set both dsragent_ring_zero_search and 
  153. // dsragent_reply_from_cache_on_propagating to false
  154. bool dsragent_dont_salvage_bad_replies = true;
  155. // if we have an xmit failure on a packet, and the packet contains a 
  156. // route reply, should we scan the reply to see if contains the dead link?
  157. // if it does, we won't salvage the packet unless there's something aside
  158. // from a reply in it (in which case we salvage, but cut out the rt reply)
  159. bool dsragent_require_bi_routes = true;
  160. // do we need to have bidirectional source routes? 
  161. // [XXX this flag doesn't control all the behaviors and code that assume
  162. // bidirectional links -dam 5/14/98]
  163. #if 0
  164. bool lsnode_holdoff_rt_reply = true;
  165. // if we have a cached route to reply to route_request with, should we
  166. // hold off and not send it for a while?
  167. bool lsnode_require_use = true;
  168. // do we require ourselves to hear a route requestor use a route
  169. // before we withold our route, or is merely hearing another (better)
  170. // route reply enough?
  171. #endif
  172. /*
  173. Our strategy is as follows:
  174.  - it's only worth discovering bidirectional routes, since all data
  175.  paths will have to have to be bidirectional for 802.11 ACKs to work
  176.  - reply to all route requests for us that we recv (not just the first one)
  177.  but reply to them by reversing the route and unicasting.  don't do
  178.  a route request (since that will end up returning the requestor lots of
  179.  routes that are potentially unidirectional). By reversing the discovered 
  180.  route for the route reply, only routes that are bidirectional will make it
  181.  back the original requestor
  182.  - once a packet goes into the sendbuffer, it can't be piggybacked on a 
  183.  route request.  the code assumes that the only thing that removes
  184.  packets from the send buff is the StickPktIn routine, or the route reply
  185.  arrives routine
  186. */
  187. /* Callback helpers */
  188. void
  189. XmitFailureCallback(Packet *pkt, void *data)
  190. {
  191.   DSRAgent *agent = (DSRAgent *)data; // cast of trust
  192.   agent->xmitFailed(pkt);
  193. }
  194. void
  195. XmitFlowFailureCallback(Packet *pkt, void *data)
  196. {
  197.   DSRAgent *agent = (DSRAgent *)data;
  198.   agent->xmitFlowFailed(pkt);
  199. }
  200. /*===========================================================================
  201.   SendBuf management and helpers
  202. ---------------------------------------------------------------------------*/
  203. void
  204. SendBufferTimer::expire(Event *) 
  205.   a_->sendBufferCheck(); 
  206.   resched(BUFFER_CHECK + BUFFER_CHECK * Random::uniform(1.0));
  207. }
  208. void
  209. DSRAgent::dropSendBuff(SRPacket &p)
  210.   // log p as being dropped by the sendbuffer in DSR agent
  211. {
  212.   trace("Ssb %.5f _%s_ dropped %s -> %s", Scheduler::instance().clock(), 
  213. net_id.dump(), p.src.dump(), p.dest.dump());
  214.   drop(p.pkt, DROP_RTR_QTIMEOUT);
  215.   p.pkt = 0;
  216.   p.route.reset();
  217. }
  218. void
  219. DSRAgent::stickPacketInSendBuffer(SRPacket& p)
  220. {
  221.   Time min = DBL_MAX;
  222.   int min_index = 0;
  223.   int c;
  224.   if (verbose)
  225.     trace("Sdebug %.5f _%s_ stuck into send buff %s -> %s",
  226.   Scheduler::instance().clock(), 
  227.   net_id.dump(), p.src.dump(), p.dest.dump());
  228.   for (c = 0 ; c < SEND_BUF_SIZE ; c ++)
  229.     if (send_buf[c].p.pkt == NULL)
  230.       {
  231. send_buf[c].t = Scheduler::instance().clock();
  232. send_buf[c].p = p;
  233. return;
  234.       }
  235.     else if (send_buf[c].t < min)
  236.       {
  237. min = send_buf[c].t;
  238. min_index = c;
  239.       }
  240.   
  241.   // kill somebody
  242.   dropSendBuff(send_buf[min_index].p);
  243.   send_buf[min_index].t = Scheduler::instance().clock();
  244.   send_buf[min_index].p = p;
  245. }
  246. void
  247. DSRAgent::sendBufferCheck()
  248.   // see if any packets in send buffer need route requests sent out
  249.   // for them, or need to be expired
  250. { // this is called about once a second.  run everybody through the
  251.   // get route for pkt routine to see if it's time to do another 
  252.   // route request or what not
  253.   int c;
  254.   for (c  = 0 ; c <SEND_BUF_SIZE ; c++) {
  255.   if (send_buf[c].p.pkt == NULL)
  256.   continue;
  257.   if (Scheduler::instance().clock() - send_buf[c].t > send_timeout) {
  258.   dropSendBuff(send_buf[c].p);
  259.   send_buf[c].p.pkt = 0;
  260.   continue;
  261.   }
  262. #ifdef DEBUG
  263.   trace("Sdebug %.5f _%s_ checking for route for dst %s",
  264. Scheduler::instance().clock(), net_id.dump(), 
  265. send_buf[c].p.dest.dump());
  266. #endif
  267.   handlePktWithoutSR(send_buf[c].p, true);
  268. #ifdef DEBUG
  269.   if (send_buf[c].p.pkt == NULL) 
  270.   trace("Sdebug %.5f _%s_ sendbuf pkt to %s liberated by handlePktWOSR",
  271. Scheduler::instance().clock(), net_id.dump(), 
  272. send_buf[c].p.dest.dump());
  273. #endif
  274.   }
  275. }
  276. /*==============================================================
  277.   Route Request backoff
  278. ------------------------------------------------------------*/
  279. static bool
  280. BackOffTest(Entry *e, Time time)
  281. // look at the entry and decide if we can send another route
  282. // request or not.  update entry as well
  283. {
  284.   Time next = ((Time) (0x1 << (e->rt_reqs_outstanding * 2))) * rt_rq_period;
  285.   if (next > rt_rq_max_period)
  286.   next = rt_rq_max_period;
  287.   if (next + e->last_rt_req > time)
  288.   return false;
  289.   // don't let rt_reqs_outstanding overflow next on the LogicalShiftsLeft's
  290.   if (e->rt_reqs_outstanding < 15)
  291.   e->rt_reqs_outstanding++;
  292.   e->last_rt_req = time;
  293.   return true;
  294. }
  295. /*===========================================================================
  296.   DSRAgent OTcl linkage
  297. ---------------------------------------------------------------------------*/
  298. static class DSRAgentClass : public TclClass {
  299. public:
  300.   DSRAgentClass() : TclClass("Agent/DSRAgent") {}
  301.   TclObject* create(int, const char*const*) {
  302.     return (new DSRAgent);
  303.   }
  304. } class_DSRAgent;
  305. /*===========================================================================
  306.   DSRAgent methods
  307. ---------------------------------------------------------------------------*/
  308. DSRAgent::DSRAgent(): Agent(PT_DSR), request_table(128), route_cache(NULL),
  309. send_buf_timer(this), flow_table(), ars_table()
  310. {
  311.   int c;
  312.   route_request_num = 1;
  313.   route_cache = makeRouteCache();
  314.   for (c = 0 ; c < RTREP_HOLDOFF_SIZE ; c++)
  315.   rtrep_holdoff[c].requested_dest = invalid_addr;
  316.   num_heldoff_rt_replies = 0;
  317.   target_ = 0;
  318.   logtarget = 0;
  319.   grat_hold_victim = 0;
  320.   for (c = 0; c < RTREP_HOLDOFF_SIZE ; c++) {
  321.     grat_hold[c].t = 0;
  322.     grat_hold[c].p.reset();
  323.   }
  324.   //bind("off_SR_", &off_sr_);
  325.   //bind("off_ll_", &off_ll_);
  326.   //bind("off_mac_", &off_mac_);
  327.   //bind("off_ip_", &off_ip_);
  328.   ll = 0;
  329.   ifq = 0;
  330.   mac_ = 0;
  331.   LIST_INSERT_HEAD(&agthead, this, link);
  332. #ifdef DSR_FILTER_TAP
  333.   bzero(tap_uid_cache, sizeof(tap_uid_cache));
  334. #endif
  335.   route_error_held = false;
  336. }
  337. DSRAgent::~DSRAgent()
  338. {
  339.   fprintf(stderr,"DFU: Don't do this! I haven't figured out ~DSRAgentn");
  340.   exit(-1);
  341. }
  342. void
  343. DSRAgent::Terminate()
  344. {
  345. int c;
  346. for (c  = 0 ; c < SEND_BUF_SIZE ; c++) {
  347. if (send_buf[c].p.pkt) {
  348. drop(send_buf[c].p.pkt, DROP_END_OF_SIMULATION);
  349. send_buf[c].p.pkt = 0;
  350. }
  351. }
  352. }
  353. void
  354. DSRAgent::testinit()
  355. {
  356.   struct hdr_sr hsr;
  357.   
  358.   if (net_id == ID(1,::IP))
  359.     {
  360.       printf("adding route to 1n");
  361.       hsr.init();
  362.       hsr.append_addr( 1, NS_AF_INET );
  363.       hsr.append_addr( 2, NS_AF_INET );
  364.       hsr.append_addr( 3, NS_AF_INET );
  365.       hsr.append_addr( 4, NS_AF_INET );
  366.       
  367.       route_cache->addRoute(Path(hsr.addrs(),
  368.  hsr.num_addrs()), 0.0, ID(1,::IP));
  369.     }
  370.   
  371.   if (net_id == ID(3,::IP))
  372.     {
  373.       printf("adding route to 3n");
  374.       hsr.init();
  375.       hsr.append_addr( 3, NS_AF_INET );
  376.       hsr.append_addr( 2, NS_AF_INET );
  377.       hsr.append_addr( 1, NS_AF_INET );
  378.       
  379.       route_cache->addRoute(Path(hsr.addrs(),
  380.  hsr.num_addrs()), 0.0, ID(3,::IP));
  381.     }
  382. }
  383. int
  384. DSRAgent::command(int argc, const char*const* argv)
  385. {
  386.   TclObject *obj;  
  387.   if (argc == 2) 
  388.     {
  389.       if (strcasecmp(argv[1], "testinit") == 0)
  390. {
  391.   testinit();
  392.   return TCL_OK;
  393. }
  394.       if (strcasecmp(argv[1], "reset") == 0)
  395. {
  396.   Terminate();
  397.   return Agent::command(argc, argv);
  398. }
  399.       if (strcasecmp(argv[1], "check-cache") == 0)
  400. {
  401.   return route_cache->command(argc, argv);
  402. }
  403.       if (strcasecmp(argv[1], "startdsr") == 0)
  404. {
  405.   if (ID(1,::IP) == net_id) 
  406.     { // log the configuration parameters of the dsragent
  407.   trace("Sconfig %.5f tap: %s snoop: rts? %s errs? %s",
  408.     Scheduler::instance().clock(),
  409.     dsragent_use_tap ? "on" : "off",
  410.     dsragent_snoop_source_routes ? "on" : "off",
  411.     dsragent_snoop_forwarded_errors ? "on" : "off");
  412.   trace("Sconfig %.5f salvage: %s !bd replies? %s",
  413.     Scheduler::instance().clock(),
  414.     dsragent_salvage_with_cache ? "on" : "off",
  415.     dsragent_dont_salvage_bad_replies ? "on" : "off");
  416.   trace("Sconfig %.5f grat error: %s grat reply: %s",
  417.             Scheduler::instance().clock(),
  418.             dsragent_propagate_last_error ? "on" : "off",
  419.             dsragent_send_grat_replies ? "on" : "off");
  420.   trace("Sconfig %.5f $reply for props: %s ring 0 search: %s",
  421.             Scheduler::instance().clock(),
  422.             dsragent_reply_from_cache_on_propagating ? "on" : "off",
  423.             dsragent_ring_zero_search ? "on" : "off");
  424.     }
  425.   // cheap source of jitter
  426.   send_buf_timer.sched(BUFFER_CHECK 
  427.        + BUFFER_CHECK * Random::uniform(1.0));   
  428.           return route_cache->command(argc,argv);
  429. }
  430.     }
  431.   else if(argc == 3) 
  432.     {
  433.       if (strcasecmp(argv[1], "addr") == 0) 
  434. {
  435.   int temp;
  436.   temp = Address::instance().str2addr(argv[2]);
  437.  net_id = ID(temp, ::IP);
  438.  flow_table.setNetAddr(net_id.addr);
  439.  route_cache->net_id = net_id;
  440.  return TCL_OK;
  441.       else if(strcasecmp(argv[1], "mac-addr") == 0) 
  442. {
  443.   MAC_id = ID(atoi(argv[2]), ::MAC);
  444.   route_cache->MAC_id = MAC_id;
  445.   return TCL_OK;
  446. }
  447.       else if(strcasecmp(argv[1], "rt_rq_max_period") == 0)
  448.         {
  449.           rt_rq_max_period = strtod(argv[2],NULL);
  450.           return TCL_OK;
  451.         }
  452.       else if(strcasecmp(argv[1], "rt_rq_period") == 0)
  453.         {
  454.           rt_rq_period = strtod(argv[2],NULL);
  455.           return TCL_OK;
  456.         }
  457.       else if(strcasecmp(argv[1], "send_timeout") == 0)
  458.         {
  459.           send_timeout = strtod(argv[2],NULL);
  460.           return TCL_OK;
  461.         }
  462.       
  463.       if( (obj = TclObject::lookup(argv[2])) == 0) 
  464. {
  465.   fprintf(stderr, "DSRAgent: %s lookup of %s failedn", argv[1],
  466.   argv[2]);
  467.   return TCL_ERROR;
  468. }
  469.       if (strcasecmp(argv[1], "log-target") == 0)  {
  470.       logtarget = (Trace*) obj;
  471.       return route_cache->command(argc, argv);
  472.       }
  473.       else if (strcasecmp(argv[1], "tracetarget") == 0 )
  474.         {
  475.   logtarget = (Trace*) obj;
  476.   return route_cache->command(argc, argv);
  477. }
  478.       else if (strcasecmp(argv[1], "install-tap") == 0)  
  479. {
  480.   mac_ = (Mac*) obj;
  481.   mac_->installTap(this);
  482.   return TCL_OK;
  483. }
  484.       else if (strcasecmp(argv[1], "node") == 0)
  485. {
  486.   node_ = (MobileNode *) obj;
  487.   return TCL_OK;
  488. }
  489.       else if (strcasecmp (argv[1], "port-dmux") == 0) 
  490. {
  491.   port_dmux_ = (NsObject *) obj;
  492.   return TCL_OK;
  493. }
  494.     }
  495.   else if (argc == 4)
  496.     {
  497.       if (strcasecmp(argv[1], "add-ll") == 0) 
  498. {
  499.   if( (obj = TclObject::lookup(argv[2])) == 0) {
  500.     fprintf(stderr, "DSRAgent: %s lookup of %s failedn", argv[1],
  501.     argv[2]);
  502.     return TCL_ERROR;
  503.   }
  504.   ll = (NsObject*) obj;
  505.   if( (obj = TclObject::lookup(argv[3])) == 0) {
  506.     fprintf(stderr, "DSRAgent: %s lookup of %s failedn", argv[1],
  507.     argv[3]);
  508.     return TCL_ERROR;
  509.   }
  510.   ifq = (CMUPriQueue *) obj;
  511.   return TCL_OK;
  512. }
  513.     }
  514.   return Agent::command(argc, argv);
  515. }
  516. void
  517. DSRAgent::sendOutBCastPkt(Packet *p)
  518. {
  519.   hdr_cmn *cmh =  hdr_cmn::access(p);
  520.   if(cmh->direction() == hdr_cmn::UP)
  521.     cmh->direction() = hdr_cmn::DOWN;
  522.   // no jitter required
  523.   Scheduler::instance().schedule(ll, p, 0.0);
  524. }
  525. void
  526. DSRAgent::recv(Packet* packet, Handler*)
  527.   /* handle packets with a MAC destination address of this host, or
  528.      the MAC broadcast addr */
  529. {
  530.   hdr_sr *srh =  hdr_sr::access(packet);
  531.   hdr_ip *iph =  hdr_ip::access(packet);
  532.   hdr_cmn *cmh =  hdr_cmn::access(packet);
  533.   // special process for GAF
  534.   if (cmh->ptype() == PT_GAF) {
  535.     if (iph->daddr() == (int)IP_BROADCAST) { 
  536.       if(cmh->direction() == hdr_cmn::UP)
  537. cmh->direction() = hdr_cmn::DOWN;
  538.       Scheduler::instance().schedule(ll,packet,0);
  539.       return;
  540.     } else {
  541.       target_->recv(packet, (Handler*)0);
  542.       return;   
  543.     }
  544.   }
  545.   assert(cmh->size() >= 0);
  546.   SRPacket p(packet, srh);
  547.   //p.dest = ID(iph->dst(),::IP);
  548.   //p.src = ID(iph->src(),::IP);
  549.   p.dest = ID((Address::instance().get_nodeaddr(iph->daddr())),::IP);
  550.   p.src = ID((Address::instance().get_nodeaddr(iph->saddr())),::IP);
  551.   assert(logtarget != 0);
  552.   if (srh->valid() != 1) {
  553.     unsigned int dst = cmh->next_hop();
  554.     if (dst == IP_BROADCAST) {
  555.       // extensions for mobileIP --Padma, 04/99.
  556.       // Brdcast pkt - treat differently
  557.       if (p.src == net_id)
  558. // I have originated this pkt
  559. sendOutBCastPkt(packet);
  560.       else 
  561. //hand it over to port-dmux
  562. port_dmux_->recv(packet, (Handler*)0);
  563.       
  564.     } else {
  565.       // this must be an outgoing packet, it doesn't have a SR header on it
  566.       
  567.       srh->init();  // give packet an SR header now
  568.       cmh->size() += IP_HDR_LEN; // add on IP header size
  569.       if (verbose)
  570. trace("S %.9f _%s_ originating %s -> %s",
  571.       Scheduler::instance().clock(), net_id.dump(), p.src.dump(), 
  572.       p.dest.dump());
  573.       handlePktWithoutSR(p, false);
  574.       goto done;
  575.     }
  576.   }
  577.   else if (srh->valid() == 1) 
  578.     {
  579.       if (p.dest == net_id || p.dest == IP_broadcast)
  580. { // this packet is intended for us
  581.   handlePacketReceipt(p);
  582.   goto done;
  583. }
  584.       
  585.       // should we check to see if it's an error packet we're handling
  586.       // and if so call processBrokenRouteError to snoop
  587.       if (dsragent_snoop_forwarded_errors && srh->route_error())
  588. {
  589.   processBrokenRouteError(p);
  590. }
  591.       if (srh->route_request())
  592. { // propagate a route_request that's not for us
  593.   handleRouteRequest(p);
  594. }
  595.       else
  596. { // we're not the intended final recpt, but we're a hop
  597.   handleForwarding(p);
  598. }
  599.     }
  600.   else {
  601.     // some invalid pkt has reached here
  602.     fprintf(stderr,"dsragent: Error-received Invalid pkt!n");
  603.     Packet::free(p.pkt);
  604.     p.pkt =0; // drop silently
  605.   }
  606.  done:
  607.   assert(p.pkt == 0);
  608.   
  609.   p.pkt = 0;
  610.   return;
  611. }
  612. /*===========================================================================
  613.   handlers for each class of packet
  614. ---------------------------------------------------------------------------*/
  615. void
  616. DSRAgent::handlePktWithoutSR(SRPacket& p, bool retry)
  617.   /* obtain a source route to p's destination and send it off.
  618.      this should be a retry if the packet is already in the sendbuffer */
  619. {
  620.   assert(HDR_SR (p.pkt)->valid());
  621.   if (p.dest == net_id)
  622.     { // it doesn't need a source route, 'cause it's for us
  623.       handlePacketReceipt(p);
  624.       return;
  625.     }
  626.   // Extensions for wired cum wireless simulation mode
  627.   //if pkt dst outside my subnet, route to base_stn
  628.   ID dest;
  629.   if (diff_subnet(p.dest,net_id)) {
  630.   dest = ID(node_->base_stn(),::IP);
  631.   p.dest = dest;
  632.   }
  633.   if (route_cache->findRoute(p.dest, p.route, 1))
  634.     { // we've got a route...
  635.       if (verbose)
  636. trace("S$hit %.5f _%s_ %s -> %s %s",
  637.       Scheduler::instance().clock(), net_id.dump(),
  638.       p.src.dump(), p.dest.dump(), p.route.dump());      
  639.       sendOutPacketWithRoute(p, true);
  640.       return;
  641.     } // end if we have a route
  642.   else
  643.     { // we don't have a route...
  644.       if (verbose) 
  645. trace("S$miss %.5f _%s_ %s -> %s", 
  646.       Scheduler::instance().clock(), net_id.dump(), 
  647.       net_id.dump(), p.dest.dump());
  648.       getRouteForPacket(p, retry);
  649.       return;
  650.     } // end of we don't have a route
  651. }
  652. void
  653. DSRAgent::handlePacketReceipt(SRPacket& p)
  654.   /* Handle a packet destined to us */
  655. {
  656.   hdr_cmn *cmh =  hdr_cmn::access(p.pkt);
  657.   hdr_sr *srh =  hdr_sr::access(p.pkt);
  658.   if (srh->route_reply())
  659.     { // we got a route_reply piggybacked on a route_request
  660.       // accept the new source route before we do anything else
  661.       // (we'll send off any packet's we have queued and waiting)
  662.       acceptRouteReply(p);
  663.     }
  664.   
  665.   if (srh->route_request())
  666.     {
  667.       if (dsragent_reply_only_to_first_rtreq  && ignoreRouteRequestp(p)) 
  668. { //we only respond to the first route request
  669.   // we receive from a host 
  670.   Packet::free(p.pkt);     // drop silently
  671.   p.pkt = 0;
  672.   return;
  673. }
  674.       else
  675. { // we're going to process this request now, so record the req_num
  676.   request_table.insert(p.src, p.src, srh->rtreq_seq());
  677.   returnSrcRouteToRequestor(p);
  678. }
  679.     }
  680.   if (srh->route_error())
  681.     { // register the dead route      
  682.       processBrokenRouteError(p);
  683.     }
  684.   if (srh->flow_unknown())
  685.     processUnknownFlowError(p, false);
  686.   if (srh->flow_default_unknown())
  687.     processUnknownFlowError(p, true);
  688.   /* give the data in the packet to our higher layer (our port dmuxer, most 
  689.    likely) */
  690.   //handPktToDmux(p);
  691.   assert(p.dest == net_id || p.dest == MAC_id);
  692.   
  693. #if 0
  694.   if (iph->dport() == 255) {
  695.     int mask = Address::instance().portmask();
  696.     int shift = Address::instance().portshift();  
  697.     iph->daddr() = ((iph->dport() & mask) << shift) | ((~(mask) << shift) & iph->dst());
  698.   }
  699. #endif
  700.   
  701.   cmh->size() -= srh->size(); // cut off the SR header 4/7/99 -dam
  702.   srh->valid() = 0;
  703.   cmh->size() -= IP_HDR_LEN;    // cut off IP header size 4/7/99 -dam
  704.   target_->recv(p.pkt, (Handler*)0);
  705.   p.pkt = 0;
  706. }
  707. void
  708. DSRAgent::handleDefaultForwarding(SRPacket &p) {
  709.   hdr_ip *iph = hdr_ip::access(p.pkt);
  710.   u_int16_t flowid;
  711.   int       flowidx;
  712.   if (!flow_table.defaultFlow(p.src.addr, p.dest.addr, flowid)) {
  713.     sendUnknownFlow(p, true);
  714.     assert(p.pkt == 0);
  715.     return;
  716.   }
  717.   if ((flowidx = flow_table.find(p.src.addr, p.dest.addr, flowid)) == -1) {
  718.     sendUnknownFlow(p, false, flowid);
  719.     assert(p.pkt == 0);
  720.     return;
  721.   }
  722.   if (iph->ttl() != flow_table[flowidx].expectedTTL) {
  723.     sendUnknownFlow(p, true);
  724.     assert(p.pkt == 0);
  725.     return;
  726.   }
  727.   // XXX should also check prevhop
  728.   handleFlowForwarding(p, flowidx);
  729. }
  730. void
  731. DSRAgent::handleFlowForwarding(SRPacket &p, int flowidx) {
  732.   hdr_sr *srh = hdr_sr::access(p.pkt);
  733.   hdr_ip *iph = hdr_ip::access(p.pkt);
  734.   hdr_cmn *cmnh =  hdr_cmn::access(p.pkt);
  735.   int amt;
  736.   assert(flowidx >= 0);
  737.   assert(!srh->num_addrs());
  738.   cmnh->next_hop() = flow_table[flowidx].nextHop;
  739.   cmnh->addr_type() = ::IP;
  740.   cmnh->xmit_failure_ = XmitFlowFailureCallback;
  741.   cmnh->xmit_failure_data_ = (void *) this;
  742.   // make sure we aren't cycling packets
  743.   //assert(p.pkt->incoming == 0); // this is an outgoing packet
  744.   assert(cmnh->direction() == hdr_cmn::UP);
  745.   if (!iph->ttl()--) {
  746.     drop(p.pkt, DROP_RTR_TTL);
  747.     p.pkt = 0;
  748.     return;
  749.   }
  750.   trace("SFf %.9f _%s_ %d [%s -> %s] %d to %d", 
  751. Scheduler::instance().clock(), net_id.dump(), cmnh->uid(),
  752. p.src.dump(), p.dest.dump(), flow_table[flowidx].flowId,
  753. flow_table[flowidx].nextHop);
  754.   // XXX ych 5/8/01 ARS also should check previous hop
  755.   if (!srh->salvaged() && 
  756.       (amt = ars_table.findAndClear(cmnh->uid(), flow_table[flowidx].flowId)) &&
  757.       p.route.index() - amt > 0) {
  758.     trace("SFARS %.9f _%s_ %d [%s -> %s] %d %d", 
  759.   Scheduler::instance().clock(), net_id.dump(), cmnh->uid(),
  760.   p.src.dump(), p.dest.dump(), flow_table[flowidx].flowId, amt);
  761.     // stamp a route in the packet...
  762.     p.route = flow_table[flowidx].sourceRoute;
  763.     p.route.index() -= amt;
  764.     sendRouteShortening(p, p.route.index(), 
  765. flow_table[flowidx].sourceRoute.index());
  766.   }
  767.   if (dsragent_always_reestablish) {
  768.     // XXX this is an utter hack. the flow_table needs to remember the original
  769.     // timeout value specified, as well as the original time to timeout. No
  770.     // establishment packets are allowed after the original time. Must make sure
  771.     // flowids assigned do not overlap. ych 5/8/01
  772.     flow_table[flowidx].timeout = Scheduler::instance().clock() + 
  773.   default_flow_timeout;
  774.   }
  775.   // set the direction pkt to be down
  776.   cmnh->direction() = hdr_cmn::DOWN;
  777.   Scheduler::instance().schedule(ll, p.pkt, 0);
  778.   p.pkt = 0;
  779. }
  780. void
  781. DSRAgent::handleFlowForwarding(SRPacket &p) {
  782.   hdr_sr *srh = hdr_sr::access(p.pkt);
  783.   hdr_ip *iph = hdr_ip::access(p.pkt);
  784.   int flowidx = flow_table.find(p.src.addr, p.dest.addr, srh->flow_id());
  785.   assert(srh->flow_header());
  786.   if (srh->num_addrs()) {
  787.     assert(srh->flow_timeout());
  788.     if (flowidx == -1) {
  789.       flow_table.cleanup();
  790.       flowidx = flow_table.createEntry(p.src.addr, p.dest.addr, srh->flow_id());
  791.       assert(flowidx != -1);
  792.       flow_table[flowidx].timeout = Scheduler::instance().clock() + 
  793.     srh->flow_timeout_time();
  794.       flow_table[flowidx].hopCount = srh->hopCount();
  795.       flow_table[flowidx].expectedTTL = iph->ttl();
  796.       flow_table[flowidx].sourceRoute = p.route;
  797.       flow_table[flowidx].nextHop = srh->get_next_addr();
  798.       assert(srh->hopCount() == srh->cur_addr());
  799.       assert(srh->get_next_type() == ::IP);
  800.       assert(flow_table[flowidx].sourceRoute[flow_table[flowidx].hopCount] == 
  801.      net_id);
  802.       flow_table[flowidx].count = 0;            // shouldn't be used
  803.       flow_table[flowidx].allowDefault = false; // shouldn't be used
  804.     }
  805.     assert(flowidx != -1);
  806.     //assert(flow_table[flowidx].hopCount == srh->hopCount());
  807.     
  808.     srh->hopCount()++;
  809.     return;
  810.   }
  811.   if (flowidx == -1) {
  812.     // return an error
  813.     sendUnknownFlow(p, false, srh->flow_id());
  814.     assert(p.pkt == 0);
  815.     return;
  816.   }
  817.   //assert(flow_table[flowidx].hopCount == srh->hopCount());
  818.   srh->hopCount()++;
  819.   // forward the packet
  820.   handleFlowForwarding(p, flowidx);
  821. }
  822. void
  823. DSRAgent::handleForwarding(SRPacket &p)
  824.   /* forward packet on to next host in source route,
  825.    snooping as appropriate */
  826. {
  827.   hdr_sr *srh =  hdr_sr::access(p.pkt);
  828.   hdr_ip *iph = hdr_ip::access(p.pkt);
  829.   hdr_cmn *ch =  hdr_cmn::access(p.pkt);
  830.   bool flowOnly = !srh->num_addrs();
  831.   if (srh->flow_header())
  832.     handleFlowForwarding(p);
  833.   else if (!srh->num_addrs())
  834.     handleDefaultForwarding(p);
  835.   if (flowOnly)
  836.     return;
  837.   assert(p.pkt); // make sure flow state didn't eat the pkt
  838.   // first make sure we are the ``current'' host along the source route.
  839.   // if we're not, the previous node set up the source route incorrectly.
  840.   assert(p.route[p.route.index()] == net_id
  841.  || p.route[p.route.index()] == MAC_id);
  842.   if (p.route.index() >= p.route.length())
  843.     {
  844.       fprintf(stderr,"dfu: ran off the end of a source routen");
  845.       trace("SDFU:  ran off the end of a source routen");
  846.       drop(p.pkt, DROP_RTR_ROUTE_LOOP);
  847.       p.pkt = 0;
  848.       // maybe we should send this packet back as an error...
  849.       return;
  850.     }
  851.   // if there's a source route, maybe we should snoop it too
  852.   if (dsragent_snoop_source_routes)
  853.     route_cache->noticeRouteUsed(p.route, Scheduler::instance().clock(), 
  854.  net_id);
  855.   // sendOutPacketWithRoute will add in the size of the src hdr, so
  856.   // we have to subtract it out here
  857.   ch->size() -= srh->size();
  858.   // we need to manually decr this, since nothing else does.
  859.   if (!iph->ttl()--) {
  860.     drop(p.pkt, DROP_RTR_TTL);
  861.     p.pkt = 0;
  862.     return;
  863.   }
  864.   // now forward the packet...
  865.   sendOutPacketWithRoute(p, false);
  866. }
  867. void
  868. DSRAgent::handleRouteRequest(SRPacket &p)
  869.   /* process a route request that isn't targeted at us */
  870. {
  871.   hdr_sr *srh =  hdr_sr::access(p.pkt);
  872.   assert (srh->route_request());
  873. #ifdef notdef
  874.   {
  875.           int src = mac_->hdr_src(HDR_MAC(p.pkt));
  876.           if(mac_->is_neighbor(src) == 0) {
  877.                   Packet::free(p.pkt);
  878.                   p.pkt = 0;
  879.                   return;
  880.           }
  881.   }
  882. #endif
  883.   if (ignoreRouteRequestp(p)) 
  884.     {
  885.       if (verbose_srr) 
  886.         trace("SRR %.5f _%s_ dropped %s #%d (ignored)",
  887.               Scheduler::instance().clock(), net_id.dump(), p.src.dump(),
  888.               srh->rtreq_seq());
  889.       Packet::free(p.pkt);  // pkt is a route request we've already processed
  890.       p.pkt = 0;
  891.       return; // drop silently
  892.     }
  893.   // we're going to process this request now, so record the req_num
  894.   request_table.insert(p.src, p.src, srh->rtreq_seq());
  895.   /*  - if it's a Ring 0 search, check the rt$ for a reply and use it if
  896.      possible.  There's not much point in doing Ring 0 search if you're 
  897.      not going to check the cache.  See the comment about turning off all
  898.      reply from cache behavior near the definition of d_r_f_c_o_p (if your 
  899.      workload had really good spatial locality, it might still make 
  900.      sense 'cause your target is probably sitting next to you)
  901.       - if reply from cache is on, check the cache and reply if possible
  902.       - otherwise, just propagate if possible. */
  903.   if ((srh->max_propagation() == 0 || dsragent_reply_from_cache_on_propagating)
  904.       && replyFromRouteCache(p))
  905.   return; // all done
  906. #ifdef NEW_REQUEST_LOGIC
  907.   /*
  908.    * If we are congested, don't forward or answer the Route Reply
  909.    */
  910.   if(ifq->prq_length() > 10) {
  911.   trace("SRR %.9f _%s_ discarding %s #%d (ifq length %d)",
  912. Scheduler::instance().clock(),
  913. net_id.dump(),
  914. p.src.dump(),
  915. srh->rtreq_seq(),
  916. ifq->prq_length());
  917.   Packet::free(p.pkt);
  918.   p.pkt = 0;
  919.   return;
  920.   }
  921.   /*
  922.    *  If "free air time" < 15%, don't forward or answer the Route Reply
  923.    */
  924.   {
  925.   double atime = mac_->air_time_free(10);
  926.   if(atime > 0.0 && atime < 0.15) {
  927.   trace("SRR %.9f _%s_ discarding %s #%d (free air time %f)",
  928. Scheduler::instance().clock(),
  929. net_id.dump(),
  930. p.src.dump(),
  931. srh->rtreq_seq(),
  932. atime);
  933.   Packet::free(p.pkt);
  934.   p.pkt = 0;
  935.   return;
  936.   }
  937.   }  
  938. #endif /* NEW_REQUEST_LOGIC */
  939.   // does the orginator want us to propagate?
  940.   if (p.route.length() > srh->max_propagation())
  941.     {  // no propagation
  942.       if (verbose_srr) 
  943.         trace("SRR %.5f _%s_ dropped %s #%d (prop limit exceeded)",
  944.               Scheduler::instance().clock(), net_id.dump(), p.src.dump(),
  945.               srh->rtreq_seq());
  946.       Packet::free(p.pkt); // pkt isn't for us, and isn't data carrying
  947.       p.pkt = 0;
  948.       return;
  949.     }
  950.   // can we propagate?
  951.   if (p.route.full())
  952.     {  // no propagation
  953.       trace("SRR %.5f _%s_ dropped %s #%d (SR full)",
  954.             Scheduler::instance().clock(), net_id.dump(), p.src.dump(),
  955.     srh->rtreq_seq());
  956.       /* pkt is a rt req, even if data carrying, we don't want to log 
  957.  the drop using drop() since many nodes could be dropping the 
  958.  packet in this fashion */
  959.       Packet::free(p.pkt);
  960.       p.pkt = 0;
  961.       return;
  962.     }
  963.   // add ourselves to the source route
  964.   p.route.appendToPath(net_id);
  965.   if (verbose_srr)
  966.     trace("SRR %.5f _%s_ rebroadcast %s #%d ->%s %s",
  967.           Scheduler::instance().clock(), net_id.dump(), p.src.dump(),
  968.           srh->rtreq_seq(), p.dest.dump(), p.route.dump());
  969.   sendOutPacketWithRoute(p, false);
  970.   return;      
  971. }
  972. /*===========================================================================
  973.   Helpers
  974. ---------------------------------------------------------------------------*/
  975. bool
  976. DSRAgent::ignoreRouteRequestp(SRPacket &p)
  977. // should we ignore this route request?
  978. {
  979.   hdr_sr *srh =  hdr_sr::access(p.pkt);
  980.   if (request_table.get(p.src) >= srh->rtreq_seq())
  981.     { // we've already processed a copy of this reqest so
  982.       // we should drop the request silently
  983.       return true;
  984.     }
  985.   if (p.route.member(net_id,MAC_id))
  986.     { // we're already on the route, drop silently
  987.       return true;
  988.     }
  989.   if (p.route.full())
  990.     { // there won't be room for us to put our address into
  991.       // the route
  992.       // so drop silently - sigh, so close, and yet so far...
  993.       // Note that since we don't record the req_id of this message yet,
  994.       // we'll process the request if it gets to us on a shorter path
  995.       return true;
  996.     }
  997.   return false;
  998. }
  999. bool
  1000. DSRAgent::replyFromRouteCache(SRPacket &p)
  1001.   /* - see if can reply to this route request from our cache
  1002.      if so, do it and return true, otherwise, return false 
  1003.      - frees or hands off p iff returns true */
  1004. {
  1005.   Path rest_of_route;
  1006.   Path complete_route = p.route;
  1007.   /* we shouldn't yet be on on the pkt's current source route */
  1008.   assert(!p.route.member(net_id, MAC_id));
  1009.   // do we have a cached route the target?
  1010.   /* XXX what if we have more than 1?  (and one is legal for reply from
  1011.      cache and one isn't?) 1/28/97 -dam */
  1012.   if (!route_cache->findRoute(p.dest, rest_of_route, 0))
  1013.     { // no route => we're done
  1014.       return false;
  1015.     }
  1016.   /* but we should be on on the remainder of the route (and should be at
  1017.    the start of the route */
  1018.   assert(rest_of_route[0] == net_id || rest_of_route[0] == MAC_id);
  1019.   if (rest_of_route.length() + p.route.length() > MAX_SR_LEN)
  1020.     return false; // too long to work with...
  1021.   // add our suggested completion to the route so far
  1022.   complete_route.appendPath(rest_of_route);
  1023.   // call compressPath to remove any double backs
  1024.   ::compressPath(complete_route);
  1025.   if (!complete_route.member(net_id, MAC_id))
  1026.     { // we're not on the suggested route, so we can't return it
  1027.       return false;
  1028.     }
  1029.   // if there is any other information piggybacked into the
  1030.   // route request pkt, we need to forward it on to the dst
  1031.   hdr_cmn *cmh =  hdr_cmn::access(p.pkt);
  1032.   hdr_sr *srh =  hdr_sr::access(p.pkt);
  1033.   int request_seqnum = srh->rtreq_seq();
  1034.   
  1035.   if (PT_DSR != cmh->ptype() // there's data
  1036.       || srh->route_reply()
  1037.       || (srh->route_error() && 
  1038.   srh->down_links()[srh->num_route_errors()-1].tell_addr 
  1039.   != GRAT_ROUTE_ERROR))
  1040.     { // must forward the packet on
  1041.       SRPacket p_copy = p;
  1042.       p.pkt = 0;
  1043.       srh->route_request() = 0;
  1044.       p_copy.route = complete_route;
  1045.       p_copy.route.setIterator(p.route.length());
  1046.       assert(p.route[p.route.index()] == net_id);
  1047.       
  1048.       if (verbose) trace("Sdebug %.9f _%s_ splitting %s to %s",
  1049.                          Scheduler::instance().clock(), net_id.dump(),
  1050.                          p.route.dump(), p_copy.route.dump());
  1051.       sendOutPacketWithRoute(p_copy,false);
  1052.     }
  1053.   else 
  1054.     {
  1055.       Packet::free(p.pkt);  // free the rcvd rt req before making rt reply
  1056.       p.pkt = 0;
  1057.     }
  1058.   // make up and send out a route reply
  1059.   p.route.appendToPath(net_id);
  1060.   p.route.reverseInPlace();
  1061.   route_cache->addRoute(p.route, Scheduler::instance().clock(), net_id);
  1062.   p.dest = p.src;
  1063.   p.src = net_id;
  1064.   p.pkt = allocpkt();
  1065.   hdr_ip *iph =  hdr_ip::access(p.pkt);
  1066.   iph->saddr() = Address::instance().create_ipaddr(p.src.addr, RT_PORT);
  1067.   iph->sport() = RT_PORT;
  1068.   iph->daddr() = Address::instance().create_ipaddr(p.dest.addr, RT_PORT);
  1069.   iph->dport() = RT_PORT;
  1070.   iph->ttl() = 255;
  1071.   srh = hdr_sr::access(p.pkt);
  1072.   srh->init();
  1073.   for (int i = 0 ; i < complete_route.length() ; i++)
  1074.     complete_route[i].fillSRAddr(srh->reply_addrs()[i]);
  1075.   srh->route_reply_len() = complete_route.length();
  1076.   srh->route_reply() = 1;
  1077.   // propagate the request sequence number in the reply for analysis purposes
  1078.   srh->rtreq_seq() = request_seqnum;
  1079.   hdr_cmn *cmnh =  hdr_cmn::access(p.pkt);
  1080.   cmnh->ptype() = PT_DSR;
  1081.   cmnh->size() = IP_HDR_LEN;
  1082.   if (verbose_srr)
  1083.     trace("SRR %.9f _%s_ cache-reply-sent %s -> %s #%d (len %d) %s",
  1084.   Scheduler::instance().clock(), net_id.dump(),
  1085.   p.src.dump(), p.dest.dump(), request_seqnum, complete_route.length(),
  1086.   complete_route.dump());
  1087.   sendOutPacketWithRoute(p, true);
  1088.   return true;
  1089. }
  1090. void
  1091. DSRAgent::sendOutPacketWithRoute(SRPacket& p, bool fresh, Time delay)
  1092.      // take packet and send it out, packet must a have a route in it
  1093.      // return value is not very meaningful
  1094.      // if fresh is true then reset the path before using it, if fresh
  1095.      //  is false then our caller wants us use a path with the index
  1096.      //  set as it currently is
  1097. {
  1098.   hdr_sr *srh =  hdr_sr::access(p.pkt);
  1099.   hdr_cmn *cmnh = hdr_cmn::access(p.pkt);
  1100.   assert(srh->valid());
  1101.   assert(cmnh->size() > 0);
  1102.   ID dest;
  1103.   if (diff_subnet(p.dest,net_id)) {
  1104.   dest = ID(node_->base_stn(),::IP);
  1105.   p.dest = dest;
  1106.   }
  1107.   if (p.dest == net_id)
  1108.     { // it doesn't need to go on the wire, 'cause it's for us
  1109.       recv(p.pkt, (Handler *) 0);
  1110.       p.pkt = 0;
  1111.       return;
  1112.     }
  1113.   if (fresh)
  1114.     {
  1115.       p.route.resetIterator();
  1116.       if (verbose && !srh->route_request())
  1117. {
  1118.   trace("SO %.9f _%s_ originating %s %s", 
  1119. Scheduler::instance().clock(), 
  1120. net_id.dump(), packet_info.name(cmnh->ptype()), p.route.dump());
  1121. }
  1122.     }
  1123.   p.route.fillSR(srh);
  1124.   // set direction of pkt to DOWN , i.e downward
  1125.   cmnh->direction() = hdr_cmn::DOWN;
  1126.   // let's see if we can snag this packet for flow state... ych 5/2/01
  1127.   if (dsragent_enable_flowstate &&
  1128.       p.src == net_id && !srh->route_request() && !srh->cur_addr() &&
  1129.       // can't yet decode flow errors and route errors/replies together
  1130.       // so don't tempt the system... ych 5/7/01
  1131.       !srh->route_error() && !srh->route_reply()) {
  1132.     hdr_ip *iph =  hdr_ip::access(p.pkt);
  1133.     int flowidx;
  1134.     u_int16_t flowid, default_flowid;
  1135.     double now = Scheduler::instance().clock();
  1136.     // hmmm, let's see if we can save us some overhead...
  1137.     if (dsragent_prefer_default_flow &&
  1138. flow_table.defaultFlow(p.src.addr, p.dest.addr, flowid) &&
  1139. -1 != (flowidx = flow_table.find(p.src.addr, p.dest.addr, flowid)) &&
  1140. flow_table[flowidx].timeout >= now &&
  1141. (!dsragent_prefer_shorter_over_default || 
  1142.   flow_table[flowidx].sourceRoute.length() <= p.route.length()) &&
  1143. !(p.route == flow_table[flowidx].sourceRoute)) {
  1144.       p.route = flow_table[flowidx].sourceRoute;
  1145.       p.route.fillSR(srh);
  1146.     }
  1147.     flowidx = flow_table.find(p.src.addr, p.dest.addr, p.route);
  1148.     if (flowidx == -1 || flow_table[flowidx].timeout < now) {
  1149.       // I guess we don't know about this flow; allocate it.
  1150.       flow_table.cleanup();
  1151.       flowid = flow_table.generateNextFlowId(p.dest.addr, true);
  1152.       flowidx = flow_table.createEntry(p.src.addr, p.dest.addr, flowid);
  1153.       assert(flowidx != -1);
  1154.       // fill out the table
  1155.       flow_table[flowidx].count = 1;
  1156.       flow_table[flowidx].lastAdvRt = Scheduler::instance().clock();
  1157.       flow_table[flowidx].timeout = now + default_flow_timeout;
  1158.       flow_table[flowidx].hopCount = 0;
  1159.       flow_table[flowidx].expectedTTL = iph->ttl();
  1160.       flow_table[flowidx].allowDefault = true;
  1161.       flow_table[flowidx].sourceRoute = p.route;
  1162.       flow_table[flowidx].nextHop = srh->get_next_addr();
  1163.       assert(srh->get_next_type() == ::IP);
  1164.       // fix up the srh for the timeout
  1165.       srh->flow_timeout() = 1;
  1166.       srh->flow_timeout_time() = default_flow_timeout;
  1167.       srh->cur_addr() = srh->cur_addr() + 1;
  1168.     } else if (flow_table[flowidx].count <= END_TO_END_COUNT ||
  1169. flow_table[flowidx].lastAdvRt < 
  1170.    (Scheduler::instance().clock() - min_adv_interval)) {
  1171.       // I've got it, but maybe someone else doesn't
  1172.       if (flow_table[flowidx].expectedTTL != iph->ttl())
  1173. flow_table[flowidx].allowDefault = false;
  1174.       flow_table[flowidx].count++;
  1175.       flow_table[flowidx].lastAdvRt = Scheduler::instance().clock();
  1176.       srh->flow_timeout() = 1;
  1177.       if (dsragent_always_reestablish)
  1178. srh->flow_timeout_time() = default_flow_timeout;
  1179.       else
  1180. srh->flow_timeout_time() = (int)(flow_table[flowidx].timeout - now);
  1181.       srh->cur_addr() = srh->cur_addr() + 1;
  1182.     } else {
  1183.       // flow is established end to end
  1184.       assert (flow_table[flowidx].sourceRoute == p.route);
  1185.       srh->flow_timeout() = srh->cur_addr() = srh->num_addrs() = 0;
  1186.     }
  1187.     if (dsragent_always_reestablish) {
  1188.       // XXX see major problems detailed above (search for dsragent_always_re..)
  1189.       flow_table[flowidx].timeout = now + default_flow_timeout;
  1190.     }
  1191.     cmnh->next_hop() = flow_table[flowidx].nextHop;
  1192.     cmnh->addr_type() = ::IP;
  1193.     if (flow_table.defaultFlow(p.src.addr, p.dest.addr, default_flowid) &&
  1194. flow_table[flowidx].flowId == default_flowid &&
  1195. !srh->num_addrs() && iph->ttl() == flow_table[flowidx].expectedTTL &&
  1196. flow_table[flowidx].allowDefault) {
  1197.       // we can go without anything... woo hoo!
  1198.       assert(!srh->flow_header());
  1199.     } else {
  1200.       srh->flow_header() = 1;
  1201.       srh->flow_id() = flow_table[flowidx].flowId;
  1202.       srh->hopCount() = 1;
  1203.     }
  1204.     trace("SF%ss %.9f _%s_ %d [%s -> %s] %d(%d) to %d %s", 
  1205. srh->num_addrs() ? "EST" : "",
  1206. Scheduler::instance().clock(), net_id.dump(), cmnh->uid(),
  1207. p.src.dump(), p.dest.dump(), flow_table[flowidx].flowId,
  1208. srh->flow_header(), flow_table[flowidx].nextHop,
  1209. srh->num_addrs() ? srh->dump() : "");
  1210.     cmnh->size() += srh->size();
  1211.     cmnh->xmit_failure_ = srh->num_addrs() ? XmitFailureCallback : 
  1212.      XmitFlowFailureCallback;
  1213.     cmnh->xmit_failure_data_ = (void *) this;
  1214.     assert(!srh->num_addrs() || srh->flow_timeout());
  1215.   } else {
  1216.     // old non-flowstate stuff...
  1217.     assert(p.src != net_id || !srh->flow_header());
  1218.     cmnh->size() += srh->size();
  1219.     if (srh->route_request())
  1220.       { // broadcast forward
  1221.         cmnh->xmit_failure_ = 0;
  1222.         cmnh->next_hop() = MAC_BROADCAST;
  1223.         cmnh->addr_type() = NS_AF_ILINK;
  1224.       }
  1225.     else
  1226.       { // forward according to source route
  1227.         cmnh->xmit_failure_ = XmitFailureCallback;
  1228.         cmnh->xmit_failure_data_ = (void *) this;
  1229.         cmnh->next_hop() = srh->get_next_addr();
  1230.         cmnh->addr_type() = srh->get_next_type();
  1231.         srh->cur_addr() = srh->cur_addr() + 1;
  1232.       } /* route_request() */
  1233.   } /* can snag for path state */
  1234.   /* put route errors at the head of the ifq somehow? -dam 4/13/98 */
  1235.   // make sure we aren't cycling packets
  1236.   
  1237. #ifdef notdef
  1238.   if (ifq->prq_length() > 25)
  1239.   trace("SIFQ %.5f _%s_ len %d",
  1240. Scheduler::instance().clock(),
  1241. net_id.dump(), ifq->prq_length());
  1242. #endif
  1243. #ifdef NEW_IFQ_LOGIC
  1244.   /*
  1245.    *  If the interface queue is full, there's no sense in sending
  1246.    *  the packet.  Drop it and generate a Route Error?
  1247.    */
  1248.   /* question for the author: this seems rife with congestion/infinite loop
  1249.    * possibilities. you're responding to an ifq full by sending a rt err.
  1250.    * sounds like the source quench problem. ych 5/5/01
  1251.    */
  1252.   if(ifq->prq_isfull(p.pkt)) {
  1253.   xmitFailed(p.pkt, DROP_IFQ_QFULL);
  1254.   p.pkt = 0;
  1255.   return;
  1256.   }
  1257. #endif /* NEW_IFQ_LOGIC */
  1258.   // ych debugging
  1259.   assert(!srh->flow_header() || !srh->num_addrs() || srh->flow_timeout());
  1260.   // off it goes!
  1261.   if (srh->route_request())
  1262.     { // route requests need to be jittered a bit
  1263.       Scheduler::instance().schedule(ll, p.pkt, 
  1264.      Random::uniform(RREQ_JITTER) + delay);
  1265.     }
  1266.   else
  1267.     { // no jitter required 
  1268.       Scheduler::instance().schedule(ll, p.pkt, delay);
  1269.     }
  1270.   p.pkt = NULL; /* packet sent off */
  1271. }
  1272. void
  1273. DSRAgent::getRouteForPacket(SRPacket &p, bool retry)
  1274.   /* try to obtain a route for packet
  1275.      pkt is freed or handed off as needed, unless retry == true
  1276.      in which case it is not touched */
  1277. {
  1278.   // since we'll commonly be only one hop away, we should
  1279.   // arp first before route discovery as an optimization...
  1280.   Entry *e = request_table.getEntry(p.dest);
  1281.   Time time = Scheduler::instance().clock();
  1282. #if 0
  1283.   /* pre 4/13/98 logic -dam removed b/c it seemed more complicated than
  1284.      needed since we're not doing piggybacking and we're returning
  1285.      route replies via a reversed route (the copy in this code is
  1286.      critical if we need to piggyback route replies on the route request to
  1287.      discover the return path) */
  1288.   /* make the route request packet */
  1289.   SRPacket rrp = p;
  1290.   rrp.pkt = p.pkt->copy();
  1291.   hdr_sr *srh = hdr_sr::access(rrp.pkt);
  1292.   hdr_ip *iph = hdr_ip::access(rrp.pkt);
  1293.   hdr_cmn *cmh =  hdr_cmn::access(rrp.pkt);
  1294.   //iph->daddr() = p.dest.getNSAddr_t();
  1295.   iph->daddr() = Address::instance().create_ipaddr(p.dest.getNSAddr_t(),RT_PORT);
  1296.   iph->dport() = RT_PORT;
  1297.   //iph->saddr() = net_id.getNSAddr_t();
  1298.   iph->saddr() = Address::instance().create_ipaddr(net_id.getNSAddr_t(),RT_PORT);
  1299.   iph->sport() = RT_PORT;
  1300.   cmnh->ptype() = PT_DSR;
  1301.   cmnh->size() = size_;
  1302.   cmnh->num_forwards() = 0;
  1303. #endif
  1304.   /* make the route request packet */
  1305.   SRPacket rrp;
  1306.   rrp.dest = p.dest;
  1307.   rrp.src = net_id;
  1308.   rrp.pkt = allocpkt();
  1309.   hdr_sr *srh = hdr_sr::access(rrp.pkt); 
  1310.   hdr_ip *iph = hdr_ip::access(rrp.pkt);
  1311.   hdr_cmn *cmnh =  hdr_cmn::access(rrp.pkt);
  1312.   
  1313.   iph->daddr() = Address::instance().create_ipaddr(p.dest.getNSAddr_t(),RT_PORT);
  1314.   iph->dport() = RT_PORT;
  1315.   iph->saddr() = Address::instance().create_ipaddr(net_id.getNSAddr_t(),RT_PORT);
  1316.   iph->sport() = RT_PORT;
  1317.   cmnh->ptype() = PT_DSR;
  1318.   cmnh->size() = size_ + IP_HDR_LEN; // add in IP header
  1319.   cmnh->num_forwards() = 0;
  1320.   
  1321.   srh->init();
  1322.   if (BackOffTest(e, time)) {
  1323.   // it's time to start another route request cycle
  1324. #ifdef NEW_SALVAGE_LOGIC
  1325.   if(p.src != net_id) {
  1326.   assert(dsr_salvage_max_requests > 0);
  1327.   assert(p.pkt);
  1328.   if(e->rt_reqs_outstanding > dsr_salvage_max_requests) {
  1329.   drop(p.pkt, DROP_RTR_NO_ROUTE);
  1330.   p.pkt = 0;
  1331.   // dump the route request packet we made up
  1332.   Packet::free(rrp.pkt);
  1333.   rrp.pkt = 0;
  1334.   return;
  1335.   }
  1336.   }
  1337. #endif /* NEW_SALVAGE_LOGIC */
  1338.   if (dsragent_ring_zero_search) {
  1339.   // do a ring zero search
  1340.   e->last_type = LIMIT0;
  1341.   sendOutRtReq(rrp, 0);
  1342.   } else {
  1343.   // do a propagating route request right now
  1344.   e->last_type = UNLIMIT;
  1345.   sendOutRtReq(rrp, MAX_SR_LEN);
  1346.   }
  1347.   e->last_arp = time;
  1348.   }  else if (LIMIT0 == e->last_type &&
  1349. #ifdef NEW_SALVAGE_LOGIC
  1350.       (dsr_salvage_allow_propagating || p.src == net_id) &&
  1351. #endif
  1352.    (time - e->last_arp) > arp_timeout) {
  1353.   // try propagating rt req since we haven't heard back
  1354.   // from limited one
  1355.   e->last_type = UNLIMIT;
  1356.   sendOutRtReq(rrp, MAX_SR_LEN);
  1357.   }
  1358.   else {
  1359.   // it's not time to send another route request...
  1360.   if (!retry && verbose_srr)
  1361.   trace("SRR %.5f _%s_ RR-not-sent %s -> %s", 
  1362. Scheduler::instance().clock(), 
  1363. net_id.dump(), rrp.src.dump(), rrp.dest.dump());
  1364.   Packet::free(rrp.pkt); // dump the route request packet we made up
  1365.   rrp.pkt = 0;
  1366.   }
  1367.   /* for now, no piggybacking at all, queue all pkts */
  1368.   if (!retry) {
  1369.   stickPacketInSendBuffer(p);
  1370.   p.pkt = 0; // pkt is handled for now (it's in sendbuffer)
  1371.   }
  1372. }
  1373. void
  1374. DSRAgent::sendOutRtReq(SRPacket &p, int max_prop)
  1375.   // turn p into a route request and launch it, max_prop of request is
  1376.   // set as specified
  1377.   // p.pkt is freed or handed off
  1378. {
  1379.   hdr_sr *srh =  hdr_sr::access(p.pkt);
  1380.   assert(srh->valid());
  1381.   srh->route_request() = 1;
  1382.   srh->rtreq_seq() = route_request_num++;
  1383.   srh->max_propagation() = max_prop;
  1384.   p.route.reset();
  1385.   p.route.appendToPath(net_id);
  1386.   if (dsragent_propagate_last_error && route_error_held 
  1387.       && Scheduler::instance().clock() - route_error_data_time  < max_err_hold)
  1388.     {
  1389.       assert(srh->num_route_errors() < MAX_ROUTE_ERRORS);
  1390.       srh->route_error() = 1;
  1391.       link_down *deadlink = &(srh->down_links()[srh->num_route_errors()]);
  1392.       deadlink->addr_type = NS_AF_INET;
  1393.       deadlink->from_addr = err_from.getNSAddr_t();
  1394.       deadlink->to_addr = err_to.getNSAddr_t();
  1395.       deadlink->tell_addr = GRAT_ROUTE_ERROR;
  1396.       srh->num_route_errors() += 1;
  1397.       /*
  1398.        * Make sure that the Route Error gets on a propagating request.
  1399.        */
  1400.       if(max_prop > 0) route_error_held = false;
  1401.     }
  1402.   if (verbose_srr)
  1403.     trace("SRR %.5f _%s_ new-request %d %s #%d -> %s", 
  1404.   Scheduler::instance().clock(), net_id.dump(), 
  1405.   max_prop, p.src.dump(), srh->rtreq_seq(), p.dest.dump());
  1406.   sendOutPacketWithRoute(p, false);
  1407. }
  1408. void
  1409. DSRAgent::returnSrcRouteToRequestor(SRPacket &p)
  1410.   // take the route in p, add us to the end of it and return the
  1411.   // route to the sender of p
  1412.   // doesn't free p.pkt
  1413. {
  1414.   hdr_sr *old_srh = hdr_sr::access(p.pkt);
  1415.   if (p.route.full()) 
  1416.     return; // alas, the route would be to long once we add ourselves
  1417.   SRPacket p_copy = p;
  1418.   p_copy.pkt = allocpkt();
  1419.   p_copy.dest = p.src;
  1420.   p_copy.src = net_id;
  1421.   p_copy.route.appendToPath(net_id);
  1422.   hdr_ip *new_iph =  hdr_ip::access(p_copy.pkt);
  1423.   //new_iph->daddr() = p_copy.dest.addr;
  1424.   new_iph->daddr() = Address::instance().create_ipaddr(p_copy.dest.getNSAddr_t(),RT_PORT);
  1425.   new_iph->dport() = RT_PORT;
  1426.   //new_iph->saddr() = p_copy.src.addr;
  1427.   new_iph->saddr() =
  1428.     Address::instance().create_ipaddr(p_copy.src.getNSAddr_t(),RT_PORT); 
  1429.   new_iph->sport() = RT_PORT;
  1430.   new_iph->ttl() = 255;
  1431.   hdr_sr *new_srh =  hdr_sr::access(p_copy.pkt);
  1432.   new_srh->init();
  1433.   for (int i = 0 ; i < p_copy.route.length() ; i++)
  1434.     p_copy.route[i].fillSRAddr(new_srh->reply_addrs()[i]);
  1435.   new_srh->route_reply_len() = p_copy.route.length();
  1436.   new_srh->route_reply() = 1;
  1437.   // propagate the request sequence number in the reply for analysis purposes
  1438.   new_srh->rtreq_seq() = old_srh->rtreq_seq();
  1439.   
  1440.   hdr_cmn *new_cmnh =  hdr_cmn::access(p_copy.pkt);
  1441.   new_cmnh->ptype() = PT_DSR;
  1442.   new_cmnh->size() = IP_HDR_LEN;
  1443.   if (verbose_srr)
  1444.     trace("SRR %.9f _%s_ reply-sent %s -> %s #%d (len %d) %s",
  1445.   Scheduler::instance().clock(), net_id.dump(),
  1446.   p_copy.src.dump(), p_copy.dest.dump(), old_srh->rtreq_seq(),
  1447.   p_copy.route.length(), p_copy.route.dump());
  1448.   // flip the route around for the return to the requestor, and 
  1449.   // cache the route for future use
  1450.   p_copy.route.reverseInPlace();
  1451.   route_cache->addRoute(p_copy.route, Scheduler::instance().clock(), net_id);
  1452.   p_copy.route.resetIterator();
  1453.   p_copy.route.fillSR(new_srh);
  1454.   new_cmnh->size() += new_srh->size();
  1455.   
  1456.   /* we now want to jitter when we first originate route replies, since
  1457.      they are a transmission we make in response to a broadcast packet 
  1458.      -dam 4/23/98
  1459.      sendOutPacketWithRoute(p_copy, true); */
  1460.   {
  1461.   double d = Random::uniform(RREQ_JITTER);
  1462. #if 0
  1463.   fprintf(stderr, "Random Delay: %fn", d);
  1464. #endif
  1465.   Scheduler::instance().schedule(this, p_copy.pkt, d);
  1466.   }
  1467. }
  1468. int
  1469. DSRAgent::diff_subnet(ID dest, ID myid) 
  1470. {
  1471. int dst = dest.addr;
  1472. int id = myid.addr;
  1473. char* dstnet = Address::instance().get_subnetaddr(dst);
  1474. char * subnet = Address::instance().get_subnetaddr(id);
  1475. if (subnet != NULL) {
  1476. if (dstnet != NULL) {
  1477. if (strcmp(dstnet, subnet) != 0) {
  1478. delete [] dstnet;
  1479. return 1;
  1480. }
  1481. delete [] dstnet;
  1482. }
  1483. delete [] subnet;
  1484. }
  1485. assert(dstnet == NULL);
  1486. return 0;
  1487. }
  1488. void
  1489. DSRAgent::acceptRouteReply(SRPacket &p)
  1490.   /* - enter the packet's source route into our cache
  1491.      - see if any packets are waiting to be sent out with this source route
  1492.      - doesn't free the pkt */
  1493. {
  1494.   hdr_sr *srh =  hdr_sr::access(p.pkt);
  1495.   Path reply_route(srh->reply_addrs(), srh->route_reply_len());
  1496.   if (!srh->route_reply())
  1497.     { // somethings wrong...
  1498.       trace("SDFU non route containing packet given to acceptRouteReply");
  1499.       fprintf(stderr,
  1500.       "dfu: non route containing packet given to acceptRouteReplyn");
  1501.     }
  1502.   bool good_reply = true;  
  1503.   //#ifdef USE_GOD_FEEDBACK
  1504.   /* check to see if this reply is valid or not using god info */
  1505.   int i;
  1506.   
  1507.   for (i = 0; i < reply_route.length()-1 ; i++) 
  1508.     if (God::instance()->hops(reply_route[i].getNSAddr_t(), 
  1509.       reply_route[i+1].getNSAddr_t()) != 1)
  1510.       {
  1511. good_reply = false;
  1512. break;
  1513.       }
  1514.   //#endif //GOD_FEEDBACK
  1515.   if (verbose_srr)
  1516.     trace("SRR %.9f _%s_ reply-received %d from %s  %s #%d -> %s %s",
  1517.   Scheduler::instance().clock(), net_id.dump(),
  1518.   good_reply ? 1 : 0,
  1519.   p.src.dump(), reply_route[0].dump(), srh->rtreq_seq(),
  1520.   reply_route[reply_route.length()-1].dump(),
  1521.   reply_route.dump());
  1522.   // add the new route into our cache
  1523.   route_cache->addRoute(reply_route, Scheduler::instance().clock(), p.src);
  1524.   // back down the route request counters
  1525.   Entry *e = request_table.getEntry(reply_route[reply_route.length()-1]);
  1526.   e->rt_reqs_outstanding = 0;
  1527.   e->last_rt_req = 0.0;  
  1528.   // see if the addtion of this route allows us to send out
  1529.   // any of the packets we have waiting
  1530.   Time delay = 0.0;
  1531.   ID dest;
  1532.   for (int c = 0; c < SEND_BUF_SIZE; c++)
  1533.     {
  1534.       if (send_buf[c].p.pkt == NULL) continue;
  1535.       // check if pkt is destined to outside domain
  1536.       if (diff_subnet(send_buf[c].p.dest,net_id)) {
  1537. dest = ID(node_->base_stn(),::IP);
  1538. send_buf[c].p.dest = dest;
  1539.       }
  1540.       if (route_cache->findRoute(send_buf[c].p.dest, send_buf[c].p.route, 1))
  1541. { // we have a route!
  1542. #ifdef DEBUG
  1543.   struct hdr_cmn *ch = HDR_CMN(send_buf[c].p.pkt);
  1544.   if(ch->size() < 0) {
  1545. drop(send_buf[c].p.pkt, "XXX");
  1546. abort();
  1547.   }
  1548. #endif
  1549.   if (verbose)
  1550.     trace("Sdebug %.9f _%s_ liberated from sendbuf %s->%s %s",
  1551.   Scheduler::instance().clock(), net_id.dump(),
  1552.   send_buf[c].p.src.dump(), send_buf[c].p.dest.dump(), 
  1553.   send_buf[c].p.route.dump());
  1554.   /* we need to spread out the rate at which we send packets
  1555.      in to the link layer to give ARP time to complete.  If we
  1556.      dump all the packets in at once, all but the last one will
  1557.      be dropped.  XXX THIS IS A MASSIVE HACK -dam 4/14/98 */
  1558.   sendOutPacketWithRoute(send_buf[c].p, true, delay);
  1559.   delay += arp_timeout;
  1560.   send_buf[c].p.pkt = NULL;
  1561. }
  1562.     }
  1563. }
  1564. void
  1565. DSRAgent::processUnknownFlowError(SRPacket &p, bool asDefault) {
  1566.   hdr_sr *srh = hdr_sr::access(p.pkt);
  1567.   int flowidx = -1;
  1568.   struct flow_error *fe;
  1569.   u_int16_t flowid;
  1570.   if (asDefault) {
  1571.     assert (srh->flow_default_unknown() && srh->num_default_unknown());
  1572.     fe = &srh->unknown_defaults()[srh->num_default_unknown()-1];
  1573.   } else {
  1574.     assert (srh->flow_unknown() && srh->num_flow_unknown());
  1575.     fe = &srh->unknown_flows()[srh->num_flow_unknown()-1];
  1576.     if (!flow_table.defaultFlow(fe->flow_src, fe->flow_dst, flowid))
  1577.       goto skip_proc;
  1578.   }
  1579.   /* not for us; hope it gets the right place... */
  1580.   if (fe->flow_src != (int) net_id.addr)
  1581.     return;
  1582.   if (-1 != (flowidx = flow_table.find(fe->flow_src, fe->flow_dst, 
  1583.        asDefault ? flowid : fe->flow_id)))
  1584.     flow_table[flowidx].count = 0;
  1585. skip_proc:
  1586.   trace("SFEr %.9f _%s_ from %d re %d : %d [%d]",
  1587. Scheduler::instance().clock(), net_id.dump(), p.src.addr, fe->flow_dst,
  1588. asDefault ? -1 : fe->flow_id, 
  1589. flowidx != -1 ? flow_table[flowidx].count : -1);
  1590.   if ((asDefault ? srh->num_default_unknown() : srh->num_flow_unknown()) == 1)
  1591.     return;
  1592.   SRPacket p_copy = p;
  1593.   p_copy.pkt = p.pkt->copy();
  1594.   hdr_sr *new_srh = hdr_sr::access(p_copy.pkt);
  1595.   hdr_ip *new_iph = hdr_ip::access(p_copy.pkt);
  1596.   
  1597.   // remove us from the list of errors
  1598.   if (asDefault)
  1599.     new_srh->num_default_unknown()--;
  1600.   else
  1601.     new_srh->num_flow_unknown()--;
  1602.   
  1603.   // send the packet to the person listed in what's now the last entry
  1604.   p_copy.dest = ID(fe[-1].flow_src, ::IP);
  1605.   p_copy.src = net_id;
  1606.   //new_iph->daddr() = p_copy.dest.addr;
  1607.   new_iph->daddr() = Address::instance().create_ipaddr(p_copy.dest.getNSAddr_t(),RT_PORT);
  1608.   new_iph->dport() = RT_PORT;
  1609.   //new_iph->saddr() = p_copy.src.addr;
  1610.   new_iph->saddr() = Address::instance().create_ipaddr(p_copy.src.getNSAddr_t(),RT_PORT);
  1611.   new_iph->sport() = RT_PORT;
  1612.   new_iph->ttl() = 255;
  1613.   new_srh->flow_header() = 0;
  1614.   new_srh->flow_timeout() = 0;
  1615.   // an error packet is a first class citizen, so we'll
  1616.   // use handlePktWOSR to obtain a route if needed
  1617.   handlePktWithoutSR(p_copy, false);
  1618. }
  1619. void
  1620. DSRAgent::processBrokenRouteError(SRPacket& p)
  1621. // take the error packet and proccess our part of it.
  1622. // if needed, send the remainder of the errors to the next person
  1623. // doesn't free p.pkt
  1624. {
  1625.   hdr_sr *srh = hdr_sr::access(p.pkt);
  1626.   if (!srh->route_error())
  1627.     return; // what happened??
  1628.   
  1629.   /* if we hear A->B is dead, should we also run the link B->A through the
  1630.      cache as being dead, since 802.11 requires bidirectional links 
  1631.       XXX -dam 4/23/98 */
  1632.   // since CPU time is cheaper than network time, we'll process
  1633.   // all the dead links in the error packet
  1634.   assert(srh->num_route_errors() > 0);
  1635.   for (int c = 0 ; c < srh->num_route_errors() ; c++)
  1636.     {
  1637.       assert(srh->down_links()[c].addr_type == NS_AF_INET);
  1638.       route_cache->noticeDeadLink(ID(srh->down_links()[c].from_addr,::IP),
  1639.  ID(srh->down_links()[c].to_addr,::IP),
  1640.  Scheduler::instance().clock());
  1641.       flow_table.noticeDeadLink(ID(srh->down_links()[c].from_addr,::IP),
  1642.  ID(srh->down_links()[c].to_addr,::IP));
  1643.       // I'll assume everything's of type NS_AF_INET for the printout... XXX
  1644.       if (verbose_srr)
  1645.         trace("SRR %.9f _%s_ dead-link tell %d  %d -> %d",
  1646.               Scheduler::instance().clock(), net_id.dump(),
  1647.               srh->down_links()[c].tell_addr,
  1648.               srh->down_links()[c].from_addr,
  1649.               srh->down_links()[c].to_addr);
  1650.     }
  1651.   ID who = ID(srh->down_links()[srh->num_route_errors()-1].tell_addr, ::IP);
  1652.   if (who != net_id && who != MAC_id)
  1653.     { // this error packet wasn't meant for us to deal with
  1654.       // since the outer entry doesn't list our name
  1655.       return;
  1656.     }
  1657.   // record this route error data for possible propagation on our next
  1658.   // route request
  1659.   route_error_held = true;
  1660.   err_from = ID(srh->down_links()[srh->num_route_errors()-1].from_addr,::IP);
  1661.   err_to = ID(srh->down_links()[srh->num_route_errors()-1].to_addr,::IP);
  1662.   route_error_data_time = Scheduler::instance().clock();
  1663.   if (1 == srh->num_route_errors())
  1664.     { // this error packet has done its job
  1665.       // it's either for us, in which case we've done what it sez
  1666.       // or it's not for us, in which case we still don't have to forward
  1667.       // it to whoever it is for
  1668.       return;
  1669.     }
  1670.   /* make a copy of the packet and send it to the next tell_addr on the
  1671.      error list.  the copy is needed in case there is other data in the
  1672.      packet (such as nested route errors) that need to be delivered */
  1673.   if (verbose) 
  1674.     trace("Sdebug %.5f _%s_ unwrapping nested route error",
  1675.           Scheduler::instance().clock(), net_id.dump());
  1676.   
  1677.   SRPacket p_copy = p;
  1678.   p_copy.pkt = p.pkt->copy();
  1679.   hdr_sr *new_srh = hdr_sr::access(p_copy.pkt);
  1680.   hdr_ip *new_iph = hdr_ip::access(p_copy.pkt);
  1681.   
  1682.   // remove us from the list of errors
  1683.   new_srh->num_route_errors() -= 1;
  1684.   
  1685.   // send the packet to the person listed in what's now the last entry
  1686.   p_copy.dest = ID(new_srh->down_links()[new_srh->num_route_errors()-1].tell_addr, ::IP);
  1687.   p_copy.src = net_id;
  1688.   //new_iph->daddr() = p_copy.dest.addr;
  1689.   new_iph->daddr() = Address::instance().create_ipaddr(p_copy.dest.getNSAddr_t(),RT_PORT);
  1690.   new_iph->dport() = RT_PORT;
  1691.   //new_iph->saddr() = p_copy.src.addr;
  1692.   new_iph->saddr() = Address::instance().create_ipaddr(p_copy.src.getNSAddr_t(),RT_PORT);
  1693.   new_iph->sport() = RT_PORT;
  1694.   new_iph->ttl() = 255;
  1695.   new_srh->flow_header() = 0;
  1696.   new_srh->flow_timeout() = 0;
  1697.       
  1698.   // an error packet is a first class citizen, so we'll
  1699.   // use handlePktWOSR to obtain a route if needed
  1700.   handlePktWithoutSR(p_copy, false);
  1701. }
  1702. #ifdef DSR_FILTER_TAP
  1703. int64_t dsr_tap = 0;
  1704. int64_t dsr_tap_skip = 0;
  1705. #endif
  1706. // Process flow state Automatic Route Shortening
  1707. void
  1708. DSRAgent::processFlowARS(const Packet *packet) {
  1709.   
  1710.   hdr_sr *srh = hdr_sr::access(packet);
  1711.   hdr_ip *iph = hdr_ip::access(packet);
  1712.   hdr_cmn *cmh = hdr_cmn::access(packet);
  1713.   //hdr_sr  *srh = (hdr_sr*) ((Packet *)packet)->access(off_sr_);
  1714.   //hdr_ip  *iph = (hdr_ip*) ((Packet *)packet)->access(off_ip_);
  1715.   //hdr_cmn *cmh =  (hdr_cmn*)((Packet *)packet)->access(off_cmn_);
  1716.   u_int16_t flowid;
  1717.   int flowidx;
  1718.   int shortamt;
  1719.   assert(!srh->num_addrs());
  1720.   if (srh->flow_header()) {
  1721.     flowid = srh->flow_id();
  1722.     // do I know about this flow?
  1723.     if (-1 == (flowidx = flow_table.find(iph->saddr(), iph->daddr(), flowid)))
  1724.       return;
  1725.     shortamt = flow_table[flowidx].hopCount - srh->hopCount();
  1726.   } else {
  1727.     // do I know which flow is default?
  1728.     if (!flow_table.defaultFlow(iph->saddr(), iph->daddr(), flowid))
  1729.       return;
  1730.     // do I know about this flow?
  1731.     if (-1 == (flowidx = flow_table.find(iph->saddr(), iph->daddr(), flowid)))
  1732.       return;
  1733.     shortamt = iph->ttl() - flow_table[flowidx].expectedTTL;
  1734.   }
  1735.   // transmitter downstream from us
  1736.   if (shortamt <= 0)
  1737.     return;
  1738.   // this is a _MAJOR_ problem!!!
  1739.   if (flow_table[flowidx].sourceRoute.length() < shortamt)
  1740.     return;
  1741.   ars_table.insert(cmh->uid(), flowid, shortamt);
  1742. }
  1743. void 
  1744. DSRAgent::tap(const Packet *packet)
  1745.   /* process packets that are promiscously listened to from the MAC layer tap
  1746.   *** do not change or free packet *** */
  1747. {
  1748.   hdr_sr *srh = hdr_sr::access(packet);
  1749.   hdr_ip *iph = hdr_ip::access(packet);
  1750.   hdr_cmn *cmh =  hdr_cmn::access(packet);
  1751.   
  1752.   if (!dsragent_use_tap) return;
  1753.   if (!srh->valid()) return; // can't do anything with it
  1754.   if (!srh->num_addrs()) {
  1755.     processFlowARS(packet);
  1756.     return;
  1757.   }
  1758.   // don't trouble me with packets I'm about to receive anyway
  1759.   /* this change added 5/13/98 -dam */
  1760.   ID next_hop(srh->addrs()[srh->cur_addr()]);
  1761.   if (next_hop == net_id || next_hop == MAC_id) return;
  1762.   SRPacket p((Packet *) packet, srh);
  1763.   //p.dest = ID(iph->dst(),::IP);
  1764.   //p.src = ID(iph->src(),::IP);
  1765.   p.dest = ID((Address::instance().get_nodeaddr(iph->daddr())),::IP);
  1766.   p.src = ID((Address::instance().get_nodeaddr(iph->saddr())),::IP);
  1767.   // don't trouble me with my own packets
  1768.   if (p.src == net_id) return; 
  1769. #ifdef DSR_FILTER_TAP
  1770.   /* 
  1771.    * Don't process packets more than once.  In real implementations
  1772.    * this can be done with the (IP Source, IP ID) pair, but it is
  1773.    * simpler to implement it with the global "uid" in simulation.
  1774.    */
  1775.   {
  1776.           int uid = cmh->uid();
  1777.           if(tap_uid_cache[(uid & TAP_BITMASK)] == uid) {
  1778.   dsr_tap_skip++;
  1779.                   return;
  1780.   }
  1781.   dsr_tap++;
  1782.           tap_uid_cache[(uid & TAP_BITMASK)] = uid;
  1783.   }
  1784. #endif
  1785.   /* snoop on the SR data */
  1786.   if (srh->route_error())
  1787.     {
  1788.       if (verbose)
  1789. trace("Sdebug _%s_ tap saw error %d",  net_id.dump(), cmh->uid());
  1790.       processBrokenRouteError(p);
  1791.     }
  1792.   if (srh->route_reply())
  1793.     {
  1794.       Path reply_path(srh->reply_addrs(), srh->route_reply_len());
  1795.       if(verbose)
  1796. trace("Sdebug _%s_ tap saw route reply %d  %s",
  1797.        net_id.dump(), cmh->uid(), reply_path.dump());
  1798.       route_cache->noticeRouteUsed(reply_path, Scheduler::instance().clock(), 
  1799.    p.src);
  1800.     }
  1801.   /* we can't decide whether we should snoop on the src routes in 
  1802.      route requests.  We've seen cases where we hear a route req from a
  1803.      node, but can't complete an arp with that node (and so can't actually
  1804.      deliver packets through it if called on to do so) -dam 4/16/98 */
  1805.   if (srh->route_request()) return; // don't path shorten route requests
  1806.   // the logic is wrong for shortening rtreq's anyway, cur_addr always = 0
  1807.   if (dsragent_snoop_source_routes)
  1808.     {
  1809.       if (verbose)
  1810. trace("Sdebug _%s_ tap saw route use %d %s", net_id.dump(), 
  1811.       cmh->uid(), p.route.dump());
  1812.       route_cache->noticeRouteUsed(p.route, Scheduler::instance().clock(), 
  1813.    net_id);
  1814.     }
  1815.   if (PT_DSR == cmh->ptype()) return; //  no route shortening on any
  1816.   // DSR packet
  1817.   /* I think we ended up sending grat route replies for source routes on 
  1818.      route replies for route requests that were answered by someone else's
  1819.      cache, resulting in the wrong node receiving the route.  For now, I 
  1820.      outlaw it.
  1821.      The root of the problem is that when we salvage a pkt from a failed
  1822.      link using a route from our cache, we break what had been an invariant
  1823.      that the IP src of a packet was also the first machine listed on the
  1824.      source route.  Here's the route of the problem that results in the 
  1825.      simulator crashing at 8.56135 when 44 recieves a route reply that
  1826.      has 24 listed as the first node in the route.
  1827. SSendFailure 8.52432 24 [10 |24 46 45 1 40 ]
  1828. S$hit 8.52432 salvaging 10 -> 40 with [(24) 44 50 9 40 ]
  1829. S$hit 8.52432 salvaging 44 -> 40 with [(24) 44 50 9 40 ]
  1830. D 8.52432 [20 42 2e 18 800] 24 DSR 156 -- 10->40 6 [0] [1 9 39] [0 0 0->0]
  1831. s 8.52438 [1b 45e 2c 18 0] 24 MAC 20
  1832. r 8.52446 [1b 45e 2c 18 0] 44 MAC 20
  1833. s 8.52454 [101b 27e 23 1b 0] 27 MAC 20
  1834. s 8.52564 [101b 27e 23 1b 0] 27 MAC 20
  1835. s 8.52580 [101b 45e 2c 18 0] 24 MAC 20
  1836. r 8.52588 [101b 45e 2c 18 0] 44 MAC 20
  1837. s 8.52589 [1c 41c 18 0 0] 44 MAC 14
  1838. r 8.52595 [1c 41c 18 0 0] 24 MAC 14
  1839. s 8.52600 [20 42 2c 18 800] 24 DSR 244 -- 10->40 5 [0] [1 9 39] [0 0 24->46]
  1840. r 8.52698 [20 42 2c 18 800] 44 DSR 216 -- 10->40 5 [0] [1 9 39] [0 0 24->46]
  1841. s 8.53947 [20 42 2c 18 800] 24 DSR 204 -- 44->40 5 [0] [1 8 39] [0 0 0->0]
  1842. r 8.54029 [20 42 2c 18 800] 44 DSR 176 -- 44->40 5 [0] [1 8 39] [0 0 0->0]
  1843. Sdebug 50 consider grat arp for [24 (44) 50 9 40 ]
  1844. SRR 8.54029 50 gratuitous-reply-sent 50 -> 44 [24 (50) 9 40 ]
  1845. SF 8.54029 44 [44 -> 40] via 0x3200 [24 |44 50 9 40 ]
  1846. s 8.54030 [1d 0 18 0 0] 44 MAC 14
  1847. r 8.54036 [1d 0 18 0 0] 24 MAC 14
  1848. s 8.54044 [101b 54f 32 2c 0] 44 MAC 20
  1849. r 8.54053 [101b 54f 32 2c 0] 50 MAC 20
  1850. s 8.54054 [1c 50d 2c 0 0] 50 MAC 14
  1851. r 8.54059 [1c 50d 2c 0 0] 44 MAC 14
  1852. s 8.54064 [20 42 32 2c 800] 44 DSR 304 -- 10->40 5 [0] [1 9 39] [0 0 24->46]
  1853. r 8.54186 [20 42 32 2c 800] 50 DSR 276 -- 10->40 5 [0] [1 9 39] [0 0 24->46]
  1854. SF 8.54186 50 [10 -> 40] via 0x900 [24 44 |50 9 40 ]
  1855. s 8.56101 [20 42 2c 18 800] 24 DSR 84 -- 50->44 2 [0] [1 4 40] [0 0 0->0]
  1856. r 8.56135 [20 42 2c 18 800] 44 DSR 56 -- 50->44 2 [0] [1 4 40] [0 0 0->0]
  1857. */
  1858.   /* check to see if we can shorten the route being used */
  1859.   if (p.route[p.route.index()] != net_id
  1860.       && p.route[p.route.index()] != MAC_id)
  1861.     { // it's not immeadiately to us
  1862.       for (int i = p.route.index() + 1; i < p.route.length(); i++)
  1863. if (p.route[i] == net_id || p.route[i] == MAC_id)
  1864.   { // but it'll get here eventually...
  1865.     sendRouteShortening(p, p.route.index(), i);
  1866.   }
  1867.     }
  1868. }
  1869. static GratReplyHoldDown *
  1870. FindGratHoldDown(GratReplyHoldDown *hd, int sz, Path& query)
  1871. {
  1872.   int c;
  1873.   for (c = 0; c < sz; c++)
  1874.     if (query == hd[c].p) return &hd[c];
  1875.   return NULL;
  1876. }
  1877. void
  1878. DSRAgent::sendRouteShortening(SRPacket &p, int heard_at, int xmit_at)
  1879.   // p was overheard at heard_at in it's SR, but we aren't supposed to
  1880.   // get it till xmit_at, so all the nodes between heard_at and xmit_at
  1881.   // can be elided.  Send originator of p a gratuitous route reply to 
  1882.   // tell them this.
  1883. {
  1884.   // this shares code with returnSrcRouteToRequestor - factor them -dam */
  1885.   if (!dsragent_send_grat_replies) return;
  1886.   if (verbose)
  1887.     trace("Sdebug %s consider grat arp for %s", net_id.dump(), p.route.dump());
  1888.   GratReplyHoldDown *g = FindGratHoldDown(grat_hold, RTREP_HOLDOFF_SIZE, 
  1889.   p.route);
  1890.   if (!g)
  1891.     { 
  1892.       grat_hold[grat_hold_victim].p = p.route;
  1893.       grat_hold_victim = (grat_hold_victim + 1) % RTREP_HOLDOFF_SIZE;
  1894.       g = &grat_hold[grat_hold_victim];      
  1895.     }
  1896.   else if (Scheduler::instance().clock() - g->t < grat_hold_down_time) return;
  1897.   g->t = Scheduler::instance().clock();
  1898.   SRPacket p_copy = p;
  1899.   p_copy.pkt = allocpkt();
  1900.   p_copy.dest = p.route[0];   // tell the originator of this long source route
  1901.   p_copy.src = net_id;
  1902.   // reverse the route to get the packet back
  1903.   p_copy.route[p_copy.route.index()] = net_id;
  1904.   p_copy.route.reverseInPlace();
  1905.   p_copy.route.removeSection(0,p_copy.route.index());
  1906.   hdr_ip *new_iph =  hdr_ip::access(p_copy.pkt);
  1907.   //new_iph->daddr() = p_copy.dest.addr;
  1908.   new_iph->daddr() = Address::instance().create_ipaddr(p_copy.dest.getNSAddr_t(),RT_PORT);
  1909.   new_iph->dport() = RT_PORT;
  1910.   //new_iph->saddr() = p_copy.src.addr;
  1911.   new_iph->saddr() = Address::instance().create_ipaddr(p_copy.src.getNSAddr_t(),RT_PORT);
  1912.   new_iph->sport() = RT_PORT;
  1913.   new_iph->ttl() = 255;
  1914.   // shorten's p's route
  1915.   p.route.removeSection(heard_at, xmit_at);
  1916.   hdr_sr *new_srh =  hdr_sr::access(p_copy.pkt);
  1917.   new_srh->init();
  1918.   for (int i = 0 ; i < p.route.length() ; i++)
  1919.     p.route[i].fillSRAddr(new_srh->reply_addrs()[i]);
  1920.   new_srh->route_reply_len() = p.route.length();
  1921.   new_srh->route_reply() = 1;
  1922.   // grat replies will have a 0 seq num (it's only for trace analysis anyway)
  1923.   new_srh->rtreq_seq() = 0;
  1924.   hdr_cmn *new_cmnh =  hdr_cmn::access(p_copy.pkt);
  1925.   new_cmnh->ptype() = PT_DSR;
  1926.   new_cmnh->size() += IP_HDR_LEN;
  1927.   if (verbose_srr)
  1928.     trace("SRR %.9f _%s_ gratuitous-reply-sent %s -> %s (len %d) %s",
  1929.   Scheduler::instance().clock(), net_id.dump(),
  1930.   p_copy.src.dump(), p_copy.dest.dump(), p.route.length(), 
  1931.   p.route.dump());
  1932.   // cache the route for future use (we learned the route from p)
  1933.   route_cache->addRoute(p_copy.route, Scheduler::instance().clock(), p.src);
  1934.   sendOutPacketWithRoute(p_copy, true);
  1935. }
  1936. /*==============================================================
  1937.   debug and trace output
  1938. ------------------------------------------------------------*/
  1939. void
  1940. DSRAgent::trace(char* fmt, ...)
  1941. {
  1942.   va_list ap;
  1943.   
  1944.   if (!logtarget) return;
  1945.   va_start(ap, fmt);
  1946.   vsprintf(logtarget->pt_->buffer(), fmt, ap);
  1947.   logtarget->pt_->dump();
  1948.   va_end(ap);
  1949. }
  1950. /*==============================================================
  1951.   Callback for link layer transmission failures
  1952. ------------------------------------------------------------*/
  1953. // XXX Obviously this structure and FilterFailure() is not used anywhere, 
  1954. // because off_cmn_ in this structure cannot be populated at all!
  1955. // Instead of deleting, I'm simply commenting them out, perhaps they'll be 
  1956. // salvaged sometime in the future. - haoboy
  1957. //  struct filterfailuredata {
  1958. //    nsaddr_t dead_next_hop;
  1959. //    int off_cmn_;
  1960. //    DSRAgent *agent;
  1961. //  };
  1962. //  int
  1963. //  FilterFailure(Packet *p, void *data)
  1964. //  {
  1965. //    struct filterfailuredata *ffd = (filterfailuredata *) data;
  1966. //    hdr_cmn *cmh = (hdr_cmn*)p->access(ffd->off_cmn_);
  1967. //    int remove = cmh->next_hop() == ffd->dead_next_hop;
  1968. //    if (remove)
  1969. //     ffd->agent->undeliverablePkt(p,1);
  1970. //    return remove;
  1971. //  }
  1972. void
  1973. DSRAgent::undeliverablePkt(Packet *pkt, int mine)
  1974.   /* when we've got a packet we can't deliver, what to do with it? 
  1975.      frees or hands off p if mine = 1, doesn't hurt it otherwise */
  1976. {
  1977.   hdr_sr *srh = hdr_sr::access(pkt);
  1978.   hdr_ip *iph = hdr_ip::access(pkt);
  1979.   hdr_cmn *cmh;
  1980.   SRPacket p(pkt,srh);
  1981.   //p.dest = ID(iph->dst(),::IP);
  1982.   //p.src = ID(iph->src(),::IP);
  1983.   p.dest = ID((Address::instance().get_nodeaddr(iph->daddr())),::IP);
  1984.   p.src = ID((Address::instance().get_nodeaddr(iph->saddr())),::IP);
  1985.   p.pkt = mine ? pkt : pkt->copy();
  1986.   srh = hdr_sr::access(p.pkt);
  1987.   iph = hdr_ip::access(p.pkt);
  1988.   cmh = hdr_cmn::access(p.pkt);
  1989.   // we're about to salvage. flowstate rules say we must strip all flow
  1990.   // state info out of this packet. ych 5/5/01
  1991.   cmh->size() -= srh->size(); // changes affect size of header...
  1992.   srh->flow_timeout() = 0;
  1993.   srh->flow_header() = 0;
  1994.   cmh->size() += srh->size(); // done fixing flow state headers
  1995.   if (ID((Address::instance().get_nodeaddr(iph->saddr())),::IP) == net_id) {
  1996.     // it's our packet we couldn't send
  1997.     cmh->size() -= srh->size(); // remove size of SR header
  1998.     assert(cmh->size() >= 0);
  1999.     
  2000.     handlePktWithoutSR(p, false);
  2001.     
  2002.     return;
  2003.   }
  2004.   /*
  2005.    * Am I allowed to salvage?
  2006.    */
  2007.   if(dsragent_salvage_with_cache == 0) {
  2008.   assert(mine);
  2009.   drop(pkt, DROP_RTR_NO_ROUTE);  
  2010.   return;
  2011.   }
  2012. #ifdef NEW_SALVAGE_LOGIC
  2013.   if(srh->salvaged() >= dsr_salvage_max_attempts) {
  2014.   assert(mine);
  2015.   drop(pkt, DROP_RTR_SALVAGE);
  2016.   return;
  2017.   }
  2018. #endif /* NEW_SALVAGE_LOGIC */
  2019.   // it's a packet we're forwarding for someone, save it if we can...
  2020.   Path salvage_route;
  2021.       
  2022.   if (route_cache->findRoute(p.dest, salvage_route, 0)) {
  2023.   // be nice and send the packet out
  2024. #if 0
  2025.   /* we'd like to create a ``proper'' source route with the
  2026.      IP src of the packet as the first node, but we can't actually 
  2027.      just append the salvage route onto the route used so far, 
  2028.      since the append creates routes with loops in them 
  2029.      like  1 2 3 4 3 5 
  2030.      If we were to squish the route to remove the loop, then we'd be
  2031.      removing ourselves from the route, which is verboten.
  2032.      If we did remove ourselves, and our salvage route contained
  2033.      a stale link, we might never hear the route error.
  2034.      -dam 5/13/98
  2035.      Could we perhaps allow SRs with loops in them on the air?
  2036.      Since it's still a finite length SR, the pkt can't loop
  2037.      forever... -dam 8/5/98 */
  2038.   // truncate the route at the bad link and append good bit
  2039.   int our_index = p.route.index();
  2040.   p.route.setLength(our_index);
  2041.   // yes this cuts us off the route,
  2042.   p.route.appendPath(salvage_route);
  2043.   // but we're at the front of s_r
  2044.   p.route.setIterator(our_index);
  2045. #else
  2046.   p.route = salvage_route;
  2047.   p.route.resetIterator();
  2048. #endif
  2049.   if (dsragent_dont_salvage_bad_replies && srh->route_reply()) {
  2050.   // check to see if we'd be salvaging a packet
  2051.   // with the dead link in it
  2052.   ID to_id(srh->addrs()[srh->cur_addr()+1].addr,
  2053.    (ID_Type) srh->addrs()[srh->cur_addr()].addr_type);
  2054.   bool bad_reply = false;
  2055.   for (int i = 0 ; i < srh->route_reply_len()-1; i++) {
  2056.   if (net_id == ID(srh->reply_addrs()[i]) &&
  2057.       to_id == ID(srh->reply_addrs()[i+1]) ||
  2058.       (dsragent_require_bi_routes &&
  2059.        to_id == ID(srh->reply_addrs()[i]) &&
  2060.        net_id == ID(srh->reply_addrs()[i+1]))) {
  2061.   
  2062.   bad_reply = true;
  2063.   break;
  2064.   }
  2065.   }
  2066.   if (bad_reply) {
  2067.   // think about killing this packet
  2068.   srh->route_reply() = 0;
  2069.   if (PT_DSR == cmh->ptype() &&
  2070.       ! srh->route_request() &&
  2071.       ! srh->route_error()) {
  2072.   // this packet has no reason to live
  2073.   if (verbose_srr)
  2074.   trace("SRR %.5f _%s_ --- %d dropping bad-reply %s -> %s", 
  2075. Scheduler::instance().clock(), net_id.dump(), 
  2076. cmh->uid(), p.src.dump(), p.dest.dump());
  2077.   if (mine)
  2078.   drop(pkt, DROP_RTR_MAC_CALLBACK);
  2079.   return;
  2080.   }
  2081.   }
  2082.   }
  2083.   if (verbose_ssalv) 
  2084.   trace("Ssalv %.5f _%s_ salvaging %s -> %s --- %d with %s",
  2085. Scheduler::instance().clock(), net_id.dump(),
  2086. p.src.dump(), p.dest.dump(),
  2087. cmh->uid(), p.route.dump());
  2088.   // remove size of SR header, added back in sendOutPacketWithRoute
  2089.   cmh->size() -= srh->size(); 
  2090.   assert(cmh->size() >= 0);
  2091. #ifdef NEW_SALVAGE_LOGIC
  2092.   srh->salvaged() += 1;
  2093. #endif
  2094.   sendOutPacketWithRoute(p, false);
  2095.   }
  2096. #ifdef NEW_SALVAGE_LOGIC
  2097.   else if(dsr_salvage_max_requests > 0) {
  2098.   /*
  2099.    * Allow the node to perform route discovery for an
  2100.    * intermediate hop.
  2101.    */
  2102.   if (verbose_ssalv) 
  2103.   trace("Ssalv %.5f _%s_ adding to SB --- %d %s -> %s [%d]", 
  2104. Scheduler::instance().clock(), 
  2105. net_id.dump(),
  2106. cmh->uid(),
  2107. p.src.dump(), p.dest.dump(),
  2108. srh->salvaged());
  2109.   stickPacketInSendBuffer(p);
  2110.   }
  2111. #endif
  2112.   else {
  2113.   // we don't have a route, and it's not worth us doing a
  2114.   // route request to try to help the originator out, since
  2115.   // it might be counter productive
  2116.   if (verbose_ssalv) 
  2117.   trace("Ssalv %.5f _%s_ dropping --- %d %s -> %s [%d]", 
  2118. Scheduler::instance().clock(), 
  2119. net_id.dump(), cmh->uid(),
  2120. p.src.dump(), p.dest.dump(),
  2121. srh->salvaged());
  2122.   if (mine)
  2123.   drop(pkt, DROP_RTR_NO_ROUTE);
  2124.   }
  2125. }
  2126. #ifdef USE_GOD_FEEDBACK
  2127. static int linkerr_is_wrong = 0;
  2128. #endif
  2129. void
  2130. DSRAgent::sendUnknownFlow(SRPacket &p, bool asDefault, u_int16_t flowid) {
  2131.   hdr_sr *srh = hdr_sr::access(p.pkt);
  2132.   hdr_ip *iph = hdr_ip::access(p.pkt);
  2133.   hdr_cmn *cmh = hdr_cmn::access(p.pkt);
  2134.   struct flow_error *fe;
  2135.   assert(!srh->num_addrs()); // flow forwarding basis only.
  2136. #if 0
  2137.   // this doesn't always hold true; if an xmit fails, we'll dump the
  2138.   // thing from our flow table, possibly before we even get here (though how
  2139.   // we found out, other than from this packet, is anyone's guess, considering
  2140.   // that underliverablePkt() should have been called in any other circumstance,
  2141.   // so we shouldn't go through the failed stuff.
  2142.   assert(p.src != net_id); // how'd it get here if it were?
  2143.   // this doesn't always hold true; I may be sending it default, fail,
  2144.   // the flow times out, but I still know the flowid (whacked paths through
  2145.   // the code, I know... ych 5/7/01
  2146.   assert(srh->flow_header() ^ asDefault); // one or the other, not both
  2147. #endif
  2148.   if (p.src == net_id) {
  2149.     Packet::free(p.pkt);
  2150.     p.pkt = 0;
  2151.     return; // gimme a break, we already know!
  2152.   }
  2153.   undeliverablePkt(p.pkt, false); // salvage, but don't molest.
  2154.  
  2155.   /* warp into an error... */
  2156.   if (asDefault) {
  2157.     if (!srh->flow_default_unknown()) {
  2158.       srh->num_default_unknown() = 1;
  2159.       srh->flow_default_unknown() = 1;
  2160.       fe = srh->unknown_defaults();
  2161.     } else if (srh->num_default_unknown() < MAX_ROUTE_ERRORS) {
  2162.       fe = srh->unknown_defaults() + srh->num_default_unknown();
  2163.       srh->num_default_unknown()++;
  2164.     } else {
  2165.       trace("SYFU  %.5f _%s_ dumping maximally nested Flow error %d -> %d",
  2166.       Scheduler::instance().clock(), net_id.dump(), p.src.addr, p.dest.addr);
  2167.       Packet::free(p.pkt);        // no drop needed
  2168.       p.pkt = 0;
  2169.       return;
  2170.     }
  2171.   } else {
  2172.     if (!srh->flow_unknown()) {
  2173.       srh->num_flow_unknown() = 1;
  2174.       srh->flow_unknown() = 1;
  2175.       fe = srh->unknown_flows();
  2176.     } else if (srh->num_default_unknown() < MAX_ROUTE_ERRORS) {
  2177.       fe = srh->unknown_flows() + srh->num_flow_unknown();
  2178.       srh->num_flow_unknown()++;
  2179.     } else {
  2180.       trace("SYFU  %.5f _%s_ dumping maximally nested Flow error %d -> %d",
  2181.       Scheduler::instance().clock(), net_id.dump(), p.src.addr, p.dest.addr);
  2182.       Packet::free(p.pkt);        // no drop needed
  2183.       p.pkt = 0;
  2184.       return;
  2185.     }
  2186.   }
  2187.   trace("SFErr %.5f _%s_ %d -> %d : %d",
  2188. Scheduler::instance().clock(), net_id.dump(), p.src.addr, p.dest.addr,
  2189. flowid);
  2190.   srh->route_reply() = 0;
  2191.   srh->route_request() = 0;
  2192.   srh->flow_header() = 0;
  2193.   srh->flow_timeout() = 0;
  2194.   //iph->daddr() = p.src.addr;
  2195.   iph->daddr() = Address::instance().create_ipaddr(p.src.getNSAddr_t(),RT_PORT);
  2196.   iph->dport() = RT_PORT;
  2197.   //iph->saddr() = net_id.addr;
  2198.   iph->saddr() = Address::instance().create_ipaddr(net_id.getNSAddr_t(),RT_PORT);
  2199.   iph->sport() = RT_PORT;
  2200.   iph->ttl() = 255;
  2201.   //fe->flow_src = p.src.addr;
  2202.   fe->flow_src = p.src.getNSAddr_t();
  2203.   //fe->flow_dst = p.dest.addr;
  2204.   fe->flow_dst = p.dest.getNSAddr_t();
  2205.   fe->flow_id  = flowid;
  2206.   //p.src = ID(iph->src(), ::IP);
  2207.   //p.dest = ID(iph->dst(), ::IP);
  2208.   p.dest = ID((Address::instance().get_nodeaddr(iph->daddr())),::IP);
  2209.   p.src = ID((Address::instance().get_nodeaddr(iph->saddr())),::IP);
  2210.   cmh->ptype() = PT_DSR;                // cut off data
  2211.   cmh->size() = IP_HDR_LEN;
  2212.   cmh->num_forwards() = 0;
  2213.   // assign this packet a new uid, since we're sending it
  2214.   cmh->uid() = uidcnt_++;
  2215.   handlePktWithoutSR(p, false);
  2216.   assert(p.pkt == 0);
  2217. }
  2218. void 
  2219. DSRAgent::xmitFlowFailed(Packet *pkt, const char* reason)
  2220. {
  2221.   hdr_sr *srh = hdr_sr::access(pkt);
  2222.   hdr_ip *iph = hdr_ip::access(pkt);
  2223.   hdr_cmn *cmh = hdr_cmn::access(pkt);
  2224.   int flowidx = flow_table.find(iph->saddr(), iph->daddr(), srh->flow_id());
  2225.   u_int16_t default_flow;
  2226.   assert(!srh->num_addrs());
  2227.   if (!srh->flow_header()) {
  2228.     if (!flow_table.defaultFlow(iph->saddr(), iph->daddr(), default_flow)) {
  2229.       SRPacket p(pkt, srh);
  2230.       //p.src = ID(iph->src(), ::IP);
  2231.       //p.dest = ID(iph->dst(), ::IP);
  2232.       p.dest = ID((Address::instance().get_nodeaddr(iph->daddr())),::IP);
  2233.       p.src = ID((Address::instance().get_nodeaddr(iph->saddr())),::IP);
  2234.       sendUnknownFlow(p, true);
  2235.       return;
  2236.     }
  2237.     flowidx = flow_table.find(iph->saddr(), iph->daddr(), default_flow);
  2238.   }
  2239.   if (flowidx == -1 || 
  2240.       flow_table[flowidx].timeout < Scheduler::instance().clock()) {
  2241.     // blah, the flow has expired, or been forgotten.
  2242.     SRPacket p(pkt, srh);
  2243.     //p.src = ID(iph->src(), ::IP);
  2244.     //p.dest = ID(iph->dst(), ::IP);
  2245.     p.dest = ID((Address::instance().get_nodeaddr(iph->daddr())),::IP);
  2246.     p.src = ID((Address::instance().get_nodeaddr(iph->saddr())),::IP);
  2247.     return;
  2248.   }
  2249.   cmh->size() -= srh->size(); // gonna change the source route size
  2250.   assert(cmh->size() >= 0);
  2251.   
  2252.   flow_table[flowidx].sourceRoute.fillSR(srh);
  2253.   srh->cur_addr() = flow_table[flowidx].hopCount;
  2254.   assert(srh->addrs()[srh->cur_addr()].addr == (nsaddr_t) net_id.addr);
  2255.   cmh->size() += srh->size();
  2256.   // xmitFailed is going to assume this was incr'ed for send
  2257.   srh->cur_addr()++;
  2258.   xmitFailed(pkt, reason);
  2259. }
  2260. void 
  2261. DSRAgent::xmitFailed(Packet *pkt, const char* reason)
  2262.   /* mark our route cache reflect the failure of the link between
  2263.      srh[cur_addr] and srh[next_addr], and then create a route err
  2264.      message to send to the orginator of the pkt (srh[0])
  2265.      p.pkt freed or handed off */
  2266. {
  2267.   hdr_sr *srh = hdr_sr::access(pkt);
  2268.   hdr_ip *iph = hdr_ip::access(pkt);
  2269.   hdr_cmn *cmh = hdr_cmn::access(pkt);
  2270.   assert(cmh->size() >= 0);
  2271.   srh->cur_addr() -= 1; // correct for inc already done on sending
  2272.   
  2273.   if (srh->cur_addr() >= srh->num_addrs() - 1)
  2274.     {
  2275.       trace("SDFU: route error beyond end of source route????");
  2276.       fprintf(stderr,"SDFU: route error beyond end of source route????n");
  2277.       Packet::free(pkt);
  2278.       return;
  2279.     }
  2280.   if (srh->route_request())
  2281.     {
  2282.       trace("SDFU: route error forwarding route request????");
  2283.       fprintf(stderr,"SDFU: route error forwarding route request????n");
  2284.       Packet::free(pkt);
  2285.       return;
  2286.     }
  2287.   ID tell_id(srh->addrs()[0].addr,
  2288.      (ID_Type) srh->addrs()[srh->cur_addr()].addr_type);
  2289.   ID from_id(srh->addrs()[srh->cur_addr()].addr,
  2290.      (ID_Type) srh->addrs()[srh->cur_addr()].addr_type);
  2291.   ID to_id(srh->addrs()[srh->cur_addr()+1].addr,
  2292.      (ID_Type) srh->addrs()[srh->cur_addr()].addr_type);
  2293.   assert(from_id == net_id || from_id == MAC_id);
  2294.   trace("SSendFailure %.9f _%s_ %d %d %d:%d %d:%d %s->%s %d %d %d %d %s",
  2295. Scheduler::instance().clock(), net_id.dump(), 
  2296. cmh->uid(), cmh->ptype(),
  2297. iph->saddr(), iph->sport(),
  2298. iph->daddr(), iph->dport(),
  2299. from_id.dump(),to_id.dump(),
  2300. God::instance()->hops(from_id.getNSAddr_t(), to_id.getNSAddr_t()),
  2301. God::instance()->hops(iph->saddr(),iph->daddr()),
  2302. God::instance()->hops(from_id.getNSAddr_t(), iph->daddr()),
  2303. srh->num_addrs(), srh->dump());
  2304. #ifdef USE_GOD_FEEDBACK
  2305.   if (God::instance()->hops(from_id.getNSAddr_t(), to_id.getNSAddr_t()) == 1)
  2306.     { /* god thinks this link is still valid */
  2307.       linkerr_is_wrong++;
  2308.       trace("SxmitFailed %.5f _%s_  %d->%d god okays #%d",
  2309.             Scheduler::instance().clock(), net_id.dump(),
  2310.             from_id.getNSAddr_t(), to_id.getNSAddr_t(), linkerr_is_wrong);
  2311.       fprintf(stderr,
  2312.       "xmitFailed on link %d->%d god okays - ignoring & recycling #%dn",
  2313.       from_id.getNSAddr_t(), to_id.getNSAddr_t(), linkerr_is_wrong);
  2314.       /* put packet back on end of ifq for xmission */
  2315.       srh->cur_addr() += 1; // correct for decrement earlier in proc 
  2316.       // make sure we aren't cycling packets
  2317.       // also change direction in pkt hdr
  2318.       cmh->direction() = hdr_cmn::DOWN;
  2319.       ll->recv(pkt, (Handler*) 0);
  2320.       return;
  2321.     }
  2322. #endif
  2323.   if(strcmp(reason, "DROP_IFQ_QFULL") != 0) {
  2324.   assert(strcmp(reason, "DROP_RTR_MAC_CALLBACK") == 0);
  2325.   /* kill any routes we have using this link */
  2326.   route_cache->noticeDeadLink(from_id, to_id,
  2327.       Scheduler::instance().clock());
  2328.   flow_table.noticeDeadLink(from_id, to_id);
  2329.   /* give ourselves a chance to save the packet */
  2330.   undeliverablePkt(pkt->copy(), 1);
  2331.   /* now kill all the other packets in the output queue that would
  2332.      use the same next hop.  This is reasonable, since 802.11 has
  2333.      already retried the xmission multiple times => a persistent
  2334.      failure. */
  2335.   /* XXX YCH 5/4/01 shouldn't each of these packets get Route Errors
  2336.    * if one hasn't already been sent? ie if two different routes
  2337.    * are using this link?
  2338.    */
  2339.   {
  2340.     Packet *r, *nr, *queue1 = 0, *queue2 = 0;
  2341.     // pkts to be recycled
  2342.     
  2343.     while((r = ifq->prq_get_nexthop(to_id.getNSAddr_t()))) {
  2344.       r->next_ = queue1;
  2345.       queue1 = r; 
  2346.     }
  2347.     // the packets are now in the reverse order of how they
  2348.     // appeared in the IFQ so reverse them again
  2349.     for(r = queue1; r; r = nr) {
  2350.       nr = r->next_;
  2351.       r->next_ = queue2;
  2352.       queue2 = r;
  2353.     }
  2354.     // now process them in order
  2355.     for(r = queue2; r; r = nr) {
  2356.       nr = r->next_;
  2357.       undeliverablePkt(r, 1);
  2358.     }
  2359.   }
  2360.   }
  2361.   
  2362.   /* warp pkt into a route error message */
  2363.   if (tell_id == net_id || tell_id == MAC_id)
  2364.     { // no need to send the route error if it's for us
  2365.       if (verbose) 
  2366.         trace("Sdebug _%s_ not bothering to send route error to ourselves", 
  2367.       tell_id.dump());
  2368.       Packet::free(pkt); // no drop needed
  2369.       pkt = 0;
  2370.       return;
  2371.     }
  2372.   if (srh->num_route_errors() >= MAX_ROUTE_ERRORS)
  2373.     { // no more room in the error packet to nest an additional error.
  2374.       // this pkt's been bouncing around so much, let's just drop and let
  2375.       // the originator retry
  2376.       // Another possibility is to just strip off the outer error, and
  2377.       // launch a Route discovey for the inner error XXX -dam 6/5/98
  2378.       trace("SDFU  %.5f _%s_ dumping maximally nested error %s  %d -> %d",
  2379.     Scheduler::instance().clock(), net_id.dump(),
  2380.     tell_id.dump(),
  2381.     from_id.dump(),
  2382.     to_id.dump());
  2383.       Packet::free(pkt); // no drop needed
  2384.       pkt = 0;
  2385.       return;
  2386.     }
  2387.   link_down *deadlink = &(srh->down_links()[srh->num_route_errors()]);
  2388.   deadlink->addr_type = srh->addrs()[srh->cur_addr()].addr_type;
  2389.   deadlink->from_addr = srh->addrs()[srh->cur_addr()].addr;
  2390.   deadlink->to_addr = srh->addrs()[srh->cur_addr()+1].addr;
  2391.   deadlink->tell_addr = srh->addrs()[0].addr;
  2392.   srh->num_route_errors() += 1;
  2393.   if (verbose)
  2394.     trace("Sdebug %.5f _%s_ sending into dead-link (nest %d) tell %d  %d -> %d",
  2395.           Scheduler::instance().clock(), net_id.dump(),
  2396.           srh->num_route_errors(),
  2397.           deadlink->tell_addr,
  2398.           deadlink->from_addr,
  2399.           deadlink->to_addr);
  2400.   srh->route_error() = 1;
  2401.   srh->route_reply() = 0;
  2402.   srh->route_request() = 0;
  2403.   srh->flow_header() = 0;
  2404.   srh->flow_timeout() = 0;
  2405.   //iph->daddr() = deadlink->tell_addr;
  2406.   iph->daddr() = Address::instance().create_ipaddr(deadlink->tell_addr,RT_PORT);
  2407.   iph->dport() = RT_PORT;
  2408.   //iph->saddr() = net_id.addr;
  2409.   iph->saddr() = Address::instance().create_ipaddr(net_id.addr,RT_PORT);
  2410.   iph->sport() = RT_PORT;
  2411.   iph->ttl() = 255;
  2412.   cmh->ptype() = PT_DSR; // cut off data
  2413.   cmh->size() = IP_HDR_LEN;
  2414.   cmh->num_forwards() = 0;
  2415.   // assign this packet a new uid, since we're sending it
  2416.   cmh->uid() = uidcnt_++;
  2417.   SRPacket p(pkt, srh);
  2418.   p.route.setLength(p.route.index()+1);
  2419.   p.route.reverseInPlace();
  2420.   p.dest = tell_id;
  2421.   p.src = net_id;
  2422.   /* send out the Route Error message */
  2423.   sendOutPacketWithRoute(p, true);
  2424. }
  2425. #if 0
  2426. /* this is code that implements Route Reply holdoff to prevent route 
  2427.    reply storms.  It's described in the kluwer paper and was used in 
  2428.    those simulations, but isn't currently used.  -dam 8/5/98 */
  2429. /*==============================================================
  2430.   Callback Timers to deal with holding off  route replies
  2431.   Basic theory: if we see a node S that has requested a route to D
  2432.   send a packet to D via a route of length <= ours then don't send
  2433.   our route.  We record that S has used a good route to D by setting
  2434.   the best_length to -1, meaning that our route can't possibly do
  2435.   S any good (unless S has been lied to, but we probably can't know
  2436.   that).
  2437.   
  2438.   NOTE: there is confusion in this code as to whether the requestor
  2439.   and requested_dest ID's are MAC or IP... It doesn't matter for now
  2440.   but will later when they are not the same.
  2441. ------------------------------------------------------------*/
  2442. struct RtHoldoffData: public EventData {
  2443.   RtHoldoffData(DSRAgent *th, Packet *pa, int ind):t(th), p(pa), index(ind)
  2444.   {}
  2445.   DSRAgent *t;
  2446.   Packet *p;
  2447.   int index;
  2448. };
  2449. void
  2450. RouteReplyHoldoffCallback(Node *node, Time time, EventData *data)
  2451. // see if the packet inside the data is still in the
  2452. // send buffer and expire it if it is
  2453. {
  2454.   Packet *p = ((RtHoldoffData *)data)->p;
  2455.   DSRAgent *t = ((RtHoldoffData *)data)->t;
  2456.   int index = ((RtHoldoffData *)data)->index;
  2457.   RtRepHoldoff *entry = &(t->rtrep_holdoff[index]);
  2458.   assert((entry->requestor == p->dest));
  2459.   // if we haven't heard the requestor use a route equal or better
  2460.   // than ours then send our reply.
  2461.   if ((lsnode_require_use && entry->best_length != -1)
  2462.       || (!lsnode_require_use && entry->best_length > entry->our_length))
  2463.     { // we send
  2464.       world_statistics.sendingSrcRtFromCache(t,time,p);
  2465.       t->sendPacket(t,time,p);
  2466.     }
  2467.   else
  2468.     { // dump our packet
  2469.       delete p;
  2470.     }
  2471.   entry->requestor = invalid_addr;
  2472.   entry->requested_dest = invalid_addr;
  2473.   delete data;
  2474.   t->num_heldoff_rt_replies--;
  2475. }
  2476. void
  2477. DSRAgent::scheduleRouteReply(Time t, Packet *new_p)
  2478.   // schedule a time to send new_p if we haven't heard a better
  2479.   // answer in the mean time.  Do not modify new_p after calling this
  2480. {
  2481.   for (int c = 0; c < RTREP_HOLDOFF_SIZE; c ++)
  2482.     if (rtrep_holdoff[c].requested_dest == invalid_addr) break;
  2483.   assert(c < RTREP_HOLDOFF_SIZE);
  2484.   Path *our_route = &(new_p->data.getRoute().source_route);
  2485.   rtrep_holdoff[c].requested_dest = (*our_route)[our_route->length() - 1];
  2486.   rtrep_holdoff[c].requestor = new_p->dest;
  2487.   rtrep_holdoff[c].best_length = MAX_ROUTE_LEN + 1;
  2488.   rtrep_holdoff[c].our_length = our_route->length();
  2489.   Time send_time = t +
  2490.     (Time) (our_route->length() - 1) * rt_rep_holdoff_period
  2491.     + U(0.0, rt_rep_holdoff_period);
  2492.   RegisterCallback(this,&RouteReplyHoldoffCallback, send_time,
  2493.    new RtHoldoffData(this,new_p,c));
  2494.   num_heldoff_rt_replies++;
  2495. }
  2496. void
  2497. DSRAgent::snoopForRouteReplies(Time t, Packet *p)
  2498.   // see if p is a route reply that we're watching for
  2499.   // or if it was sent off using a route reply we're watching for
  2500. {
  2501.   for (int c = 0 ; c <RTREP_HOLDOFF_SIZE ; c ++)
  2502.     {
  2503.       RtRepHoldoff *entry = &(rtrep_holdoff[c]);
  2504.       // there is no point in doing this first check if we're always
  2505.       // going to send our route reply unless we hear the requester use one
  2506.       // better or equal to ours
  2507.       if (entry->requestor == p->dest
  2508.   && (p->type == ::route_reply || p->data.sourceRoutep()))
  2509. { // see if this route reply is one we're watching for
  2510.   Path *srcrt = &(p->data.getRoute().source_route);
  2511.   if (!(entry->requested_dest == (*srcrt)[srcrt->length()-1]))
  2512.     continue; // it's not ours
  2513.   if (entry->best_length > srcrt->length())
  2514.     entry->best_length = srcrt->length();
  2515. } // end if we heard a route reply being sent
  2516.       else if (entry->requestor == p->src
  2517.        && entry->requested_dest == p->dest)
  2518. { // they're using a route  reply! see if ours is better
  2519.           if (p->route.length() <= entry->our_length)
  2520.             { // Oh no! they've used a better path than ours!
  2521.               entry->best_length = -1; //there's no point in replying.
  2522.             }
  2523.         } // end if they used used route reply
  2524.       else
  2525.         continue;
  2526.     }
  2527. }
  2528. #endif //0