📄 aodv.cc
字号:
re->unreachable_dst[re->DestCount] = rt->rt_dst; re->unreachable_dst_seqno[re->DestCount] = rt->rt_seqno; re->DestCount += 1; } #ifdef DEBUG fprintf(stderr, "!!! %d - NRTE dst=%d, sending RERR.................\n", index, rt->rt_dst);#endif sendError(rerr, false); drop(p, DROP_RTR_NO_ROUTE); }}voidAODV::rt_purge() { aodv_rt_entry *rt, *rtn; double now = CURRENT_TIME; double delay = 0.0; Packet *p; //My modification**************************************// aodv_rt_entry *default_rt = rtable.rt_lookup(DEFAULT); //*****************************************************// for(rt = rtable.head(); rt; rt = rtn) { // for each rt entry rtn = rt->rt_link.le_next; /* 1. If a valid route has expired, purge all packets from sendbuffer and invalidate the route. My modification I added the third condition: Route to fixed node should always have DEFAULT as nexthop! Don't call route down if the expired route is a route to a fixed node. */ if((rt->rt_flags == RTF_UP) && (rt->rt_expire < now) && (rt->rt_nexthop != DEFAULT) ) { assert(rt->rt_hops != INFINITY2); while((p = rqueue.deque(rt->rt_dst))) {#ifdef DEBUG fprintf(stderr, "%s: calling drop()\n", __FUNCTION__);#endif // DEBUG drop(p, DROP_RTR_NO_ROUTE); } rt->rt_seqno++; assert (rt->rt_seqno%2); rt_down(rt); } //My modification********************************************************// /* 2. If the route has not expired and it is a route to a fixed node and a valid default route exists and there are packets in the sendbuffer waiting, forward them. */ else if(rt->rt_flags == RTF_UP && rt->rt_nexthop == DEFAULT && find_send_entry(rt)->rt_flags == RTF_UP) { assert(default_rt->rt_hops != INFINITY2); int j = 0; while((p = rqueue.deque(rt->rt_dst))) { ++j; //==> I've changed "rt" to "find_send_entry(rt)". forward (find_send_entry(rt), p, delay); delay += ARP_DELAY; }#ifdef DEBUG if(j > 0 && rt->rt_nexthop == DEFAULT) { fprintf(stderr,"%d - %d packet(s) destined to %d emptied from " "sendbuffer at %f\n\tGW is %d (rt_purge)\n", index, j, 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 (rt_purge)\n", index, j, rt->rt_dst, CURRENT_TIME, default_rt->rt_nexthop); } else if(j > 0) { fprintf(stderr,"%d - %d packet(s) destined to %d emptied from " "sendbuffer at %f\n (rt_purge)\n", index, j, rt->rt_dst, CURRENT_TIME); printf("%d - %d packet(s) destined to %d emptied from sendbuffer at %f" ", (rt_purge)\n", index, j, rt->rt_dst, CURRENT_TIME); }#endif } //***********************************************************************// /* 3. If the route has not expired, and there are packets in the sendbuffer waiting, forward them. This should not be needed, but this extra check does no harm. My modification I added the second condition below in order to prevent packets getting forwarded to the default route (-10) although it is down. */ else if(rt->rt_flags == RTF_UP && rt->rt_nexthop != DEFAULT) { assert(rt->rt_hops != INFINITY2); while((p = rqueue.deque(rt->rt_dst))) { //==> I've changed "rt" to "find_send_entry(rt)". forward (find_send_entry(rt), p, delay); delay += ARP_DELAY; } } /* 4. If the route is down and if there is a packet for this destination waiting in the sendbuffer, then send out route request. sendRequest will check whether it is time to really send out request or not. This may not be crucial to do it here, as each generated packet will do a sendRequest anyway. */ else if(rqueue.find(rt->rt_dst)) { sendRequest(rt->rt_dst, 0x00); } }}/* ===================================================================== Packet Reception Routines ===================================================================== */voidAODV::recv(Packet *p, Handler*) { struct hdr_cmn *ch = HDR_CMN(p); struct hdr_ip *ih = HDR_IP(p); assert(initialized()); /* //assert(p->incoming == 0); 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. */ //print_routing_table(); if(ch->ptype() == PT_AODV) { ih->ttl_ -= 1; recvAODV(p); return; } /* * Must be a packet I'm originating... */ if((ih->saddr() == index) && (ch->num_forwards() == 0)) { //Add the IP Header ch->size() += IP_HDR_LEN; ih->ttl_ = NETWORK_DIAMETER; } /* * I received a packet that I sent. Probably a routing loop. */ else if(ih->saddr() == index) { drop(p, DROP_RTR_ROUTE_LOOP); return; } /* * Packet I'm forwarding... */ else { // Check the TTL. If it is zero, then discard. if(--ih->ttl_ == 0) { if(DATA_PACKET(ch->ptype())) { fprintf(stderr, "\n%d - TTL=0 ==> DATA PACKET!!!\n\n", index); } drop(p, DROP_RTR_TTL); return; } } rt_resolve(p);}voidAODV::recvAODV(Packet *p) { struct hdr_aodv *ah = HDR_AODV(p); struct hdr_ip *ih = HDR_IP(p); assert(ih->sport() == RT_PORT); assert(ih->dport() == RT_PORT); /* * Incoming Packets. */ switch(ah->ah_type) { case AODVTYPE_RREQ: recvRequest(p); break; case AODVTYPE_RREP: recvReply(p); break; case AODVTYPE_RERR: recvError(p); break; case AODVTYPE_HELLO: recvHello(p); break; //My modification********************************************************// /* Implementing proactive gateway discovery... */ case AODVTYPE_ADVERTISEMENT: recvAdvertisement(p); break; //***********************************************************************// default: fprintf(stderr, "Invalid AODV type (%x)\n", ah->ah_type); exit(1); }}voidAODV::recvRequest(Packet *p) { struct hdr_ip *ih = HDR_IP(p); struct hdr_aodv_request *rq = HDR_AODV_REQUEST(p); aodv_rt_entry *rt; /* * Drop if: 1. I'm the source 2. I recently heard this request */ if(rq->rq_src == index) {#ifdef DEBUG //fprintf(stderr, "%d - got my own RREQ, drop it\n", index);#endif // DEBUG Packet::free(p); return; } if(id_lookup(rq->rq_src, rq->rq_bcast_id)) {#ifdef DEBUG //fprintf(stderr, "%d - discarding RREQ\n", index);#endif // DEBUG Packet::free(p); return; } /* * Cache the broadcast ID */ id_insert(rq->rq_src, rq->rq_bcast_id); /* * We are either going to forward the REQUEST or generate a REPLY. Before we * do anything, we make sure that the REVERSE route is in the route table. */ aodv_rt_entry *rt0; // rt0 is the reverse route rt0 = rtable.rt_lookup(rq->rq_src); if(rt0 == 0) { /* if not in the route table */ // Create an entry for the reverse route. rt0 = rtable.rt_add(rq->rq_src); } rt0->rt_expire = max(rt0->rt_expire, (CURRENT_TIME + REV_ROUTE_LIFE)); if((rq->rq_src_seqno > rt0->rt_seqno ) || ((rq->rq_src_seqno == rt0->rt_seqno) && (rq->rq_hop_count < rt0->rt_hops)) ) { // If we have a fresher sequence number or less #hops for the same sequence // number, update the rt entry. Else don't bother. rt_update(rt0, rq->rq_src_seqno, rq->rq_hop_count, ih->saddr(), max(rt0->rt_expire, (CURRENT_TIME + REV_ROUTE_LIFE)) ); if(rt0->rt_req_timeout > 0.0) { // Reset the soft state and // set expiry time to CURRENT_TIME + ACTIVE_ROUTE_TIMEOUT. // This is because route is used in the forward direction, // but only sources get benefited by this change. rt0->rt_req_cnt = 0; rt0->rt_req_timeout = 0.0; rt0->rt_req_last_ttl = rq->rq_hop_count; rt0->rt_expire = CURRENT_TIME + ACTIVE_ROUTE_TIMEOUT; } /* Find out whether any buffered packet can benefit from the * reverse route. * May need some change in the following code - Mahesh 09/11/99 */ assert (rt0->rt_flags == RTF_UP); Packet *buffered_pkt; while((buffered_pkt = rqueue.deque(rt0->rt_dst))) { if(rt0 && (rt0->rt_flags == RTF_UP)) { assert(rt0->rt_hops != INFINITY2); forward(rt0, buffered_pkt, NO_DELAY); } } } // End for putting reverse route in rt table /* * We have taken care of the reverse route stuff. * Now see whether we can send a route reply. */ rt = rtable.rt_lookup(rq->rq_dst); /* * 1. First check if I am the destination .. */ if(rq->rq_dst == index) {#ifdef DEBUG fprintf(stderr, "%d - destination sending RREP at %f s\n", index, CURRENT_TIME);#endif // DEBUG // Just to be safe, I use the max. Somebody may have // incremented the dst seqno. seqno = max(seqno, rq->rq_dst_seqno) + 1; if(seqno%2) seqno++; sendReply(rq->rq_src, // Destination IP address from RREQ message 1, // Hop Count index, // Dest IP Address seqno, // Dest Sequence Num MY_ROUTE_TIMEOUT, // Lifetime rq->rq_timestamp, // timestamp 0x00); //Flag Packet::free(p); } /* * 2. I am not the destination, but I may have a fresh enough route. * * My modification * I added the third condition so intermediate MNs don't send RREP to RREQs * for FN! If they do, the source thinks FN is a MN! */ else if(rt && (rt->rt_hops != INFINITY2) && (rt->rt_seqno >= rq->rq_dst_seqno) && rt->rt_nexthop != DEFAULT) {#ifdef DEBUG fprintf(stderr, "%d - Intermediate node sending RREP\n", index);#endif assert(rq->rq_dst == rt->rt_dst); //assert ((rt->rt_seqno%2) == 0); // is the seqno even? sendReply(rq->rq_src, // Destination IP address from RREQ message rt->rt_hops + 1, rq->rq_dst, rt->rt_seqno, (u_int32_t) (rt->rt_expire - CURRENT_TIME), rq->rq_timestamp, 0x00); // Insert nexthops to RREQ source and RREQ destination in the // precursor lists of destination and source respectively rt->pc_insert(rt0->rt_nexthop); // nexthop to RREQ source rt0->pc_insert(rt->rt_nexthop); // nexthop to RREQ destination // TODO: send grat RREP to dst if G flag set in RREQ //My comment*********************************// /* TODO: If I'm GW and I have a route to the destination (which is a MN), send a RREP_I besides the RREP packet! */ //*******************************************// Packet::free(p); } //My modification**********************************************************// /* * 3. I am not the destination, I don't have a route, but maybe I'm a gateway * and this is a RREQ_I packet destined to ALL_MANET_GW_MULTICAST. */ /* If receive RREQ_I && GW: send RREP_I If receive RREQ_I && !GW: forward RREQ_I (see else below) */ else if(rq->rq_flags == RREQ_IFLAG && index == thisnode->base_stn() && rq->rq_dst == ALL_MANET_GW_MULTICAST) {#ifdef DEBUG fprintf(stderr, "%d - GW received RREQ_I ==> GW sending RREP_I\n", index);#endif seqno = max(seqno, rq->rq_dst_seqno) + 1; if(seqno%2) seqno++; sendReply(rq->rq_src, //Address of the node who sent the RREQ 1, // Hop Count index, // Dest IP Address seqno, // Dest Sequence Num GWINFO_LIFETIME, //Lifetime, defined to 10 sec rq->rq_timestamp, //Timestamp, when the RREQ was sent RREP_IFLAG); //I Flag Packet::free(p); } /* * 4. I am not the destination, I don't have a route, this is not a RREQ_I * packet but maybe I'm a gateway. */ else if(rt == 0 && index == thisnode->base_stn()) {#ifdef DEBUG fprintf(stderr, "%d - GW sending RREP_I\n", index);#endif seqno = max(seqno, rq->rq_dst_seqno) + 1; if(seqno%2) seqno++; sendReply(rq->rq_src, //Address of the node who sent the RREQ 1, // Hop Count index, // Dest IP Address seqno, // Dest Sequence Num
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -