📄 aodv.cc
字号:
voidAODV::rt_update(aodv_rt_entry *rt, u_int32_t seqnum, u_int16_t metric, nsaddr_t nexthop, double expire_time) { rt->rt_seqno = seqnum; rt->rt_hops = metric; rt->rt_flags = RTF_UP; rt->rt_nexthop = nexthop; rt->rt_expire = expire_time;#ifdef PREDICTION rt->rt_prevnode_warning = 0;#endif#ifdef IMPROVEMENT rt->rt_retry_pid = 0; rt->rt_retry_times = 0;#endif}voidAODV::rt_down(aodv_rt_entry *rt) { /* * Make sure that you don't "down" a route more than once. */ if(rt->rt_flags == RTF_DOWN) { return; } // assert (rt->rt_seqno%2); // is the seqno odd? rt->rt_last_hop_count = rt->rt_hops; rt->rt_hops = INFINITY2; rt->rt_flags = RTF_DOWN; rt->rt_nexthop = 0; rt->rt_expire = 0;} /* rt_down function *//* Route Handling Functions*/voidAODV::rt_resolve(Packet *p) {struct hdr_cmn *ch = HDR_CMN(p);struct hdr_ip *ih = HDR_IP(p);aodv_rt_entry *rt; /* * Set the transmit failure callback. That * won't change. */ ch->xmit_failure_ = aodv_rt_failed_callback; ch->xmit_failure_data_ = (void*) this; rt = rtable.rt_lookup(ih->daddr()); if(rt == 0) { rt = rtable.rt_add(ih->daddr()); } /* * If the route is up, forward the packet */ //if (ch->uid() == 32 && index == 3) printf("---------rt flag is %d, %.9f\n", rt->rt_flags, CURRENT_TIME); if(rt->rt_flags == RTF_UP) { assert(rt->rt_hops != INFINITY2);#ifdef PREDICTION double breakTime = 2000.0; if (ch->num_forwards() != 0 && ch->next_hop_ == index){ Node *currentNode = Node::get_node_by_address(index); breakTime = currentNode->getTime(ch->prev_hop_); if (breakTime < 2000.0 && breakTime > CURRENT_TIME && (breakTime - CURRENT_TIME < PREDICTION_TIME_FOR_UNICAST) && (rt->rt_prevnode_warning == 0)){ //printf("\nPREDICTION:: at %.9f on node %d prev node %d , dst %d, will break at %.9f\n", CURRENT_TIME, index, ch->prev_hop_, ih->daddr(), breakTime); sendLPW(ch->prev_hop_, breakTime); rt->rt_prevnode_warning ++; } }#endif forward(rt, p, NO_DELAY); }#ifdef PREDICTION else if (rt->rt_flags == RTF_PREDICTION || rt->rt_flags == RTF_P_LINK) { if (rt->rt_expire <= CURRENT_TIME){ rt->rt_seqno++; rt_down(rt); if (index == ih->saddr()) { rqueue.enque(p); sendRequest(ih->daddr()); } else forward(rt, p, NO_DELAY); //because this is only prediction broken time, try to forward it anyway. } else { forward(rt,p,NO_DELAY); if (index == ih->saddr()) { sendRequest(ih->daddr()); } } }#endif /* * if I am the source of the packet, then do a Route Request. */ else if(ih->saddr() == index) { rqueue.enque(p); sendRequest(rt->rt_dst); } /* * A local repair is in progress. Buffer the packet. */ else if (rt->rt_flags == RTF_IN_REPAIR) { rqueue.enque(p); } /* * I am trying to forward a packet for someone else to which * I don't have a route. */ else {#ifdef MULTICAST sendMACT(rt->rt_dst, MACT_P, 0, ch->prev_hop_);#endif Packet *rerr = Packet::alloc(); struct hdr_aodv_error *re = HDR_AODV_ERROR(rerr); /* * For now, drop the packet and send error upstream. * Now the route errors are broadcast to upstream * neighbors - Mahesh 09/11/99 */ assert (rt->rt_flags == RTF_DOWN); re->DestCount = 0; re->unreachable_dst[re->DestCount] = rt->rt_dst; re->unreachable_dst_seqno[re->DestCount] = rt->rt_seqno; re->DestCount += 1;#ifdef DEBUG fprintf(stderr, "%s: sending RERR...\n", __FUNCTION__);#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; for(rt = rtable.head(); rt; rt = rtn) { // for each rt entry rtn = rt->rt_link.le_next; if (#ifdef PREDICTION (rt->rt_flags == RTF_UP || rt->rt_flags == RTF_P_LINK || rt->rt_flags == RTF_PREDICTION)#else (rt->rt_flags == RTF_UP)#endif && (rt->rt_expire < now)) { // if a valid route has expired, purge all packets from // send buffer and invalidate the route. 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); } else if #ifdef PREDICTION (rt->rt_flags == RTF_UP || rt->rt_flags == RTF_P_LINK || rt->rt_flags == RTF_PREDICTION)#else (rt->rt_flags == RTF_UP)#endif {#ifdef PREDICTION if (rt->rt_flags == RTF_UP){#endif // If the route is not expired, // and there are packets in the sendbuffer waiting, // forward them. This should not be needed, but this extra // check does no harm. assert(rt->rt_hops != INFINITY2); while((p = rqueue.deque(rt->rt_dst))) { forward(rt, p, delay); delay += ARP_DELAY; }#ifdef PREDICTION }#endif } else if (rqueue.find(rt->rt_dst)) // 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. sendRequest(rt->rt_dst); }}/* 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); // 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.#ifdef MULTICAST if(ih->saddr() != index || ch->num_forwards() != 0) { AODV_Neighbor *nb = nb_lookup(ch->prev_hop_); if(nb == 0) { nb_insert(ch->prev_hop_); } else { nb->nb_expire = CURRENT_TIME + ALLOWED_HELLO_LOSS * MaxHelloInterval; } }#endif 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; // Added by Parag Dadhania && John Novatnack to handle broadcasting if ( (u_int32_t)ih->daddr() != IP_BROADCAST) ih->ttl_ = NETWORK_DIAMETER;} /* * I received a packet that I sent. Probably * a routing loop. */else if(ih->saddr() == index) { #ifdef MULTICAST if (ih->daddr() < IP_MULTICAST) drop(p, DROP_RTR_ROUTE_LOOP); else Packet::free(p);#else drop(p, DROP_RTR_ROUTE_LOOP);#endif return; } /* * Packet I'm forwarding... */ else {#ifdef MULTICAST ih->ttl_--;#else /* * Check the TTL. If it is zero, then discard. */ if(--ih->ttl_ == 0) { drop(p, DROP_RTR_TTL); return; }#endif }#ifdef MULTICAST if ((u_int32_t)ih->daddr() < IP_MULTICAST) rt_resolve(p); else if ((u_int32_t)ih->daddr() == IP_BROADCAST) forward((aodv_rt_entry*) 0, p, NO_DELAY); else mt_resolve(p);#else// Added by Parag Dadhania && John Novatnack to handle broadcasting if ( (u_int32_t)ih->daddr() != IP_BROADCAST) rt_resolve(p); else forward((aodv_rt_entry*) 0, p, NO_DELAY);#endif}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:#ifdef MULTICAST Packet::free(p);#else recvHello(p);#endif break;#ifdef PREDICTION case AODVTYPE_LPW: { struct hdr_aodv_lpw *rp = HDR_AODV_LPW(p); recvLPW(ih->saddr(), rp->breakTime); Packet::free(p); } break; case AODVTYPE_RPE: recvRPE(p); break; case AODVTYPE_LINK_RREQ: recvRequest_P(p); break;#endif#ifdef MULTICAST case AODVTYPE_MACT: recvMACT(p); break; case AODVTYPE_GRPH: recvMGRPH(p); break; case AODVTYPE_WARN: recvMWARN(p); break;#endif 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: * - I'm the source * - I recently heard this request. */ if(rq->rq_src == index) {#ifdef DEBUG fprintf(stderr, "%s: got my own REQUEST\n", __FUNCTION__);#endif // DEBUG Packet::free(p); return; } if (id_lookup(rq->rq_src, rq->rq_bcast_id)) {#ifdef DEBUG fprintf(stderr, "%s: discarding request\n", __FUNCTION__);#endif // DEBUG Packet::free(p); return; } /* * Cache the broadcast ID */#ifndef PREDICTION id_insert(rq->rq_src, rq->rq_bcast_id);#endif /* * 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); }#ifdef PREDICTION if (rt0->rt_flags == RTF_P_LINK){ Packet::free(p); return; } else id_insert(rq->rq_src, rq->rq_bcast_id);#endif 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 seq no. or lesser #hops for the // same seq no., 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; double delay=0.0; 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. */#ifdef MULTICAST if (rq->rq_dst >= IP_MULTICAST){ if (rq->rq_flags != RREQ_NO_FLAG && (CURRENT_TIME - rq->rq_timestamp) > 2*RREP_WAIT_TIME) {Packet::free(p); return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -