NS2中AODV协议解释
- 格式:docx
- 大小:92.15 KB
- 文档页数:37
分类:ns仿真2012-05-28 20:23 1285人阅读评论(5) 收藏举报dststructrtfdelaytclfunction[cpp]view plaincopy1.//#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 DEBUG13.//#define ERROR14.15.#ifdef DEBUG16.static int extra_route_reply = 0;17.static int limit_route_request = 0;18.static int route_request = 0;19.#endif20.21.22./*23. TCL Hooks24.*/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.int48.AODV::command(int argc, const char*const* argv) {49.if(argc == 2) {//命令的参数个数是250. Tcl& tcl = Tcl::instance();51.52.if(strncasecmp(argv[1], "id", 2) == 0) {//命令所要求的操作为id53. tcl.resultf("%d", index);54.return TCL_OK;55. }56.57.if(strncasecmp(argv[1], "start", 2) == 0) {//命令所要求的操作为start58. btimer.handle((Event*) 0);59.60.#ifndef AODV_LINK_LAYER_DETECTION61. htimer.handle((Event*) 0);62. ntimer.handle((Event*) 0);63.#endif // LINK LAYER DETECTION64.65. rtimer.handle((Event*) 0);66.return TCL_OK;67. }68. }69.else if(argc == 3) {//命令参数个数等于370.if(strcmp(argv[1], "index") == 0) {//命令所要求的操作为index71. index = atoi(argv[2]);72.return TCL_OK;73. }74.//命令所要求的操作为log-target或者tracetarget75.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-target84.int stat = mand(argc,argv);85.if (stat != TCL_OK) return stat;86.return Agent::command(argc, argv);87. }88.89.//命令所要求的操作if-queue90.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-dmux98.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. Constructor113.*/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. Timers133.*/134.//广播定时器135.void136.BroadcastTimer::handle(Event*) {137. agent->id_purge();138. Scheduler::instance().schedule(this, &intr, BCAST_ID_SAVE);139.}140.//hello报文定时器141.void142.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.void151.NeighborTimer::handle(Event*) {152. agent->nb_purge();153. Scheduler::instance().schedule(this, &intr, HELLO_INTERVAL);154.}155.路由缓存定时器156.void157.RouteCacheTimer::handle(Event*) {158. agent->rt_purge();159.#define FREQUENCY 0.5 // sec160. Scheduler::instance().schedule(this, &intr, FREQUENCY);161.}162.//路由缓存定时器163.void164.LocalRepairTimer::handle(Event* p) { // SRD: 5/4/99165.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 repaired176.// I will be conservative and bring down the route177.// 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 RERR184.#ifdef DEBUG185. fprintf(stderr,"Node %d: Dst - %d, failed local repair\n",index, rt->rt_dst); 186.#endif187. }188. Packet::free((Packet *)p);189.}190.191.192./*193. Broadcast ID Management Functions194.*/195.196.197.void198.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.bool208.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.void220.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 Functions236.*/237.238.double239.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.else255.return((double) NODE_TRAVERSAL_TIME);256.257.}258.259./*260. Link Failure Management Functions261.*/262.263.static void264.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.void273.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_DETECTION280. drop(p, DROP_RTR_MAC_CALLBACK);281.#else282.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_REPAIR301./* 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 repair308.// retrieve all the packets in the ifq using this link,309.// queue the packets for which local repair is done,310.return;311. }312.else313.#endif // LOCAL REPAIR314.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 -Mahesh319.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 DETECTION326.}327./*当发现邻居失效的时候,就会调用此函数*/328.void329.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 entry337. 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 DEBUG346. 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 // DEBUG350. re->DestCount += 1;351. rt_down(rt);//将此路由down掉352. }353.// remove the lost neighbor from all the precursor lists354. rt->pc_delete(id);//删除此路由的前缀列表355. }356./*如果存在通过此邻居到达目的节点的路由,则发送错误报文*/357.if (re->DestCount > 0) {358.#ifdef DEBUG359. fprintf(stderr, "%s(%f): %d\tsending RERR...\n", __FUNCTION__, CURRENT_TIME, index); 360.#endif // DEBUG361. sendError(rerr, false);362. }363.else {364. Packet::free(rerr);365. }366.}367.368.void369.AODV::local_rt_repair(aodv_rt_entry *rt, Packet *p) {370.#ifdef DEBUG371. fprintf(stderr,"%s: Dst - %d\n", __FUNCTION__, rt->rt_dst);372.#endif373.// Buffer the packet374. rqueue.enque(p);375.376.// mark the route as under repair377. rt->rt_flags = RTF_IN_REPAIR;378.379. sendRequest(rt->rt_dst);380.381.// set up a timer interrupt382. Scheduler::instance().schedule(&lrtimer, p->copy(), rt->rt_req_timeout);383.}384./*更新路由条目*/385.void386.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.void397.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 Functions417.*/418.419.void420.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. That427. * 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 packet439. */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 upstream474. * neighbors - Mahesh 09/11/99475. */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 DEBUG483. fprintf(stderr, "%s: sending RERR...\n", __FUNCTION__); 484.#endif485. sendError(rerr, false);486.487. drop(p, DROP_RTR_NO_ROUTE);488. }489.490.}491./*定时查看路由缓存条目*/492.void493.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.//如果此路由条目标注为有效,但是生存时间为0502.//丢弃前往目的分组,并且将此路由条目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 DEBUG509. fprintf(stderr, "%s: calling drop()\n",510. __FUNCTION__);511.#endif // DEBUG512. 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 and533.// 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 Routines547.*/548.549.void550.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_ i n 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 Header572. */573. ch->size() += IP_HDR_LEN;574.// Added by Parag Dadhania && John Novatnack to handle broadcasting575.if ( (u_int32_t)ih->daddr() != IP_BROADCAST)576. ih->ttl_ = NETWORK_DIAMETER;577.}578./*579. * I received a packet that I sent. Probably580. * 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.else605. forward((aodv_rt_entry*) 0, p, NO_DELAY);606.}607.608.609.void610.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.void647.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 source655. * - I recently heard this request.656. */657./*如果此节点就是源节点,出现环路,丢弃路由请求报文*/658.if(rq->rq_src == index) {659.#ifdef DEBUG660. fprintf(stderr, "%s: got my own REQUEST\n", __FUNCTION__); 661.#endif // DEBUG662. Packet::free(p);663.return;664. }665./*如果已经收到了源地址和请求序列号相等的请求报文,丢弃*/666.if (id_lookup(rq->rq_src, rq->rq_bcast_id)) {667.668.#ifdef DEBUG669. fprintf(stderr, "%s: discarding request\n", __FUNCTION__); 670.#endif // DEBUG671.672. Packet::free(p);673.return;674. }675.676./*677. * Cache the broadcast ID678. */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 route691.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 the705.// 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 and711.// Set expiry time to CURRENT_TIME + ACTIVE_ROUTE_TIMEOUT712.// This is because route is used in the forward direction,713.// but only sources get benefited by this change714. 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 the721. * reverse route.722. * May need some change in the following code - Mahesh 09/11/99723. */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 table735.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 DEBUG749. fprintf(stderr, "%d - %s: destination sending reply\n", 750. index, __FUNCTION__);751.#endif // DEBUG752.753.754.// Just to be safe, I use the max. Somebody may have755.// 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 Destination760. 1, // Hop Count761. index, // Dest IP Address762. seqno, // Dest Sequence Num763. MY_ROUTE_TIMEOUT, // Lifetime764. rq->rq_timestamp); // timestamp765.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 the785.// precursor lists of destination and source respectively786. rt->pc_insert(rt0->rt_nexthop); // 加入前缀列表787. rt0->pc_insert(rt->rt_nexthop); // 加入前缀列表788.789.#ifdef RREQ_GRAT_RREP790.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.#endif799.800.// TODO: send grat RREP to dst if G flag set in RREQ using rq->rq_src_seqno, rq->rq_hop_counT801.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 Request808. */809.//不能应答此报文,则继续广播810.else {811. ih->saddr() = index;812. ih->daddr() = IP_BROADCAST;813. rq->rq_hop_count += 1;814.// Maximum sequence number seen en route815.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.void823.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 DEBUG832. fprintf(stderr, "%d - %s: received a REPLY\n", index, __FUNCTION__); 833.#endif // DEBUG834.835.836./*837. * Got a reply. So reset the "soft state" maintained for838. * route requests in the request table. We don't really have839. * have a separate request table. It is just a part of the840. * routing table itself.841. */842.// Note that rp_dst is the dest of the data packets, not the843.// 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... adding849. */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 following856. * Perkins-Royer AODV paper almost literally - SRD 5/99857. */858./*如果应答报文中目的序列号大于路由序列号或者859.两者序列号相等但是跳数较小,则更新路由表*/860.if ( (rt->rt_seqno < rp->rp_dst_seqno) || // newer route861. ((rt->rt_seqno == rp->rp_dst_seqno) &&862. (rt->rt_hops > rp->rp_hop_count)) ) { // shorter or better route 863.864.// Update the rt entry865. 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 state869. 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 source874.// Update the route discovery latency statistics875.// rp->rp_timestamp is the time of request origination876.877. rt->rt_disc_latency[rt->hist_indx] = (CURRENT_TIME - rp->rp_timestamp) 878. / (double) rp->rp_hop_count; 879.// increment indx for next time880. rt->hist_indx = (rt->hist_indx + 1) % MAX_HISTORY;881. }882.883./*884. * Send all packets queued in the sendbuffer destined for885. * 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 ARP894.// may drop packets. -SRD 5/23/99895. 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 entry917.aodv_rt_entry *rt0 = rtable.rt_lookup(ih->daddr());918.// If the rt is up, forward919.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 to927.// the precursor list of the RREQ destination928. rt->pc_insert(rt0->rt_nexthop); // nexthop to RREQ source 929.。