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

通讯编程

开发平台:

Visual C++

  1. /*
  2. Copyright (c) 1997, 1998 Carnegie Mellon University.  All Rights
  3. Reserved. 
  4. Redistribution and use in source and binary forms, with or without
  5. modification, are permitted provided that the following conditions are met:
  6. 1. Redistributions of source code must retain the above copyright notice,
  7. this list of conditions and the following disclaimer.
  8. 2. Redistributions in binary form must reproduce the above copyright notice,
  9. this list of conditions and the following disclaimer in the documentation
  10. and/or other materials provided with the distribution.
  11. 3. The name of the author may not be used to endorse or promote products
  12. derived from this software without specific prior written permission.
  13. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  14. IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  15. OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  16. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  17. SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  18. PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  19. OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  20. WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  21. OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  22. ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  23. The AODV code developed by the CMU/MONARCH group was optimized and tuned by Samir Das and Mahesh Marina, University of Cincinnati. The work was partially done in Sun Microsystems. Modified for gratuitous replies by Anant Utgikar, 09/16/02.
  24. */
  25. //#include <ip.h>
  26. #include <aodv/aodv.h>
  27. #include <aodv/aodv_packet.h>
  28. #include <random.h>
  29. #include <cmu-trace.h>
  30. //#include <energy-model.h>
  31. #define max(a,b)        ( (a) > (b) ? (a) : (b) )
  32. #define CURRENT_TIME    Scheduler::instance().clock()
  33. //#define DEBUG
  34. //#define ERROR
  35. #ifdef DEBUG
  36. static int extra_route_reply = 0;
  37. static int limit_route_request = 0;
  38. static int route_request = 0;
  39. #endif
  40. /*
  41.   TCL Hooks
  42. */
  43. int hdr_aodv::offset_;
  44. static class AODVHeaderClass : public PacketHeaderClass {
  45. public:
  46.         AODVHeaderClass() : PacketHeaderClass("PacketHeader/AODV",
  47.                                               sizeof(hdr_all_aodv)) {
  48.   bind_offset(&hdr_aodv::offset_);
  49. } class_rtProtoAODV_hdr;
  50. static class AODVclass : public TclClass {
  51. public:
  52.         AODVclass() : TclClass("Agent/AODV") {}
  53.         TclObject* create(int argc, const char*const* argv) {
  54.           assert(argc == 5);
  55.           //return (new AODV((nsaddr_t) atoi(argv[4])));
  56.   return (new AODV((nsaddr_t) Address::instance().str2addr(argv[4])));
  57.         }
  58. } class_rtProtoAODV;
  59. int
  60. AODV::command(int argc, const char*const* argv) {
  61.   if(argc == 2) {
  62.   Tcl& tcl = Tcl::instance();
  63.     
  64.     if(strncasecmp(argv[1], "id", 2) == 0) {
  65.       tcl.resultf("%d", index);
  66.       return TCL_OK;
  67.     }
  68.     
  69.     if(strncasecmp(argv[1], "start", 2) == 0) {
  70.       btimer.handle((Event*) 0);
  71. #ifndef AODV_LINK_LAYER_DETECTION
  72.       htimer.handle((Event*) 0);
  73.       ntimer.handle((Event*) 0);
  74. #endif // LINK LAYER DETECTION
  75.       rtimer.handle((Event*) 0);
  76.       return TCL_OK;
  77.      }               
  78.   }
  79.   else if(argc == 3) {
  80.     if(strcmp(argv[1], "index") == 0) {
  81.       index = atoi(argv[2]);
  82.       return TCL_OK;
  83.     }
  84.     else if(strcmp(argv[1], "log-target") == 0 || strcmp(argv[1], "tracetarget") == 0) {
  85.       logtarget = (Trace*) TclObject::lookup(argv[2]);
  86.       if(logtarget == 0)
  87. return TCL_ERROR;
  88.       return TCL_OK;
  89.     }
  90.     else if(strcmp(argv[1], "drop-target") == 0) {
  91.     int stat = rqueue.command(argc,argv);
  92.       if (stat != TCL_OK) return stat;
  93.       return Agent::command(argc, argv);
  94.     }
  95.     else if(strcmp(argv[1], "if-queue") == 0) {
  96.     ifqueue = (PriQueue*) TclObject::lookup(argv[2]);
  97.       
  98.       if(ifqueue == 0)
  99. return TCL_ERROR;
  100.       return TCL_OK;
  101.     }
  102.     else if (strcmp(argv[1], "port-dmux") == 0) {
  103.      dmux_ = (PortClassifier *)TclObject::lookup(argv[2]);
  104. if (dmux_ == 0) {
  105. fprintf (stderr, "%s: %s lookup of %s failedn", __FILE__,
  106. argv[1], argv[2]);
  107. return TCL_ERROR;
  108. }
  109. return TCL_OK;
  110.     }
  111.   }
  112.   return Agent::command(argc, argv);
  113. }
  114. /* 
  115.    Constructor
  116. */
  117. AODV::AODV(nsaddr_t id) : Agent(PT_AODV),
  118.   btimer(this), htimer(this), ntimer(this), 
  119.   rtimer(this), lrtimer(this), rqueue() {
  120.  
  121.                 
  122.   index = id;
  123.   seqno = 2;
  124.   bid = 1;
  125.   LIST_INIT(&nbhead);
  126.   LIST_INIT(&bihead);
  127.   logtarget = 0;
  128.   ifqueue = 0;
  129. }
  130. /*
  131.   Timers
  132. */
  133. void
  134. BroadcastTimer::handle(Event*) {
  135.   agent->id_purge();
  136.   Scheduler::instance().schedule(this, &intr, BCAST_ID_SAVE);
  137. }
  138. void
  139. HelloTimer::handle(Event*) {
  140.    agent->sendHello();
  141.    double interval = MinHelloInterval + 
  142.                  ((MaxHelloInterval - MinHelloInterval) * Random::uniform());
  143.    assert(interval >= 0);
  144.    Scheduler::instance().schedule(this, &intr, interval);
  145. }
  146. void
  147. NeighborTimer::handle(Event*) {
  148.   agent->nb_purge();
  149.   Scheduler::instance().schedule(this, &intr, HELLO_INTERVAL);
  150. }
  151. void
  152. RouteCacheTimer::handle(Event*) {
  153.   agent->rt_purge();
  154. #define FREQUENCY 0.5 // sec
  155.   Scheduler::instance().schedule(this, &intr, FREQUENCY);
  156. }
  157. void
  158. LocalRepairTimer::handle(Event* p)  {  // SRD: 5/4/99
  159. aodv_rt_entry *rt;
  160. struct hdr_ip *ih = HDR_IP( (Packet *)p);
  161.    /* you get here after the timeout in a local repair attempt */
  162.    /* fprintf(stderr, "%sn", __FUNCTION__); */
  163.     rt = agent->rtable.rt_lookup(ih->daddr());
  164.     if (rt && rt->rt_flags != RTF_UP) {
  165.     // route is yet to be repaired
  166.     // I will be conservative and bring down the route
  167.     // and send route errors upstream.
  168.     /* The following assert fails, not sure why */
  169.     /* assert (rt->rt_flags == RTF_IN_REPAIR); */
  170.       //rt->rt_seqno++;
  171.       agent->rt_down(rt);
  172.       // send RERR
  173. #ifdef DEBUG
  174.       fprintf(stderr,"Node %d: Dst - %d, failed local repairn",index, rt->rt_dst);
  175. #endif      
  176.     }
  177.     Packet::free((Packet *)p);
  178. }
  179. /*
  180.    Broadcast ID Management  Functions
  181. */
  182. void
  183. AODV::id_insert(nsaddr_t id, u_int32_t bid) {
  184. BroadcastID *b = new BroadcastID(id, bid);
  185.  assert(b);
  186.  b->expire = CURRENT_TIME + BCAST_ID_SAVE;
  187.  LIST_INSERT_HEAD(&bihead, b, link);
  188. }
  189. /* SRD */
  190. bool
  191. AODV::id_lookup(nsaddr_t id, u_int32_t bid) {
  192. BroadcastID *b = bihead.lh_first;
  193.  
  194.  // Search the list for a match of source and bid
  195.  for( ; b; b = b->link.le_next) {
  196.    if ((b->src == id) && (b->id == bid))
  197.      return true;     
  198.  }
  199.  return false;
  200. }
  201. void
  202. AODV::id_purge() {
  203. BroadcastID *b = bihead.lh_first;
  204. BroadcastID *bn;
  205. double now = CURRENT_TIME;
  206.  for(; b; b = bn) {
  207.    bn = b->link.le_next;
  208.    if(b->expire <= now) {
  209.      LIST_REMOVE(b,link);
  210.      delete b;
  211.    }
  212.  }
  213. }
  214. /*
  215.   Helper Functions
  216. */
  217. double
  218. AODV::PerHopTime(aodv_rt_entry *rt) {
  219. int num_non_zero = 0, i;
  220. double total_latency = 0.0;
  221.  if (!rt)
  222.    return ((double) NODE_TRAVERSAL_TIME );
  223.  for (i=0; i < MAX_HISTORY; i++) {
  224.    if (rt->rt_disc_latency[i] > 0.0) {
  225.       num_non_zero++;
  226.       total_latency += rt->rt_disc_latency[i];
  227.    }
  228.  }
  229.  if (num_non_zero > 0)
  230.    return(total_latency / (double) num_non_zero);
  231.  else
  232.    return((double) NODE_TRAVERSAL_TIME);
  233. }
  234. /*
  235.   Link Failure Management Functions
  236. */
  237. static void
  238. aodv_rt_failed_callback(Packet *p, void *arg) {
  239.   ((AODV*) arg)->rt_ll_failed(p);
  240. }
  241. /*
  242.  * This routine is invoked when the link-layer reports a route failed.
  243.  */
  244. void
  245. AODV::rt_ll_failed(Packet *p) {
  246. struct hdr_cmn *ch = HDR_CMN(p);
  247. struct hdr_ip *ih = HDR_IP(p);
  248. aodv_rt_entry *rt;
  249. nsaddr_t broken_nbr = ch->next_hop_;
  250. #ifndef AODV_LINK_LAYER_DETECTION
  251.  drop(p, DROP_RTR_MAC_CALLBACK);
  252. #else 
  253.  /*
  254.   * Non-data packets and Broadcast Packets can be dropped.
  255.   */
  256.   if(! DATA_PACKET(ch->ptype()) ||
  257.      (u_int32_t) ih->daddr() == IP_BROADCAST) {
  258.     drop(p, DROP_RTR_MAC_CALLBACK);
  259.     return;
  260.   }
  261.   log_link_broke(p);
  262. if((rt = rtable.rt_lookup(ih->daddr())) == 0) {
  263.     drop(p, DROP_RTR_MAC_CALLBACK);
  264.     return;
  265.   }
  266.   log_link_del(ch->next_hop_);
  267. #ifdef AODV_LOCAL_REPAIR
  268.   /* if the broken link is closer to the dest than source, 
  269.      attempt a local repair. Otherwise, bring down the route. */
  270.   if (ch->num_forwards() > rt->rt_hops) {
  271.     local_rt_repair(rt, p); // local repair
  272.     // retrieve all the packets in the ifq using this link,
  273.     // queue the packets for which local repair is done, 
  274.     return;
  275.   }
  276.   else
  277. #endif // LOCAL REPAIR
  278.   {
  279.     drop(p, DROP_RTR_MAC_CALLBACK);
  280.     // Do the same thing for other packets in the interface queue using the
  281.     // broken link -Mahesh
  282. while((p = ifqueue->filter(broken_nbr))) {
  283.      drop(p, DROP_RTR_MAC_CALLBACK);
  284.     }
  285.     nb_delete(broken_nbr);
  286.   }
  287. #endif // LINK LAYER DETECTION
  288. }
  289. void
  290. AODV::handle_link_failure(nsaddr_t id) {
  291. aodv_rt_entry *rt, *rtn;
  292. Packet *rerr = Packet::alloc();
  293. struct hdr_aodv_error *re = HDR_AODV_ERROR(rerr);
  294.  re->DestCount = 0;
  295.  for(rt = rtable.head(); rt; rt = rtn) {  // for each rt entry
  296.    rtn = rt->rt_link.le_next; 
  297.    if ((rt->rt_hops != INFINITY2) && (rt->rt_nexthop == id) ) {
  298.      assert (rt->rt_flags == RTF_UP);
  299.      assert((rt->rt_seqno%2) == 0);
  300.      rt->rt_seqno++;
  301.      re->unreachable_dst[re->DestCount] = rt->rt_dst;
  302.      re->unreachable_dst_seqno[re->DestCount] = rt->rt_seqno;
  303. #ifdef DEBUG
  304.      fprintf(stderr, "%s(%f): %dt(%dt%ut%d)n", __FUNCTION__, CURRENT_TIME,
  305.      index, re->unreachable_dst[re->DestCount],
  306.      re->unreachable_dst_seqno[re->DestCount], rt->rt_nexthop);
  307. #endif // DEBUG
  308.      re->DestCount += 1;
  309.      rt_down(rt);
  310.    }
  311.    // remove the lost neighbor from all the precursor lists
  312.    rt->pc_delete(id);
  313.  }   
  314.  if (re->DestCount > 0) {
  315. #ifdef DEBUG
  316.    fprintf(stderr, "%s(%f): %dtsending RERR...n", __FUNCTION__, CURRENT_TIME, index);
  317. #endif // DEBUG
  318.    sendError(rerr, false);
  319.  }
  320.  else {
  321.    Packet::free(rerr);
  322.  }
  323. }
  324. void
  325. AODV::local_rt_repair(aodv_rt_entry *rt, Packet *p) {
  326. #ifdef DEBUG
  327.   fprintf(stderr,"%s: Dst - %dn", __FUNCTION__, rt->rt_dst); 
  328. #endif  
  329.   // Buffer the packet 
  330.   rqueue.enque(p);
  331.   // mark the route as under repair 
  332.   rt->rt_flags = RTF_IN_REPAIR;
  333.   sendRequest(rt->rt_dst);
  334.   // set up a timer interrupt
  335.   Scheduler::instance().schedule(&lrtimer, p->copy(), rt->rt_req_timeout);
  336. }
  337. void
  338. AODV::rt_update(aodv_rt_entry *rt, u_int32_t seqnum, u_int16_t metric,
  339.         nsaddr_t nexthop, double expire_time) {
  340.      rt->rt_seqno = seqnum;
  341.      rt->rt_hops = metric;
  342.      rt->rt_flags = RTF_UP;
  343.      rt->rt_nexthop = nexthop;
  344.      rt->rt_expire = expire_time;
  345. }
  346. void
  347. AODV::rt_down(aodv_rt_entry *rt) {
  348.   /*
  349.    *  Make sure that you don't "down" a route more than once.
  350.    */
  351.   if(rt->rt_flags == RTF_DOWN) {
  352.     return;
  353.   }
  354.   // assert (rt->rt_seqno%2); // is the seqno odd?
  355.   rt->rt_last_hop_count = rt->rt_hops;
  356.   rt->rt_hops = INFINITY2;
  357.   rt->rt_flags = RTF_DOWN;
  358.   rt->rt_nexthop = 0;
  359.   rt->rt_expire = 0;
  360. } /* rt_down function */
  361. /*
  362.   Route Handling Functions
  363. */
  364. void
  365. AODV::rt_resolve(Packet *p) {
  366. struct hdr_cmn *ch = HDR_CMN(p);
  367. struct hdr_ip *ih = HDR_IP(p);
  368. aodv_rt_entry *rt;
  369.  /*
  370.   *  Set the transmit failure callback.  That
  371.   *  won't change.
  372.   */
  373.  ch->xmit_failure_ = aodv_rt_failed_callback;
  374.  ch->xmit_failure_data_ = (void*) this;
  375. rt = rtable.rt_lookup(ih->daddr());
  376.  if(rt == 0) {
  377.   rt = rtable.rt_add(ih->daddr());
  378.  }
  379.  /*
  380.   * If the route is up, forward the packet 
  381.   */
  382.  if(rt->rt_flags == RTF_UP) {
  383.    assert(rt->rt_hops != INFINITY2);
  384.    forward(rt, p, NO_DELAY);
  385.  }
  386.  /*
  387.   *  if I am the source of the packet, then do a Route Request.
  388.   */
  389. else if(ih->saddr() == index) {
  390.    rqueue.enque(p);
  391.    sendRequest(rt->rt_dst);
  392.  }
  393.  /*
  394.   * A local repair is in progress. Buffer the packet. 
  395.   */
  396.  else if (rt->rt_flags == RTF_IN_REPAIR) {
  397.    rqueue.enque(p);
  398.  }
  399.  /*
  400.   * I am trying to forward a packet for someone else to which
  401.   * I don't have a route.
  402.   */
  403.  else {
  404.  Packet *rerr = Packet::alloc();
  405.  struct hdr_aodv_error *re = HDR_AODV_ERROR(rerr);
  406.  /* 
  407.   * For now, drop the packet and send error upstream.
  408.   * Now the route errors are broadcast to upstream
  409.   * neighbors - Mahesh 09/11/99
  410.   */
  411.  
  412.    assert (rt->rt_flags == RTF_DOWN);
  413.    re->DestCount = 0;
  414.    re->unreachable_dst[re->DestCount] = rt->rt_dst;
  415.    re->unreachable_dst_seqno[re->DestCount] = rt->rt_seqno;
  416.    re->DestCount += 1;
  417. #ifdef DEBUG
  418.    fprintf(stderr, "%s: sending RERR...n", __FUNCTION__);
  419. #endif
  420.    sendError(rerr, false);
  421.    drop(p, DROP_RTR_NO_ROUTE);
  422.  }
  423. }
  424. void
  425. AODV::rt_purge() {
  426. aodv_rt_entry *rt, *rtn;
  427. double now = CURRENT_TIME;
  428. double delay = 0.0;
  429. Packet *p;
  430.  for(rt = rtable.head(); rt; rt = rtn) {  // for each rt entry
  431.    rtn = rt->rt_link.le_next;
  432.    if ((rt->rt_flags == RTF_UP) && (rt->rt_expire < now)) {
  433.    // if a valid route has expired, purge all packets from 
  434.    // send buffer and invalidate the route.                    
  435. assert(rt->rt_hops != INFINITY2);
  436.      while((p = rqueue.deque(rt->rt_dst))) {
  437. #ifdef DEBUG
  438.        fprintf(stderr, "%s: calling drop()n",
  439.                        __FUNCTION__);
  440. #endif // DEBUG
  441.        drop(p, DROP_RTR_NO_ROUTE);
  442.      }
  443.      rt->rt_seqno++;
  444.      assert (rt->rt_seqno%2);
  445.      rt_down(rt);
  446.    }
  447.    else if (rt->rt_flags == RTF_UP) {
  448.    // If the route is not expired,
  449.    // and there are packets in the sendbuffer waiting,
  450.    // forward them. This should not be needed, but this extra 
  451.    // check does no harm.
  452.      assert(rt->rt_hops != INFINITY2);
  453.      while((p = rqueue.deque(rt->rt_dst))) {
  454.        forward (rt, p, delay);
  455.        delay += ARP_DELAY;
  456.      }
  457.    } 
  458.    else if (rqueue.find(rt->rt_dst))
  459.    // If the route is down and 
  460.    // if there is a packet for this destination waiting in
  461.    // the sendbuffer, then send out route request. sendRequest
  462.    // will check whether it is time to really send out request
  463.    // or not.
  464.    // This may not be crucial to do it here, as each generated 
  465.    // packet will do a sendRequest anyway.
  466.      sendRequest(rt->rt_dst); 
  467.    }
  468. }
  469. /*
  470.   Packet Reception Routines
  471. */
  472. void
  473. AODV::recv(Packet *p, Handler*) {
  474. struct hdr_cmn *ch = HDR_CMN(p);
  475. struct hdr_ip *ih = HDR_IP(p);
  476.  assert(initialized());
  477.  //assert(p->incoming == 0);
  478.  // XXXXX NOTE: use of incoming flag has been depracated; In order to track direction of pkt flow, direction_ in hdr_cmn is used instead. see packet.h for details.
  479.  if(ch->ptype() == PT_AODV) {
  480.    ih->ttl_ -= 1;
  481.    recvAODV(p);
  482.    return;
  483.  }
  484.  /*
  485.   *  Must be a packet I'm originating...
  486.   */
  487. if((ih->saddr() == index) && (ch->num_forwards() == 0)) {
  488.  /*
  489.   * Add the IP Header
  490.   */
  491.    ch->size() += IP_HDR_LEN;
  492.    // Added by Parag Dadhania && John Novatnack to handle broadcasting
  493.    if ( (u_int32_t)ih->daddr() != IP_BROADCAST)
  494.      ih->ttl_ = NETWORK_DIAMETER;
  495. }
  496.  /*
  497.   *  I received a packet that I sent.  Probably
  498.   *  a routing loop.
  499.   */
  500. else if(ih->saddr() == index) {
  501.    drop(p, DROP_RTR_ROUTE_LOOP);
  502.    return;
  503.  }
  504.  /*
  505.   *  Packet I'm forwarding...
  506.   */
  507.  else {
  508.  /*
  509.   *  Check the TTL.  If it is zero, then discard.
  510.   */
  511.    if(--ih->ttl_ == 0) {
  512.      drop(p, DROP_RTR_TTL);
  513.      return;
  514.    }
  515.  }
  516. // Added by Parag Dadhania && John Novatnack to handle broadcasting
  517.  if ( (u_int32_t)ih->daddr() != IP_BROADCAST)
  518.    rt_resolve(p);
  519.  else
  520.    forward((aodv_rt_entry*) 0, p, NO_DELAY);
  521. }
  522. void
  523. AODV::recvAODV(Packet *p) {
  524.  struct hdr_aodv *ah = HDR_AODV(p);
  525.  assert(HDR_IP (p)->sport() == RT_PORT);
  526.  assert(HDR_IP (p)->dport() == RT_PORT);
  527.  /*
  528.   * Incoming Packets.
  529.   */
  530.  switch(ah->ah_type) {
  531.  case AODVTYPE_RREQ:
  532.    recvRequest(p);
  533.    break;
  534.  case AODVTYPE_RREP:
  535.    recvReply(p);
  536.    break;
  537.  case AODVTYPE_RERR:
  538.    recvError(p);
  539.    break;
  540.  case AODVTYPE_HELLO:
  541.    recvHello(p);
  542.    break;
  543.         
  544.  default:
  545.    fprintf(stderr, "Invalid AODV type (%x)n", ah->ah_type);
  546.    exit(1);
  547.  }
  548. }
  549. void
  550. AODV::recvRequest(Packet *p) {
  551. struct hdr_ip *ih = HDR_IP(p);
  552. struct hdr_aodv_request *rq = HDR_AODV_REQUEST(p);
  553. aodv_rt_entry *rt;
  554.   /*
  555.    * Drop if:
  556.    *      - I'm the source
  557.    *      - I recently heard this request.
  558.    */
  559.   if(rq->rq_src == index) {
  560. #ifdef DEBUG
  561.     fprintf(stderr, "%s: got my own REQUESTn", __FUNCTION__);
  562. #endif // DEBUG
  563.     Packet::free(p);
  564.     return;
  565.   } 
  566.  if (id_lookup(rq->rq_src, rq->rq_bcast_id)) {
  567. #ifdef DEBUG
  568.    fprintf(stderr, "%s: discarding requestn", __FUNCTION__);
  569. #endif // DEBUG
  570.  
  571.    Packet::free(p);
  572.    return;
  573.  }
  574.  /*
  575.   * Cache the broadcast ID
  576.   */
  577.  id_insert(rq->rq_src, rq->rq_bcast_id);
  578.  /* 
  579.   * We are either going to forward the REQUEST or generate a
  580.   * REPLY. Before we do anything, we make sure that the REVERSE
  581.   * route is in the route table.
  582.   */
  583.  aodv_rt_entry *rt0; // rt0 is the reverse route 
  584.    
  585.    rt0 = rtable.rt_lookup(rq->rq_src);
  586.    if(rt0 == 0) { /* if not in the route table */
  587.    // create an entry for the reverse route.
  588.      rt0 = rtable.rt_add(rq->rq_src);
  589.    }
  590.   
  591.    rt0->rt_expire = max(rt0->rt_expire, (CURRENT_TIME + REV_ROUTE_LIFE));
  592.    if ( (rq->rq_src_seqno > rt0->rt_seqno ) ||
  593.      ((rq->rq_src_seqno == rt0->rt_seqno) && 
  594.  (rq->rq_hop_count < rt0->rt_hops)) ) {
  595.    // If we have a fresher seq no. or lesser #hops for the 
  596.    // same seq no., update the rt entry. Else don't bother.
  597. rt_update(rt0, rq->rq_src_seqno, rq->rq_hop_count, ih->saddr(),
  598.              max(rt0->rt_expire, (CURRENT_TIME + REV_ROUTE_LIFE)) );
  599.      if (rt0->rt_req_timeout > 0.0) {
  600.      // Reset the soft state and 
  601.      // Set expiry time to CURRENT_TIME + ACTIVE_ROUTE_TIMEOUT
  602.      // This is because route is used in the forward direction,
  603.      // but only sources get benefited by this change
  604.        rt0->rt_req_cnt = 0;
  605.        rt0->rt_req_timeout = 0.0; 
  606.        rt0->rt_req_last_ttl = rq->rq_hop_count;
  607.        rt0->rt_expire = CURRENT_TIME + ACTIVE_ROUTE_TIMEOUT;
  608.      }
  609.      /* Find out whether any buffered packet can benefit from the 
  610.       * reverse route.
  611.       * May need some change in the following code - Mahesh 09/11/99
  612.       */
  613.      assert (rt0->rt_flags == RTF_UP);
  614.      Packet *buffered_pkt;
  615.      while ((buffered_pkt = rqueue.deque(rt0->rt_dst))) {
  616.        if (rt0 && (rt0->rt_flags == RTF_UP)) {
  617. assert(rt0->rt_hops != INFINITY2);
  618.          forward(rt0, buffered_pkt, NO_DELAY);
  619.        }
  620.      }
  621.    } 
  622.    // End for putting reverse route in rt table
  623.  /*
  624.   * We have taken care of the reverse route stuff.
  625.   * Now see whether we can send a route reply. 
  626.   */
  627.  rt = rtable.rt_lookup(rq->rq_dst);
  628.  // First check if I am the destination ..
  629.  if(rq->rq_dst == index) {
  630. #ifdef DEBUG
  631.    fprintf(stderr, "%d - %s: destination sending replyn",
  632.                    index, __FUNCTION__);
  633. #endif // DEBUG
  634.                
  635.    // Just to be safe, I use the max. Somebody may have
  636.    // incremented the dst seqno.
  637.    seqno = max(seqno, rq->rq_dst_seqno)+1;
  638.    if (seqno%2) seqno++;
  639.    sendReply(rq->rq_src,           // IP Destination
  640.              1,                    // Hop Count
  641.              index,                // Dest IP Address
  642.              seqno,                // Dest Sequence Num
  643.              MY_ROUTE_TIMEOUT,     // Lifetime
  644.              rq->rq_timestamp);    // timestamp
  645.  
  646.    Packet::free(p);
  647.  }
  648.  // I am not the destination, but I may have a fresh enough route.
  649.  else if (rt && (rt->rt_hops != INFINITY2) && 
  650.    (rt->rt_seqno >= rq->rq_dst_seqno) ) {
  651.    //assert (rt->rt_flags == RTF_UP);
  652.    assert(rq->rq_dst == rt->rt_dst);
  653.    //assert ((rt->rt_seqno%2) == 0); // is the seqno even?
  654.    sendReply(rq->rq_src,
  655.              rt->rt_hops + 1,
  656.              rq->rq_dst,
  657.              rt->rt_seqno,
  658.      (u_int32_t) (rt->rt_expire - CURRENT_TIME),
  659.      //             rt->rt_expire - CURRENT_TIME,
  660.              rq->rq_timestamp);
  661.    // Insert nexthops to RREQ source and RREQ destination in the
  662.    // precursor lists of destination and source respectively
  663.    rt->pc_insert(rt0->rt_nexthop); // nexthop to RREQ source
  664.    rt0->pc_insert(rt->rt_nexthop); // nexthop to RREQ destination
  665. #ifdef RREQ_GRAT_RREP  
  666.    sendReply(rq->rq_dst,
  667.              rq->rq_hop_count,
  668.              rq->rq_src,
  669.              rq->rq_src_seqno,
  670.      (u_int32_t) (rt->rt_expire - CURRENT_TIME),
  671.      //             rt->rt_expire - CURRENT_TIME,
  672.              rq->rq_timestamp);
  673. #endif
  674.    
  675. // TODO: send grat RREP to dst if G flag set in RREQ using rq->rq_src_seqno, rq->rq_hop_counT
  676.    
  677. // DONE: Included gratuitous replies to be sent as per IETF aodv draft specification. As of now, G flag has not been dynamically used and is always set or reset in aodv-packet.h --- Anant Utgikar, 09/16/02.
  678. Packet::free(p);
  679.  }
  680.  /*
  681.   * Can't reply. So forward the  Route Request
  682.   */
  683.  else {
  684.    ih->saddr() = index;
  685.    ih->daddr() = IP_BROADCAST;
  686.    rq->rq_hop_count += 1;
  687.    // Maximum sequence number seen en route
  688.    if (rt) rq->rq_dst_seqno = max(rt->rt_seqno, rq->rq_dst_seqno);
  689.    forward((aodv_rt_entry*) 0, p, DELAY);
  690.  }
  691. }
  692. void
  693. AODV::recvReply(Packet *p) {
  694. //struct hdr_cmn *ch = HDR_CMN(p);
  695. struct hdr_ip *ih = HDR_IP(p);
  696. struct hdr_aodv_reply *rp = HDR_AODV_REPLY(p);
  697. aodv_rt_entry *rt;
  698. char suppress_reply = 0;
  699. double delay = 0.0;
  700. #ifdef DEBUG
  701.  fprintf(stderr, "%d - %s: received a REPLYn", index, __FUNCTION__);
  702. #endif // DEBUG
  703.  /*
  704.   *  Got a reply. So reset the "soft state" maintained for 
  705.   *  route requests in the request table. We don't really have
  706.   *  have a separate request table. It is just a part of the
  707.   *  routing table itself. 
  708.   */
  709.  // Note that rp_dst is the dest of the data packets, not the
  710.  // the dest of the reply, which is the src of the data packets.
  711.  rt = rtable.rt_lookup(rp->rp_dst);
  712.         
  713.  /*
  714.   *  If I don't have a rt entry to this host... adding
  715.   */
  716.  if(rt == 0) {
  717.    rt = rtable.rt_add(rp->rp_dst);
  718.  }
  719.  /*
  720.   * Add a forward route table entry... here I am following 
  721.   * Perkins-Royer AODV paper almost literally - SRD 5/99
  722.   */
  723.  if ( (rt->rt_seqno < rp->rp_dst_seqno) ||   // newer route 
  724.       ((rt->rt_seqno == rp->rp_dst_seqno) &&  
  725.        (rt->rt_hops > rp->rp_hop_count)) ) { // shorter or better route
  726.   // Update the rt entry 
  727.   rt_update(rt, rp->rp_dst_seqno, rp->rp_hop_count,
  728. rp->rp_src, CURRENT_TIME + rp->rp_lifetime);
  729.   // reset the soft state
  730.   rt->rt_req_cnt = 0;
  731.   rt->rt_req_timeout = 0.0; 
  732.   rt->rt_req_last_ttl = rp->rp_hop_count;
  733.   
  734. if (ih->daddr() == index) { // If I am the original source
  735.   // Update the route discovery latency statistics
  736.   // rp->rp_timestamp is the time of request origination
  737.     rt->rt_disc_latency[(unsigned char)rt->hist_indx] = (CURRENT_TIME - rp->rp_timestamp)
  738.                                          / (double) rp->rp_hop_count;
  739.     // increment indx for next time
  740.     rt->hist_indx = (rt->hist_indx + 1) % MAX_HISTORY;
  741.   }
  742.   /*
  743.    * Send all packets queued in the sendbuffer destined for
  744.    * this destination. 
  745.    * XXX - observe the "second" use of p.
  746.    */
  747.   Packet *buf_pkt;
  748.   while((buf_pkt = rqueue.deque(rt->rt_dst))) {
  749.     if(rt->rt_hops != INFINITY2) {
  750.           assert (rt->rt_flags == RTF_UP);
  751.     // Delay them a little to help ARP. Otherwise ARP 
  752.     // may drop packets. -SRD 5/23/99
  753.       forward(rt, buf_pkt, delay);
  754.       delay += ARP_DELAY;
  755.     }
  756.   }
  757.  }
  758.  else {
  759.   suppress_reply = 1;
  760.  }
  761.  /*
  762.   * If reply is for me, discard it.
  763.   */
  764. if(ih->daddr() == index || suppress_reply) {
  765.    Packet::free(p);
  766.  }
  767.  /*
  768.   * Otherwise, forward the Route Reply.
  769.   */
  770.  else {
  771.  // Find the rt entry
  772. aodv_rt_entry *rt0 = rtable.rt_lookup(ih->daddr());
  773.    // If the rt is up, forward
  774.    if(rt0 && (rt0->rt_hops != INFINITY2)) {
  775.         assert (rt0->rt_flags == RTF_UP);
  776.      rp->rp_hop_count += 1;
  777.      rp->rp_src = index;
  778.      forward(rt0, p, NO_DELAY);
  779.      // Insert the nexthop towards the RREQ source to 
  780.      // the precursor list of the RREQ destination
  781.      rt->pc_insert(rt0->rt_nexthop); // nexthop to RREQ source
  782.      
  783.    }
  784.    else {
  785.    // I don't know how to forward .. drop the reply. 
  786. #ifdef DEBUG
  787.      fprintf(stderr, "%s: dropping Route Replyn", __FUNCTION__);
  788. #endif // DEBUG
  789.      drop(p, DROP_RTR_NO_ROUTE);
  790.    }
  791.  }
  792. }
  793. void
  794. AODV::recvError(Packet *p) {
  795. struct hdr_ip *ih = HDR_IP(p);
  796. struct hdr_aodv_error *re = HDR_AODV_ERROR(p);
  797. aodv_rt_entry *rt;
  798. u_int8_t i;
  799. Packet *rerr = Packet::alloc();
  800. struct hdr_aodv_error *nre = HDR_AODV_ERROR(rerr);
  801.  nre->DestCount = 0;
  802.  for (i=0; i<re->DestCount; i++) {
  803.  // For each unreachable destination
  804.    rt = rtable.rt_lookup(re->unreachable_dst[i]);
  805.    if ( rt && (rt->rt_hops != INFINITY2) &&
  806. (rt->rt_nexthop == ih->saddr()) &&
  807.       (rt->rt_seqno <= re->unreachable_dst_seqno[i]) ) {
  808. assert(rt->rt_flags == RTF_UP);
  809. assert((rt->rt_seqno%2) == 0); // is the seqno even?
  810. #ifdef DEBUG
  811.      fprintf(stderr, "%s(%f): %dt(%dt%ut%d)t(%dt%ut%d)n", __FUNCTION__,CURRENT_TIME,
  812.      index, rt->rt_dst, rt->rt_seqno, rt->rt_nexthop,
  813.      re->unreachable_dst[i],re->unreachable_dst_seqno[i],
  814.              ih->saddr());
  815. #endif // DEBUG
  816.       rt->rt_seqno = re->unreachable_dst_seqno[i];
  817.       rt_down(rt);
  818.    // Not sure whether this is the right thing to do
  819.    Packet *pkt;
  820. while((pkt = ifqueue->filter(ih->saddr()))) {
  821.          drop(pkt, DROP_RTR_MAC_CALLBACK);
  822.       }
  823.      // if precursor list non-empty add to RERR and delete the precursor list
  824.       if (!rt->pc_empty()) {
  825.       nre->unreachable_dst[nre->DestCount] = rt->rt_dst;
  826.       nre->unreachable_dst_seqno[nre->DestCount] = rt->rt_seqno;
  827.       nre->DestCount += 1;
  828. rt->pc_delete();
  829.       }
  830.    }
  831.  } 
  832.  if (nre->DestCount > 0) {
  833. #ifdef DEBUG
  834.    fprintf(stderr, "%s(%f): %dt sending RERR...n", __FUNCTION__, CURRENT_TIME, index);
  835. #endif // DEBUG
  836.    sendError(rerr);
  837.  }
  838.  else {
  839.    Packet::free(rerr);
  840.  }
  841.  Packet::free(p);
  842. }
  843. /*
  844.    Packet Transmission Routines
  845. */
  846. void
  847. AODV::forward(aodv_rt_entry *rt, Packet *p, double delay) {
  848. struct hdr_cmn *ch = HDR_CMN(p);
  849. struct hdr_ip *ih = HDR_IP(p);
  850.  if(ih->ttl_ == 0) {
  851. #ifdef DEBUG
  852.   fprintf(stderr, "%s: calling drop()n", __PRETTY_FUNCTION__);
  853. #endif // DEBUG
  854.  
  855.   drop(p, DROP_RTR_TTL);
  856.   return;
  857.  }
  858.  if (ch->ptype() != PT_AODV && ch->direction() == hdr_cmn::UP &&
  859. ((u_int32_t)ih->daddr() == IP_BROADCAST)
  860. || (ih->daddr() == here_.addr_)) {
  861. dmux_->recv(p,0);
  862. return;
  863.  }
  864.  if (rt) {
  865.    assert(rt->rt_flags == RTF_UP);
  866.    rt->rt_expire = CURRENT_TIME + ACTIVE_ROUTE_TIMEOUT;
  867.    ch->next_hop_ = rt->rt_nexthop;
  868.    ch->addr_type() = NS_AF_INET;
  869.    ch->direction() = hdr_cmn::DOWN;       //important: change the packet's direction
  870.  }
  871.  else { // if it is a broadcast packet
  872.    // assert(ch->ptype() == PT_AODV); // maybe a diff pkt type like gaf
  873.    assert(ih->daddr() == (nsaddr_t) IP_BROADCAST);
  874.    ch->addr_type() = NS_AF_NONE;
  875.    ch->direction() = hdr_cmn::DOWN;       //important: change the packet's direction
  876.  }
  877. if (ih->daddr() == (nsaddr_t) IP_BROADCAST) {
  878.  // If it is a broadcast packet
  879.    assert(rt == 0);
  880.    if (ch->ptype() == PT_AODV) {
  881.      /*
  882.       *  Jitter the sending of AODV broadcast packets by 10ms
  883.       */
  884.      Scheduler::instance().schedule(target_, p,
  885.           0.01 * Random::uniform());
  886.    } else {
  887.      Scheduler::instance().schedule(target_, p, 0.);  // No jitter
  888.    }
  889.  }
  890.  else { // Not a broadcast packet 
  891.    if(delay > 0.0) {
  892.      Scheduler::instance().schedule(target_, p, delay);
  893.    }
  894.    else {
  895.    // Not a broadcast packet, no delay, send immediately
  896.      Scheduler::instance().schedule(target_, p, 0.);
  897.    }
  898.  }
  899. }
  900. void
  901. AODV::sendRequest(nsaddr_t dst) {
  902. // Allocate a RREQ packet 
  903. Packet *p = Packet::alloc();
  904. struct hdr_cmn *ch = HDR_CMN(p);
  905. struct hdr_ip *ih = HDR_IP(p);
  906. struct hdr_aodv_request *rq = HDR_AODV_REQUEST(p);
  907. aodv_rt_entry *rt = rtable.rt_lookup(dst);
  908.  assert(rt);
  909.  /*
  910.   *  Rate limit sending of Route Requests. We are very conservative
  911.   *  about sending out route requests. 
  912.   */
  913.  if (rt->rt_flags == RTF_UP) {
  914.    assert(rt->rt_hops != INFINITY2);
  915.    Packet::free((Packet *)p);
  916.    return;
  917.  }
  918.  if (rt->rt_req_timeout > CURRENT_TIME) {
  919.    Packet::free((Packet *)p);
  920.    return;
  921.  }
  922.  // rt_req_cnt is the no. of times we did network-wide broadcast
  923.  // RREQ_RETRIES is the maximum number we will allow before 
  924.  // going to a long timeout.
  925.  if (rt->rt_req_cnt > RREQ_RETRIES) {
  926.    rt->rt_req_timeout = CURRENT_TIME + MAX_RREQ_TIMEOUT;
  927.    rt->rt_req_cnt = 0;
  928.  Packet *buf_pkt;
  929.    while ((buf_pkt = rqueue.deque(rt->rt_dst))) {
  930.        drop(buf_pkt, DROP_RTR_NO_ROUTE);
  931.    }
  932.    Packet::free((Packet *)p);
  933.    return;
  934.  }
  935. #ifdef DEBUG
  936.    fprintf(stderr, "(%2d) - %2d sending Route Request, dst: %dn",
  937.                     ++route_request, index, rt->rt_dst);
  938. #endif // DEBUG
  939.  // Determine the TTL to be used this time. 
  940.  // Dynamic TTL evaluation - SRD
  941.  rt->rt_req_last_ttl = max(rt->rt_req_last_ttl,rt->rt_last_hop_count);
  942.  if (0 == rt->rt_req_last_ttl) {
  943.  // first time query broadcast
  944.    ih->ttl_ = TTL_START;
  945.  }
  946.  else {
  947.  // Expanding ring search.
  948.    if (rt->rt_req_last_ttl < TTL_THRESHOLD)
  949.      ih->ttl_ = rt->rt_req_last_ttl + TTL_INCREMENT;
  950.    else {
  951.    // network-wide broadcast
  952.      ih->ttl_ = NETWORK_DIAMETER;
  953.      rt->rt_req_cnt += 1;
  954.    }
  955.  }
  956.  // remember the TTL used  for the next time
  957.  rt->rt_req_last_ttl = ih->ttl_;
  958.  // PerHopTime is the roundtrip time per hop for route requests.
  959.  // The factor 2.0 is just to be safe .. SRD 5/22/99
  960.  // Also note that we are making timeouts to be larger if we have 
  961.  // done network wide broadcast before. 
  962.  rt->rt_req_timeout = 2.0 * (double) ih->ttl_ * PerHopTime(rt); 
  963.  if (rt->rt_req_cnt > 0)
  964.    rt->rt_req_timeout *= rt->rt_req_cnt;
  965.  rt->rt_req_timeout += CURRENT_TIME;
  966.  // Don't let the timeout to be too large, however .. SRD 6/8/99
  967.  if (rt->rt_req_timeout > CURRENT_TIME + MAX_RREQ_TIMEOUT)
  968.    rt->rt_req_timeout = CURRENT_TIME + MAX_RREQ_TIMEOUT;
  969.  rt->rt_expire = 0;
  970. #ifdef DEBUG
  971.  fprintf(stderr, "(%2d) - %2d sending Route Request, dst: %d, tout %f msn",
  972.          ++route_request, 
  973.  index, rt->rt_dst, 
  974.  rt->rt_req_timeout - CURRENT_TIME);
  975. #endif // DEBUG
  976.  // Fill out the RREQ packet 
  977.  // ch->uid() = 0;
  978.  ch->ptype() = PT_AODV;
  979.  ch->size() = IP_HDR_LEN + rq->size();
  980.  ch->iface() = -2;
  981.  ch->error() = 0;
  982.  ch->addr_type() = NS_AF_NONE;
  983.  ch->prev_hop_ = index;          // AODV hack
  984.  ih->saddr() = index;
  985.  ih->daddr() = IP_BROADCAST;
  986.  ih->sport() = RT_PORT;
  987.  ih->dport() = RT_PORT;
  988.  // Fill up some more fields. 
  989.  rq->rq_type = AODVTYPE_RREQ;
  990.  rq->rq_hop_count = 1;
  991.  rq->rq_bcast_id = bid++;
  992.  rq->rq_dst = dst;
  993.  rq->rq_dst_seqno = (rt ? rt->rt_seqno : 0);
  994.  rq->rq_src = index;
  995.  seqno += 2;
  996.  assert ((seqno%2) == 0);
  997.  rq->rq_src_seqno = seqno;
  998.  rq->rq_timestamp = CURRENT_TIME;
  999.  Scheduler::instance().schedule(target_, p, 0.);
  1000. }
  1001. void
  1002. AODV::sendReply(nsaddr_t ipdst, u_int32_t hop_count, nsaddr_t rpdst,
  1003.                 u_int32_t rpseq, u_int32_t lifetime, double timestamp) {
  1004. Packet *p = Packet::alloc();
  1005. struct hdr_cmn *ch = HDR_CMN(p);
  1006. struct hdr_ip *ih = HDR_IP(p);
  1007. struct hdr_aodv_reply *rp = HDR_AODV_REPLY(p);
  1008. aodv_rt_entry *rt = rtable.rt_lookup(ipdst);
  1009. #ifdef DEBUG
  1010. fprintf(stderr, "sending Reply from %d at %.2fn", index, Scheduler::instance().clock());
  1011. #endif // DEBUG
  1012.  assert(rt);
  1013.  rp->rp_type = AODVTYPE_RREP;
  1014.  //rp->rp_flags = 0x00;
  1015.  rp->rp_hop_count = hop_count;
  1016.  rp->rp_dst = rpdst;
  1017.  rp->rp_dst_seqno = rpseq;
  1018.  rp->rp_src = index;
  1019.  rp->rp_lifetime = lifetime;
  1020.  rp->rp_timestamp = timestamp;
  1021.    
  1022.  // ch->uid() = 0;
  1023.  ch->ptype() = PT_AODV;
  1024.  ch->size() = IP_HDR_LEN + rp->size();
  1025.  ch->iface() = -2;
  1026.  ch->error() = 0;
  1027.  ch->addr_type() = NS_AF_INET;
  1028.  ch->next_hop_ = rt->rt_nexthop;
  1029.  ch->prev_hop_ = index;          // AODV hack
  1030.  ch->direction() = hdr_cmn::DOWN;
  1031.  ih->saddr() = index;
  1032.  ih->daddr() = ipdst;
  1033.  ih->sport() = RT_PORT;
  1034.  ih->dport() = RT_PORT;
  1035.  ih->ttl_ = NETWORK_DIAMETER;
  1036.  Scheduler::instance().schedule(target_, p, 0.);
  1037. }
  1038. void
  1039. AODV::sendError(Packet *p, bool jitter) {
  1040. struct hdr_cmn *ch = HDR_CMN(p);
  1041. struct hdr_ip *ih = HDR_IP(p);
  1042. struct hdr_aodv_error *re = HDR_AODV_ERROR(p);
  1043.     
  1044. #ifdef ERROR
  1045. fprintf(stderr, "sending Error from %d at %.2fn", index, Scheduler::instance().clock());
  1046. #endif // DEBUG
  1047.  re->re_type = AODVTYPE_RERR;
  1048.  //re->reserved[0] = 0x00; re->reserved[1] = 0x00;
  1049.  // DestCount and list of unreachable destinations are already filled
  1050.  // ch->uid() = 0;
  1051.  ch->ptype() = PT_AODV;
  1052.  ch->size() = IP_HDR_LEN + re->size();
  1053.  ch->iface() = -2;
  1054.  ch->error() = 0;
  1055.  ch->addr_type() = NS_AF_NONE;
  1056.  ch->next_hop_ = 0;
  1057.  ch->prev_hop_ = index;          // AODV hack
  1058.  ch->direction() = hdr_cmn::DOWN;       //important: change the packet's direction
  1059.  ih->saddr() = index;
  1060.  ih->daddr() = IP_BROADCAST;
  1061.  ih->sport() = RT_PORT;
  1062.  ih->dport() = RT_PORT;
  1063.  ih->ttl_ = 1;
  1064.  // Do we need any jitter? Yes
  1065.  if (jitter)
  1066.   Scheduler::instance().schedule(target_, p, 0.01*Random::uniform());
  1067.  else
  1068.   Scheduler::instance().schedule(target_, p, 0.0);
  1069. }
  1070. /*
  1071.    Neighbor Management Functions
  1072. */
  1073. void
  1074. AODV::sendHello() {
  1075. Packet *p = Packet::alloc();
  1076. struct hdr_cmn *ch = HDR_CMN(p);
  1077. struct hdr_ip *ih = HDR_IP(p);
  1078. struct hdr_aodv_reply *rh = HDR_AODV_REPLY(p);
  1079. #ifdef DEBUG
  1080. fprintf(stderr, "sending Hello from %d at %.2fn", index, Scheduler::instance().clock());
  1081. #endif // DEBUG
  1082.  rh->rp_type = AODVTYPE_HELLO;
  1083.  //rh->rp_flags = 0x00;
  1084.  rh->rp_hop_count = 1;
  1085.  rh->rp_dst = index;
  1086.  rh->rp_dst_seqno = seqno;
  1087.  rh->rp_lifetime = (1 + ALLOWED_HELLO_LOSS) * HELLO_INTERVAL;
  1088.  // ch->uid() = 0;
  1089.  ch->ptype() = PT_AODV;
  1090.  ch->size() = IP_HDR_LEN + rh->size();
  1091.  ch->iface() = -2;
  1092.  ch->error() = 0;
  1093.  ch->addr_type() = NS_AF_NONE;
  1094.  ch->prev_hop_ = index;          // AODV hack
  1095.  ih->saddr() = index;
  1096.  ih->daddr() = IP_BROADCAST;
  1097.  ih->sport() = RT_PORT;
  1098.  ih->dport() = RT_PORT;
  1099.  ih->ttl_ = 1;
  1100.  Scheduler::instance().schedule(target_, p, 0.0);
  1101. }
  1102. void
  1103. AODV::recvHello(Packet *p) {
  1104. //struct hdr_ip *ih = HDR_IP(p);
  1105. struct hdr_aodv_reply *rp = HDR_AODV_REPLY(p);
  1106. AODV_Neighbor *nb;
  1107.  nb = nb_lookup(rp->rp_dst);
  1108.  if(nb == 0) {
  1109.    nb_insert(rp->rp_dst);
  1110.  }
  1111.  else {
  1112.    nb->nb_expire = CURRENT_TIME +
  1113.                    (1.5 * ALLOWED_HELLO_LOSS * HELLO_INTERVAL);
  1114.  }
  1115.  Packet::free(p);
  1116. }
  1117. void
  1118. AODV::nb_insert(nsaddr_t id) {
  1119. AODV_Neighbor *nb = new AODV_Neighbor(id);
  1120.  assert(nb);
  1121.  nb->nb_expire = CURRENT_TIME +
  1122.                 (1.5 * ALLOWED_HELLO_LOSS * HELLO_INTERVAL);
  1123.  LIST_INSERT_HEAD(&nbhead, nb, nb_link);
  1124.  seqno += 2;             // set of neighbors changed
  1125.  assert ((seqno%2) == 0);
  1126. }
  1127. AODV_Neighbor*
  1128. AODV::nb_lookup(nsaddr_t id) {
  1129. AODV_Neighbor *nb = nbhead.lh_first;
  1130.  for(; nb; nb = nb->nb_link.le_next) {
  1131.    if(nb->nb_addr == id) break;
  1132.  }
  1133.  return nb;
  1134. }
  1135. /*
  1136.  * Called when we receive *explicit* notification that a Neighbor
  1137.  * is no longer reachable.
  1138.  */
  1139. void
  1140. AODV::nb_delete(nsaddr_t id) {
  1141. AODV_Neighbor *nb = nbhead.lh_first;
  1142.  log_link_del(id);
  1143.  seqno += 2;     // Set of neighbors changed
  1144.  assert ((seqno%2) == 0);
  1145.  for(; nb; nb = nb->nb_link.le_next) {
  1146.    if(nb->nb_addr == id) {
  1147.      LIST_REMOVE(nb,nb_link);
  1148.      delete nb;
  1149.      break;
  1150.    }
  1151.  }
  1152.  handle_link_failure(id);
  1153. }
  1154. /*
  1155.  * Purges all timed-out Neighbor Entries - runs every
  1156.  * HELLO_INTERVAL * 1.5 seconds.
  1157.  */
  1158. void
  1159. AODV::nb_purge() {
  1160. AODV_Neighbor *nb = nbhead.lh_first;
  1161. AODV_Neighbor *nbn;
  1162. double now = CURRENT_TIME;
  1163.  for(; nb; nb = nbn) {
  1164.    nbn = nb->nb_link.le_next;
  1165.    if(nb->nb_expire <= now) {
  1166.      nb_delete(nb->nb_addr);
  1167.    }
  1168.  }
  1169. }