📄 aodv.cc
字号:
*/ //if(ih->dst_ == index) { if(ih->daddr() == index) { Packet::free(p); } /* * Otherwise, forward the Route Reply. */ else { // Find the rt entry //rt_entry *rt0 = rtable.rt_lookup(ih->dst_); rt_entry *rt0 = rtable.rt_lookup(ih->daddr()); // If the rt is up, forward if(rt0 && (rt0->rt_flags == RTF_UP)) {#ifdef ERROR_BROADCAST rt_entry *rt_dst = rtable.rt_lookup(rp->rp_dst); (rt_dst->error_propagate_counter)++; // Mahesh 09/11/99#endif rp->rp_hop_count += 1; forward(rt0, p, NO_DELAY); thisnode = Node::get_node_by_address(index); if (thisnode->powersaving()) { thisnode->set_node_sleep(0); thisnode->set_node_state(INROUTE); } } else { // I don't know how to forward .. drop the reply. #ifdef DEBUG fprintf(stderr, "%s: droping Route Reply\n", __FUNCTION__);#endif drop(p, DROP_RTR_NO_ROUTE); } } /* * Send all packets queued in the sendbuffer destined for * this destination. * XXX - observe the "second" use of p. */ while((p = rqueue.deque(rt->rt_dst))) { if(rt->rt_flags == RTF_UP) { // Delay them a little to help ARP. Otherwise ARP // may drop packets. -SRD 5/23/99 forward(rt, p, delay); delay += ARP_DELAY; } }}voidAODV::recvTriggeredReply(Packet *p){ struct hdr_ip *ih = HDR_IP(p); struct hdr_aodv_reply *rp = HDR_AODV_REPLY(p); rt_entry *rt = rtable.rt_lookup(rp->rp_dst); if(rt && (rt->rt_flags == RTF_UP)) { // We bring down the route if the source of the // triggered reply is my next hop. We don't check // sequence numbers (!!!) as this next hop won't // forward packets for me anyways. // if (rt->rt_nexthop == ih->src_) { if (rt->rt_nexthop == ih->saddr()) { rt->rt_seqno = rp->rp_dst_seqno; rt_down(rt); } } Packet::free(p);}voidAODV::recvHello(Packet *p){ struct hdr_aodv_reply *rp = HDR_AODV_REPLY(p); Neighbor *nb; /* * XXX: I use a separate TYPE for hello messages rather than * a bastardized Route Reply. */ nb = nb_lookup(rp->rp_dst); if(nb == 0) { nb_insert(rp->rp_dst); } else { nb->nb_expire = CURRENT_TIME + (1.5 * ALLOWED_HELLO_LOSS * HELLO_INTERVAL); } Packet::free(p);}/* ====================================================================== Packet Transmission Routines ===================================================================== */voidAODV::forward(rt_entry *rt, Packet *p, double delay){ struct hdr_cmn *ch = HDR_CMN(p); struct hdr_ip *ih = HDR_IP(p); Neighbor *nb; if(ih->ttl_ == 0) {#ifdef DEBUG fprintf(stderr, "%s: calling drop()\n", __PRETTY_FUNCTION__);#endif drop(p, DROP_RTR_TTL); return; }#ifndef ERROR_BROADCAST /* * Keep the "official" Neighbor List up-to-date. */ if(nb_lookup(ch->prev_hop_) == 0) { nb_insert(ch->prev_hop_); }#endif if(rt) { // If it is a unicast packet to be forwarded assert(rt->rt_flags == RTF_UP); rt->rt_expire = CURRENT_TIME + ACTIVE_ROUTE_TIMEOUT;#ifndef ERROR_BROADCAST /* * Need to maintain the per-route Neighbor List. This is * kept separate from the Neighbor list that is the list * of ACTIVE neighbors. */ if(rt->nb_lookup(ch->prev_hop_) == 0) { rt->nb_insert(ch->prev_hop_); } // set the expiry times nb = rt->nb_lookup(ch->prev_hop_); nb->nb_expire = CURRENT_TIME + ACTIVE_ROUTE_TIMEOUT;#endif ch->prev_hop_ = index; ch->next_hop_ = rt->rt_nexthop; ch->addr_type() = NS_AF_INET; ch->direction() = hdr_cmn::DOWN; //important: change the packet's direction } else { // if it is a broadcast packet assert(ch->ptype() == PT_AODV); //assert(ih->dst_ == (nsaddr_t) IP_BROADCAST); assert(ih->daddr() == (nsaddr_t) IP_BROADCAST); ch->addr_type() = NS_AF_NONE; ch->direction() = hdr_cmn::DOWN; } //if (ih->dst_ == (nsaddr_t) IP_BROADCAST) { if (ih->daddr() == (nsaddr_t) IP_BROADCAST) { // If it is a broadcast packet assert(rt == 0); /* * Jitter the sending of broadcast packets by 10ms */ Scheduler::instance().schedule(target_, p, 0.01 * Random::uniform()); } else // Not a broadcast packet if(delay > 0.0) { Scheduler::instance().schedule(target_, p, delay); } else { // Not a broadcast packet, no delay, send immediately //target_->recv(p, (Handler*) 0); Scheduler::instance().schedule(target_, p, 0.); }}voidAODV::sendRequest(nsaddr_t dst){Node *thisnode = Node::get_node_by_address(index);// Allocate a RREQ packet Packet *p = Packet::alloc();struct hdr_cmn *ch = HDR_CMN(p);struct hdr_ip *ih = HDR_IP(p);struct hdr_aodv_request *rq = HDR_AODV_REQUEST(p);rt_entry *rt = rtable.rt_lookup(dst); assert(rt); /* * Rate limit sending of Route Requests. We are very conservative * about sending out route requests. */ if ((rt->rt_flags == RTF_UP) || (rt->rt_req_timeout > CURRENT_TIME)) return; // rt_req_cnt is the no. of times we did network-wide broadcast // RREQ_RETRIES is the maximum number we will allow before // going to a long timeout. if (rt->rt_req_cnt > RREQ_RETRIES) { rt->rt_req_timeout = CURRENT_TIME + MAX_RREQ_TIMEOUT; rt->rt_req_cnt = 0; return; }#ifdef DEBUG fprintf(stderr, "(%2d) - %2d sending Route Request, dst: %d\n", ++route_request, index, rt->rt_dst);#endif // set node into active state and remain it for MAX_RREQ_TIMEOUT if (thisnode->powersaving()) { thisnode->set_node_sleep(0); thisnode->set_node_state(WAITING); } // Fill out the RREQ packet // ch->uid() = 0; ch->ptype() = PT_AODV; ch->size() = IP_HDR_LEN + sizeof(*rq); ch->iface() = -2; ch->error() = 0; ch->addr_type() = NS_AF_NONE; ch->prev_hop_ = index; // AODV hack /* ih->src_ = index; ih->dst_ = IP_BROADCAST; ih->sport_ = RT_PORT; ih->dport_ = RT_PORT; */ ih->saddr() = index; ih->daddr() = IP_BROADCAST; ih->sport() = RT_PORT; ih->dport() = RT_PORT; // Determine the TTL to be used this time. if (0 == rt->rt_req_last_ttl) { // first time query broadcast ih->ttl_ = TTL_START; } else { // Expanding ring search. if (rt->rt_req_last_ttl < TTL_THRESHOLD) ih->ttl_ = rt->rt_req_last_ttl + TTL_INCREMENT; else { // network-wide broadcast ih->ttl_ = NETWORK_DIAMETER; rt->rt_req_cnt += 1; } } // PerHopTime is the roundtrip time per hop for route requests. // The factor 2.0 is just to be safe .. SRD 5/22/99 // Also note that we are making timeouts to be larger if we have // done network wide broadcast before. rt->rt_req_timeout = 2.0 * (double) ih->ttl_ * PerHopTime(rt); if (rt->rt_req_cnt > 0) rt->rt_req_timeout *= rt->rt_req_cnt; //printf("timeout=%f\n",rt->rt_req_timeout); rt->rt_req_timeout += CURRENT_TIME; // Don't let the timeout to be too large, however .. SRD 6/8/99 if (rt->rt_req_timeout > CURRENT_TIME + MAX_RREQ_TIMEOUT) rt->rt_req_timeout = CURRENT_TIME + MAX_RREQ_TIMEOUT; rt->rt_expire = 0;#ifdef DEBUG fprintf(stderr, "(%2d) - %2d sending Route Request, dst: %d, tout %f ms\n", ++route_request, index, rt->rt_dst, rt->rt_req_timeout - CURRENT_TIME);#endif // remember the TTL used for the next time rt->rt_req_last_ttl = ih->ttl_; // Fill up some more fields. rq->rq_type = AODVTYPE_RREQ; rq->rq_hop_count = 0; rq->rq_bcast_id = bid++; rq->rq_dst = dst; rq->rq_dst_seqno = (rt ? rt->rt_seqno : 0); rq->rq_src = index; rq->rq_src_seqno = seqno++; // Mahesh - 09/11/99 rq->rq_timestamp = CURRENT_TIME; // target_->recv(p, (Handler*) 0); Scheduler::instance().schedule(target_, p, 0.);}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);rt_entry *rt = rtable.rt_lookup(ipdst); assert(rt); // ch->uid() = 0; ch->ptype() = PT_AODV; ch->size() = IP_HDR_LEN + sizeof(*rp); ch->iface() = -2; ch->error() = 0; ch->addr_type() = NS_AF_INET; ch->next_hop_ = rt->rt_nexthop; ch->prev_hop_ = index; // AODV hack ch->direction() = hdr_cmn::DOWN; /* ih->src_ = index; ih->dst_ = ipdst; ih->sport_ = RT_PORT; ih->dport_ = RT_PORT; */ ih->saddr() = index; ih->daddr() = ipdst; ih->sport() = RT_PORT; ih->dport() = RT_PORT; ih->ttl_ = NETWORK_DIAMETER; 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_lifetime = lifetime; rp->rp_timestamp = timestamp; //target_->recv(p, (Handler*) 0); Scheduler::instance().schedule(target_, p, 0.);}#ifndef ERROR_BROADCASTvoidAODV::sendTriggeredReply(nsaddr_t ipdst, nsaddr_t rpdst, u_int32_t rpseq){ // 08/28/98 - added this extra check if(ipdst == 0 || ipdst == index) return; 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); // ch->uid() = 0; ch->ptype() = PT_AODV; ch->size() = IP_HDR_LEN + sizeof(*rp); ch->iface() = -2; ch->error() = 0; ch->addr_type() = NS_AF_NONE; ch->next_hop_ = 0; ch->prev_hop_ = index; // AODV hack /* ih->src_ = index; ih->dst_ = ipdst; ih->sport_ = RT_PORT; ih->dport_ = RT_PORT; */ ih->saddr() = index; ih->daddr() = ipdst; ih->sport() = RT_PORT; ih->dport() = RT_PORT; ih->ttl_ = 1; rp->rp_type = AODVTYPE_UREP; rp->rp_flags = 0x00; rp->rp_hop_count = INFINITY2; rp->rp_dst = rpdst; rp->rp_dst_seqno = rpseq; rp->rp_lifetime = 0; // XXX target_->recv(p, (Handler*) 0); }#elsevoidAODV::sendTriggeredReply(nsaddr_t rpdst, u_int32_t rpseq) {// Broadcast unsolicited route replies - Mahesh 09/11/99rt_entry *rt = rtable.rt_lookup(rpdst); if (rt->error_propagate_counter == 0) return;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); // ch->uid() = 0; ch->ptype() = PT_AODV; ch->size() = IP_HDR_LEN + sizeof(*rp); ch->iface() = -2; ch->error() = 0; ch->addr_type() = NS_AF_NONE; ch->next_hop_ = 0; ch->prev_hop_ = index; // AODV hack ih->src_ = index; ih->dst_ = IP_BROADCAST; ih->sport_ = RT_PORT; ih->dport_ = RT_PORT; ih->ttl_ = 1; rp->rp_type = AODVTYPE_UREP; rp->rp_flags = 0x00; rp->rp_hop_count = INFINITY2; rp->rp_dst = rpdst; rp->rp_dst_seqno = rpseq; rp->rp_lifetime = 0; //target_->recv(p, (Handler*) 0); // Do we need any jitter? Scheduler::instance().schedule(target_, p, 0.);}#endifvoidAODV::sendHello(){ Packet *p = Packet::alloc(); struct hdr_cmn *ch = HDR_CMN(p); struct hdr_ip *ih = HDR_IP(p); struct hdr_aodv_reply *rh = HDR_AODV_REPLY(p); // ch->uid() = 0; ch->ptype() = PT_AODV; ch->size() = IP_HDR_LEN + sizeof(*rh); ch->iface() = -2; ch->error() = 0; ch->addr_type() = NS_AF_NONE; ch->prev_hop_ = index; // AODV hack /* ih->src_ = index; ih->dst_ = IP_BROADCAST; ih->sport_ = RT_PORT; ih->dport_ = RT_PORT; */ ih->saddr() = index; ih->daddr() = IP_BROADCAST; ih->sport() = RT_PORT; ih->dport() = RT_PORT; ih->ttl_ = 1; rh->rp_type = AODVTYPE_HELLO; rh->rp_flags = 0x00; rh->rp_hop_count = 0; rh->rp_dst = index; rh->rp_dst_seqno = seqno; rh->rp_lifetime = (1 + ALLOWED_HELLO_LOSS) * HELLO_INTERVAL; target_->recv(p, (Handler*) 0);}/*====================================================================== Helper routines=======================================================================*/doubleAODV::PerHopTime(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);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -