加注释的ns2-AODV源代码_nsv接口使用代码-程序员宅基地

技术标签: AODV代码  ns2  注释  

/*ns2 中aodv.cc的源代码,并加了一定的注解,便于理解和查阅。*/

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.  /* 

42.    TCL Hooks 

43.  */  

44.    

45.  int hdr_aodv::offset_;  

46.  static class AODVHeaderClass : public PacketHeaderClass {  

47.  public:  

48.          AODVHeaderClass() : PacketHeaderClass("PacketHeader/AODV",  

49.                                                sizeof(hdr_all_aodv)) {  

50.        bind_offset(&hdr_aodv::offset_);  

51.      }   

52.  } class_rtProtoAODV_hdr;  

53.  static class AODVclass : public TclClass {  

54.  public:  

55.          AODVclass() : TclClass("Agent/AODV") {}  

56.          TclObject* create(int argc, const char*const* argv) {  

57.            assert(argc == 5);  

58.            //return (new AODV((nsaddr_t) atoi(argv[4])));  

59.        return (new AODV((nsaddr_t) Address::instance().str2addr(argv[4])));  

60.          }  

61.  } class_rtProtoAODV;  

62.    

63.  int  

64.  AODV::command(int argc, const char*const* argv) {  

65.    if(argc == 2) {  

66.    Tcl& tcl = Tcl::instance();  

67.        

68.      if(strncasecmp(argv[1], "id", 2) == 0) {  

69.        tcl.resultf("%d", index);  

70.        return TCL_OK;  

71.      }  

72.        

73.      if(strncasecmp(argv[1], "start", 2) == 0) {  

74.        btimer.handle((Event*) 0);  

75.  #ifndef AODV_LINK_LAYER_DETECTION  

76.        htimer.handle((Event*) 0);  

77.        ntimer.handle((Event*) 0);  

78.  #endif // LINK LAYER DETECTION  

79.        rtimer.handle((Event*) 0);  

80.        return TCL_OK;  

81.       }                 

82.    }  

83.    else if(argc == 3) {  

84.      if(strcmp(argv[1], "index") == 0) {  

85.        index = atoi(argv[2]);  

86.        return TCL_OK;  

87.      }  

88.      else if(strcmp(argv[1], "log-target") == 0 || strcmp(argv[1], "tracetarget") == 0) {  

89.        logtarget = (Trace*) TclObject::lookup(argv[2]);  

90.        if(logtarget == 0)  

91.      return TCL_ERROR;  

92.        return TCL_OK;  

93.      }  

94.      else if(strcmp(argv[1], "drop-target") == 0) {  

95.      int stat = rqueue.command(argc,argv);  

96.        if (stat != TCL_OK) return stat;  

97.        return Agent::command(argc, argv);  

98.      }  

99.      else if(strcmp(argv[1], "if-queue") == 0) {  

100.      ifqueue = (PriQueue*) TclObject::lookup(argv[2]);  

101.          

102.        if(ifqueue == 0)  

103.      return TCL_ERROR;  

104.        return TCL_OK;  

105.      }  

106.      else if (strcmp(argv[1], "port-dmux") == 0) {  

107.          dmux_ = (PortClassifier *)TclObject::lookup(argv[2]);  

108.      if (dmux_ == 0) {  

109.          fprintf (stderr, "%s: %s lookup of %s failed/n", __FILE__,  

110.          argv[1], argv[2]);  

111.          return TCL_ERROR;  

112.      }  

113.      return TCL_OK;  

114.      }  

115.    }  

116.    return Agent::command(argc, argv);  

117.  }  

118.  /*  

119.     Constructor 

120.  */  

121.  AODV::AODV(nsaddr_t id) : Agent(PT_AODV),  

122.                btimer(this), htimer(this), ntimer(this),   

123.                rtimer(this), lrtimer(this), rqueue() {  

124.     

125.                    

126.    index = id;  

127.    seqno = 2;  

128.    bid = 1;  

129.    LIST_INIT(&nbhead);  

130.    LIST_INIT(&bihead);  

131.    logtarget = 0;  

132.    ifqueue = 0;  

133.  }  

134.  /* 

135.    Timers 

136.  */  

137.  void  

138.  BroadcastTimer::handle(Event*) {  

139.    agent->id_purge();  

140.    Scheduler::instance().schedule(this, &intr, BCAST_ID_SAVE);  

141.  }  

142.  void  

143.  HelloTimer::handle(Event*) {  

144.     agent->sendHello();  

145.     double interval = MinHelloInterval +   

146.                   ((MaxHelloInterval - MinHelloInterval) * Random::uniform());  

147.     assert(interval >= 0);  

148.     Scheduler::instance().schedule(this, &intr, interval);  

149.  }  

150.  void  

151.  NeighborTimer::handle(Event*) {  

152.    agent->nb_purge();  

153.    Scheduler::instance().schedule(this, &intr, HELLO_INTERVAL);  

154.  }  

155.  void  

156.  RouteCacheTimer::handle(Event*) {  

157.    agent->rt_purge();  

158.  #define FREQUENCY 0.5 // sec  

159.    Scheduler::instance().schedule(this, &intr, FREQUENCY);  

160.  }  

161.  void  

162.  LocalRepairTimer::handle(Event* p)  {  // SRD: 5/4/99  

163.  aodv_rt_entry *rt;  

164.  struct hdr_ip *ih = HDR_IP( (Packet *)p);  

165.     /* you get here after the timeout in a local repair attempt */  

166.     /*   fprintf(stderr, "%s/n", __FUNCTION__); */  

167.    

168.      rt = agent->rtable.rt_lookup(ih->daddr());  

169.        

170.      if (rt && rt->rt_flags != RTF_UP) {  

171.      // route is yet to be repaired  

172.      // I will be conservative and bring down the route  

173.      // and send route errors upstream.  

174.      /* The following assert fails, not sure why */  

175.      /* assert (rt->rt_flags == RTF_IN_REPAIR); */  

176.            

177.        //rt->rt_seqno++;  

178.        agent->rt_down(rt);  

179.        // send RERR  

180.  #ifdef DEBUG  

181.        fprintf(stderr,"Node %d: Dst - %d, failed local repair/n",index, rt->rt_dst);  

182.  #endif        

183.      }  

184.      Packet::free((Packet *)p);  

185.  }  

186.    

187.  /* 

188.     Broadcast ID Management  Functions 

189.  */  

190.    

191.  void  

192.  AODV::id_insert(nsaddr_t id, u_int32_t bid) {  

193.  BroadcastID *b = new BroadcastID(id, bid);  

194.   assert(b);  

195.   b->expire = CURRENT_TIME + BCAST_ID_SAVE;  

196.   LIST_INSERT_HEAD(&bihead, b, link);  

197.  }  

198.  /* SRD */  

199.  bool  

200.  AODV::id_lookup(nsaddr_t id, u_int32_t bid) {  

201.  BroadcastID *b = bihead.lh_first;  

202.     

203.   // Search the list for a match of source and bid  

204.   for( ; b; b = b->link.le_next) {  

205.     if ((b->src == id) && (b->id == bid))  

206.       return true;       

207.   }  

208.   return false;  

209.  }  

210.  void  

211.  AODV::id_purge() {  

212.  BroadcastID *b = bihead.lh_first;  

213.  BroadcastID *bn;  

214.  double now = CURRENT_TIME;  

215.   for(; b; b = bn) {  

216.     bn = b->link.le_next;  

217.     if(b->expire <= now) {  

218.       LIST_REMOVE(b,link);  

219.       delete b;  

220.     }  

221.   }  

222.  }  

223.  /* 

224.    Helper Functions 

225.  */  

226.  double  

227.  AODV::PerHopTime(aodv_rt_entry *rt) {  

228.  int num_non_zero = 0, i;  

229.  double total_latency = 0.0;  

230.   if (!rt)  

231.     return ((double) NODE_TRAVERSAL_TIME );  

232.        

233.   for (i=0; i < MAX_HISTORY; i++) {  

234.     if (rt->rt_disc_latency[i] > 0.0) {  

235.        num_non_zero++;  

236.        total_latency += rt->rt_disc_latency[i];  

237.     }  

238.   }  

239.   if (num_non_zero > 0)  

240.     return(total_latency / (double) num_non_zero);  

241.   else  

242.     return((double) NODE_TRAVERSAL_TIME);  

243.  }  

244.  /* 

245.    Link Failure Management Functions 

246.  */  

247.  static void  

248.  aodv_rt_failed_callback(Packet *p, void *arg) {  

249.    ((AODV*) arg)->rt_ll_failed(p);  

250.  }  

251.  /* 

252.   * This routine is invoked when the link-layer reports a route failed. 

253.   */  

254.  void  

255.  AODV::rt_ll_failed(Packet *p) {  

256.  struct hdr_cmn *ch = HDR_CMN(p);  

257.  struct hdr_ip *ih = HDR_IP(p);  

258.  aodv_rt_entry *rt;  

259.  nsaddr_t broken_nbr = ch->next_hop_;  

260.  #ifndef AODV_LINK_LAYER_DETECTION  

261.   drop(p, DROP_RTR_MAC_CALLBACK);  

262.  #else   

263.   /* 

264.    * Non-data packets and Broadcast Packets can be dropped. 

265.    */  

266.    if(! DATA_PACKET(ch->ptype()) ||  

267.       (u_int32_t) ih->daddr() == IP_BROADCAST) {  

268.      drop(p, DROP_RTR_MAC_CALLBACK);  

269.      return;  

270.    }  

271.    log_link_broke(p);  

272.      if((rt = rtable.rt_lookup(ih->daddr())) == 0) {  

273.      drop(p, DROP_RTR_MAC_CALLBACK);  

274.      return;  

275.    }  

276.    log_link_del(ch->next_hop_);  

277.  #ifdef AODV_LOCAL_REPAIR  

278.    /* if the broken link is closer to the dest than source,  

279.       attempt a local repair. Otherwise, bring down the route. */  

280.    

281.    if (ch->num_forwards() > rt->rt_hops) {  

282.      local_rt_repair(rt, p); // local repair  

283.      // retrieve all the packets in the ifq using this link,  

284.      // queue the packets for which local repair is done,   

285.      return;  

286.    }  

287.    else    

288.  #endif // LOCAL REPAIR    

289.    {  

290.      drop(p, DROP_RTR_MAC_CALLBACK);  

291.      // Do the same thing for other packets in the interface queue using the  

292.      // broken link -Mahesh  

293.  while((p = ifqueue->filter(broken_nbr))) {  

294.       drop(p, DROP_RTR_MAC_CALLBACK);  

295.      }     

296.      nb_delete(broken_nbr);  

297.    }  

298.  #endif // LINK LAYER DETECTION  

299.  }  

300.  void  

301.  AODV::handle_link_failure(nsaddr_t id) {  

302.  aodv_rt_entry *rt, *rtn;  

303.  Packet *rerr = Packet::alloc();  

304.  struct hdr_aodv_error *re = HDR_AODV_ERROR(rerr);  

305.   re->DestCount = 0;  

306.   for(rt = rtable.head(); rt; rt = rtn) {  // for each rt entry  

307.     rtn = rt->rt_link.le_next;   

308.     if ((rt->rt_hops != INFINITY2) && (rt->rt_nexthop == id) ) {  

309.       assert (rt->rt_flags == RTF_UP);  

310.       assert((rt->rt_seqno%2) == 0);  

311.       rt->rt_seqno++;  

312.       re->unreachable_dst[re->DestCount] = rt->rt_dst;  

313.       re->unreachable_dst_seqno[re->DestCount] = rt->rt_seqno;  

314.  #ifdef DEBUG  

315.       fprintf(stderr, "%s(%f): %d/t(%d/t%u/t%d)/n", __FUNCTION__, CURRENT_TIME,  

316.               index, re->unreachable_dst[re->DestCount],  

317.               re->unreachable_dst_seqno[re->DestCount], rt->rt_nexthop);  

318.  #endif // DEBUG  

319.       re->DestCount += 1;  

320.       rt_down(rt);  

321.     }  

322.     // remove the lost neighbor from all the precursor lists  

323.     rt->pc_delete(id);  

324.   }     

325.   if (re->DestCount > 0) {  

326.  #ifdef DEBUG  

327.     fprintf(stderr, "%s(%f): %d/tsending RERR.../n", __FUNCTION__, CURRENT_TIME, index);  

328.  #endif // DEBUG  

329.     sendError(rerr, false);  

330.   }  

331.   else {  

332.     Packet::free(rerr);  

333.   }  

334.  }  

335.  void  

336.  AODV::local_rt_repair(aodv_rt_entry *rt, Packet *p) {  

337.  #ifdef DEBUG  

338.    fprintf(stderr,"%s: Dst - %d/n", __FUNCTION__, rt->rt_dst);   

339.  #endif    

340.    // Buffer the packet   

341.    rqueue.enque(p);  

342.    // mark the route as under repair   

343.    rt->rt_flags = RTF_IN_REPAIR;  

344.    sendRequest(rt->rt_dst);  

345.    // set up a timer interrupt  

346.    Scheduler::instance().schedule(&lrtimer, p->copy(), rt->rt_req_timeout);  

347.  }  

348.  void  

349.  AODV::rt_update(aodv_rt_entry *rt, u_int32_t seqnum, u_int16_t metric,  

350.              nsaddr_t nexthop, double expire_time) {  

351.       rt->rt_seqno = seqnum;  

352.       rt->rt_hops = metric;  

353.       rt->rt_flags = RTF_UP;  

354.       rt->rt_nexthop = nexthop;  

355.       rt->rt_expire = expire_time;  

356.  }  

357.  void  

358.  AODV::rt_down(aodv_rt_entry *rt) {  

359.    /* 

360.     *  Make sure that you don't "down" a route more than once. 

361.     */  

362.    if(rt->rt_flags == RTF_DOWN) {  

363.      return;  

364.    }  

365.    // assert (rt->rt_seqno%2); // is the seqno odd?  

366.    rt->rt_last_hop_count = rt->rt_hops;  

367.    rt->rt_hops = INFINITY2;  

368.    rt->rt_flags = RTF_DOWN;  

369.    rt->rt_nexthop = 0;  

370.    rt->rt_expire = 0;  

371.  } /* rt_down function */  

372.  /* 

373.    Route Handling Functions 

374.  */  

375.  void  

376.  AODV::rt_resolve(Packet *p) {//解析收到的分组  

377.  struct hdr_cmn *ch = HDR_CMN(p);  

378.  struct hdr_ip *ih = HDR_IP(p);  

379.  aodv_rt_entry *rt;  

380.   /* 

381.    *  Set the transmit failure callback.  That 

382.    *  won't change. 

383.    */  

384.   ch->xmit_failure_ = aodv_rt_failed_callback;  

385.   ch->xmit_failure_data_ = (void*) this;  

386.      rt = rtable.rt_lookup(ih->daddr());//查找是否又到目的节点的路由  

387.   if(rt == 0) {//如果没有到目的节点的路由,那么就添加该目的节点的路由,此时添加的路由是无效  

388.      //的  

389.        rt = rtable.rt_add(ih->daddr());  

390.   }  

391.   /* 

392.    * If the route is up, forward the packet  

393.    */  

394.  //如果路由有效,则根据路由表中的信息转发分组。  

395.   if(rt->rt_flags == RTF_UP) {  

396.     assert(rt->rt_hops != INFINITY2);  

397.     forward(rt, p, NO_DELAY);  

398.   }  

399.   /* 

400.    *  if I am the source of the packet, then do a Route Request. 

401.    */  

402.   //如果本节点是该分组的源节点,那么说明没有到目的节点的路由,发送RREQ找路。  

403.      else if(ih->saddr() == index) {  

404.     rqueue.enque(p);  

405.     sendRequest(rt->rt_dst);  

406.   }  

407.   /* 

408.    * A local repair is in progress. Buffer the packet.  

409.    */  

410.  //链路中断,进行所谓的路由维护。  

411.   else if (rt->rt_flags == RTF_IN_REPAIR) {  

412.     rqueue.enque(p);  

413.   }  

414.   /* 

415.    * I am trying to forward a packet for someone else to which 

416.    * I don't have a route. 

417.    */  

418.   //本节点转发数据分组,但是不知道到目的节点的路由,发送RRER说明链路中断。  

419.   else {  

420.   Packet *rerr = Packet::alloc();  

421.   struct hdr_aodv_error *re = HDR_AODV_ERROR(rerr);  

422.   /*  

423.    * For now, drop the packet and send error upstream. 

424.    * Now the route errors are broadcast to upstream 

425.    * neighbors - Mahesh 09/11/99 

426.    */      

427.     

428.     assert (rt->rt_flags == RTF_DOWN);  

429.     re->DestCount = 0;  

430.     re->unreachable_dst[re->DestCount] = rt->rt_dst;  

431.     re->unreachable_dst_seqno[re->DestCount] = rt->rt_seqno;  

432.     re->DestCount += 1;  

433.  #ifdef DEBUG  

434.     fprintf(stderr, "%s: sending RERR.../n", __FUNCTION__);  

435.  #endif  

436.     sendError(rerr, false);  

437.     drop(p, DROP_RTR_NO_ROUTE);  

438.   }  

439.  }  

440.  void  

441.  AODV::rt_purge() {  

442.  aodv_rt_entry *rt, *rtn;  

443.  double now = CURRENT_TIME;  

444.  double delay = 0.0;  

445.  Packet *p;  

446.   for(rt = rtable.head(); rt; rt = rtn) {  // for each rt entry  

447.     rtn = rt->rt_link.le_next;  

448.     if ((rt->rt_flags == RTF_UP) && (rt->rt_expire < now)) {  

449.     // if a valid route has expired, purge all packets from   

450.     // send buffer and invalidate the route.                      

451.      assert(rt->rt_hops != INFINITY2);  

452.       while((p = rqueue.deque(rt->rt_dst))) {  

453.  #ifdef DEBUG  

454.         fprintf(stderr, "%s: calling drop()/n",  

455.                         __FUNCTION__);  

456.  #endif // DEBUG  

457.         drop(p, DROP_RTR_NO_ROUTE);  

458.       }  

459.       rt->rt_seqno++;  

460.       assert (rt->rt_seqno%2);  

461.       rt_down(rt);  

462.     }  

463.     else if (rt->rt_flags == RTF_UP) {  

464.     // If the route is not expired,  

465.     // and there are packets in the sendbuffer waiting,  

466.     // forward them. This should not be needed, but this extra   

467.     // check does no harm.  

468.       assert(rt->rt_hops != INFINITY2);  

469.       while((p = rqueue.deque(rt->rt_dst))) {  

470.         forward (rt, p, delay);  

471.         delay += ARP_DELAY;  

472.       }  

473.     }   

474.     else if (rqueue.find(rt->rt_dst))  

475.     // If the route is down and   

476.     // if there is a packet for this destination waiting in  

477.     // the sendbuffer, then send out route request. sendRequest  

478.     // will check whether it is time to really send out request  

479.     // or not.  

480.     // This may not be crucial to do it here, as each generated   

481.     // packet will do a sendRequest anyway.  

482.       sendRequest(rt->rt_dst);   

483.     }  

484.  }  

485.  /* 

486.    Packet Reception Routines 

487.  */  

488.  void  

489.  AODV::recv(Packet *p, Handler*) {  

490.  //  

491.  struct hdr_cmn *ch = HDR_CMN(p);  

492.  struct hdr_ip *ih = HDR_IP(p);  

493.   assert(initialized());  

494.   //assert(p->incoming == 0);  

495.   // 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.  

496.   if(ch->ptype() == PT_AODV) {//判断是不是aodv的包,如果是的话那么就调用recvAODV(p)  

497.     ih->ttl_ -= 1;  

498.     recvAODV(p);  

499.     return;  

500.   }  

501.    

502.   /* 

503.    *  Must be a packet I'm originating... 

504.    */  

505.   //本节点产生的aodv包,添加ip头;  

506.  if((ih->saddr() == index) && (ch->num_forwards() == 0)) {  

507.   /* 

508.    * Add the IP Header 

509.    */  

510.     ch->size() += IP_HDR_LEN;  

511.     // Added by Parag Dadhania && John Novatnack to handle broadcasting  

512.     if ( (u_int32_t)ih->daddr() != IP_BROADCAST)  

513.       ih->ttl_ = NETWORK_DIAMETER;  

514.  }  

515.   /* 

516.    *  I received a packet that I sent.  Probably 

517.    *  a routing loop. 

518.    */  

519.    //收到本节点发出的包,说明有路由环,丢掉它;  

520.  else if(ih->saddr() == index) {  

521.     drop(p, DROP_RTR_ROUTE_LOOP);  

522.     return;  

523.   }  

524.   /* 

525.    *  Packet I'm forwarding... 

526.    */  

527.    //本节点是中间节点,  

528.   else {  

529.   /* 

530.    *  Check the TTL.  If it is zero, then discard. 

531.    */  

532.    //TTL是分组最多可以转发的次数。  

533.     if(--ih->ttl_ == 0) {  

534.       drop(p, DROP_RTR_TTL);  

535.       return;  

536.     }  

537.   }  

538.     

539.  // Added by Parag Dadhania && John Novatnack to handle broadcasting  

540.   if ( (u_int32_t)ih->daddr() != IP_BROADCAST)  

541.  //收到的不是广播分组,解析分组  

542.     rt_resolve(p);  

543.     

544.  //收到的是广播分组就转发  

545.   else  

546.     forward((aodv_rt_entry*) 0, p, NO_DELAY);  

547.  }  

548.    

549.  void  

550.  AODV::recvAODV(Packet *p) {//根据包的类型调用不同的函数。  

551.   struct hdr_aodv *ah = HDR_AODV(p);  

552.   assert(HDR_IP (p)->sport() == RT_PORT);  

553.   assert(HDR_IP (p)->dport() == RT_PORT);  

554.   /* 

555.    * Incoming Packets. 

556.    */  

557.   switch(ah->ah_type) {  

558.   case AODVTYPE_RREQ:  

559.     recvRequest(p);  

560.     break;  

561.   case AODVTYPE_RREP:  

562.     recvReply(p);  

563.     break;  

564.   case AODVTYPE_RERR:  

565.     recvError(p);  

566.     break;  

567.   case AODVTYPE_HELLO:  

568.     recvHello(p);  

569.     break;  

570.            

571.   default:  

572.     fprintf(stderr, "Invalid AODV type (%x)/n", ah->ah_type);  

573.     exit(1);  

574.   }  

575.  }  

576.    

577.  void  

578.  AODV::recvRequest(Packet *p) {//收到RREQ  

579.  struct hdr_ip *ih = HDR_IP(p);  

580.  struct hdr_aodv_request *rq = HDR_AODV_REQUEST(p);  

581.  aodv_rt_entry *rt;  

582.    /* 

583.     * Drop if: 

584.     *      - I'm the source 

585.     *      - I recently heard this request. 

586.     */  

587.    if(rq->rq_src == index) {         //看看这个request是不是自己发出来的。  

588.  #ifdef DEBUG  

589.      fprintf(stderr, "%s: got my own REQUEST/n", __FUNCTION__);  

590.  #endif // DEBUG  

591.      Packet::free(p);                //如果是的话就将这个包丢弃。  

592.      return;  

593.    }   

594.   if (id_lookup(rq->rq_src, rq->rq_bcast_id)) {//看看是不是曾经收到过的rreq.  

595.      //两个判据一个是request source(源节点IP地址) 一个是 广播序列号  

596.  #ifdef DEBUG  

597.     fprintf(stderr, "%s: discarding request/n", __FUNCTION__);  

598.  #endif // DEBUG  

599.     

600.     Packet::free(p);                           //如果是的话就丢弃  

601.     return;  

602.   }  

603.   /* 

604.    * Cache the broadcast ID 

605.    */  

606.    //用于判断是否已经收到过该RREQ  

607.   id_insert(rq->rq_src, rq->rq_bcast_id);   //刷新自己节点的RREQ的broadcast id(就是RREQ)  

608.    

609.   /* 在这种情况下我们有两种选择,一种是将RREQ继续传播下去,一种是产生RREP 

610.    * 在这之前我们要确定,反向路由已经在路由表中存在。如果存在反向路由,在考虑 

611.    是否应该想源节点发送RREP 

612.    */  

613.   aodv_rt_entry *rt0; // rt0 is the reverse route   

614.       

615.     rt0 = rtable.rt_lookup(rq->rq_src);         //寻找反向路由  

616.     if(rt0 == 0) { /* if not in the route table 如果不在路由表中的话*/  

617.     // create an entry for the reverse route.  

618.       rt0 = rtable.rt_add(rq->rq_src);          //将反向路由写入路由表  

619.     }  

620.      

621.     rt0->rt_expire = max(rt0->rt_expire, (CURRENT_TIME + REV_ROUTE_LIFE));  

622.  //定义ROUTE的生命期  

623.     if ( (rq->rq_src_seqno > rt0->rt_seqno ) ||  

624.          ((rq->rq_src_seqno == rt0->rt_seqno) &&   

625.       (rq->rq_hop_count < rt0->rt_hops)) ) {  

626.       //这里就是路由判据,当遇到新的RREQ的时候  

627.       //比较在路由表中已经存在的到目的节点的路由,比较目的节点的序列号(用来保证使用最新路由  

628.       //防止路由环)在目的节点序列号相同的情况下,采用跳数较小的。在这种情况下  

629.       //就更新路由表。  

630.     // If we have a fresher seq no. or lesser #hops for the   

631.     // same seq no., update the rt entry. Else don't bother.  

632.  rt_update(rt0, rq->rq_src_seqno, rq->rq_hop_count, ih->saddr(),  

633.                 max(rt0->rt_expire, (CURRENT_TIME + REV_ROUTE_LIFE)) );  

634.      //上面两行命令就是如何更新路由表,更新路由表中的哪些项。  

635.       if (rt0->rt_req_timeout > 0.0) {  

636.       // Reset the soft state and   

637.       // Set expiry time to CURRENT_TIME + ACTIVE_ROUTE_TIMEOUT  

638.       // This is because route is used in the forward direction,  

639.       // but only sources get benefited by this change  

640.         rt0->rt_req_cnt = 0;  

641.         rt0->rt_req_timeout = 0.0;   

642.         rt0->rt_req_last_ttl = rq->rq_hop_count;  

643.         rt0->rt_expire = CURRENT_TIME + ACTIVE_ROUTE_TIMEOUT;  

644.       }  

645.       /* Find out whether any buffered packet can benefit from the  

646.        * reverse route. 

647.        * May need some change in the following code - Mahesh 09/11/99 

648.        */  

649.        //缓存中是否有到源节点的路由,有则删除,无则添加  

650.        //缓存中是否有到源节点的数据分组,有则,建立好路由开始发送数据。  

651.        //查找是否有到目的节点的有效路由,有则向源节点发送RREP,没有则继续发送RREQ。  

652.        //注意转发前要更新RREQ的部分内容;  

653.       assert (rt0->rt_flags == RTF_UP);  

654.       Packet *buffered_pkt;  

655.       while ((buffered_pkt = rqueue.deque(rt0->rt_dst))) {  

656.         if (rt0 && (rt0->rt_flags == RTF_UP)) {  

657.      assert(rt0->rt_hops != INFINITY2);  

658.           forward(rt0, buffered_pkt, NO_DELAY);  

659.         }  

660.       }  

661.     }   

662.     // End for putting reverse route in rt table  

663.    

664.   /*反向路径已经清楚了(搞定了) 

665.    * We have taken care of the reverse route stuff. 

666.    * Now see whether we can send a route reply. 

667.    //现在就看看是否应该在此节点处发送RREP  

668.    */  

669.   rt = rtable.rt_lookup(rq->rq_dst);//在路由表中查找目的节点是RREQ_DEST的路由参看aodv_rtable  

670.   //.cc文件中的rt_lookup函数。  

671.   // First check if I am the destination ..  

672.   if(rq->rq_dst == index) {  

673.      #ifdef DEBUG  

674.     fprintf(stderr, "%d - %s: destination sending reply/n",  

675.                     index, __FUNCTION__);  

676.    #endif // DEBUG  

677.                   

678.     // Just to be safe, I use the max. Somebody may have为了安全起见,使用目的节点序列号最大  

679.     //的路由+1  

680.     // incremented the dst seqno.  

681.     seqno = max(seqno, rq->rq_dst_seqno)+1;  

682.     if (seqno%2) seqno++;//如果目的节点序列号是奇数就将其变成偶数,保证目的节点序列号是偶数  

683.     sendReply(rq->rq_src,           // IP Destination目的节点IP  

684.               1,                    // Hop Count  

685.               index,                // Dest IP Address  

686.               seqno,                // Dest Sequence Num目的节点序列号  

687.               MY_ROUTE_TIMEOUT,     // Lifetime  

688.               rq->rq_timestamp);    // timestamp没搞清楚什么东西  

689.     

690.     Packet::free(p);                  //释放RREQ ,产生RREP(这是后话)  

691.  #ifdef DEBUG  

692.     fprintf(stderr, "%d - %s: destination sending reply/n",  

693.                     index, __FUNCTION__);  

694.  #endif // DEBUG  

695.                   

696.     // Just to be safe, I use the max. Somebody may have  

697.     // incremented the dst seqno.  

698.     seqno = max(seqno, rq->rq_dst_seqno)+1;  

699.     if (seqno%2) seqno++;  

700.     sendReply(rq->rq_src,           // IP Destination  

701.               1,                    // Hop Count  

702.               index,                // Dest IP Address  

703.               seqno,                // Dest Sequence Num  

704.               MY_ROUTE_TIMEOUT,     // Lifetime  

705.               rq->rq_timestamp);    // timestamp  

706.     

707.     Packet::free(p);  

708.   }  

709.   // I am not the destination, but I may have a fresh enough route.  

710.   //如果不是destination,但是有够新的路由  

711.   else if (rt && (rt->rt_hops != INFINITY2) &&   

712.          (rt->rt_seqno >= rq->rq_dst_seqno) ) {//保证够新(目的节点序列号)  

713.     //assert (rt->rt_flags == RTF_UP);  

714.     assert(rq->rq_dst == rt->rt_dst);  

715.     //assert ((rt->rt_seqno%2) == 0); // is the seqno even?  

716.     sendReply(rq->rq_src,  

717.               rt->rt_hops + 1,   //如果是目的节点的话就设成一,这里不是目的节点就在  

718.                                  //这个RREQ中的跳数加1;  

719.               rq->rq_dst,        //如果是目的节点这一项就是目的节点的IP地址(这个节点本身的地址),   

720.                                  //这里是RREQ中的目的节点IP地址  

721.               rt->rt_seqno,  

722.           (u_int32_t) (rt->rt_expire - CURRENT_TIME),  

723.           //             rt->rt_expire - CURRENT_TIME,  

724.               rq->rq_timestamp);  

725.     // Insert nexthops to RREQ source and RREQ destination in the  

726.     // precursor lists of destination and source respectively  

727.     //将下一跳节点分别加入前向路由,反向路由中;  

728.     rt->pc_insert(rt0->rt_nexthop); // nexthop to RREQ source  

729.     rt0->pc_insert(rt->rt_nexthop); // nexthop to RREQ destination  

730.  #ifdef RREQ_GRAT_RREP    

731.     sendReply(rq->rq_dst,  

732.               rq->rq_hop_count,  

733.               rq->rq_src,  

734.               rq->rq_src_seqno,  

735.           (u_int32_t) (rt->rt_expire - CURRENT_TIME),  

736.           //             rt->rt_expire - CURRENT_TIME,就是剩下的生命周期  

737.               rq->rq_timestamp);  

738.  #endif  

739.       

740.  // TODO: send grat RREP to dst if G flag set in RREQ using rq->rq_src_seqno, rq->rq_hop_counT  

741.  //产生RREP发向源节点(RREP的目的节点)RREP中使用RREQ中的rq->rq_src_seqno,rq->rq_hop_count  

742.  // DONE: Included gratuitous replies to be sent as per IETF aodv draft specification.   

743.  //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.  

744.  //G flag用来设定或者重设aodv packet.  

745.      Packet::free(p);  

746.   }  

747.   /* 

748.    * Can't reply. So forward the  Route Request 

749.    */  

750.    //  

751.   else {  

752.     ih->saddr() = index;  

753.     ih->daddr() = IP_BROADCAST;  

754.     rq->rq_hop_count += 1;  

755.     // Maximum sequence number seen en route  

756.     if (rt) rq->rq_dst_seqno = max(rt->rt_seqno, rq->rq_dst_seqno);  

757.     forward((aodv_rt_entry*) 0, p, DELAY);  

758.   }  

759.  }  

760.    

761.  void  

762.  AODV::recvReply(Packet *p) {  

763.      //查看是否有到目的节点的路由,没有则建立,否则就更新。  

764.      //如果收到信息的节点是RREP的目的节点也就是发送信息的源节点,则建立到目的节点的路由。  

765.      //否则根据路由表中到源节点的路由(这个路由在建立RREQ的过程中已经建立,也就是  

766.      //reverse路由)转发RREP;  

767.  //struct hdr_cmn *ch = HDR_CMN(p);  

768.  struct hdr_ip *ih = HDR_IP(p);  

769.  struct hdr_aodv_reply *rp = HDR_AODV_REPLY(p);  

770.  aodv_rt_entry *rt;  

771.  char suppress_reply = 0;  

772.  double delay = 0.0;  

773.        

774.  #ifdef DEBUG  

775.   fprintf(stderr, "%d - %s: received a REPLY/n", index, __FUNCTION__);  

776.  #endif // DEBUG  

777.    

778.   /* 

779.    *  Got a reply. So reset the "soft state" maintained for  

780.    *  route requests in the request table. We don't really have 

781.    *  have a separate request table. It is just a part of the 

782.    *  routing table itself. 收到一个reply就更新发送请求表,但是没有单独的发送请求表, 

783.    //发送请求表示路由表的一部分。 

784.    */  

785.   // Note that rp_dst(RREP_dest) is the dest of the data packets, not the  

786.   // the dest of the reply(不是REPLY的终点), which is the src of the data packets.  

787.   //而是数据包的的源点。  

788.   rt = rtable.rt_lookup(rp->rp_dst);  

789.            

790.   /*  收到reply后就查看这个reply是否已经收到过。 

791.    *  If I don't have a rt entry to this host... adding 

792.    */  

793.   if(rt == 0) {  

794.      //如果没有收到就就将其添加进路由表中。  

795.     rt = rtable.rt_add(rp->rp_dst);  

796.   }  

797.   /* 

798.    * Add a forward route table entry... here I am following  

799.    * Perkins-Royer AODV paper almost literally - SRD 5/99 

800.    */  

801.   if ( (rt->rt_seqno < rp->rp_dst_seqno) ||   // newer route   

802.        ((rt->rt_seqno == rp->rp_dst_seqno) &&    

803.         (rt->rt_hops > rp->rp_hop_count)) ) { // shorter or better route  

804.      //还是路由判据,如果收到reply就比较以前收到的reply目的节点序列号,如果目的节点序列号相同就比较  

805.      //比较跳数,取跳数较小的,然后将不合格的RREP删除。  

806.      //aodv的RREQ没走一步就会建立一个反向路径就会产生一个RREP,然后将跳数以及中间节点,  

807.      //目的节点序列号  

808.      //加入路由表中,  

809.    // Update the rt entry   

810.    rt_update(rt, rp->rp_dst_seqno, rp->rp_hop_count,  

811.          rp->rp_src, CURRENT_TIME + rp->rp_lifetime);  

812.    //参看这个文件中的rt_update函数。  

813.    // reset the soft state  

814.    rt->rt_req_cnt = 0;  

815.    rt->rt_req_timeout = 0.0;   

816.    rt->rt_req_last_ttl = rp->rp_hop_count;  

817.      

818.  if (ih->daddr() == index) {   

819.      // If I am the original source,如果收到rrep的是源节点  

820.    // Update the route discovery latency statistics,更新路由发现潜存策略  

821.    // rp->rp_timestamp is the time of request origination??????不清楚  

822.            

823.      rt->rt_disc_latency[(unsigned char)rt->hist_indx] = (CURRENT_TIME - rp->rp_timestamp)  

824.                                           / (double) rp->rp_hop_count;  

825.      // increment indx for next time  

826.      rt->hist_indx = (rt->hist_indx + 1) % MAX_HISTORY;  

827.    }   

828.    /* 

829.     * Send all packets queued in the sendbuffer destined for 

830.     * this destination. 路由建立之后将放在缓存区中的要发向目的节点所有数据包都发出去。 

831.     * XXX - observe the "second" use of p. 

832.     */  

833.    Packet *buf_pkt;  

834.    while((buf_pkt = rqueue.deque(rt->rt_dst))) {  

835.      if(rt->rt_hops != INFINITY2) {  

836.            assert (rt->rt_flags == RTF_UP);  

837.      // Delay them a little to help ARP. Otherwise ARP   

838.      //我们都知道ns软件中有ARP模块(连接链路层)用来将ip地址转化为mac地址.这个过程需要时间,所以  

839.      //要为它设定预留延迟,否则就会出现丢包现象  

840.      // may drop packets. -SRD 5/23/99  

841.        forward(rt, buf_pkt, delay);  

842.        delay += ARP_DELAY;//为ARP模块预留命令  

843.      }  

844.    }  

845.   }  

846.   else {  

847.      //如果收到RREP的不是源节点  

848.    suppress_reply = 1;  

849.   }  

850.   /* 

851.    * If reply is for me, discard it. 

852.    *如果目的节点受到了rrep直接DISCARD 

853.    */  

854.  if(ih->daddr() == index || suppress_reply) {  

855.     Packet::free(p);  

856.   }  

857.   /* 

858.    * Otherwise, forward the Route Reply. 

859.    *不是的话就继续向前发rrep 

860.    */  

861.   else {  

862.   // Find the rt entry  

863.   aodv_rt_entry *rt0 = rtable.rt_lookup(ih->daddr());  

864.     // If the rt is up, forward  

865.     if(rt0 && (rt0->rt_hops != INFINITY2)) {  

866.          assert (rt0->rt_flags == RTF_UP);  

867.       rp->rp_hop_count += 1;  

868.       rp->rp_src = index;  

869.       forward(rt0, p, NO_DELAY);  

870.       //  

871.       // Insert the nexthop towards the RREQ source to   

872.       // the precursor list of the RREQ destination  

873.       rt->pc_insert(rt0->rt_nexthop); // nexthop to RREQ source  

874.         

875.     }  

876.     else {  

877.     // I don't know how to forward .. drop the reply.   

878.  #ifdef DEBUG  

879.       fprintf(stderr, "%s: dropping Route Reply/n", __FUNCTION__);  

880.  #endif // DEBUG  

881.       drop(p, DROP_RTR_NO_ROUTE);  

882.     }  

883.   }  

884.  }  

885.    

886.  void  

887.  AODV::recvError(Packet *p) {//收到RERR,查看那些路径受到了中断链路的影响,  

888.      //更新RERR,并向受影响的节点发送RERR  

889.  struct hdr_ip *ih = HDR_IP(p);  

890.  struct hdr_aodv_error *re = HDR_AODV_ERROR(p);  

891.  aodv_rt_entry *rt;  

892.  u_int8_t i;  

893.  Packet *rerr = Packet::alloc();  

894.  struct hdr_aodv_error *nre = HDR_AODV_ERROR(rerr);  

895.   nre->DestCount = 0;  

896.   for (i=0; i<re->DestCount; i++) {  

897.   // For each unreachable destination  

898.     rt = rtable.rt_lookup(re->unreachable_dst[i]);  

899.     if ( rt && (rt->rt_hops != INFINITY2) &&  

900.      (rt->rt_nexthop == ih->saddr()) &&  

901.          (rt->rt_seqno <= re->unreachable_dst_seqno[i]) ) {  

902.      assert(rt->rt_flags == RTF_UP);  

903.      assert((rt->rt_seqno%2) == 0); // is the seqno even?  

904.  #ifdef DEBUG  

905.       fprintf(stderr, "%s(%f): %d/t(%d/t%u/t%d)/t(%d/t%u/t%d)/n", __FUNCTION__,CURRENT_TIME,  

906.               index, rt->rt_dst, rt->rt_seqno, rt->rt_nexthop,  

907.               re->unreachable_dst[i],re->unreachable_dst_seqno[i],  

908.                   ih->saddr());  

909.  #endif // DEBUG  

910.          rt->rt_seqno = re->unreachable_dst_seqno[i];  

911.          rt_down(rt);  

912.     // Not sure whether this is the right thing to do  

913.     Packet *pkt;  

914.      while((pkt = ifqueue->filter(ih->saddr()))) {  

915.              drop(pkt, DROP_RTR_MAC_CALLBACK);  

916.          }  

917.       // if precursor list non-empty add to RERR and delete the precursor list  

918.          if (!rt->pc_empty()) {  

919.              nre->unreachable_dst[nre->DestCount] = rt->rt_dst;  

920.              nre->unreachable_dst_seqno[nre->DestCount] = rt->rt_seqno;  

921.              nre->DestCount += 1;  

922.          rt->pc_delete();  

923.          }  

924.     }  

925.   }   

926.   if (nre->DestCount > 0) {  

927.  #ifdef DEBUG  

928.     fprintf(stderr, "%s(%f): %d/t sending RERR.../n", __FUNCTION__, CURRENT_TIME, index);  

929.  #endif // DEBUG  

930.     sendError(rerr);  

931.   }  

932.   else {  

933.     Packet::free(rerr);  

934.   }  

935.   Packet::free(p);  

936.  }  

937.    

938.  /* 

939.     Packet Transmission Routines 

940.  */  

941.  void  

942.  AODV::forward(aodv_rt_entry *rt, Packet *p, double delay) {  

943.  struct hdr_cmn *ch = HDR_CMN(p);  

944.  struct hdr_ip *ih = HDR_IP(p);  

945.   if(ih->ttl_ == 0) {  

946.  #ifdef DEBUG  

947.    fprintf(stderr, "%s: calling drop()/n", __PRETTY_FUNCTION__);  

948.  #endif // DEBUG  

949.     

950.    drop(p, DROP_RTR_TTL);  

951.    return;  

952.   }  

953.   if (ch->ptype() != PT_AODV && ch->direction() == hdr_cmn::UP &&  

954.      ((u_int32_t)ih->daddr() == IP_BROADCAST)  

955.          || (ih->daddr() == here_.addr_)) {  

956.      dmux_->recv(p,0);  

957.      return;  

958.   }  

959.   if (rt) {  

960.     assert(rt->rt_flags == RTF_UP);  

961.     rt->rt_expire = CURRENT_TIME + ACTIVE_ROUTE_TIMEOUT;  

962.     ch->next_hop_ = rt->rt_nexthop;  

963.     ch->addr_type() = NS_AF_INET;  

964.     ch->direction() = hdr_cmn::DOWN;       //important: change the packet's direction  

965.   }  

966.   else { // if it is a broadcast packet  

967.     // assert(ch->ptype() == PT_AODV); // maybe a diff pkt type like gaf  

968.     assert(ih->daddr() == (nsaddr_t) IP_BROADCAST);  

969.     ch->addr_type() = NS_AF_NONE;  

970.     ch->direction() = hdr_cmn::DOWN;       //important: change the packet's direction  

971.   }  

972.  if (ih->daddr() == (nsaddr_t) IP_BROADCAST) {  

973.   // If it is a broadcast packet  

974.     assert(rt == 0);  

975.     /* 

976.      *  Jitter the sending of broadcast packets by 10ms 

977.      */  

978.     Scheduler::instance().schedule(target_, p,  

979.                         0.01 * Random::uniform());  

980.   }  

981.   else { // Not a broadcast packet   

982.     if(delay > 0.0) {  

983.       Scheduler::instance().schedule(target_, p, delay);  

984.     }  

985.     else {  

986.     // Not a broadcast packet, no delay, send immediately  

987.       Scheduler::instance().schedule(target_, p, 0.);  

988.     }  

989.   }  

990.  }  

991.    

992.  void  

993.  AODV::sendRequest(nsaddr_t dst) {//发送RREQ  

994.  // Allocate a RREQ packet   

995.  Packet *p = Packet::alloc();  

996.  struct hdr_cmn *ch = HDR_CMN(p);  

997.  struct hdr_ip *ih = HDR_IP(p);  

998.  struct hdr_aodv_request *rq = HDR_AODV_REQUEST(p);  

999.  aodv_rt_entry *rt = rtable.rt_lookup(dst);//添加到目的节点的路由,此时路由是不可用的,无效。  

1000.             assert(rt);  

1001.             /* 

1002.              *  Rate limit sending of Route Requests. We are very conservative 

1003.              *  about sending out route requests.  

1004.              */  

1005.             if (rt->rt_flags == RTF_UP) {//不清楚  

1006.               assert(rt->rt_hops != INFINITY2);  

1007.               Packet::free((Packet *)p);  

1008.               return;  

1009.             }  

1010.             if (rt->rt_req_timeout > CURRENT_TIME) {//不到RREQ的发送时间,注意文件开头的RREQ定时器  

1011.                //若没有收到RREP,那么要定时发送RREQ;  

1012.               Packet::free((Packet *)p);  

1013.               return;  

1014.             }  

1015.             // rt_req_cnt is the no. of times we did network-wide broadcast  

1016.             // RREQ_RETRIES is the maximum number we will allow before   

1017.             // going to a long timeout.生命期就是我们允许RREQ重播的次数  

1018.            //如果AODV中多次发送RREQ,仍然找不到到目的节点的路由,那么丢包。(这个if中代码干的事)  

1019.             if (rt->rt_req_cnt > RREQ_RETRIES) {  

1020.               rt->rt_req_timeout = CURRENT_TIME + MAX_RREQ_TIMEOUT;  

1021.               rt->rt_req_cnt = 0;  

1022.             Packet *buf_pkt;  

1023.               while ((buf_pkt = rqueue.deque(rt->rt_dst))) {  

1024.                   drop(buf_pkt, DROP_RTR_NO_ROUTE);  

1025.               }  

1026.               Packet::free((Packet *)p);  

1027.               return;  

1028.             }  

1029.            //下面的内容是填充路由表以及RREQ数据分组的内容,需要结合路由表文件来看。  

1030.            #ifdef DEBUG  

1031.               fprintf(stderr, "(%2d) - %2d sending Route Request, dst: %d/n",  

1032.                                ++route_request, index, rt->rt_dst);  

1033.            #endif // DEBUG  

1034.             // Determine the TTL to be used this time. 动态的确定这次RREQ的生命期,  

1035.             // Dynamic TTL evaluation - SRD            用SRD来球RREQ。  

1036.             rt->rt_req_last_ttl = max(rt->rt_req_last_ttl,rt->rt_last_hop_count);  

1037.             if (0 == rt->rt_req_last_ttl) {  

1038.             // first time query broadcast第一次广播  

1039.               ih->ttl_ = TTL_START;  

1040.             }  

1041.             else {  

1042.             // Expanding ring search.  

1043.               if (rt->rt_req_last_ttl < TTL_THRESHOLD)  

1044.                 ih->ttl_ = rt->rt_req_last_ttl + TTL_INCREMENT;//逐步增加生命周期,知道最大值(TTL_  

1045.                 //_THRESHOLD)  

1046.               else {//如果已经超期了,那么RREQ的广播次数加一  

1047.               // network-wide broadcast  

1048.                 ih->ttl_ = NETWORK_DIAMETER;  

1049.                 rt->rt_req_cnt += 1;  

1050.               }  

1051.             }  

1052.             // remember the TTL used  for the next time  

1053.             rt->rt_req_last_ttl = ih->ttl_;  

1054.             // PerHopTime is the roundtrip time per hop for route requests.每一跳的时间,就是ROUTE  

1055.             //REQUEST在两节点间传播一次时间  

1056.             // The factor 2.0 is just to be safe .. SRD 5/22/99将这个时间设成2.0是比较安全的,  

1057.             //当然我们也可以改  

1058.             // Also note that we are making timeouts to be larger if we have   

1059.             // done network wide broadcast before.   

1060.             rt->rt_req_timeout = 2.0 * (double) ih->ttl_ * PerHopTime(rt); //?  

1061.             if (rt->rt_req_cnt > 0)//如果不是第一次传播  

1062.               rt->rt_req_timeout *= rt->rt_req_cnt;  

1063.             rt->rt_req_timeout += CURRENT_TIME;  

1064.             // Don't let the timeout to be too large, however .. SRD 6/8/99如果不想让生命期太长  

1065.             if (rt->rt_req_timeout > CURRENT_TIME + MAX_RREQ_TIMEOUT)  

1066.               rt->rt_req_timeout = CURRENT_TIME + MAX_RREQ_TIMEOUT;  

1067.             rt->rt_expire = 0;  

1068.            #ifdef DEBUG  

1069.             fprintf(stderr, "(%2d) - %2d sending Route Request, dst: %d, tout %f ms/n",  

1070.                         ++route_request,   

1071.                     index, rt->rt_dst,   

1072.                     rt->rt_req_timeout - CURRENT_TIME);  

1073.            #endif  // DEBUG  

1074.                  

1075.             // Fill out the RREQ packet 填写RREQ数据包的各个元素。  

1076.             // ch->uid() = 0;  

1077.             ch->ptype() = PT_AODV;  

1078.             ch->size() = IP_HDR_LEN + rq->size();  

1079.             ch->iface() = -2;  

1080.             ch->error() = 0;  

1081.             ch->addr_type() = NS_AF_NONE;  

1082.             ch->prev_hop_ = index;          // AODV hack  

1083.             ih->saddr() = index;  

1084.             ih->daddr() = IP_BROADCAST;  

1085.             ih->sport() = RT_PORT;  

1086.             ih->dport() = RT_PORT;  

1087.             // Fill up some more fields.   

1088.             rq->rq_type = AODVTYPE_RREQ;  

1089.             rq->rq_hop_count = 1;  

1090.             rq->rq_bcast_id = bid++;  

1091.             rq->rq_dst = dst;  

1092.             rq->rq_dst_seqno = (rt ? rt->rt_seqno : 0);  

1093.             rq->rq_src = index;  

1094.             seqno += 2;  

1095.             assert ((seqno%2) == 0);  

1096.             rq->rq_src_seqno = seqno;  

1097.             rq->rq_timestamp = CURRENT_TIME;  

1098.             Scheduler::instance().schedule(target_, p, 0.);  

1099.            }  

1100.            //这个函数主要是填充RREP的内容(我注解的可能有问题)  

1101.            void  

1102.            AODV::sendReply(nsaddr_t ipdst, u_int32_t hop_count, nsaddr_t rpdst,  

1103.                            u_int32_t rpseq, u_int32_t lifetime, double timestamp) {  

1104.            //目的节点IP地址,从源节点到目的节点的跳数,rrep目的节点(源节点IP地址),  

1105.            //目的节点序列号,生命周期,最后一个不清楚  

1106.            Packet *p = Packet::alloc();  

1107.            struct hdr_cmn *ch = HDR_CMN(p);  

1108.            struct hdr_ip *ih = HDR_IP(p);  

1109.            struct hdr_aodv_reply *rp = HDR_AODV_REPLY(p);  

1110.            aodv_rt_entry *rt = rtable.rt_lookup(ipdst);  

1111.            /*这个就是lookup函数 

1112.            aodv_rtable::rt_lookup(nsaddr_t id) 

1113.            { 

1114.            aodv_rt_entry *rt = rthead.lh_first; 

1115.             for(; rt; rt = rt->rt_link.le_next) { 

1116.               if(rt->rt_dst == id) 

1117.                 break; 

1118.             } 

1119.             return rt; 

1120.            } 

1121.            */  

1122.            #ifdef DEBUG  

1123.            fprintf(stderr, "sending Reply from %d at %.2f/n", index, Scheduler::instance().clock());  

1124.            #endif // DEBUG  

1125.             assert(rt);  

1126.             rp->rp_type = AODVTYPE_RREP;  //确定数据包的类型为RREP  

1127.             //rp->rp_flags = 0x00;  

1128.             rp->rp_hop_count = hop_count; // hop_count = rt_hops + 1,通告上一个节点到达目的节点的跳书  

1129.             rp->rp_dst = rpdst;  //路由询问rq的目标IP地址  

1130.             rp->rp_dst_seqno = rpseq;  

1131.             rp->rp_src = index;  //rq的源是本节点的IP地址  

1132.             rp->rp_lifetime = lifetime;  

1133.             rp->rp_timestamp = timestamp;  

1134.                 

1135.             // ch->uid() = 0;  

1136.             ch->ptype() = PT_AODV;  

1137.             ch->size() = IP_HDR_LEN + rp->size();  

1138.             ch->iface() = -2;  

1139.             ch->error() = 0;  

1140.             ch->addr_type() = NS_AF_INET;  

1141.             ch->next_hop_ = rt->rt_nexthop;  

1142.             ch->prev_hop_ = index;          // AODV hack  

1143.             ch->direction() = hdr_cmn::DOWN;  

1144.             ih->saddr() = index; //定义了发送节点的ip地址  

1145.             ih->daddr() = ipdst; //目的节点  

1146.             ih->sport() = RT_PORT;  

1147.             ih->dport() = RT_PORT;  

1148.             ih->ttl_ = NETWORK_DIAMETER;  

1149.             Scheduler::instance().schedule(target_, p, 0.);  

1150.            }  

1151.            void  

1152.            AODV::sendError(Packet *p, bool jitter) {//链路中断,需要发送RRER。  

1153.                //通知所有受影响的节点,函数体关于填充RRER的内容,不用细看。  

1154.            struct hdr_cmn *ch = HDR_CMN(p);  

1155.            struct hdr_ip *ih = HDR_IP(p);  

1156.            struct hdr_aodv_error *re = HDR_AODV_ERROR(p);  

1157.                  

1158.            #ifdef ERROR  

1159.            fprintf(stderr, "sending Error from %d at %.2f/n", index, Scheduler::instance().clock());  

1160.            #endif // DEBUG  

1161.             re->re_type = AODVTYPE_RERR;  

1162.             //re->reserved[0] = 0x00; re->reserved[1] = 0x00;  

1163.             // DestCount and list of unreachable destinations are already filled  

1164.             // ch->uid() = 0;  

1165.             ch->ptype() = PT_AODV;  

1166.             ch->size() = IP_HDR_LEN + re->size();  

1167.             ch->iface() = -2;  

1168.             ch->error() = 0;  

1169.             ch->addr_type() = NS_AF_NONE;  

1170.             ch->next_hop_ = 0;  

1171.             ch->prev_hop_ = index;          // AODV hack  

1172.             ch->direction() = hdr_cmn::DOWN;       //important: change the packet's direction  

1173.             ih->saddr() = index;  

1174.             ih->daddr() = IP_BROADCAST;  

1175.             ih->sport() = RT_PORT;  

1176.             ih->dport() = RT_PORT;  

1177.             ih->ttl_ = 1;  

1178.             // Do we need any jitter? Yes  

1179.             if (jitter)  

1180.                Scheduler::instance().schedule(target_, p, 0.01*Random::uniform());  

1181.             else  

1182.                Scheduler::instance().schedule(target_, p, 0.0);  

1183.            }  

1184.              

1185.            /* 

1186.               Neighbor Management Functions 

1187.            */  

1188.            void  

1189.            AODV::sendHello() {//周期发送HELLOW分组,以检测邻居节点的联通性。  

1190.            Packet *p = Packet::alloc();  

1191.            struct hdr_cmn *ch = HDR_CMN(p);  

1192.            struct hdr_ip *ih = HDR_IP(p);  

1193.            struct hdr_aodv_reply *rh = HDR_AODV_REPLY(p);  

1194.            #ifdef DEBUG  

1195.            fprintf(stderr, "sending Hello from %d at %.2f/n", index, Scheduler::instance().clock());  

1196.            #endif // DEBUG  

1197.             rh->rp_type = AODVTYPE_HELLO;  

1198.             //rh->rp_flags = 0x00;  

1199.             rh->rp_hop_count = 1;  

1200.             rh->rp_dst = index;  

1201.             rh->rp_dst_seqno = seqno;  

1202.             rh->rp_lifetime = (1 + ALLOWED_HELLO_LOSS) * HELLO_INTERVAL;  

1203.             // ch->uid() = 0;  

1204.             ch->ptype() = PT_AODV;  

1205.             ch->size() = IP_HDR_LEN + rh->size();  

1206.             ch->iface() = -2;  

1207.             ch->error() = 0;  

1208.             ch->addr_type() = NS_AF_NONE;  

1209.             ch->prev_hop_ = index;          // AODV hack  

1210.             ih->saddr() = index;  

1211.             ih->daddr() = IP_BROADCAST;  

1212.             ih->sport() = RT_PORT;  

1213.             ih->dport() = RT_PORT;  

1214.             ih->ttl_ = 1;  

1215.             Scheduler::instance().schedule(target_, p, 0.0);  

1216.            }  

1217.              

1218.            void  

1219.            AODV::recvHello(Packet *p) {  

1220.            //struct hdr_ip *ih = HDR_IP(p);  

1221.            struct hdr_aodv_reply *rp = HDR_AODV_REPLY(p);  

1222.            AODV_Neighbor *nb;  

1223.             nb = nb_lookup(rp->rp_dst);  

1224.             if(nb == 0) {  

1225.               nb_insert(rp->rp_dst);  

1226.             }  

1227.             else {  

1228.               nb->nb_expire = CURRENT_TIME +  

1229.                               (1.5 * ALLOWED_HELLO_LOSS * HELLO_INTERVAL);  

1230.             }  

1231.             Packet::free(p);  

1232.            }  

1233.            void  

1234.            AODV::nb_insert(nsaddr_t id) {  

1235.            AODV_Neighbor *nb = new AODV_Neighbor(id);  

1236.             assert(nb);  

1237.             nb->nb_expire = CURRENT_TIME +  

1238.                            (1.5 * ALLOWED_HELLO_LOSS * HELLO_INTERVAL);  

1239.             LIST_INSERT_HEAD(&nbhead, nb, nb_link);  

1240.             seqno += 2;             // set of neighbors changed  

1241.             assert ((seqno%2) == 0);  

1242.            }  

1243.              

1244.            AODV_Neighbor*  

1245.            AODV::nb_lookup(nsaddr_t id) {  

1246.            AODV_Neighbor *nb = nbhead.lh_first;  

1247.             for(; nb; nb = nb->nb_link.le_next) {  

1248.               if(nb->nb_addr == id) break;  

1249.             }  

1250.             return nb;  

1251.            }  

1252.              

1253.            /* 

1254.             * Called when we receive *explicit* notification that a Neighbor 

1255.             * is no longer reachable. 

1256.             */  

1257.            void  

1258.            AODV::nb_delete(nsaddr_t id) {  

1259.            AODV_Neighbor *nb = nbhead.lh_first;  

1260.             log_link_del(id);  

1261.             seqno += 2;     // Set of neighbors changed  

1262.             assert ((seqno%2) == 0);  

1263.             for(; nb; nb = nb->nb_link.le_next) {  

1264.               if(nb->nb_addr == id) {  

1265.                 LIST_REMOVE(nb,nb_link);  

1266.                 delete nb;  

1267.                 break;  

1268.               }  

1269.             }  

1270.             handle_link_failure(id);  

1271.            }  

1272.              

1273.            /* 

1274.             * Purges all timed-out Neighbor Entries - runs every 

1275.             * HELLO_INTERVAL * 1.5 seconds. 

1276.             */  

1277.            void  

1278.            AODV::nb_purge() {  

1279.            AODV_Neighbor *nb = nbhead.lh_first;  

1280.            AODV_Neighbor *nbn;  

1281.            double now = CURRENT_TIME;  

1282.             for(; nb; nb = nbn) {  

1283.               nbn = nb->nb_link.le_next;  

1284.               if(nb->nb_expire <= now) {  

1285.                 nb_delete(nb->nb_addr);  

1286.               }  

1287.             }  

1288.            }  

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/fumaocai0706/article/details/8842767

智能推荐

【详细】Spring Boot框架整合Spring Security实现安全访问控制_springboot org.springframework.security.web.access-程序员宅基地

文章浏览阅读3.4w次,点赞39次,收藏191次。一、 前言:项目舍弃了原本的SSH框架,改用Spring Boot框架,并且要引入Spring Security为系统提供安全访问控制解决方案,接下来记录一下这两天在Spring Boot中引入Spring Security 的过程。主要参考了以下项目、博客和手册:(目前最新的Spring Security版本为5.0.4,我使用的是5.0.3,前三个链接中用的应该都是Spring Securit..._springboot org.springframework.security.web.access.intercept.filtersecurityi

pack_padded_sequence用法与完整示例-程序员宅基地

文章浏览阅读486次。是 PyTorch 中用于处理变长序列数据的函数。它的主要作用是将一个批次的序列数据打包成适合输入到 RNN(循环神经网络)模型中的形式,以避免对填充部分进行多余的计算。在自然语言处理任务中,例如文本分类、机器翻译等,输入的文本序列长度往往不同,为了方便进行批量处理,需要对较短的序列进行填充(padding)使其与最长序列的长度相同。但是,在某些情况下,填充的部分对模型来说是没有意义的,而且会导致额外的计算开销。因此,函数将填充的部分从计算中移除,以提高模型的效率。下面是一个示例,介绍了如何使用。_pack_padded_sequence

在java中使用oracle绑定变量_java oracle绑定变量-程序员宅基地

文章浏览阅读1.1k次。为什么要使用绑定变量:在JAVA中的SQL 语句的编写方面,没有使用ORACLE 绑定变量,很大程度上降低了数据库的性能,表现在两个方面:1、SQL语句硬分析(Hard Parse)太多,严重消耗CPU资源,延长了SQL语句总的执行时间。SQL语句的执行过程分几个步骤:语法检查、分析、执行、返回结果。其中分析又分为硬分析(Hard Parse)和软分析(Soft P..._java oracle绑定变量

Flutter mixin混入_flutter mixin 混入 mixin-程序员宅基地

文章浏览阅读127次。flutter mixin_flutter mixin 混入 mixin

Windows Terminal美化界面,优雅的办公带来超高的效率_aka terminal美化-程序员宅基地

文章浏览阅读888次。贴个图众所周知,Windows Terminal没有美化后那个傻大蓝,沉默黑简直不忍直视。没有像官方演示的那么美观(所以得自己捯饬捯饬好看的样子)美化开始第一步安装相关的模块和PowerLine主题Install-Module posh-git -Scope CurrentUserInstall-Module oh-my-posh -Scope CurrentUser如果你使用管理员权限打开PowerShell并且想把oh-my-posh安装到所有用户,则输入Install-Module _aka terminal美化

Qt编写控件属性设计器-程序员宅基地

文章浏览阅读435次。一、前言自从研究Qt编写自定义控件以来,一发不可收拾,越多越多人有类似的需求找我定制控件,陆陆续续写了上百个控件,目前已超过150个,于是逐渐衍生了另外一个需求,提供一个控件属性设计器,类似QtDesigner一样,可以方便的拖曳控件,改变属性,立即应用,并导出到文件方便下次直接加载,这个设计器有点像组态中的一个雏形,提供了基本的加载控件,导入导出数据,数据源绑定等。本系列文章将从加..._qt实现属性编辑

随便推点

【效率提升】maven 转 gradle 实战 | 京东云技术团队_maven转gradle插件-程序员宅基地

文章浏览阅读512次。gradle 是一个打包工具, 是一个开源构建自动化工具,足够灵活,可以构建几乎任何类型的软件,高性能、可扩展、能洞察等。其中洞察,可以用于分析构建过程中数据,提供分析参考,方便排查问题和不断优化构建性能,以下一次编译分析报告。_maven转gradle插件

java在线问卷调查系统的设计与实现(springboot+mysql源码+文档)-程序员宅基地

文章浏览阅读979次,点赞21次,收藏9次。基于java的在线问卷调查系统的设计与实现的主要使用者分为:管理员权限操作的功能包括对注册用户信息的管理,对问卷,题目,问卷调查,新闻资讯等信息的管理。用户权限操作的功能包括参与问卷调查,查看新闻,查看问卷调查记录。

几何矩求解椭圆_二阶矩确认椭圆-程序员宅基地

文章浏览阅读974次。勒让德惯性椭圆求解1.matlab利用二阶矩求解椭圆长轴、短轴、离心率、长轴与x轴夹角xbar=stats(k).Centroid(1);%区域的重心坐标ybar = stats(k).Centroid(2); x = list(:,1) - xbar; y = -(list(:,2) - ybar); % This is negative for the % orientation calculation (measured in the % counter-clockwise dire_二阶矩确认椭圆

《Python编程》专栏简介-程序员宅基地

文章浏览阅读155次。在本教程中,我们涵盖了Python编程的主要主题,包括Python基础知识、Python数学、Python网络编程、Python算法和数据结构、Python机器学习、Python Web开发和Python游戏开发。

在Ubuntu 12.04 64 位 搭载Android4.4源码编译环境-程序员宅基地

文章浏览阅读67次。在Ubuntu 12.04 64 位 搭载Android4.4源码编译环境 一、准备工作:(1) VMare Workstation 10(2)Ubuntu12.04 64bit(3) JDK1.6(4)Android 4.4 源码(PS:...

图像数据增广_图像增广-程序员宅基地

文章浏览阅读1.2k次,点赞19次,收藏24次。本文主要介绍了图像数据的几种增广方式,其中包括随机翻转、随机裁剪和随机颜色变换等,使用时一般在训练集上综合使用以达到鲁棒效果。_图像增广