📄 cbrpagent.cc
字号:
trace("cbrp RREQ%d: ignored %d, route(%s)",myaddr_,p_adj->neighbor_cluster,p.route.dump());#endif p_adj= p_adj->next; continue; } // i don't send to 3-hop neighbor head in cluster adjacency table if it is within 2-hop range if (ntable->GetAdjEntry(p_adj->neighbor_cluster,1)) {#ifdef CBRP_DEBUG trace("cbrp RREQ%d: ignored (sent it to 2-hop gw) %d, route(%s)",myaddr_,p_adj->neighbor_cluster,p.route.dump());#endif p_adj= p_adj->next; continue; } for (j=0;j<total;j++) { if (p_adj->neighbor_cluster == cbrph->forwarders[j].which_head) {#ifdef CBRP_DEBUG trace("cbrp RREQ%d: ignored %d, duplicate in previous broadcast",myaddr_,p_adj->neighbor_cluster);#endif break; } } if (j >= total ) { new_cbrph->forwarders[i].which_gateway= p_adj->next_hop->next_node; new_cbrph->forwarders[i++].which_head= p_adj->neighbor_cluster; } p_adj = p_adj->next; } DONE: new_cbrph->num_forwarders() = i; if (i != 0) { hdr_cmn *new_cmnh=(hdr_cmn*)p_copy->access(off_cmn_); new_cmnh->size() = new_cbrph->size();#ifdef CBRP_DEBUG trace("cbrp %.5f _%d_ my route addres size %d forward path %s",Scheduler::instance().clock(), myaddr_, new_cbrph->num_addrs(),return_RREQ_forward_nodes(p_copy,off_cbrp_));#endif trace("CBRP %.5f _%d_ broadcast-request %d->%d", Scheduler::instance().clock(),myaddr_, iph->src(),cbrph->request_destination()); Scheduler::instance().schedule(ll,p_copy,0.0); } Packet::free(p.pkt); p.pkt = NULL; }int CBRP_Agent::UnicastRREQ(CBRP_Packet &p, nsaddr_t nextcluster){ hdr_cbrp *cbrph = (hdr_cbrp*)p.pkt->access(off_cbrp_); hdr_cmn *cmnh = (hdr_cmn*)p.pkt->access(off_cmn_); hdr_ip *iph = (hdr_ip*)p.pkt->access(off_ip_); cmnh->addr_type() = AF_INET; if (ntable->isNeighbor(cbrph->request_destination())) { //directly unicast to the destination cmnh->next_hop() = cbrph->request_destination(); iph->dst() = cbrph->request_destination(); cbrph->num_forwarders() = 0; cmnh->size() = cbrph->size(); Scheduler &s = Scheduler::instance(); s.schedule(ll,p.pkt,0.0); return 1; } if (cbrp_reply_from_cache_on_propagating && replyFromRouteCache(p)) { p.pkt = NULL; return 1; } if (ntable->isNeighbor(nextcluster)) { cmnh->next_hop() = nextcluster; iph->dst() = nextcluster; }else if ((cmnh->next_hop() = ntable->GetQuickNextNode(nextcluster))) { iph->dst() = nextcluster; }else { trace("CBRP %.5f _%d_ drop-request : dropped(does not know how to reach next cluster %d), route(%s) cluster head? %s",Scheduler::instance().clock(),myaddr_,nextcluster,p.route.dump(), (ntable->my_status == CLUSTER_HEAD )? "yes":"no"); Packet::free(p.pkt); p.pkt = NULL; return 0; } cmnh->xmit_failure_ = CBRP_XmitFailureCallback; cmnh->xmit_failure_data_ = (void *) this; trace("cbrp %.5f _%s_ relay %s #%d ->%d %s to designated head %d via %d",Scheduler::instance().clock(), net_id.dump(), p.src.dump(), cbrph->rtreq_seq(), cbrph->request_destination(), p.route.dump(), nextcluster, cmnh->next_hop()); cmnh->size() = cbrph->size(); Scheduler::instance().schedule(ll,p.pkt, 0.0); p.pkt = NULL; return 1;}/*=========================================================================== Helpers---------------------------------------------------------------------------*/boolCBRP_Agent::ignoreRouteRequestp(CBRP_Packet &p)// should we ignore this route request? by dmaltz from DSR{ hdr_cbrp *cbrph = (hdr_cbrp*)p.pkt->access(off_cbrp_); if (request_table.get(p.src) >= cbrph->rtreq_seq()) { // we've already processed a copy of this reqest so // we should drop the request silently return true; } if (p.route.member(net_id,MAC_id)) { // we're already on the route, drop silently return true; } if (p.route.full()) { return true; } return false;}boolCBRP_Agent::replyFromRouteCache(CBRP_Packet &p) /* - see if can reply to this route request from our cache if so, do it and return true, otherwise, return false - frees or hands off p iff returns true by dmaltz from DSR,modified for CBRP - CBRP does not reply from route-cache by default*/{ Path rest_of_route; // do we have a cached route the target? /* XXX what if we have more than 1? (and one is legal for reply from cache and one isn't?) 1/28/97 -dam */ hdr_cbrp *old_cbrph = (hdr_cbrp *)p.pkt->access(off_cbrp_); p.dest = ID(old_cbrph->request_destination(),::IP); if (!route_cache->findRoute(p.dest, rest_of_route, 0)) { // no route => we're done return false; } /* but we should be on on the remainder of the route (and should be at the start of the route */ assert(rest_of_route[0] == net_id || rest_of_route[0] == MAC_id); if (rest_of_route.length() + 2 * p.route.length() > MAX_SR_LEN) return false; // too long to work with... // if there is any other information piggybacked into the // route request pkt, we need to forward it on to the dst hdr_cbrp *cbrph = (hdr_cbrp*)p.pkt->access(off_cbrp_); int request_seqnum = cbrph->rtreq_seq(); // make up and send out a route reply Packet* rrp = allocpkt(); hdr_ip *iph = (hdr_ip*)rrp->access(off_ip_); iph->src() = myaddr_; iph->sport() = RT_PORT; iph->dst() = p.src.addr; iph->dport() = RT_PORT; iph->ttl() = 255; cbrph = (hdr_cbrp*)rrp->access(off_cbrp_); cbrph->init(); cbrph->route_reply() = 1; int len = rest_of_route.length(); for (int i = 0 ; i < len ; i++) rest_of_route[len - i - 1].fillSRAddr(cbrph->reply_addrs()[i]); cbrph->route_reply_len() = len; // propagate the request sequence number in the reply for analysis purposes cbrph->rtreq_seq() = request_seqnum; hdr_cmn *cmnh = (hdr_cmn*)rrp->access(off_cmn_); cmnh->ptype() = PT_CBRP; cmnh->size() = cbrph->size(); // copy the rest of cluster head by cluster head route over fillCBRPPath(p.route,cbrph); cbrph->cur_addr() = cbrph->num_addrs() - 1; nsaddr_t next_cluster; if (cbrph->cur_addr() >= 0) { next_cluster = cbrph->addrs[cbrph->cur_addr()].addr; }else { next_cluster = iph->dst(); } adjtable_ent *adj_ent; if ((cmnh->next_hop() = ntable->GetQuickNextNode(next_cluster))) { goto DONE; }else if ((adj_ent = ntable->GetAdjEntry(next_cluster, 0))) { cmnh->next_hop() = adj_ent->next_hop->next_node; goto DONE; }else { Packet::free(rrp); return false; }DONE: Scheduler::instance().schedule(ll,rrp,0); trace("CBRP %.9f _%s_ cache-reply-sent %d -> %d #%d (len %d) %s", Scheduler::instance().clock(), net_id.dump(), iph->src(), iph->dst(), request_seqnum, rest_of_route.length(), rest_of_route.dump()); Packet::free(p.pkt); p.pkt = NULL; return true;}voidCBRP_Agent::sendOutPacketWithRoute(CBRP_Packet& p, bool fresh, Time delay = 0.0) // take packet and send it out, packet must a have a route in it // This packet should not not be a RREQ packet // if fresh is true then reset the path before using it, if fresh // is false then our caller wants us use a path with the index // set as it currently is{ hdr_cbrp *cbrph = (hdr_cbrp*)p.pkt->access(off_cbrp_); hdr_cmn *cmnh = (hdr_cmn*)p.pkt->access(off_cmn_); assert(cbrph->valid()); assert(!cbrph->route_request()); if ((p.dest == net_id)) //Jinyang { // it doesn't need to go on the wire, 'cause it's for us recv(p.pkt, (Handler *) 0); p.pkt = 0; return; } if (fresh) { p.route.resetIterator(); if (verbose_) { trace("SO %.9f _%s_ originating %s, RREP? %s", Scheduler::instance().clock(), net_id.dump(), p.route.dump(), cbrph->route_reply()?"yes":"no" ); } } fillCBRPPath(p.route,cbrph); assert((unsigned long)cbrph->addrs[cbrph->cur_addr()].addr == net_id.addr); // check if we could shorten the route by looking at our two-hop-topology table // we don't shorten the route for route errors and RREP (route reply) if ((!cbrph->route_error()) && (!cbrph->route_reply()) && cbrp_shortening_route_if_possible && (cbrph->cur_addr()< cbrph->num_addrs()-2)) { //we only check to see if the node after next is reachable or not. //cause that's the most likely case. :) nsaddr_t next_next_node = cbrph->addrs[cbrph->cur_addr()+2].addr; if (ntable->isNeighbor(next_next_node)) { //I'll send the packet directly to the next next node. :) cmnh->next_hop() = next_next_node; cbrph->cur_addr() += 2; //set the flag to indicate I'm temporarily shortening the route, //no changes are made to route at this point of time. cbrph->route_shortening() = 1; trace("cbrp %.5f _%d_ trying to shorten the route %d->%d",Scheduler::instance().clock(),myaddr_,myaddr_,cbrph->addrs[cbrph->cur_addr()].addr); }else { cmnh->next_hop() = cbrph->get_next_addr(); cbrph->cur_addr() = cbrph->cur_addr() + 1; } } else { cmnh->next_hop() = cbrph->get_next_addr(); cbrph->cur_addr() = cbrph->cur_addr() + 1; } cmnh->xmit_failure_ = CBRP_XmitFailureCallback; cmnh->xmit_failure_data_ = (void *) this; cmnh->prev_hop_ = net_id.getNSAddr_t(); cmnh->addr_type() = AF_INET; assert(p.pkt->incoming == 0); // this is an outgoing packet if (ifq->length() > 25) trace("SIFQ %.5f _%s_ len %d", Scheduler::instance().clock(), net_id.dump(), ifq->length()); //calculate the packet size if (cbrph->route_reply() || cbrph->route_error()) { cmnh->size() = cbrph->size(); }else { cmnh->size() += cbrph->size(); } // off it goes!!!! //assert(cmnh->ptype() == PT_CBR || cbrph->route_reply() || cbrph->route_error()); Scheduler::instance().schedule(ll, p.pkt, delay); p.pkt = NULL; }voidCBRP_Agent::getRouteForPacket(CBRP_Packet &p, bool retry) /* try to obtain a route for packet pkt is freed or handed off as needed, unless retry == true in which case it is not touched */{ Entry *e = request_table.getEntry(p.dest); Time time = Scheduler::instance().clock(); if (!retry) { stickPacketInSendBuffer(p); p.pkt = 0; // pkt is handled for now (it's in sendbuffer) } /* make the route request packet */ CBRP_Packet rrq; rrq.dest = ID(0, ::IP); // the ip destination of RREQ is not necessarily same the destinate node rrq.src = net_id; rrq.pkt = allocpkt(); hdr_cbrp *cbrph = (hdr_cbrp*)rrq.pkt->access(off_cbrp_); hdr_ip *iph = (hdr_ip*)rrq.pkt->access(off_ip_); hdr_cmn *cmnh = (hdr_cmn*)rrq.pkt->access(off_cmn_); iph->dport() = RT_PORT; iph->src() = net_id.getNSAddr_t(); iph->sport() = RT_PORT; cmnh->ptype() = PT_CBRP; cmnh->num_forwards() = 0; cmnh->addr_type() = AF_INET; cbrph->init(); //set the requested destination node cbrph->route_request() = 1; cbrph->request_destination() = p.dest.getNSAddr_t(); if (BackOffTest(e, time)) { // it's time to start another route request cycle // CBRP does not have ring_zero search, but we still set the appropriate // e->last_type for reusing this part of DSR's code e->last_type = UNLIMIT; sendOutRtReq(rrq, MAX_SR_LEN); e->last_arp = time; } else if (LIMIT0 == e->last_type && (time - e->last_arp) > cbrp_arp_timeout) { // try propagating rt req since we haven't heard back from limited one // Actually this part of the code will never be executed by CBRP - Li Jinyang e->last_type = UNLIMIT; sendOutRtReq(rrq, MAX_SR_LEN); } else { // it's not time to send another route request... if (!retry && verbose_srr) { trace("SRR %.5f _%s_ RR-not-sent %s -> %s", Scheduler::instance().clock(), net_id.dump(), rrq.src.dump(), p.dest.dump()); } trace("cbrp %s -> %s, request entry rt_reqs_outstanding %d, last_rt_req %.9f",rrq.src.dump(), p.dest.dump(),e->rt_reqs_outstanding, e->last_rt_req); Packet::free(rrq.pkt); // dump the route request packet we made up rrq.pkt = 0; }}voidCBRP_Agent::sendOutRtReq(CBRP_Packet &p, int max_prop) // Send out the Route request packet we have made{ hdr_cbrp *cbrph = (hdr_cbrp*)p.pkt->access(off_cbrp_); hdr_ip *iph = (hdr_ip*)p.pkt->access(off_ip_); hdr_cmn *cmnh = (hdr_cmn*)p.pkt->access(off_cmn_); int i=0; assert(cbrph->valid()); cbrph->rtreq_seq() = route_request_num++; cbrph->max_propagation() = max_prop; p.route.reset(); // CBRP does not propagate last error seen on Route Request, if you are // interested to see how this might help as it does for DSR, turn it on and try if (cbrp_propagate_last_error && route_error_held
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -