⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aodv.cc

📁 一个无线自组网aodv路由的扩展版---AOMDV(多径路由协议)。
💻 CC
📖 第 1 页 / 共 4 页
字号:
 	seqno += 2; 	assert ((seqno%2) == 0); 	rq->rq_src_seqno = seqno; 	rq->rq_timestamp = CURRENT_TIME; 	Scheduler::instance().schedule(target_, p, 0.);}doubleAODV::PerHopTime(aodv_rt_entry *rt) {int num_non_zero = 0, i;double total_latency = 0.0; if (!rt)   return ((double) NODE_TRAVERSAL_TIME );	 for (i=0; i < MAX_HISTORY; i++) {   if (rt->rt_disc_latency[i] > 0.0) {      num_non_zero++;      total_latency += rt->rt_disc_latency[i];   } } if (num_non_zero > 0)   return(total_latency / (double) num_non_zero); else   return((double) NODE_TRAVERSAL_TIME);}#ifndef AOMDVvoidAODV::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  */ 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);   }     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+1, ih->src_,     	       max(rt0->rt_expire, (CURRENT_TIME + REV_ROUTE_LIFE)) );     // Reset the soft state     rt0->rt_req_timeout = 0.0;      rt0->rt_req_last_ttl = 0;     rt0->rt_req_cnt = 0;     /* Find out whether any buffered packet can benefit from the       * reverse route.      */     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 != INFINITY);         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); // 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 // DEBUG                  // Just to be safe, I use the max. Somebody may have   // incremented the dst seqno.   if (seqno < rq->rq_dst_seqno)  	seqno = max(seqno, rq->rq_dst_seqno)+1;   if (seqno%2) seqno++;   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); } // I am not the destination, but I may have a fresh enough route. else if (rt && (rt->rt_hops != INFINITY) && 	  	(rt->rt_seqno >= rq->rq_dst_seqno) ) {   assert (rt->rt_flags == RTF_UP);   assert(rq->rq_dst == rt->rt_dst);   assert ((rt->rt_seqno%2) == 0);	// is the seqno even?   // CHANGE   rt->rt_error = true;	   // CHANGE   sendReply(rq->rq_src,             rt->rt_hops,             rq->rq_dst,             rt->rt_seqno,             rt->rt_expire - CURRENT_TIME,             rq->rq_timestamp);   Packet::free(p); } /*  * Can't reply. So forward the  Route Request  */ else {   ih->src_ = index;   ih->dst_ = 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::sendReply(nsaddr_t ipdst, u_int32_t hop_count, nsaddr_t rpdst,                u_int32_t rpseq, u_int32_t lifetime, double timestamp) {Packet *p = Packet::alloc();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 = rtable.rt_lookup(ipdst);#ifdef DEBUGfprintf(stderr, "sending Reply from %d at %.2f\n", index, Scheduler::instance().clock());#endif // DEBUG assert(rt); rp->rp_type = AODVTYPE_RREP; //rp->rp_flags = 0x00; rp->rp_hop_count = hop_count; rp->rp_dst = rpdst; rp->rp_dst_seqno = rpseq; rp->rp_src = index; rp->rp_lifetime = lifetime; rp->rp_timestamp = timestamp;    // ch->uid() = 0; ch->ptype() = PT_AODV; ch->size() = IP_HDR_LEN + rp->size(); ch->iface() = -2; ch->error() = 0; ch->addr_type() = AF_INET; ch->next_hop_ = rt->rt_nexthop; ch->xmit_failure_ = aodv_rt_failed_callback; ch->xmit_failure_data_ = (void*) this; ih->src_ = index; ih->dst_ = ipdst; ih->sport_ = RT_PORT; ih->dport_ = RT_PORT; ih->ttl_ = NETWORK_DIAMETER; Scheduler::instance().schedule(target_, p, 0.);}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 fprintf(stderr, "%d - %s: received a REPLY\n", index, __FUNCTION__);#endif // DEBUG /*  *  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.         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  */ if ( (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   rt_update(rt, rp->rp_dst_seqno, rp->rp_hop_count+1,		rp->rp_src, max(rt->rt_expire, (CURRENT_TIME + rp->rp_lifetime)));  // reset the soft state  rt->rt_req_timeout = 0.0;   rt->rt_req_last_ttl = 0;  rt->rt_req_cnt = 0;    if (ih->dst_ == index) { // If I am the original source  // Update the route discovery latency statistics  // rp->rp_timestamp is the time of request origination		#ifdef DYNAMIC_RREQ_RETRY_TIMEOUT  if (rp->rp_type == AODVTYPE_RREP) {    rt->rt_disc_latency[rt->hist_indx] = (CURRENT_TIME - rp->rp_timestamp)                                         / (double) (rp->rp_hop_count+1);    // increment indx for next time    rt->hist_indx = (rt->hist_indx + 1) % MAX_HISTORY;  }#endif DYNAMIC_RREQ_RETRY_TIMEOUT  }	  /*   * Send all packets queued in the sendbuffer destined for   * this destination.    */  Packet *buf_pkt;  while((buf_pkt = rqueue.deque(rt->rt_dst))) {    if(rt->rt_hops != INFINITY) {      assert (rt->rt_flags == RTF_UP);      forward(rt, buf_pkt, NO_DELAY);    // Delay them a little to help ARP. Otherwise ARP     // may drop packets. -SRD 5/23/99      // delay += ARP_DELAY;    }  } } else if (rt->rt_flags != RTF_UP) { // do not send a reply unless there is a forward path  suppress_reply = 1; }	 /*  * If reply is for me, discard it.  */ if(ih->dst_ == index || suppress_reply) {   Packet::free(p); } /*  * Otherwise, forward the Route Reply.  */ else { // Find the rt entry   aodv_rt_entry *rt0 = rtable.rt_lookup(ih->dst_);   // If the rt is up, forward   if(rt0 && (rt0->rt_hops != INFINITY)) {     assert (rt0->rt_flags == RTF_UP);     rp->rp_hop_count += 1;     rp->rp_src = index;     // CHANGE     rt->rt_error = true;	     // CHANGE     forward(rt0, p, NO_DELAY);   }   else {   // I don't know how to forward .. drop the reply. #ifdef DEBUG     fprintf(stderr, "%s: droping Route Reply\n", __FUNCTION__);#endif // DEBUG     drop(p, DROP_RTR_NO_ROUTE);   } }}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;}#endif AOMDV/* * Route maintenance *//*  Link Failure Management Functions*//* * This routine is invoked when the link-layer reports a route failed. */voidAODV::rt_ll_failed(Packet *p) {struct hdr_cmn *ch = HDR_CMN(p);struct hdr_ip *ih = HDR_IP(p);nsaddr_t broken_nbr = ch->next_hop_;#ifndef AODV_LINK_LAYER_DETECTION drop(p, DROP_RTR_MAC_CALLBACK);#else  /*  * Non-data packets and Broadcast Packets can be dropped.  */  //if ( !DATA_PACKET(ch->ptype()) ||  //     ((u_int32_t) ih->dst_ == IP_BROADCAST) ||  //     (broken_nbr == 0) ) {  //  drop(p, DROP_RTR_MAC_CALLBACK);  //  return;  //} /*  * Broadcast Packets can be dropped.  */  if ( ((u_int32_t) ih->dst_ == IP_BROADCAST) ||       (broken_nbr == 0) ) {    drop(p, DROP_RTR_MAC_CALLBACK);    return;  }  log_link_broke(p);  /*  if((rt = rtable.rt_lookup(ih->dst_)) == 0) {    drop(p, DROP_RTR_MAC_CALLBACK);    return;  }  */  log_link_del(ch->next_hop_);#ifdef AODV_LOCAL_REPAIR  /* if the broken link is closer to the dest than source,      attempt a local repair. Otherwise, bring down the route. */  if (ch->num_forwards() > rt->rt_hops) {    local_rt_repair(rt, p); // local repair    // retrieve all the packets in the ifq using this link,    // queue the packets for which local repair is done,     return;  }  else	#endif // LOCAL REPAIR	  {    handle_link_failure(broken_nbr);#ifdef AOMDV_PACKET_SALVAGING    if ( !DATA_PACKET(ch->ptype()) ) drop(p, DROP_RTR_MAC_CALLBACK);    else {    // salvage the packet using an alternate path if available.    aodv_rt_entry *rt = rtable.rt_lookup(ih->dst_);    	if ( rt && (rt->rt_flags == RTF_UP) && (ch->aomdv_salvage_count_ < AOMDV_MAX_SALVAGE_COUNT) ) {		ch->aomdv_salvage_count_ += 1;	       	forward(rt, p, NO_DELAY);	}	else drop(p, DROP_RTR_MAC_CALLBACK);    }    while((p = ifqueue->prq_get_nexthop(broken_nbr))) {    struct hdr_cmn *ch = HDR_CMN(p);    struct hdr_ip *ih = HDR_IP(p);    	if ( !DATA_PACKET(ch->ptype()) ) drop(p, DROP_RTR_MAC_CALLBACK);    	else {    	// salvage the packet using an alternate path if available.    	aodv_rt_entry *rt = rtable.rt_lookup(ih->dst_);    		if ( rt && (rt->rt_flags == RTF_UP) && (ch->aomdv_salvage_count_ < AOMDV_MAX_SALVAGE_COUNT) ) {			ch->aomdv_salvage_count_ += 1;		       	forward(rt, p, NO_DELAY);		}		else drop(p, DROP_RTR_MAC_CALLBACK);	}    }	#else // NO PACKET SALVAGING    drop(p, DROP_RTR_MAC_CALLBACK);    while((p = ifqueue->prq_get_nexthop(broken_nbr))) {    	drop(p, DROP_RTR_MAC_CALLBACK);    }	#endif // NO PACKET SALVAGING  }#endif // LINK LAYER DETECTION}#ifndef AOMDVvoidAODV::handle_link_failure(nsaddr_t id, bool error=true) {aodv_rt_entry *rt, *rtn;Packet *rerr = Packet::alloc();struct hdr_aodv_error *re = HDR_AODV_ERROR(rerr); re->DestCount = 0; for(rt = rtable.head(); rt; rt = rtn) {  // for each rt entry   rtn = rt->rt_link.le_next;    if ((rt->rt_hops != INFINITY) && (rt->rt_nexthop == id) ) {     assert (rt->rt_flags == RTF_UP);     assert((rt->rt_seqno%2) == 0);     rt->rt_seqno++;     // CHANGE     if (rt->rt_error) {     	re->unreachable_dst[re->DestCount] = rt->rt_dst;     	re->unreachable_dst_seqno[re->DestCount] = rt->rt_seqno;#ifdef DEBUG     fprintf(stderr, "%s(%f): %d\t(%d\t%u\t%d)\n", __FUNCTION__, CURRENT_TIME,		     index, re->unreachable_dst[re->DestCount],		     re->unreachable_dst_seqno[re->DestCount], rt->rt_nexthop);#endif // DEBUG     	re->DestCount += 1;	rt->rt_error = false;     }     // CHANGE     rt_down(rt);   } }    if ( (re->DestCount > 0) && (error) ) {#ifdef DEBUG   fprintf(stdout, "%s(%f): %d\tsending RERR...\n", __FUNCTION__, CURRENT_TIME, index);#endif // DEBUG   sendError(rerr, false); } else {   Packet::free(rerr); }}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 = INFINITY;  rt->rt_flags = RTF_DOWN;  rt->rt_nexthop = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -