📄 aodv.cc
字号:
GWINFO_LIFETIME, //Lifetime, defined to 10 sec rq->rq_timestamp, //Timestamp, when the RREQ was sent RREP_IFLAG); //I Flag Packet::free(p); } //*************************************************************************// /* * 5. I'm not destination; I don't have a route, I'm not gateway. * Can't reply. So forward the Route Request */ else { ih->saddr() = index; ih->daddr() = IP_BROADCAST; rq->rq_hop_count += 1; // Maximum sequence number seen en route if(rt) rq->rq_dst_seqno = max(rt->rt_seqno, rq->rq_dst_seqno); forward((aodv_rt_entry*) 0, p, DELAY); }}voidAODV::recvReply(Packet *p) { //struct hdr_cmn *ch = HDR_CMN(p); struct hdr_ip *ih = HDR_IP(p); struct hdr_aodv_reply *rp = HDR_AODV_REPLY(p); aodv_rt_entry *rt; char suppress_reply = 0; double delay = 0.0;#ifdef DEBUG if(ih->daddr() == index && rp->rp_flags == RREP_IFLAG) { fprintf(stderr, "%d - source received RREP_I from %d\n",index, rp->rp_dst); } else if(ih->daddr() == index) { fprintf(stderr, "%d - source received RREP from %d\n", index, rp->rp_dst); } else if(rp->rp_flags == RREP_IFLAG && ih->daddr() != (nsaddr_t)IP_BROADCAST){ fprintf(stderr, "%d - received RREP_I, forward RREP_I\n", index); } else if(rp->rp_flags != RREP_IFLAG) { fprintf(stderr, "%d - received RREP, forward RREP\n", index); }#endif // DEBUG //My modification**********************************************************// /* Implementing hybrid gateway discovery method... */ if(rp->rp_flags == RREP_IFLAG && index == thisnode->base_stn()) { Packet::free(p); return; } //*************************************************************************// /* * Got a reply. So reset the "soft state" maintained for * route requests in the request table. We don't really have * have a separate request table. It is just a part of the * routing table itself. * * Note that rp_dst is the dest of the DATA packets, not the dest of the * RREP, which is the src of the data packets. * */ rt = rtable.rt_lookup(rp->rp_dst); /* * If I don't have a rt entry to this host... adding */ if(rt == 0) { rt = rtable.rt_add(rp->rp_dst); } /* * Add a forward route table entry... here I am following * Perkins-Royer AODV paper almost literally - SRD 5/99 */ //My modification //I added the condition "inactive route". if((rt->rt_flags != RTF_UP) || // inactive route (rt->rt_seqno < rp->rp_dst_seqno) || // newer route ((rt->rt_seqno == rp->rp_dst_seqno) && (rt->rt_hops > rp->rp_hop_count)) ) { // shorter or better route // Update the rt entry //My modification**************************************// //Bug fix from Riadh /*rt_update(rt, rp->rp_dst_seqno, rp->rp_hop_count, rp->rp_src, CURRENT_TIME + rp->rp_lifetime);*/ rt_update(rt, rp->rp_dst_seqno, rp->rp_hop_count, ih->saddr(), CURRENT_TIME + rp->rp_lifetime); //*****************************************************// // reset the soft state rt->rt_req_cnt = 0; rt->rt_req_timeout = 0.0; rt->rt_req_last_ttl = rp->rp_hop_count; if(ih->daddr() == index) { // If I am the original source // Update the route discovery latency statistics // rp->rp_timestamp is the time of request origination rt->rt_disc_latency[rt->hist_indx] = (CURRENT_TIME - rp->rp_timestamp) / (double) rp->rp_hop_count; // increment indx for next time rt->hist_indx = (rt->hist_indx + 1) % MAX_HISTORY; } /* * Send all packets queued in the sendbuffer destined for * this destination. * XXX - observe the "second" use of p. */ Packet *buf_pkt; int j = 0; while((buf_pkt = rqueue.deque(rt->rt_dst))) { if(rt->rt_hops != INFINITY2) { assert (rt->rt_flags == RTF_UP); // Delay them a little to help ARP. Otherwise ARP // may drop packets. -SRD 5/23/99 ++j; forward(rt, buf_pkt, delay); delay += ARP_DELAY; } /*if*/ } /*while*/#ifdef DEBUG if(j > 0) { fprintf(stderr,"%d - %d packet(s) destined to %d emptied from sendbuffer" " at %f\n (recvReply)\n", index, j, rt->rt_dst, CURRENT_TIME); }#endif } /*if newer/shorter rt*/ else { suppress_reply = 1; } //My modification**********************************************************// /* Add/update Default Route if you've received a RREP_I... */ if(rp->rp_flags == RREP_IFLAG) { suppress_reply = 0; aodv_rt_entry *ALL_GW_rt; if((ALL_GW_rt = rtable.rt_lookup(ALL_MANET_GW_MULTICAST))) { // reset the soft state ALL_GW_rt->rt_req_timeout = 0.0; if(rp->rp_hop_count != INFINITY2) { ALL_GW_rt->rt_req_last_ttl = rp->rp_hop_count; } } /* 2. GATEWAY SELECTION 1. If Default Route does not exist: Create and update route 2. If Default Route already exists: Update route if number of hops to the new gateway is less than the number of hops to the current gateway NOTE: In the current form, a MN that receives a RREP_I from another GW than its default GW, will select the new GW ONLY if the new GW is closer than the default GW! It means that it will forward a RREP_I from the new GW although it doesn't use that GW as its default GW! So when the destination receives the RREP_I, it will think that it is using the new GW, which is not correct. This might cause problems! One way to solve it might be to force a MN that receives a RREP_I from a new GW, to select the new GW if it is going to forward the RREP_I to another MN! See the commented code below... This problem also applies to recvAdvertisement()! See comment in recvError! */ aodv_rt_entry *default_rt = rtable.rt_lookup(DEFAULT); if(default_rt == 0) { default_rt = rtable.rt_add(DEFAULT); } if((default_rt->rt_flags != RTF_UP) || // no route before (rp->rp_dst == default_rt->rt_nexthop && rp->rp_dst_seqno > default_rt->rt_seqno) || // newer route (rp->rp_dst == default_rt->rt_nexthop && rp->rp_dst_seqno == default_rt->rt_seqno && rp->rp_hop_count < default_rt->rt_hops) || // shorter route (rp->rp_dst != default_rt->rt_nexthop && rp->rp_hop_count < default_rt->rt_hops) /* || // new GW & newer route (rp->rp_dst != default_rt->rt_nexthop && ih->daddr() != index && ih->daddr() != IP_BROADCAST && ih->ttl_ != 0)*/ //RREP_I will be forwarded ) { thisnode->set_base_stn(rp->rp_dst); rt_update(default_rt, rp->rp_dst_seqno, rp->rp_hop_count, rp->rp_dst, CURRENT_TIME + rp->rp_lifetime); /* 2a. Update the route to the fixed node. */ aodv_rt_entry *rtn, *this_rt; for(this_rt = rtable.head(); this_rt; this_rt = rtn) { rtn = this_rt->rt_link.le_next; if(this_rt->rt_nexthop == DEFAULT) { rt_update(this_rt, rp->rp_dst_seqno, rp->rp_hop_count, DEFAULT, CURRENT_TIME + rp->rp_lifetime); } } #ifdef DEQUE_AFTER_RREP_I /* 2b. If the route is a route to a fixed node and a valid default route exists and there are packets in the sendbuffer waiting, forward them. */ aodv_rt_entry *fn_rt = find_fn_entry(); if(ih->daddr() == index && fn_rt && fn_rt->rt_flags == RTF_UP && find_send_entry(fn_rt)->rt_flags == RTF_UP) { assert(default_rt->rt_hops != INFINITY2); int j = 0; Packet *buf_pkt; while((buf_pkt = rqueue.deque(fn_rt->rt_dst))) { ++j; forward(find_send_entry(fn_rt), buf_pkt, delay); delay += ARP_DELAY; }#ifdef DEBUG if(j > 0) { fprintf(stderr,"%d - %d packet(s) destined to %d emptied from " "sendbuffer at %f\n\tGW is %d (recvReply)\n", index, j, fn_rt->rt_dst, CURRENT_TIME, default_rt->rt_nexthop); printf("%d - %d packet(s) destined to %d emptied from " "sendbuffer at %f, GW is %d (recvReply)\n", index, j, fn_rt->rt_dst, CURRENT_TIME, default_rt->rt_nexthop); }#endif }#endif //DEQUE_AFTER_RREP_I } else { suppress_reply = 1; } } /*if RREP_I*/ //*************************************************************************//#ifdef DEBUG if(suppress_reply && rp->rp_flags != RREP_IFLAG) { fprintf(stderr, "%d - received RREP, suppress RREP\n", index); }#endif // DEBUG /* * 1. If reply is for me, discard it. */ //My modification***********************************// /* RREP_Is should not be suppressed! */ //**************************************************// if(ih->daddr() == index || (suppress_reply && rp->rp_flags != RREP_IFLAG)) { Packet::free(p); } /* * 2. Otherwise, forward the Route Reply. */ else { // Find the rt entry aodv_rt_entry *rt0 = rtable.rt_lookup(ih->daddr()); /* 2a. If the rt is up, forward */ if(rt0 && (rt0->rt_hops != INFINITY2)) { assert (rt0->rt_flags == RTF_UP); rp->rp_hop_count += 1; //My modification**************// //Bug fix from Riadh //rp->rp_src = index; ih->saddr() = index; //****************************// forward(rt0, p, NO_DELAY); // Insert the nexthop towards the RREQ source to // the precursor list of the RREQ destination rt->pc_insert(rt0->rt_nexthop); // nexthop to RREQ source } //My modifications*******************************************************// /* Implementing hybrid gateway discovery method... 2b. If RREP_I that should be rebroadcasted, rebroadcast it. */ else if(rp->rp_flags == RREP_IFLAG && ih->daddr() == (nsaddr_t) IP_BROADCAST) { //Broadcast the RREP_I to other mobile nodes (your neighbors) aodv_rt_entry *default_rt = rtable.rt_lookup(DEFAULT); ih->saddr() = index; if(rp->rp_hop_count != INFINITY2 && default_rt && rp->rp_hop_count > default_rt->rt_hops) { rp->rp_hop_count = default_rt->rt_hops + 1; } else { rp->rp_hop_count += 1; } struct hdr_cmn *ch = HDR_CMN(p); ch->prev_hop_ = index; //Randomize the sending of broadcast packets to reduce collisions //(100 ms jitter) //forward((aodv_rt_entry*) 0, p, DELAY); forward((aodv_rt_entry*) 0, p, 0.01 * Random::uniform()); //Precursor list?? } //***********************************************************************// /* 2c. I don't know how to forward .. drop the reply. */ else {#ifdef DEBUG fprintf(stderr, "%d - dropping RREP\n", index);#endif // DEBUG drop(p, DROP_RTR_NO_ROUTE); } }}voidAODV::recvError(Packet *p) { struct hdr_ip *ih = HDR_IP(p); struct hdr_aodv_error *re = HDR_AODV_ERROR(p); aodv_rt_entry *rt; u_int8_t i; Packet *rerr = Packet::alloc(); struct hdr_aodv_error *nre = HDR_AODV_ERROR(rerr); nre->DestCount = 0; //My modification******************************************// /* I added some conditions to the if statement below. */ //Find route to fixed node aodv_rt_entry *default_rt = rtable.rt_lookup(DEFAULT); aodv_rt_entry *gw_rt; if(default_rt && default_rt->rt_flags == RTF_UP) gw_rt = rtable.rt_lookup(default_rt->rt_nexthop); //*********************************************************// for(i=0; i<re->DestCount; i++) { // For each unreachable destination rt = rtable.rt_lookup(re->unreachable_dst[i]); if((rt && (rt->rt_hops != INFINITY2) && (rt->rt_nexthop == ih->saddr()) && (rt->rt_seqno <= re->unreachable_dst_seqno[i])) || (rt && (rt->rt_hops != INFINITY2) && (rt->rt_nexthop == ih->saddr()) && (rt->rt_seqno <= re->unreachable_dst_seqno[i]) && default_rt && rt->rt_dst == default_rt->rt_nexthop) ) { assert(rt->rt_flags == RTF_UP); assert((rt->rt_seqno%2) == 0); // is the seqno even? #ifdef DEBUG fprintf(stderr, "%d - receiving RERR; src=%d, dst=%d, unr=%d, nh=%d\n", index, ih->saddr(), rt->rt_dst, re->unreachable_dst[i], rt->rt_nexthop);#endif // DEBUG rt->rt_seqno = re->unreachable_dst_seqno[i]; rt_down(rt); // Not sure whether this is the right thing to do Packet *pkt; while((pkt = ifqueue->filter(ih->saddr()))) { drop(pkt, DROP_RTR_MAC_CALLBACK); } // if precursor list non-empty add to RERR and delete the precursor list if(!rt->pc_empty()) { nre->unreachable_dst[nre->DestCount] = rt->rt_dst; nre->unreachable_dst_seqno[nre->DestCount] = rt->rt_seqno; nre->DestCount += 1; rt->pc_delete(); //My modification*************************************// if(default_rt && rt->rt_dst == default_rt->rt_nexthop) { nre->unreachable_dst[nre->DestCount] = default_rt->rt_dst; nre->unreachable_dst_seqno[nre->DestCount] = default_rt->rt_seqno; nre->DestCount += 1; } //****************************************************// } //My modification******************************************// //If this is a route to a GW, bring down default route. if(default_rt && rt->rt_dst == default_rt->rt_nexthop) { //Seqno not correct, but it seems it's ok... //default_rt->rt_seqno = re->unreachable_dst_seqno[i]; rt_down(default_rt); } //*********************************************************// } /*if*/ } /*for*/ //My modification**********************************************************// /* If this is a route to a GW (any GW!), bring down default route.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -