NS2下AODV协议aodv.cc注释

2024-03-05 00:38
文章标签 协议 注释 cc ns2 aodv

本文主要是介绍NS2下AODV协议aodv.cc注释,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原文地址:http://blog.csdn.net/ise_gaoyue1990/article/details/7610522

 

[cpp] view plain copy print ?
  1. //#include <ip.h>   
  2.   
  3. #include <aodv/aodv.h>   
  4. #include <aodv/aodv_packet.h>   
  5. #include <random.h>   
  6. #include <cmu-trace.h>   
  7. //#include <energy-model.h>   
  8.   
  9. #define max(a,b)        ( (a) > (b) ? (a) : (b) )   
  10. #define CURRENT_TIME    Scheduler::instance().clock()   
  11.   
  12. //#define DEBUG   
  13. //#define ERROR   
  14.   
  15. #ifdef DEBUG   
  16. static int extra_route_reply = 0;  
  17. static int limit_route_request = 0;  
  18. static int route_request = 0;  
  19. #endif   
  20.   
  21.   
  22. /* 
  23.   TCL Hooks 
  24. */  
  25.   
  26.   
  27. int hdr_aodv::offset_;  
  28. static class AODVHeaderClass : public PacketHeaderClass {  
  29. public:  
  30.         AODVHeaderClass() : PacketHeaderClass("PacketHeader/AODV",  
  31.                                               sizeof(hdr_all_aodv)) {  
  32.       bind_offset(&hdr_aodv::offset_);  
  33.     }   
  34. } class_rtProtoAODV_hdr;  
  35. /*AODVclass 只有两个函数,构造函数和creat函数*/  
  36. static class AODVclass : public TclClass {  
  37. public:  
  38.         AODVclass() : TclClass("Agent/AODV") {}  
  39.         TclObject* create(int argc, const char*const* argv) {  
  40.           assert(argc == 5);  
  41.           //return (new AODV((nsaddr_t) atoi(argv[4])));   
  42.       return (new AODV((nsaddr_t) Address::instance().str2addr(argv[4])));  
  43.         }  
  44. } class_rtProtoAODV;  
  45.   
  46. /*command函数实现了命令的分发*/  
  47. int  
  48. AODV::command(int argc, const char*const* argv) {  
  49.   if(argc == 2) {//命令的参数个数是2   
  50.   Tcl& tcl = Tcl::instance();  
  51.       
  52.     if(strncasecmp(argv[1], "id", 2) == 0) {//命令所要求的操作为id   
  53.       tcl.resultf("%d", index);  
  54.       return TCL_OK;  
  55.     }  
  56.       
  57.     if(strncasecmp(argv[1], "start", 2) == 0) {//命令所要求的操作为start   
  58.       btimer.handle((Event*) 0);  
  59.   
  60. #ifndef AODV_LINK_LAYER_DETECTION   
  61.       htimer.handle((Event*) 0);  
  62.       ntimer.handle((Event*) 0);  
  63. #endif // LINK LAYER DETECTION   
  64.   
  65.       rtimer.handle((Event*) 0);  
  66.       return TCL_OK;  
  67.      }                 
  68.   }  
  69.   else if(argc == 3) {//命令参数个数等于3   
  70.     if(strcmp(argv[1], "index") == 0) {//命令所要求的操作为index   
  71.       index = atoi(argv[2]);  
  72.       return TCL_OK;  
  73.     }  
  74. //命令所要求的操作为log-target或者tracetarget   
  75.     else if(strcmp(argv[1], "log-target") == 0 || strcmp(argv[1], "tracetarget") == 0) {  
  76.       logtarget = (Trace*) TclObject::lookup(argv[2]);  
  77.       if(logtarget == 0)  
  78.     return TCL_ERROR;  
  79.       return TCL_OK;  
  80.     }  
  81.     else if(strcmp(argv[1], "drop-target") == 0)   
  82.     {  
  83.     //命令所要求的操作为drop-target   
  84.     int stat = rqueue.command(argc,argv);  
  85.       if (stat != TCL_OK) return stat;  
  86.       return Agent::command(argc, argv);  
  87.     }  
  88.   
  89.     //命令所要求的操作if-queue   
  90.     else if(strcmp(argv[1], "if-queue") == 0) {  
  91.     ifqueue = (PriQueue*) TclObject::lookup(argv[2]);  
  92.         
  93.       if(ifqueue == 0)  
  94.     return TCL_ERROR;  
  95.       return TCL_OK;  
  96.     }  
  97.     //命令所要求的操作为port-dmux   
  98.     else if (strcmp(argv[1], "port-dmux") == 0) {  
  99.         dmux_ = (PortClassifier *)TclObject::lookup(argv[2]);  
  100.     if (dmux_ == 0) {  
  101.         fprintf (stderr, "%s: %s lookup of %s failed\n", __FILE__,  
  102.         argv[1], argv[2]);  
  103.         return TCL_ERROR;  
  104.     }  
  105.     return TCL_OK;  
  106.     }  
  107.   }  
  108.   return Agent::command(argc, argv);  
  109. }  
  110.   
  111. /*  
  112.    Constructor 
  113. */  
  114.   
  115. AODV::AODV(nsaddr_t id) : Agent(PT_AODV),  
  116.               btimer(this), htimer(this), ntimer(this),   
  117.               rtimer(this), lrtimer(this), rqueue() {  
  118.    
  119.                   
  120.   index = id;  
  121.   seqno = 2;  
  122.   bid = 1;  
  123.   
  124.   LIST_INIT(&nbhead);  
  125.   LIST_INIT(&bihead);  
  126.   
  127.   logtarget = 0;  
  128.   ifqueue = 0;  
  129. }  
  130.   
  131. /* 
  132.   Timers 
  133. */  
  134. //广播定时器   
  135. void  
  136. BroadcastTimer::handle(Event*) {  
  137.   agent->id_purge();  
  138.   Scheduler::instance().schedule(this, &intr, BCAST_ID_SAVE);  
  139. }  
  140. //hello报文定时器   
  141. void  
  142. HelloTimer::handle(Event*) {  
  143.    agent->sendHello();  
  144.    double interval = MinHelloInterval +   
  145.                  ((MaxHelloInterval - MinHelloInterval) * Random::uniform());  
  146.    assert(interval >= 0);  
  147.    Scheduler::instance().schedule(this, &intr, interval);  
  148. }  
  149. //邻居定时器   
  150. void  
  151. NeighborTimer::handle(Event*) {  
  152.   agent->nb_purge();  
  153.   Scheduler::instance().schedule(this, &intr, HELLO_INTERVAL);  
  154. }  
  155. 路由缓存定时器  
  156. void  
  157. RouteCacheTimer::handle(Event*) {  
  158.   agent->rt_purge();  
  159. #define FREQUENCY 0.5 // sec   
  160.   Scheduler::instance().schedule(this, &intr, FREQUENCY);  
  161. }  
  162. //路由缓存定时器   
  163. void  
  164. LocalRepairTimer::handle(Event* p)  {  // SRD: 5/4/99   
  165. aodv_rt_entry *rt;  
  166. struct hdr_ip *ih = HDR_IP( (Packet *)p);  
  167.   
  168.    /* you get here after the timeout in a local repair attempt */  
  169.    /*   fprintf(stderr, "%s\n", __FUNCTION__); */  
  170.   
  171.   
  172.     rt = agent->rtable.rt_lookup(ih->daddr());  
  173.       
  174.     if (rt && rt->rt_flags != RTF_UP) {  
  175.     // route is yet to be repaired   
  176.     // I will be conservative and bring down the route   
  177.     // and send route errors upstream.   
  178.     /* The following assert fails, not sure why */  
  179.     /* assert (rt->rt_flags == RTF_IN_REPAIR); */  
  180.           
  181.       //rt->rt_seqno++;   
  182.       agent->rt_down(rt);  
  183.       // send RERR   
  184. #ifdef DEBUG   
  185.       fprintf(stderr,"Node %d: Dst - %d, failed local repair\n",index, rt->rt_dst);  
  186. #endif         
  187.     }  
  188.     Packet::free((Packet *)p);  
  189. }  
  190.   
  191.   
  192. /* 
  193.    Broadcast ID Management  Functions 
  194. */  
  195.   
  196.   
  197. void  
  198. AODV::id_insert(nsaddr_t id, u_int32_t bid) {  
  199. BroadcastID *b = new BroadcastID(id, bid);  
  200.   
  201.  assert(b);  
  202.  b->expire = CURRENT_TIME + BCAST_ID_SAVE;  
  203.  LIST_INSERT_HEAD(&bihead, b, link);  
  204. }  
  205.   
  206. /* SRD */  
  207. bool  
  208. AODV::id_lookup(nsaddr_t id, u_int32_t bid) {  
  209. BroadcastID *b = bihead.lh_first;  
  210.    
  211.  // Search the list for a match of source and bid   
  212.  for( ; b; b = b->link.le_next) {  
  213.    if ((b->src == id) && (b->id == bid))  
  214.      return true;       
  215.  }  
  216.  return false;  
  217. }  
  218.   
  219. void  
  220. AODV::id_purge() {  
  221. BroadcastID *b = bihead.lh_first;  
  222. BroadcastID *bn;  
  223. double now = CURRENT_TIME;  
  224.   
  225.  for(; b; b = bn) {  
  226.    bn = b->link.le_next;  
  227.    if(b->expire <= now) {  
  228.      LIST_REMOVE(b,link);  
  229.      delete b;  
  230.    }  
  231.  }  
  232. }  
  233.   
  234. /* 
  235.   Helper Functions 
  236. */  
  237.   
  238. double  
  239. AODV::PerHopTime(aodv_rt_entry *rt) {  
  240. int num_non_zero = 0, i;  
  241. double total_latency = 0.0;  
  242.   
  243.  if (!rt)  
  244.    return ((double) NODE_TRAVERSAL_TIME );  
  245.       
  246.  for (i=0; i < MAX_HISTORY; i++) {  
  247.    if (rt->rt_disc_latency[i] > 0.0) {  
  248.       num_non_zero++;  
  249.       total_latency += rt->rt_disc_latency[i];  
  250.    }  
  251.  }  
  252.  if (num_non_zero > 0)  
  253.    return(total_latency / (double) num_non_zero);  
  254.  else  
  255.    return((double) NODE_TRAVERSAL_TIME);  
  256.   
  257. }  
  258.   
  259. /* 
  260.   Link Failure Management Functions 
  261. */  
  262.   
  263. static void  
  264. aodv_rt_failed_callback(Packet *p, void *arg) {  
  265.   ((AODV*) arg)->rt_ll_failed(p);  
  266. }  
  267.   
  268. /* 
  269.  * This routine is invoked when the link-layer reports a route failed. 
  270.  */  
  271.  /*邻居链路down掉,处理*/  
  272. void  
  273. AODV::rt_ll_failed(Packet *p) {  
  274. struct hdr_cmn *ch = HDR_CMN(p);  
  275. struct hdr_ip *ih = HDR_IP(p);  
  276. aodv_rt_entry *rt;  
  277. nsaddr_t broken_nbr = ch->next_hop_;//记录下一跳邻居的地址   
  278.   
  279. #ifndef AODV_LINK_LAYER_DETECTION   
  280.  drop(p, DROP_RTR_MAC_CALLBACK);  
  281. #else    
  282.   
  283.  /* 
  284.   * Non-data packets and Broadcast Packets can be dropped. 
  285.   */  
  286.   //如果是非数据或者广播报文,则可以直接丢弃   
  287.   if(! DATA_PACKET(ch->ptype()) ||  
  288.      (u_int32_t) ih->daddr() == IP_BROADCAST) {  
  289.     drop(p, DROP_RTR_MAC_CALLBACK);  
  290.     return;  
  291.   }  
  292.   log_link_broke(p);  
  293.   //如果不存在到达目的节点的路径,丢弃报文   
  294.     if((rt = rtable.rt_lookup(ih->daddr())) == 0) {  
  295.     drop(p, DROP_RTR_MAC_CALLBACK);  
  296.     return;  
  297.   }  
  298.   log_link_del(ch->next_hop_);  
  299.   
  300. #ifdef AODV_LOCAL_REPAIR   
  301.   /* if the broken link is closer to the dest than source,  
  302.      attempt a local repair. Otherwise, bring down the route. */  
  303.   
  304. //如果转发的跳数大于到达目的节点的跳数,则进行路由修复;否则丢弃通过此邻居的   
  305. //数据并且删除此邻居   
  306.   if (ch->num_forwards() > rt->rt_hops) {  
  307.     local_rt_repair(rt, p); // local repair   
  308.     // retrieve all the packets in the ifq using this link,   
  309.     // queue the packets for which local repair is done,    
  310.     return;  
  311.   }  
  312.   else    
  313. #endif // LOCAL REPAIR     
  314.   
  315.   {  
  316.     drop(p, DROP_RTR_MAC_CALLBACK);  
  317.     // Do the same thing for other packets in the interface queue using the   
  318.     // broken link -Mahesh   
  319. while((p = ifqueue->filter(broken_nbr))) {  
  320.      drop(p, DROP_RTR_MAC_CALLBACK);  
  321.     }     
  322.     nb_delete(broken_nbr);  
  323.   }  
  324.   
  325. #endif // LINK LAYER DETECTION   
  326. }  
  327. /*当发现邻居失效的时候,就会调用此函数*/  
  328. void  
  329. AODV::handle_link_failure(nsaddr_t id) {  
  330. aodv_rt_entry *rt, *rtn;  
  331. Packet *rerr = Packet::alloc();  
  332. struct hdr_aodv_error *re = HDR_AODV_ERROR(rerr);  
  333.   
  334.  re->DestCount = 0;  
  335.  //查找通过此邻居节点到达目的的路由,   
  336.  for(rt = rtable.head(); rt; rt = rtn) {  // for each rt entry   
  337.    rtn = rt->rt_link.le_next;   
  338.    //如果跳数不是无限大并且下一跳就是失效的邻居   
  339.    if ((rt->rt_hops != INFINITY2) && (rt->rt_nexthop == id) ) {  
  340.      assert (rt->rt_flags == RTF_UP);  
  341.      assert((rt->rt_seqno%2) == 0);  
  342.      rt->rt_seqno++;  
  343.      re->unreachable_dst[re->DestCount] = rt->rt_dst;  
  344.      re->unreachable_dst_seqno[re->DestCount] = rt->rt_seqno;  
  345. #ifdef DEBUG   
  346.      fprintf(stderr, "%s(%f): %d\t(%d\t%u\t%d)\n", __FUNCTION__, CURRENT_TIME,  
  347.              index, re->unreachable_dst[re->DestCount],  
  348.              re->unreachable_dst_seqno[re->DestCount], rt->rt_nexthop);  
  349. #endif // DEBUG   
  350.      re->DestCount += 1;  
  351.      rt_down(rt);//将此路由down掉   
  352.    }  
  353.    // remove the lost neighbor from all the precursor lists   
  354.    rt->pc_delete(id);//删除此路由的前缀列表   
  355.  }     
  356. /*如果存在通过此邻居到达目的节点的路由,则发送错误报文*/  
  357.  if (re->DestCount > 0) {  
  358. #ifdef DEBUG   
  359.    fprintf(stderr, "%s(%f): %d\tsending RERR...\n", __FUNCTION__, CURRENT_TIME, index);  
  360. #endif // DEBUG   
  361.    sendError(rerr, false);  
  362.  }  
  363.  else {  
  364.    Packet::free(rerr);  
  365.  }  
  366. }  
  367.   
  368. void  
  369. AODV::local_rt_repair(aodv_rt_entry *rt, Packet *p) {  
  370. #ifdef DEBUG   
  371.   fprintf(stderr,"%s: Dst - %d\n", __FUNCTION__, rt->rt_dst);   
  372. #endif     
  373.   // Buffer the packet    
  374.   rqueue.enque(p);  
  375.   
  376.   // mark the route as under repair    
  377.   rt->rt_flags = RTF_IN_REPAIR;  
  378.   
  379.   sendRequest(rt->rt_dst);  
  380.   
  381.   // set up a timer interrupt   
  382.   Scheduler::instance().schedule(&lrtimer, p->copy(), rt->rt_req_timeout);  
  383. }  
  384. /*更新路由条目*/  
  385. void  
  386. AODV::rt_update(aodv_rt_entry *rt, u_int32_t seqnum, u_int16_t metric,  
  387.             nsaddr_t nexthop, double expire_time) {  
  388.   
  389.      rt->rt_seqno = seqnum;  
  390.      rt->rt_hops = metric;  
  391.      rt->rt_flags = RTF_UP;  
  392.      rt->rt_nexthop = nexthop;  
  393.      rt->rt_expire = expire_time;  
  394. }  
  395. /*将此路由条目down掉*/  
  396. void  
  397. AODV::rt_down(aodv_rt_entry *rt) {  
  398.   /* 
  399.    *  Make sure that you don't "down" a route more than once. 
  400.    */  
  401.   
  402.   if(rt->rt_flags == RTF_DOWN) {  
  403.     return;  
  404.   }  
  405.   
  406.   // assert (rt->rt_seqno%2); // is the seqno odd?   
  407.   rt->rt_last_hop_count = rt->rt_hops;  
  408.   rt->rt_hops = INFINITY2;  
  409.   rt->rt_flags = RTF_DOWN;  
  410.   rt->rt_nexthop = 0;  
  411.   rt->rt_expire = 0;  
  412.   
  413. /* rt_down function */  
  414.   
  415. /* 
  416.   Route Handling Functions 
  417. */  
  418.   
  419. void  
  420. AODV::rt_resolve(Packet *p) {  
  421. struct hdr_cmn *ch = HDR_CMN(p);  
  422. struct hdr_ip *ih = HDR_IP(p);  
  423. aodv_rt_entry *rt;  
  424.   
  425.  /* 
  426.   *  Set the transmit failure callback.  That 
  427.   *  won't change. 
  428.   */  
  429.   //这是一个指针,具体请看另一篇博客   
  430.  ch->xmit_failure_ = aodv_rt_failed_callback;  
  431.  ch->xmit_failure_data_ = (void*) this;  
  432.     rt = rtable.rt_lookup(ih->daddr());  
  433.  if(rt == 0) {  
  434.       rt = rtable.rt_add(ih->daddr());  
  435.  }  
  436.   
  437.  /* 
  438.   * If the route is up, forward the packet  
  439.   */  
  440.     //如果存在路由,则转发   
  441.  if(rt->rt_flags == RTF_UP) {  
  442.    assert(rt->rt_hops != INFINITY2);  
  443.    forward(rt, p, NO_DELAY);  
  444.  }  
  445.  /* 
  446.   *  if I am the source of the packet, then do a Route Request. 
  447.   */  
  448.     else if(ih->saddr() == index)   
  449.     // {   
  450.     //如果是源节点且没有到达目的节点的路由,缓存数分组   
  451.     //发送路由请求   
  452.    rqueue.enque(p);  
  453.    sendRequest(rt->rt_dst);  
  454.  }  
  455.  /* 
  456.   * A local repair is in progress. Buffer the packet.  
  457.   */  
  458.   //如果此路由处于修复状态,则缓存分组   
  459.  else if (rt->rt_flags == RTF_IN_REPAIR) {  
  460.    rqueue.enque(p);  
  461.  }  
  462.   
  463.  /* 
  464.   * I am trying to forward a packet for someone else to which 
  465.   * I don't have a route. 
  466.   */  
  467.   //否则发送错误报文   
  468.  else {  
  469.  Packet *rerr = Packet::alloc();  
  470.  struct hdr_aodv_error *re = HDR_AODV_ERROR(rerr);  
  471.  /*  
  472.   * For now, drop the packet and send error upstream. 
  473.   * Now the route errors are broadcast to upstream 
  474.   * neighbors - Mahesh 09/11/99 
  475.   */      
  476.    
  477.    assert (rt->rt_flags == RTF_DOWN);  
  478.    re->DestCount = 0;  
  479.    re->unreachable_dst[re->DestCount] = rt->rt_dst;  
  480.    re->unreachable_dst_seqno[re->DestCount] = rt->rt_seqno;  
  481.    re->DestCount += 1;  
  482. #ifdef DEBUG   
  483.    fprintf(stderr, "%s: sending RERR...\n", __FUNCTION__);  
  484. #endif   
  485.    sendError(rerr, false);  
  486.   
  487.    drop(p, DROP_RTR_NO_ROUTE);  
  488.  }  
  489.   
  490. }  
  491. /*定时查看路由缓存条目*/  
  492. void  
  493. AODV::rt_purge() {  
  494. aodv_rt_entry *rt, *rtn;  
  495. double now = CURRENT_TIME;  
  496. double delay = 0.0;  
  497. Packet *p;  
  498.   
  499.  for(rt = rtable.head(); rt; rt = rtn) {  // for each rt entry   
  500.    rtn = rt->rt_link.le_next;  
  501.    //如果此路由条目标注为有效,但是生存时间为0   
  502.    //丢弃前往目的分组,并且将此路由条目down掉   
  503.    if ((rt->rt_flags == RTF_UP) && (rt->rt_expire < now)) {  
  504.    // if a valid route has expired, purge all packets from    
  505.    // send buffer and invalidate the route.                       
  506.     assert(rt->rt_hops != INFINITY2);  
  507.      while((p = rqueue.deque(rt->rt_dst))) {  
  508. #ifdef DEBUG   
  509.        fprintf(stderr, "%s: calling drop()\n",  
  510.                        __FUNCTION__);  
  511. #endif // DEBUG   
  512.        drop(p, DROP_RTR_NO_ROUTE);  
  513.      }  
  514.      rt->rt_seqno++;  
  515.      assert (rt->rt_seqno%2);  
  516.      rt_down(rt);  
  517.    }  
  518.    //如果此路由条目并没有过期,则可以发送分组   
  519.    else if (rt->rt_flags == RTF_UP) {  
  520.    // If the route is not expired,   
  521.    // and there are packets in the sendbuffer waiting,   
  522.    // forward them. This should not be needed, but this extra    
  523.    // check does no harm.   
  524.      assert(rt->rt_hops != INFINITY2);  
  525.      while((p = rqueue.deque(rt->rt_dst))) {  
  526.        forward (rt, p, delay);  
  527.        delay += ARP_DELAY;  
  528.      }  
  529.    }   
  530.    //如果此路由条目已经down掉,但是有前往目的的分组,则发送路由请求   
  531.    else if (rqueue.find(rt->rt_dst))  
  532.    // If the route is down and    
  533.    // if there is a packet for this destination waiting in   
  534.    // the sendbuffer, then send out route request. sendRequest   
  535.    // will check whether it is time to really send out request   
  536.    // or not.   
  537.    // This may not be crucial to do it here, as each generated    
  538.    // packet will do a sendRequest anyway.   
  539.   
  540.      sendRequest(rt->rt_dst);   
  541.    }  
  542.   
  543. }  
  544.   
  545. /* 
  546.   Packet Reception Routines 
  547. */  
  548.   
  549. void  
  550. AODV::recv(Packet *p, Handler*) {  
  551. struct hdr_cmn *ch = HDR_CMN(p);  
  552. struct hdr_ip *ih = HDR_IP(p);  
  553.   
  554.  assert(initialized());  
  555.  //assert(p->incoming == 0);   
  556.  // 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.   
  557. //如果分组类型是AODV类型,则交给recvAodv函数   
  558.  if(ch->ptype() == PT_AODV) {  
  559.    ih->ttl_ -= 1;  
  560.    recvAODV(p);  
  561.    return;  
  562.  }  
  563.   
  564.   
  565.  /* 
  566.   *  Must be a packet I'm originating... 
  567.   */  
  568.   //如果是我发送的报文,加上包头,ch->num_forward()是转发的跳数   
  569. if((ih->saddr() == index) && (ch->num_forwards() == 0)) {  
  570.  /* 
  571.   * Add the IP Header 
  572.   */  
  573.    ch->size() += IP_HDR_LEN;  
  574.    // Added by Parag Dadhania && John Novatnack to handle broadcasting   
  575.    if ( (u_int32_t)ih->daddr() != IP_BROADCAST)  
  576.      ih->ttl_ = NETWORK_DIAMETER;  
  577. }  
  578.  /* 
  579.   *  I received a packet that I sent.  Probably 
  580.   *  a routing loop. 
  581.   */  
  582.   //出现路由环路,丢弃   
  583. else if(ih->saddr() == index) {  
  584.    drop(p, DROP_RTR_ROUTE_LOOP);  
  585.    return;  
  586.  }  
  587.  /* 
  588.   *  Packet I'm forwarding... 
  589.   */  
  590.  else {  
  591.  /* 
  592.   *  Check the TTL.  If it is zero, then discard. 
  593.   */  
  594.   //如果ttl值为零,丢弃   
  595.    if(--ih->ttl_ == 0) {  
  596.      drop(p, DROP_RTR_TTL);  
  597.      return;  
  598.    }  
  599.  }  
  600. // Added by Parag Dadhania && John Novatnack to handle broadcasting   
  601. //如果不是广播报文,交给re_resolve函数处理;如果是广播报文,则转发   
  602.  if ( (u_int32_t)ih->daddr() != IP_BROADCAST)  
  603.    rt_resolve(p);  
  604.  else  
  605.    forward((aodv_rt_entry*) 0, p, NO_DELAY);  
  606. }  
  607.   
  608.   
  609. void  
  610. AODV::recvAODV(Packet *p) {  
  611. struct hdr_aodv *ah = HDR_AODV(p);  
  612. struct hdr_ip *ih = HDR_IP(p);  
  613.   
  614.  assert(ih->sport() == RT_PORT);  
  615.  assert(ih->dport() == RT_PORT);  
  616.   
  617.  /* 
  618.   * Incoming Packets. 
  619.   */  
  620.  switch(ah->ah_type) {  
  621.   
  622.  case AODVTYPE_RREQ:  
  623.    recvRequest(p);  
  624.    break;  
  625.   
  626.  case AODVTYPE_RREP:  
  627.    recvReply(p);  
  628.    break;  
  629.   
  630.  case AODVTYPE_RERR:  
  631.    recvError(p);  
  632.    break;  
  633.   
  634.  case AODVTYPE_HELLO:  
  635.    recvHello(p);  
  636.    break;  
  637.           
  638.  default:  
  639.    fprintf(stderr, "Invalid AODV type (%x)\n", ah->ah_type);  
  640.    exit(1);  
  641.  }  
  642.   
  643. }  
  644.   
  645.   
  646. void  
  647. AODV::recvRequest(Packet *p) {  
  648. struct hdr_ip *ih = HDR_IP(p);  
  649. struct hdr_aodv_request *rq = HDR_AODV_REQUEST(p);  
  650. aodv_rt_entry *rt;  
  651.   
  652.   /* 
  653.    * Drop if: 
  654.    *      - I'm the source 
  655.    *      - I recently heard this request. 
  656.    */  
  657. /*如果此节点就是源节点,出现环路,丢弃路由请求报文*/  
  658.   if(rq->rq_src == index) {  
  659. #ifdef DEBUG   
  660.     fprintf(stderr, "%s: got my own REQUEST\n", __FUNCTION__);  
  661. #endif // DEBUG   
  662.     Packet::free(p);  
  663.     return;  
  664.   }   
  665. /*如果已经收到了源地址和请求序列号相等的请求报文,丢弃*/  
  666.  if (id_lookup(rq->rq_src, rq->rq_bcast_id)) {  
  667.   
  668. #ifdef DEBUG   
  669.    fprintf(stderr, "%s: discarding request\n", __FUNCTION__);  
  670. #endif // DEBUG   
  671.    
  672.    Packet::free(p);  
  673.    return;  
  674.  }  
  675.   
  676.  /* 
  677.   * Cache the broadcast ID 
  678.   */  
  679.   /*缓存此路由请求*/  
  680.  id_insert(rq->rq_src, rq->rq_bcast_id);  
  681.   
  682.   
  683.   
  684.  /*  
  685.   * We are either going to forward the REQUEST or generate a 
  686.   * REPLY. Before we do anything, we make sure that the REVERSE 
  687.   * route is in the route table. 
  688.   */  
  689.   //建立反向路径   
  690.  aodv_rt_entry *rt0; // rt0 is the reverse route    
  691.      
  692.    rt0 = rtable.rt_lookup(rq->rq_src);  
  693.    if(rt0 == 0) { /* if not in the route table */  
  694.    // create an entry for the reverse route.   
  695.      rt0 = rtable.rt_add(rq->rq_src);  
  696.    }  
  697.   //更新此路由条目的生存时间   
  698.    rt0->rt_expire = max(rt0->rt_expire, (CURRENT_TIME + REV_ROUTE_LIFE));  
  699. /*如果请求序列号大于路由序列号或者两者序列号相等但是跳数 
  700. 比源路由跳数小,则更新*/  
  701.    if ( (rq->rq_src_seqno > rt0->rt_seqno ) ||  
  702.         ((rq->rq_src_seqno == rt0->rt_seqno) &&   
  703.      (rq->rq_hop_count < rt0->rt_hops)) ) {  
  704.    // If we have a fresher seq no. or lesser #hops for the    
  705.    // same seq no., update the rt entry. Else don't bother.   
  706. rt_update(rt0, rq->rq_src_seqno, rq->rq_hop_count, ih->saddr(),  
  707.                max(rt0->rt_expire, (CURRENT_TIME + REV_ROUTE_LIFE)) );  
  708.    /*如果此前请求过该路由条目,则更新信息*/  
  709.      if (rt0->rt_req_timeout > 0.0) {  
  710.      // Reset the soft state and    
  711.      // Set expiry time to CURRENT_TIME + ACTIVE_ROUTE_TIMEOUT   
  712.      // This is because route is used in the forward direction,   
  713.      // but only sources get benefited by this change   
  714.        rt0->rt_req_cnt = 0;  
  715.        rt0->rt_req_timeout = 0.0;   
  716.        rt0->rt_req_last_ttl = rq->rq_hop_count;  
  717.        rt0->rt_expire = CURRENT_TIME + ACTIVE_ROUTE_TIMEOUT;  
  718.      }  
  719.   
  720.      /* Find out whether any buffered packet can benefit from the  
  721.       * reverse route. 
  722.       * May need some change in the following code - Mahesh 09/11/99 
  723.       */  
  724.       /*如果有到反向路径的分组报文,则发送*/  
  725.      assert (rt0->rt_flags == RTF_UP);  
  726.      Packet *buffered_pkt;  
  727.      while ((buffered_pkt = rqueue.deque(rt0->rt_dst))) {  
  728.        if (rt0 && (rt0->rt_flags == RTF_UP)) {  
  729.     assert(rt0->rt_hops != INFINITY2);  
  730.          forward(rt0, buffered_pkt, NO_DELAY);  
  731.        }  
  732.      }  
  733.    }   
  734.    // End for putting reverse route in rt table   
  735.   
  736.   
  737.  /* 
  738.   * We have taken care of the reverse route stuff. 
  739.   * Now see whether we can send a route reply.  
  740.   */  
  741. //寻找到目的节点的路由   
  742.  rt = rtable.rt_lookup(rq->rq_dst);  
  743.   
  744.  // First check if I am the destination ..   
  745. /*如果本节点就是目的节点,直接发送路由应答报文*/  
  746.  if(rq->rq_dst == index) {  
  747.   
  748. #ifdef DEBUG   
  749.    fprintf(stderr, "%d - %s: destination sending reply\n",  
  750.                    index, __FUNCTION__);  
  751. #endif // DEBUG   
  752.   
  753.                  
  754.    // Just to be safe, I use the max. Somebody may have   
  755.    // incremented the dst seqno.   
  756.    seqno = max(seqno, rq->rq_dst_seqno)+1;  
  757.    if (seqno%2) seqno++;  
  758.   
  759.    sendReply(rq->rq_src,           // IP Destination   
  760.              1,                    // Hop Count   
  761.              index,                // Dest IP Address   
  762.              seqno,                // Dest Sequence Num   
  763.              MY_ROUTE_TIMEOUT,     // Lifetime   
  764.              rq->rq_timestamp);    // timestamp   
  765.    
  766.    Packet::free(p);  
  767.  }  
  768.   
  769.  // I am not the destination, but I may have a fresh enough route.   
  770. /*如果不是目的节点,但是有到目的节点的路径,也发送路由应答报文*/  
  771.  else if (rt && (rt->rt_hops != INFINITY2) &&   
  772.         (rt->rt_seqno >= rq->rq_dst_seqno) ) {  
  773.   
  774.    //assert (rt->rt_flags == RTF_UP);   
  775.    assert(rq->rq_dst == rt->rt_dst);  
  776.    //assert ((rt->rt_seqno%2) == 0); // is the seqno even?   
  777.    sendReply(rq->rq_src,  
  778.              rt->rt_hops + 1,  
  779.              rq->rq_dst,  
  780.              rt->rt_seqno,  
  781.          (u_int32_t) (rt->rt_expire - CURRENT_TIME),  
  782.          //             rt->rt_expire - CURRENT_TIME,   
  783.              rq->rq_timestamp);  
  784.    // Insert nexthops to RREQ source and RREQ destination in the   
  785.    // precursor lists of destination and source respectively   
  786.    rt->pc_insert(rt0->rt_nexthop); // 加入前缀列表   
  787.    rt0->pc_insert(rt->rt_nexthop); // 加入前缀列表   
  788.   
  789. #ifdef RREQ_GRAT_RREP     
  790.   
  791.    sendReply(rq->rq_dst,  
  792.              rq->rq_hop_count,  
  793.              rq->rq_src,  
  794.              rq->rq_src_seqno,  
  795.          (u_int32_t) (rt->rt_expire - CURRENT_TIME),  
  796.          //             rt->rt_expire - CURRENT_TIME,   
  797.              rq->rq_timestamp);  
  798. #endif   
  799.      
  800. // TODO: send grat RREP to dst if G flag set in RREQ using rq->rq_src_seqno, rq->rq_hop_counT   
  801.      
  802. // 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.   
  803.   
  804.     Packet::free(p);  
  805.  }  
  806.  /* 
  807.   * Can't reply. So forward the  Route Request 
  808.   */  
  809.   //不能应答此报文,则继续广播   
  810.  else {  
  811.    ih->saddr() = index;  
  812.    ih->daddr() = IP_BROADCAST;  
  813.    rq->rq_hop_count += 1;  
  814.    // Maximum sequence number seen en route   
  815.    if (rt) rq->rq_dst_seqno = max(rt->rt_seqno, rq->rq_dst_seqno);  
  816.    forward((aodv_rt_entry*) 0, p, DELAY);  
  817.  }  
  818.   
  819. }  
  820.   
  821.   
  822. void  
  823. AODV::recvReply(Packet *p) {  
  824. //struct hdr_cmn *ch = HDR_CMN(p);   
  825. struct hdr_ip *ih = HDR_IP(p);  
  826. struct hdr_aodv_reply *rp = HDR_AODV_REPLY(p);  
  827. aodv_rt_entry *rt;  
  828. char suppress_reply = 0;  
  829. double delay = 0.0;  
  830.       
  831. #ifdef DEBUG   
  832.  fprintf(stderr, "%d - %s: received a REPLY\n", index, __FUNCTION__);  
  833. #endif // DEBUG   
  834.   
  835.   
  836.  /* 
  837.   *  Got a reply. So reset the "soft state" maintained for  
  838.   *  route requests in the request table. We don't really have 
  839.   *  have a separate request table. It is just a part of the 
  840.   *  routing table itself.  
  841.   */  
  842.  // Note that rp_dst is the dest of the data packets, not the   
  843.  // the dest of the reply, which is the src of the data packets.   
  844.   
  845.  rt = rtable.rt_lookup(rp->rp_dst);//建立反向路径   
  846.           
  847.  /* 
  848.   *  If I don't have a rt entry to this host... adding 
  849.   */  
  850.  if(rt == 0) {  
  851.    rt = rtable.rt_add(rp->rp_dst);  
  852.  }  
  853.   
  854.  /* 
  855.   * Add a forward route table entry... here I am following  
  856.   * Perkins-Royer AODV paper almost literally - SRD 5/99 
  857.   */  
  858. /*如果应答报文中目的序列号大于路由序列号或者 
  859.  两者序列号相等但是跳数较小,则更新路由表*/  
  860.  if ( (rt->rt_seqno < rp->rp_dst_seqno) ||   // newer route    
  861.       ((rt->rt_seqno == rp->rp_dst_seqno) &&    
  862.        (rt->rt_hops > rp->rp_hop_count)) ) { // shorter or better route   
  863.       
  864.   // Update the rt entry    
  865.   rt_update(rt, rp->rp_dst_seqno, rp->rp_hop_count,  
  866.         rp->rp_src, CURRENT_TIME + rp->rp_lifetime);  
  867.   
  868.   // reset the soft state   
  869.   rt->rt_req_cnt = 0;//路由请求次数归零   
  870.   rt->rt_req_timeout = 0.0; //路由请求剩余时间归零   
  871.   rt->rt_req_last_ttl = rp->rp_hop_count;  
  872.   /*如果此节点是目的节点*/  
  873. if (ih->daddr() == index) { // If I am the original source   
  874.   // Update the route discovery latency statistics   
  875.   // rp->rp_timestamp is the time of request origination   
  876.           
  877.     rt->rt_disc_latency[rt->hist_indx] = (CURRENT_TIME - rp->rp_timestamp)  
  878.                                          / (double) rp->rp_hop_count;  
  879.     // increment indx for next time   
  880.     rt->hist_indx = (rt->hist_indx + 1) % MAX_HISTORY;  
  881.   }   
  882.   
  883.   /* 
  884.    * Send all packets queued in the sendbuffer destined for 
  885.    * this destination.  
  886.    * XXX - observe the "second" use of p. 
  887.    */  
  888.    /*如果有到反向路径的数据包,则发送*/  
  889.   Packet *buf_pkt;  
  890.   while((buf_pkt = rqueue.deque(rt->rt_dst))) {  
  891.     if(rt->rt_hops != INFINITY2) {  
  892.           assert (rt->rt_flags == RTF_UP);  
  893.     // Delay them a little to help ARP. Otherwise ARP    
  894.     // may drop packets. -SRD 5/23/99   
  895.       forward(rt, buf_pkt, delay);  
  896.       delay += ARP_DELAY;  
  897.     }  
  898.   }  
  899.  }  
  900.  else {  
  901.   suppress_reply = 1;//序列号过小且没有更小的跳数   
  902.  }  
  903.   
  904.  /* 
  905.   * If reply is for me, discard it. 
  906.   */  
  907.   
  908. if(ih->daddr() == index || suppress_reply)   
  909.  {//如果此节点是源节点或者应答报文不够新且没有更小的跳数   
  910.    Packet::free(p);  
  911.  }  
  912.  /* 
  913.   * Otherwise, forward the Route Reply. 
  914.   */  
  915.  else {  
  916.  // Find the rt entry   
  917. aodv_rt_entry *rt0 = rtable.rt_lookup(ih->daddr());  
  918.    // If the rt is up, forward   
  919.    if(rt0 && (rt0->rt_hops != INFINITY2))   
  920.     {  
  921.    //如果存在到源节点的路径,则转发应答报文,否则丢弃应答报文   
  922.         assert (rt0->rt_flags == RTF_UP);  
  923.      rp->rp_hop_count += 1;  
  924.      rp->rp_src = index;  
  925.      forward(rt0, p, NO_DELAY);  
  926.      // Insert the nexthop towards the RREQ source to    
  927.      // the precursor list of the RREQ destination   
  928.      rt->pc_insert(rt0->rt_nexthop); // nexthop to RREQ source   
  929.        
  930.    }  
  931.    else {//   
  932.    // I don't know how to forward .. drop the reply.    
  933. #ifdef DEBUG   
  934.      fprintf(stderr, "%s: dropping Route Reply\n", __FUNCTION__);  
  935. #endif // DEBUG   
  936.      drop(p, DROP_RTR_NO_ROUTE);  
  937.    }  
  938.  }  
  939. }  
  940.   
  941. /*从邻居那里收到错误分组,检查自己路由表是否有通过此邻居到达目的地的 
  942. 路由条目,如果有,则将此路由删除,并继续向邻居广播错误分组*/  
  943. void  
  944. AODV::recvError(Packet *p) {  
  945. struct hdr_ip *ih = HDR_IP(p);  
  946. struct hdr_aodv_error *re = HDR_AODV_ERROR(p);  
  947. aodv_rt_entry *rt;  
  948. u_int8_t i;  
  949. Packet *rerr = Packet::alloc();  
  950. struct hdr_aodv_error *nre = HDR_AODV_ERROR(rerr);  
  951.   
  952.  nre->DestCount = 0;  
  953. /*遍历错误分组中每一个不可达路由*/  
  954.  for (i=0; i<re->DestCount; i++) {  
  955.  // For each unreachable destination   
  956.    rt = rtable.rt_lookup(re->unreachable_dst[i]);  
  957.  /*是否存在经过发送错误分组的邻居的路由*/  
  958.    if ( rt && (rt->rt_hops != INFINITY2) &&  
  959.     (rt->rt_nexthop == ih->saddr()) &&  
  960.         (rt->rt_seqno <= re->unreachable_dst_seqno[i]) ) {  
  961.     assert(rt->rt_flags == RTF_UP);  
  962.     assert((rt->rt_seqno%2) == 0); // 奇数代表无穷大,无效的意思   
  963. #ifdef DEBUG   
  964.      fprintf(stderr, "%s(%f): %d\t(%d\t%u\t%d)\t(%d\t%u\t%d)\n", __FUNCTION__,CURRENT_TIME,  
  965.              index, rt->rt_dst, rt->rt_seqno, rt->rt_nexthop,  
  966.              re->unreachable_dst[i],re->unreachable_dst_seqno[i],  
  967.                  ih->saddr());  
  968. #endif // DEBUG   
  969.         rt->rt_seqno = re->unreachable_dst_seqno[i];  
  970.         rt_down(rt);//将此路由down掉   
  971.   
  972.    // Not sure whether this is the right thing to do   
  973.    /*查看队列中是否有下一跳是此邻居的分组 
  974.    若有的话,直接丢包;具体请看queue/priqueue.cc的filter函数*/  
  975.    Packet *pkt;  
  976.     while((pkt = ifqueue->filter(ih->saddr()))) {  
  977.             drop(pkt, DROP_RTR_MAC_CALLBACK);  
  978.         }  
  979.   
  980.      // if precursor list non-empty add to RERR and delete the precursor list   
  981.      /*如果此路由的前缀列表非空,将此节点不可达的目的地记录在新的路由分组中 
  982.      并且删除此路由的前缀列表*/  
  983.         if (!rt->pc_empty()) {  
  984.             nre->unreachable_dst[nre->DestCount] = rt->rt_dst;  
  985.             nre->unreachable_dst_seqno[nre->DestCount] = rt->rt_seqno;  
  986.             nre->DestCount += 1;  
  987.         rt->pc_delete();  
  988.         }  
  989.    }  
  990.  }   
  991. /*如果此节点有不可达路由,则继续广播错误分组*/  
  992.  if (nre->DestCount > 0) {  
  993. #ifdef DEBUG   
  994.    fprintf(stderr, "%s(%f): %d\t sending RERR...\n", __FUNCTION__, CURRENT_TIME, index);  
  995. #endif // DEBUG   
  996.    sendError(rerr);  
  997.  }  
  998.  else {  
  999.    Packet::free(rerr);  
  1000.  }  
  1001.   
  1002.  Packet::free(p);  
  1003. }  
  1004.   
  1005.   
  1006. /* 
  1007.    Packet Transmission Routines 
  1008. */  
  1009.   
  1010. void  
  1011. AODV::forward(aodv_rt_entry *rt, Packet *p, double delay) {  
  1012. struct hdr_cmn *ch = HDR_CMN(p);  
  1013. struct hdr_ip *ih = HDR_IP(p);  
  1014. /*如果跳数为零,直接丢弃*/  
  1015.  if(ih->ttl_ == 0) {  
  1016.   
  1017. #ifdef DEBUG   
  1018.   fprintf(stderr, "%s: calling drop()\n", __PRETTY_FUNCTION__);  
  1019. #endif // DEBUG   
  1020.    
  1021.   drop(p, DROP_RTR_TTL);  
  1022.   return;  
  1023.  }  
  1024. /*如果不是AODV数据包并且链路方向是上行并且是广播包或者此节点就是目的地址*/  
  1025.  if (ch->ptype() != PT_AODV && ch->direction() == hdr_cmn::UP &&  
  1026.     ((u_int32_t)ih->daddr() == IP_BROADCAST)  
  1027.         || ((u_int32_t)ih->daddr() == here_.addr_)) {  
  1028.     dmux_->recv(p,0);//交给分类器   
  1029.     return;  
  1030.  }  
  1031.   
  1032.  if (rt) {//如果存在去往目的的路由,设置一系列参数   
  1033.    assert(rt->rt_flags == RTF_UP);  
  1034.    rt->rt_expire = CURRENT_TIME + ACTIVE_ROUTE_TIMEOUT;  
  1035.    ch->next_hop_ = rt->rt_nexthop;  
  1036.    ch->addr_type() = NS_AF_INET;  
  1037.    ch->direction() = hdr_cmn::DOWN;       //important: change the packet's direction   
  1038.  }  
  1039.  else { // if it is a broadcast packet   
  1040.    // assert(ch->ptype() == PT_AODV); // maybe a diff pkt type like gaf   
  1041.    assert(ih->daddr() == (nsaddr_t) IP_BROADCAST);//如果这是一个广播报文   
  1042.    ch->addr_type() = NS_AF_NONE;  
  1043.    ch->direction() = hdr_cmn::DOWN;       //important: change the packet's direction   
  1044.  }  
  1045.   
  1046. if (ih->daddr() == (nsaddr_t) IP_BROADCAST) {//广播报文   
  1047.  // If it is a broadcast packet   
  1048.    assert(rt == 0);  
  1049.    /* 
  1050.     *  Jitter the sending of broadcast packets by 10ms 
  1051.     */  
  1052.    Scheduler::instance().schedule(target_, p,  
  1053.                        0.01 * Random::uniform());//加入定时器   
  1054.  }  
  1055.  else { // 非广播报文   
  1056.    if(delay > 0.0) {  
  1057.      Scheduler::instance().schedule(target_, p, delay);  
  1058.    }  
  1059.    else {  
  1060.    // Not a broadcast packet, no delay, send immediately   
  1061.      Scheduler::instance().schedule(target_, p, 0.);  
  1062.    }  
  1063.  }  
  1064.   
  1065. }  
  1066.   
  1067.   
  1068. void  
  1069. AODV::sendRequest(nsaddr_t dst) {  
  1070. // Allocate a RREQ packet    
  1071. Packet *p = Packet::alloc();  
  1072. struct hdr_cmn *ch = HDR_CMN(p);  
  1073. struct hdr_ip *ih = HDR_IP(p);  
  1074. struct hdr_aodv_request *rq = HDR_AODV_REQUEST(p);  
  1075. aodv_rt_entry *rt = rtable.rt_lookup(dst);  
  1076.   
  1077.  assert(rt);  
  1078.   
  1079.  /* 
  1080.   *  Rate limit sending of Route Requests. We are very conservative 
  1081.   *  about sending out route requests.  
  1082.   */  
  1083.  //如果有到目的节点的路由,则终止请求   
  1084.  if (rt->rt_flags == RTF_UP) {  
  1085.    assert(rt->rt_hops != INFINITY2);  
  1086.    Packet::free((Packet *)p);  
  1087.    return;  
  1088.  }  
  1089. //如果请求时间还有到,则不发送   
  1090.  if (rt->rt_req_timeout > CURRENT_TIME) {  
  1091.    Packet::free((Packet *)p);  
  1092.    return;  
  1093.  }  
  1094.   
  1095.  // rt_req_cnt is the no. of times we did network-wide broadcast   
  1096.  // RREQ_RETRIES is the maximum number we will allow before    
  1097.  // going to a long timeout.   
  1098. //如果请求次数大于最大的发送请求次数,则丢掉分组,不发送请求   
  1099.  if (rt->rt_req_cnt > RREQ_RETRIES) {  
  1100.    rt->rt_req_timeout = CURRENT_TIME + MAX_RREQ_TIMEOUT;  
  1101.    rt->rt_req_cnt = 0;  
  1102.  Packet *buf_pkt;  
  1103.    while ((buf_pkt = rqueue.deque(rt->rt_dst))) {  
  1104.        drop(buf_pkt, DROP_RTR_NO_ROUTE);  
  1105.    }  
  1106.    Packet::free((Packet *)p);  
  1107.    return;  
  1108.  }  
  1109.   
  1110. #ifdef DEBUG   
  1111.    fprintf(stderr, "(%2d) - %2d sending Route Request, dst: %d\n",  
  1112.                     ++route_request, index, rt->rt_dst);  
  1113. #endif // DEBUG   
  1114.   
  1115.  // Determine the TTL to be used this time.    
  1116.  // Dynamic TTL evaluation - SRD   
  1117.   
  1118.  rt->rt_req_last_ttl = max(rt->rt_req_last_ttl,rt->rt_last_hop_count);  
  1119. //路由请求的环搜索   
  1120. //第一次广播请求,选择初始跳数;随后逐渐扩大   
  1121.  if (0 == rt->rt_req_last_ttl) {  
  1122.  // first time query broadcast   
  1123.    ih->ttl_ = TTL_START;  
  1124.  }  
  1125.  else {  
  1126.  // Expanding ring search.   
  1127.    if (rt->rt_req_last_ttl < TTL_THRESHOLD)  
  1128.      ih->ttl_ = rt->rt_req_last_ttl + TTL_INCREMENT;  
  1129.    else {  
  1130.    // network-wide broadcast   
  1131.      ih->ttl_ = NETWORK_DIAMETER;  
  1132.      rt->rt_req_cnt += 1;  
  1133.    }  
  1134.  }  
  1135.   
  1136.  // remember the TTL used  for the next time   
  1137.  rt->rt_req_last_ttl = ih->ttl_;//为下次使用做记录   
  1138.   
  1139.  // PerHopTime is the roundtrip time per hop for route requests.   
  1140.  // The factor 2.0 is just to be safe .. SRD 5/22/99   
  1141.  // Also note that we are making timeouts to be larger if we have    
  1142.  // done network wide broadcast before.    
  1143.   
  1144.  rt->rt_req_timeout = 2.0 * (double) ih->ttl_ * PerHopTime(rt);   
  1145.  if (rt->rt_req_cnt > 0)  
  1146.    rt->rt_req_timeout *= rt->rt_req_cnt;  
  1147.  rt->rt_req_timeout += CURRENT_TIME;  
  1148.   
  1149.  // Don't let the timeout to be too large, however .. SRD 6/8/99   
  1150.  if (rt->rt_req_timeout > CURRENT_TIME + MAX_RREQ_TIMEOUT)  
  1151.    rt->rt_req_timeout = CURRENT_TIME + MAX_RREQ_TIMEOUT;  
  1152.  rt->rt_expire = 0;  
  1153.   
  1154. #ifdef DEBUG   
  1155.  fprintf(stderr, "(%2d) - %2d sending Route Request, dst: %d, tout %f ms\n",  
  1156.              ++route_request,   
  1157.          index, rt->rt_dst,   
  1158.          rt->rt_req_timeout - CURRENT_TIME);  
  1159. #endif  // DEBUG   
  1160.       
  1161.   
  1162.  // Fill out the RREQ packet    
  1163.  // ch->uid() = 0;   
  1164.  ch->ptype() = PT_AODV;  
  1165.  ch->size() = IP_HDR_LEN + rq->size();  
  1166.  ch->iface() = -2;  
  1167.  ch->error() = 0;  
  1168.  ch->addr_type() = NS_AF_NONE;  
  1169.  ch->prev_hop_ = index;          // AODV hack   
  1170.   
  1171.  ih->saddr() = index;  
  1172.  ih->daddr() = IP_BROADCAST;  
  1173.  ih->sport() = RT_PORT;  
  1174.  ih->dport() = RT_PORT;  
  1175.   
  1176.  // Fill up some more fields.    
  1177.  rq->rq_type = AODVTYPE_RREQ;  
  1178.  rq->rq_hop_count = 1;  
  1179.  rq->rq_bcast_id = bid++;  
  1180.  rq->rq_dst = dst;  
  1181.  rq->rq_dst_seqno = (rt ? rt->rt_seqno : 0);  
  1182.  rq->rq_src = index;  
  1183.  seqno += 2;  
  1184.  assert ((seqno%2) == 0);  
  1185.  rq->rq_src_seqno = seqno;  
  1186.  rq->rq_timestamp = CURRENT_TIME;  
  1187.   
  1188.  Scheduler::instance().schedule(target_, p, 0.);  
  1189.   
  1190. }  
  1191.   
  1192. void  
  1193. AODV::sendReply(nsaddr_t ipdst, u_int32_t hop_count, nsaddr_t rpdst,  
  1194.                 u_int32_t rpseq, u_int32_t lifetime, double timestamp) {  
  1195. Packet *p = Packet::alloc();  
  1196. struct hdr_cmn *ch = HDR_CMN(p);  
  1197. struct hdr_ip *ih = HDR_IP(p);  
  1198. struct hdr_aodv_reply *rp = HDR_AODV_REPLY(p);  
  1199. aodv_rt_entry *rt = rtable.rt_lookup(ipdst);  
  1200.   
  1201. #ifdef DEBUG   
  1202. fprintf(stderr, "sending Reply from %d at %.2f\n", index, Scheduler::instance().clock());  
  1203. #endif // DEBUG   
  1204.  assert(rt);  
  1205.   
  1206.  rp->rp_type = AODVTYPE_RREP;  
  1207.  //rp->rp_flags = 0x00;   
  1208.  rp->rp_hop_count = hop_count;  
  1209.  rp->rp_dst = rpdst;  
  1210.  rp->rp_dst_seqno = rpseq;  
  1211.  rp->rp_src = index;  
  1212.  rp->rp_lifetime = lifetime;  
  1213.  rp->rp_timestamp = timestamp;  
  1214.      
  1215.  // ch->uid() = 0;   
  1216.  ch->ptype() = PT_AODV;  
  1217.  ch->size() = IP_HDR_LEN + rp->size();  
  1218.  ch->iface() = -2;  
  1219.  ch->error() = 0;  
  1220.  ch->addr_type() = NS_AF_INET;  
  1221.  ch->next_hop_ = rt->rt_nexthop;  
  1222.  ch->prev_hop_ = index;          // AODV hack   
  1223.  ch->direction() = hdr_cmn::DOWN;  
  1224.   
  1225.  ih->saddr() = index;  
  1226.  ih->daddr() = ipdst;  
  1227.  ih->sport() = RT_PORT;  
  1228.  ih->dport() = RT_PORT;  
  1229.  ih->ttl_ = NETWORK_DIAMETER;  
  1230.   
  1231.  Scheduler::instance().schedule(target_, p, 0.);  
  1232.   
  1233. }  
  1234.   
  1235. void  
  1236. AODV::sendError(Packet *p, bool jitter) {  
  1237. struct hdr_cmn *ch = HDR_CMN(p);  
  1238. struct hdr_ip *ih = HDR_IP(p);  
  1239. struct hdr_aodv_error *re = HDR_AODV_ERROR(p);  
  1240.       
  1241. #ifdef ERROR   
  1242. fprintf(stderr, "sending Error from %d at %.2f\n", index, Scheduler::instance().clock());  
  1243. #endif // DEBUG   
  1244.   
  1245.  re->re_type = AODVTYPE_RERR;  
  1246.  //re->reserved[0] = 0x00; re->reserved[1] = 0x00;   
  1247.  // DestCount and list of unreachable destinations are already filled   
  1248.   
  1249.  // ch->uid() = 0;   
  1250.  ch->ptype() = PT_AODV;  
  1251.  ch->size() = IP_HDR_LEN + re->size();  
  1252.  ch->iface() = -2;  
  1253.  ch->error() = 0;  
  1254.  ch->addr_type() = NS_AF_NONE;  
  1255.  ch->next_hop_ = 0;  
  1256.  ch->prev_hop_ = index;          // AODV hack   
  1257.  ch->direction() = hdr_cmn::DOWN;       //important: change the packet's direction   
  1258.   
  1259.  ih->saddr() = index;  
  1260.  ih->daddr() = IP_BROADCAST;  
  1261.  ih->sport() = RT_PORT;  
  1262.  ih->dport() = RT_PORT;  
  1263.  ih->ttl_ = 1;  
  1264.   
  1265.  // Do we need any jitter? Yes   
  1266.  if (jitter)  
  1267.     Scheduler::instance().schedule(target_, p, 0.01*Random::uniform());  
  1268.  else  
  1269.     Scheduler::instance().schedule(target_, p, 0.0);  
  1270.   
  1271. }  
  1272.   
  1273.   
  1274. /* 
  1275.    Neighbor Management Functions 
  1276. */  
  1277.   
  1278. void  
  1279. AODV::sendHello() {  
  1280. Packet *p = Packet::alloc();  
  1281. struct hdr_cmn *ch = HDR_CMN(p);  
  1282. struct hdr_ip *ih = HDR_IP(p);  
  1283. struct hdr_aodv_reply *rh = HDR_AODV_REPLY(p);  
  1284.   
  1285. #ifdef DEBUG   
  1286. fprintf(stderr, "sending Hello from %d at %.2f\n", index, Scheduler::instance().clock());  
  1287. #endif // DEBUG   
  1288.   
  1289.  rh->rp_type = AODVTYPE_HELLO;  
  1290.  //rh->rp_flags = 0x00;   
  1291.  rh->rp_hop_count = 1;  
  1292.  rh->rp_dst = index;  
  1293.  rh->rp_dst_seqno = seqno;  
  1294.  rh->rp_lifetime = (1 + ALLOWED_HELLO_LOSS) * HELLO_INTERVAL;  
  1295.   
  1296.  // ch->uid() = 0;   
  1297.  ch->ptype() = PT_AODV;  
  1298.  ch->size() = IP_HDR_LEN + rh->size();  
  1299.  ch->iface() = -2;  
  1300.  ch->error() = 0;  
  1301.  ch->addr_type() = NS_AF_NONE;  
  1302.  ch->prev_hop_ = index;          // AODV hack   
  1303.   
  1304.  ih->saddr() = index;  
  1305.  ih->daddr() = IP_BROADCAST;  
  1306.  ih->sport() = RT_PORT;  
  1307.  ih->dport() = RT_PORT;  
  1308.  ih->ttl_ = 1;  
  1309.   
  1310.  Scheduler::instance().schedule(target_, p, 0.0);  
  1311. }  
  1312.   
  1313.   
  1314. void  
  1315. AODV::recvHello(Packet *p) {  
  1316. //struct hdr_ip *ih = HDR_IP(p);   
  1317. struct hdr_aodv_reply *rp = HDR_AODV_REPLY(p);  
  1318. AODV_Neighbor *nb;  
  1319.   
  1320.  nb = nb_lookup(rp->rp_dst);  
  1321.  if(nb == 0) {  
  1322.    nb_insert(rp->rp_dst);  
  1323.  }  
  1324.  else {  
  1325.    nb->nb_expire = CURRENT_TIME +  
  1326.                    (1.5 * ALLOWED_HELLO_LOSS * HELLO_INTERVAL);  
  1327.  }  
  1328.   
  1329.  Packet::free(p);  
  1330. }  
  1331.   
  1332. void  
  1333. AODV::nb_insert(nsaddr_t id) {  
  1334. AODV_Neighbor *nb = new AODV_Neighbor(id);  
  1335.   
  1336.  assert(nb);  
  1337.  nb->nb_expire = CURRENT_TIME +  
  1338.                 (1.5 * ALLOWED_HELLO_LOSS * HELLO_INTERVAL);  
  1339.  LIST_INSERT_HEAD(&nbhead, nb, nb_link);  
  1340.  seqno += 2;             // set of neighbors changed   
  1341.  assert ((seqno%2) == 0);  
  1342. }  
  1343.   
  1344.   
  1345. AODV_Neighbor*  
  1346. AODV::nb_lookup(nsaddr_t id) {  
  1347. AODV_Neighbor *nb = nbhead.lh_first;  
  1348.   
  1349.  for(; nb; nb = nb->nb_link.le_next) {  
  1350.    if(nb->nb_addr == id) break;  
  1351.  }  
  1352.  return nb;  
  1353. }  
  1354.   
  1355.   
  1356. /* 
  1357.  * Called when we receive *explicit* notification that a Neighbor 
  1358.  * is no longer reachable. 
  1359.  */  
  1360. void  
  1361. AODV::nb_delete(nsaddr_t id) {  
  1362. AODV_Neighbor *nb = nbhead.lh_first;  
  1363.   
  1364.  log_link_del(id);  
  1365.  seqno += 2;     // Set of neighbors changed   
  1366.  assert ((seqno%2) == 0);  
  1367.   
  1368.  for(; nb; nb = nb->nb_link.le_next) {  
  1369.    if(nb->nb_addr == id) {  
  1370.      LIST_REMOVE(nb,nb_link);  
  1371.      delete nb;  
  1372.      break;  
  1373.    }  
  1374.  }  
  1375.   
  1376.  handle_link_failure(id);  
  1377.   
  1378. }  
  1379.   
  1380.   
  1381. /* 
  1382.  * Purges all timed-out Neighbor Entries - runs every 
  1383.  * HELLO_INTERVAL * 1.5 seconds. 
  1384.  */  
  1385. void  
  1386. AODV::nb_purge() {  
  1387. AODV_Neighbor *nb = nbhead.lh_first;  
  1388. AODV_Neighbor *nbn;  
  1389. double now = CURRENT_TIME;  
  1390.   
  1391.  for(; nb; nb = nbn) {  
  1392.    nbn = nb->nb_link.le_next;  
  1393.    if(nb->nb_expire <= now) {  
  1394.      nb_delete(nb->nb_addr);  
  1395.    }  
  1396.  }  
  1397.   
  1398. }  

这篇关于NS2下AODV协议aodv.cc注释的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/774776

相关文章

Java如何接收并解析HL7协议数据

《Java如何接收并解析HL7协议数据》文章主要介绍了HL7协议及其在医疗行业中的应用,详细描述了如何配置环境、接收和解析数据,以及与前端进行交互的实现方法,文章还分享了使用7Edit工具进行调试的经... 目录一、前言二、正文1、环境配置2、数据接收:HL7Monitor3、数据解析:HL7Busines

【Linux】应用层http协议

一、HTTP协议 1.1 简要介绍一下HTTP        我们在网络的应用层中可以自己定义协议,但是,已经有大佬定义了一些现成的,非常好用的应用层协议,供我们直接使用,HTTP(超文本传输协议)就是其中之一。        在互联网世界中,HTTP(超文本传输协议)是一个至关重要的协议,他定义了客户端(如浏览器)与服务器之间如何进行通信,以交换或者传输超文本(比如HTML文档)。

vscode中文乱码问题,注释,终端,调试乱码一劳永逸版

忘记咋回事突然出现了乱码问题,很多方法都试了,注释乱码解决了,终端又乱码,调试窗口也乱码,最后经过本人不懈努力,终于全部解决了,现在分享给大家我的方法。 乱码的原因是各个地方用的编码格式不统一,所以把他们设成统一的utf8. 1.电脑的编码格式 开始-设置-时间和语言-语言和区域 管理语言设置-更改系统区域设置-勾选Bata版:使用utf8-确定-然后按指示重启 2.vscode

【Go】go连接clickhouse使用TCP协议

离开你是傻是对是错 是看破是软弱 这结果是爱是恨或者是什么 如果是种解脱 怎么会还有眷恋在我心窝 那么爱你为什么                      🎵 黄品源/莫文蔚《那么爱你为什么》 package mainimport ("context""fmt""log""time""github.com/ClickHouse/clickhouse-go/v2")func main(

2024.9.8 TCP/IP协议学习笔记

1.所谓的层就是数据交换的深度,电脑点对点就是单层,物理层,加上集线器还是物理层,加上交换机就变成链路层了,有地址表,路由器就到了第三层网络层,每个端口都有一个mac地址 2.A 给 C 发数据包,怎么知道是否要通过路由器转发呢?答案:子网 3.将源 IP 与目的 IP 分别同这个子网掩码进行与运算****,相等则是在一个子网,不相等就是在不同子网 4.A 如何知道,哪个设备是路由器?答案:在 A

Modbus-RTU协议

一、协议概述 Modbus-RTU(Remote Terminal Unit)是一种基于主从架构的通信协议,采用二进制数据表示,消息中的每个8位字节含有两个4位十六进制字符。它主要通过RS-485、RS-232、RS-422等物理接口实现数据的传输,传输距离远、抗干扰能力强、通信效率高。 二、报文结构 一个标准的Modbus-RTU报文通常包含以下部分: 地址域:单个字节,表示从站设备

网络原理之TCP协议(万字详解!!!)

目录 前言 TCP协议段格式 TCP协议相关特性 1.确认应答 2.超时重传 3.连接管理(三次握手、四次挥手) 三次握手(建立TCP连接) 四次挥手(断开连接)  4.滑动窗口 5.流量控制 6.拥塞控制 7.延迟应答 8.捎带应答  9.基于字节流 10.异常情况的处理 小结  前言 在前面,我们已经讲解了有关UDP协议的相关知识,但是在传输层,还有

DNS协议基础笔记

1.定义 DNS(Domain Name System,域名系统)是互联网的一项核心服务,它作为将域名和 IP 地址相互映射的一个分布式数据库,能够使人更方便地访问互联网。 2.域名解析过程 当用户在浏览器中输入一个域名,浏览器首先会检查自己的缓存中是否有该域名对应的 IP 地址。本地 DNS 服务器收到查询请求后,首先会检查自己的缓存中是否有该域名对应的 IP 地址。根域名服务器收到查询请

在 Qt Creator 中,输入 /** 并按下Enter可以自动生成 Doxygen 风格的注释

在 Qt Creator 中,当你输入 /** 时,确实会自动补全标准的 Doxygen 风格注释。这是因为 Qt Creator 支持 Doxygen 以及类似的文档注释风格,并且提供了代码自动补全功能。 以下是如何在 Qt Creator 中使用和显示这些注释标记的步骤: 1. 自动补全 Doxygen 风格注释 在 Qt Creator 中,你可以这样操作: 在你的代码中,将光标放在

4G模块、WIFI模块、NBIOT模块通过AT指令连接华为云物联网服务器(MQTT协议)

MQTT协议概述 MQTT(Message Queuing Telemetry Transport)是一种轻量级的消息传输协议,它被设计用来提供一对多的消息分发和应用之间的通讯,尤其适用于远程位置的设备和高延迟或低带宽的网络。MQTT协议基于客户端-服务器架构,客户端可以订阅任意数量的主题,并可以发布消息到这些主题。服务器(通常称为MQTT Broker)则负责接受来自客户端的连接请求,并转发消