📄 aodv.cc
字号:
sendRequest(ih->daddr()); } else { // else drop the packet. We don't try to salvage anything // on an intermediate node. drop(p, DROP_RTR_NO_ROUTE); } } /* while */ } /* purge ifq */} /* rt_down function */voidAODV::rt_resolve(Packet *p){ struct hdr_cmn *ch = HDR_CMN(p); struct hdr_ip *ih = HDR_IP(p); 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->dst_); rt = rtable.rt_lookup(ih->daddr()); if(rt == 0) { // rt = rtable.rt_add(ih->dst_); rt = rtable.rt_add(ih->daddr()); } /* * If the route is up, forward the packet */ if(rt->rt_flags == RTF_UP) { forward(rt, p, NO_DELAY); } /* * A local repair is in progress. Buffer the packet. */ else if (rt->rt_flags == RTF_IN_REPAIR) { rqueue.enque(p); } /* * if I am the source of the packet, then do a Route Request. */ // else if(ih->src_ == index) { else if(ih->saddr() == index) { rqueue.enque(p); sendRequest(rt->rt_dst); } /* * I am trying to forward a packet for someone else to which * I don't have a route. */ else {#ifndef ERROR_BROADCAST /* * For now, drop the packet and send triggered reply upstream. * Now the unsolicited route replies are broadcast to upstream * neighbors - Mahesh 09/11/99 */ sendTriggeredReply(ch->prev_hop_,rt->rt_dst, rt->rt_seqno);#else sendTriggeredReply(rt->rt_dst, rt->rt_seqno);#endif drop(p, DROP_RTR_NO_ROUTE); }}voidAODV::rt_purge(){ 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 ((rt->rt_flags == RTF_UP) && (rt->rt_expire < now)) { // if a valid route has expired, purge all packets from // send buffer and invalidate the route. while((p = rqueue.deque(rt->rt_dst))) {#ifdef DEBUG fprintf(stderr, "%s: calling drop()\n", __FUNCTION__);#endif // drop(p, DROP_RTR_RTEXPIRE); drop(p, DROP_RTR_NO_ROUTE); } rt->rt_flags = RTF_DOWN; /* LIST_REMOVE(rt, rt_link); delete rt; */ } else if (rt->rt_flags == RTF_UP) { // 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. while((p = rqueue.deque(rt->rt_dst))) { forward (rt, p, delay); delay += ARP_DELAY; } } 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); if(ch->ptype() == PT_AODV) { ih->ttl_ -= 1; recvAODV(p); return; } /* * Must be a packet I'm originating... */ // if(ih->src_ == index && ch->num_forwards() == 0) { 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->src_ == index) { 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) { drop(p, DROP_RTR_TTL); return; } } rt_resolve(p);}voidAODV::recvAODV(Packet *p){ struct hdr_ip *ih = HDR_IP(p); struct hdr_aodv *ah = HDR_AODV(p); //assert(ih->sport_ == RT_PORT); //assert(ih->dport_ == RT_PORT); assert(ih->sport() == RT_PORT); assert(ih->dport() == RT_PORT); /* * Incoming Packets. */ switch(ah->ah_type) { case AODVTYPE_HELLO: recvHello(p); break; case AODVTYPE_RREQ: recvRequest(p); break; case AODVTYPE_RREP: recvReply(p); break; case AODVTYPE_UREP: recvTriggeredReply(p); break; default: fprintf(stderr, "Invalid AODV type (%x)\n", ah->ah_type); exit(1); }}voidAODV::recvRequest(Packet *p){ Node *thisnode; struct hdr_ip *ih = HDR_IP(p); struct hdr_aodv_request *rq = HDR_AODV_REQUEST(p); 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 Packet::free(p); return; } if (id_lookup(rq->rq_src,rq->rq_bcast_id) == ID_FOUND) {#ifdef DEBUG fprintf(stderr, "%s: discarding request\n", __FUNCTION__);#endif Packet::free(p); return; } /* * Cache the broadcast ID */ id_insert(rq->rq_src, rq->rq_bcast_id); rt = rtable.rt_lookup(rq->rq_dst); /* * 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. */ { rt_entry *rt0; // rt0 is the reverse route Packet *buffered_pkt; 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); } /* * Changed to make sure the expiry times are set * appropriately - Mahesh 09/11/99 */ if (rt0->rt_flags != RTF_UP) { // Route wasn't up 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; if (rq->rq_hop_count != INFINITY2) rt0->rt_req_last_ttl = rq->rq_hop_count; rt0->rt_expire = CURRENT_TIME + ACTIVE_ROUTE_TIMEOUT; } else { // Set expiry time to CURRENT_TIME + REV_ROUTE_LIFE rt0->rt_expire = CURRENT_TIME + REV_ROUTE_LIFE; } // In any case, change your entry rt0->rt_flags = RTF_UP;#ifdef ERROR_BROADCAST rt0->error_propagate_counter = 0; // Mahesh 09/11/99#endif rt0->rt_hops = rq->rq_hop_count; rt0->rt_seqno = rq->rq_src_seqno; // rt0->rt_nexthop = ih->src_; rt0->rt_nexthop = ih->saddr(); } else // Route was up if ((rq->rq_src_seqno > rt0->rt_seqno ) || ((rt0->rt_seqno == rq->rq_src_seqno) && (rt0->rt_hops > rq->rq_hop_count))) { // If we have a fresher seq no. or lesser #hops for the // same seq no., update the rt entry. Else don't bother. rt0->rt_expire = max(rt0->rt_expire, CURRENT_TIME + REV_ROUTE_LIFE); rt0->rt_flags = RTF_UP;#ifdef ERROR_BROADCAST // Only if next hop is changed // rt0->error_propagate_counter = 0; Mahesh 09/11/99#endif rt0->rt_hops = rq->rq_hop_count; rt0->rt_seqno = rq->rq_src_seqno; //rt0->rt_nexthop = ih->src_; rt0->rt_nexthop = ih->saddr(); } /* Find out whether any buffered packet can benefit from the * reverse route. */ assert (rt0->rt_flags == RTF_UP); while ((buffered_pkt = rqueue.deque(rt0->rt_dst))) { if (rt0 && (rt0->rt_flags == RTF_UP)) /* need to do the above check again, * as deque has side-effects */ 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. */ // First check if I am the destination .. if(rq->rq_dst == index) {#ifdef DEBUG fprintf(stderr, "%d - %s: destination sending reply\n", index, __FUNCTION__);#endif // Just to be safe, I use the max. Somebody may have // incremented the dst seqno. // seqno = max((unsigned)seqno, (unsigned)rq->rq_dst_seqno) + 1; sendReply(rq->rq_src, // IP Destination 0, // Hop Count index, // Dest IP Address seqno, // Dest Sequence Num MY_ROUTE_TIMEOUT, // Lifetime rq->rq_timestamp); // timestamp Packet::free(p); // Sending replying, I am in the route thisnode = Node::get_node_by_address(index); if (thisnode->powersaving()) { thisnode->set_node_sleep(0); thisnode->set_node_state(INROUTE); } } // I am not the destination, but I may have a fresh enough route. else if (rt && (rt->rt_flags == RTF_UP) && (rt->rt_seqno >= rq->rq_dst_seqno)) { sendReply(rq->rq_src, rt->rt_hops + 1, rq->rq_dst, rt->rt_seqno, (u_int32_t) (rt->rt_expire - CURRENT_TIME), rq->rq_timestamp); Packet::free(p); thisnode = Node::get_node_by_address(index); if (thisnode->powersaving()) { thisnode->set_node_sleep(0); thisnode->set_node_state(INROUTE); } } /* * Can't reply. So forward the Route Request */ else { //ih->dst_ = IP_BROADCAST; //ih->src_ = index; ih->daddr() = IP_BROADCAST; ih->saddr() = index; rq->rq_hop_count += 1; forward((rt_entry*) 0, p, DELAY); thisnode = Node::get_node_by_address(index); if (thisnode->powersaving()) { thisnode->set_node_sleep(0); thisnode->set_node_state(WAITING); } }}voidAODV::recvReply(Packet *p){ Node *thisnode; struct hdr_cmn *ch = HDR_CMN(p); struct hdr_ip *ih = HDR_IP(p); struct hdr_aodv_reply *rp = HDR_AODV_REPLY(p); rt_entry *rt; // char suppress_reply = 0; double delay = 0.0;#ifdef DEBUG fprintf(stderr, "%d - %s: received a REPLY\n", index, __FUNCTION__);#endif /* * Handle "Route Errors" separately... */ if(rp->rp_hop_count == INFINITY2) { recvTriggeredReply(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 // the dest of the reply, which is the src of the data packets. if((rt = rtable.rt_lookup(rp->rp_dst))) { // reset the soft state rt->rt_req_cnt = 0; rt->rt_req_timeout = 0.0; if (rp->rp_hop_count != INFINITY2) rt->rt_req_last_ttl = rp->rp_hop_count; } /* * 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 */ if ((rt->rt_flags != RTF_UP) || // no route before ((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 equal route // Update the rt entry rt->rt_expire = CURRENT_TIME + rp->rp_lifetime;#ifdef ERROR_BROADCAST if (rt->rt_flags != RTF_UP) // or next hop changed rt->error_propagate_counter = 0; // Mahesh 09/11/99#endif rt->rt_flags = RTF_UP; rt->rt_hops = rp->rp_hop_count; rt->rt_seqno = rp->rp_dst_seqno; rt->rt_nexthop = ch->prev_hop_;#ifdef AODV_LINK_LAYER_DETECTION rt->rt_errors = 0; rt->rt_error_time = 0.0;#endif // if (ih->dst_ == index) { // If I am the original source if (ih->daddr() == index) { //assert(rp->rp_hop_count); // 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; } } /* * If reply is for me, discard it.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -