📄 cbrpagent.cc
字号:
&& Scheduler::instance().clock() - route_error_data_time < cbrp_max_err_hold) { assert(cbrph->num_route_errors() < MAX_ROUTE_ERRORS); cbrph->route_error() = 1; link_down_cbrp *deadlink = &(cbrph->down_links()[cbrph->num_route_errors()]); deadlink->addr_type = AF_INET; deadlink->from_addr = err_from.getNSAddr_t(); deadlink->to_addr = err_to.getNSAddr_t(); deadlink->tell_addr = GRAT_ROUTE_ERROR; cbrph->num_route_errors() += 1; /* * Make sure that the Route Error gets on a propagating request. */ if(max_prop > 0) route_error_held = false; } trace("CBRP %.5f _%s_ new-request %d %s #%d -> %d", Scheduler::instance().clock(), net_id.dump(), max_prop, p.src.dump(), cbrph->rtreq_seq(), cbrph->request_destination()); //Jinyang - if i am the cluster head, append myself to the path before sending RREQ if (ntable->my_status == CLUSTER_HEAD) { p.route.appendToPath(net_id); fillCBRPPath(p.route,cbrph); //I will include all my 2-hop neighbor cluster head on forwarders list adjtable_ent *p_ent = ntable->adjtable_1; while (p_ent && (i<MAX_NEIGHBORS)) { cbrph->forwarders[i].which_gateway= p_ent->next_hop->next_node; cbrph->forwarders[i].which_head = p_ent->neighbor_cluster;#ifdef CBRP_DEBUG trace("cbrp %.5f _%s_(head) RREQ(%d->%d) broadcasted to 2-hop head %d via %d", Scheduler::instance().clock(),net_id.dump(), cbrph->rtreq_seq(), cbrph->request_destination(),p_ent->neighbor_cluster, p_ent->next_hop->next_node);#endif i++; p_ent = p_ent->next; } // I will include all my 3-hop neighbor cluster head on forwarders list p_ent = ntable->adjtable_2; while (p_ent && (i<MAX_NEIGHBORS)) { cbrph->forwarders[i].which_gateway= p_ent->next_hop->next_node; cbrph->forwarders[i].which_head= p_ent->neighbor_cluster;#ifdef CBRP_DEBUG trace("cbrp %.5f _%s_(head) RREQ(%d->%d) broadcasted to 3-hop head %d via %d", Scheduler::instance().clock(),net_id.dump(), cbrph->rtreq_seq(), cbrph->request_destination(),p_ent->neighbor_cluster, p_ent->next_hop->next_node);#endif i++; p_ent = p_ent->next; } }else { //I have to send the route request to one of my cluster head ntable_ent *ent = ntable->head; while (ent && (i< MAX_NEIGHBORS)) { if (ent->neighbor_status == CLUSTER_HEAD) { cbrph->forwarders[i].which_gateway= ent->neighbor; cbrph->forwarders[i].which_head = ent->neighbor;#ifdef CBRP_DEBUG trace("cbrp %.5f _%s_ RREQ(%d->%d) broadcasted to 1-hop head %d", Scheduler::instance().clock(),net_id.dump(),cbrph->rtreq_seq(), cbrph->request_destination(),ent->neighbor);#endif i++; } ent = ent->next; } // I will include all 2-hop cluster head in forwarders list adjtable_ent *adjent=ntable->adjtable_1; while (adjent && (i<MAX_NEIGHBORS)) { // if the 2-hop cluster head is "really" not directly reachable if (!ntable->GetEntry(adjent->neighbor_cluster)) { cbrph->forwarders[i].which_gateway= adjent->next_hop->next_node; cbrph->forwarders[i].which_head= adjent->neighbor_cluster;#ifdef CBRP_DEBUG trace("cbrp %.5f _%s_ RREQ(%d->%d) broadcasted to 2-hop head %d via %d", Scheduler::instance().clock(),net_id.dump(),cbrph->rtreq_seq(), cbrph->request_destination(),adjent->neighbor_cluster,adjent->next_hop->next_node);#endif i++; } adjent = adjent->next; } } cbrph->num_forwarders() = i; cmnh->next_hop() = MAC_BROADCAST; iph->dst() = IP_BROADCAST; iph->src() = myaddr_; cmnh->size() = cbrph->size(); Scheduler::instance().schedule(ll,p.pkt,0.0);} voidCBRP_Agent::returnSrcRouteToRequestor(CBRP_Packet &p) // take the route in p, add us to the end of it and return the // RREP to the sender of p // doesn't free p.pkt{ hdr_cbrp *old_cbrph = (hdr_cbrp*)p.pkt->access(off_cbrp_); if (p.route.full()) return; // alas, the route would be to long once we add ourselves CBRP_Packet p_copy = p; p_copy.pkt = allocpkt(); p_copy.dest = p.src; hdr_ip *new_iph = (hdr_ip*)p_copy.pkt->access(off_ip_); hdr_cbrp *new_cbrph = (hdr_cbrp*)p_copy.pkt->access(off_cbrp_); hdr_cmn *new_cmnh = (hdr_cmn*)p_copy.pkt->access(off_cmn_); new_cbrph->init(); new_cbrph->route_reply() = 1; trace("CBRP %.5f _%s_ reply-sent %s->%d %s", Scheduler::instance().clock(),net_id.dump(), p.src.dump(),old_cbrph->request_destination(),p.route.dump()); assert(old_cbrph->request_destination() == net_id.getNSAddr_t()); p_copy.src = net_id; //if i am the cluster head, i have to complete the recorded route first if (ntable->my_status == CLUSTER_HEAD) { new_cbrph->reply_addrs()[0].addr = net_id.addr; new_cbrph->reply_addrs()[0].addr_type = AF_INET; new_cbrph->route_reply_len() = 1; p_copy.route.appendToPath(net_id); } fillCBRPPath(p_copy.route,new_cbrph); // just in case the route is empty if (!old_cbrph->num_addrs()) { //try to reach the sender directly! if ((new_cmnh->next_hop() = ntable->GetQuickNextNode(p_copy.dest.addr))) { new_cbrph->reply_addrs()[0].addr = p_copy.src.addr; new_cbrph->reply_addrs()[0].addr_type = AF_INET; new_cbrph->route_reply_len() = 1; new_iph->dst() = p_copy.dest.addr; new_iph->src() = myaddr_; new_cmnh->size() = new_cbrph->size(); Scheduler::instance().schedule(ll,p_copy.pkt,0.0); }else { Packet::free(p_copy.pkt); } return; } //initialize route index pointer new_cbrph->cur_addr() = p_copy.route.length()-1; p_copy.route.setIterator(new_cbrph->cur_addr()); new_iph->dst() = p_copy.dest.addr; new_iph->dport() = RT_PORT; new_iph->src() = p_copy.src.addr; new_iph->sport() = RT_PORT; new_iph->ttl() = 255; // propagate the request sequence number in the reply for analysis purposes new_cbrph->rtreq_seq() = old_cbrph->rtreq_seq(); new_cmnh->ptype() = PT_CBRP; handleRREP(p_copy);}voidCBRP_Agent::acceptRREP(CBRP_Packet &p) /* - enter the packet's source route into our cache - see if any packets are waiting to be sent out with this source route - doesn't free the pkt */{ Path reply_route; hdr_cbrp *cbrph = (hdr_cbrp*)p.pkt->access(off_cbrp_); if (cbrph->route_repaired()) { trace("CBRP %.5f _%d_ grat-reply-repair from %d, route %s", Scheduler::instance().clock(),myaddr_, p.src.addr, p.route.dump()); }else if (cbrph->route_shortened()){ trace("CBRP %.5f _%d_ grat-reply-shorten from %d, route %s", Scheduler::instance().clock(),myaddr_, p.src.addr, p.route.dump()); }else { trace("CBRP %.5f _%d_ reply-received from %d, route %s", Scheduler::instance().clock(),myaddr_,p.src.addr,p.route.dump()); } if (!cbrph->route_reply()) { // somethings wrong... trace("SDFU non route containing packet given to acceptRREP"); fprintf(stderr, "dfu: non route containing packet given to acceptRRP\n"); } if ((!cbrph->route_repaired()) && (!cbrph->route_shortened())) { Path reverse_reply_route(cbrph->reply_addrs(), cbrph->route_reply_len()); //Jinyang - in CBRP, the returned source route is in reverse order reverse_reply_route.appendToPath(net_id); reply_route = reverse_reply_route.reverse(); }else { Path reverse_reply_route(cbrph->addrs, cbrph->num_addrs()); reply_route = reverse_reply_route.reverse(); } /* check to see if this reply is valid or not using god info */ int i; bool good_reply = true; for (i = 0; i < reply_route.length()-1 ; i++) if (God::instance()->hops(reply_route[i].getNSAddr_t(), reply_route[i+1].getNSAddr_t()) != 1) { good_reply = false; break; }#ifdef CBRP_DEBUG trace("cbrp %.9f _%s_ reply-received %d from %s %s #%d -> %s %s", Scheduler::instance().clock(), net_id.dump(), good_reply ? 1 : 0, p.src.dump(), reply_route[0].dump(), cbrph->rtreq_seq(), reply_route[reply_route.length()-1].dump(), reply_route.dump());#endif // add the new route into our cache route_cache->addRoute(reply_route, Scheduler::instance().clock(), p.src); // add the new loose source route to our loose source route cache Path source_route(cbrph->addrs,cbrph->num_addrs()); // back down the route request counters Entry *e = request_table.getEntry(reply_route[reply_route.length()-1]); e->rt_reqs_outstanding = 0; e->last_rt_req = 0.0; // see if the addtion of this route allows us to send out // any of the packets we have waiting Time delay = 0.0; for (int c = 0; c < SEND_BUF_SIZE; c++) { if (send_buf[c].p.pkt == NULL) continue; if (route_cache->findRoute(send_buf[c].p.dest, send_buf[c].p.route, 1)) { // we have a route!#ifdef CBRP_DEBUG struct hdr_cmn *ch = HDR_CMN(send_buf[c].p.pkt); if(ch->size() < 0) { drop(send_buf[c].p.pkt, "XXX"); abort(); }#endif if (verbose_) trace("Sdebug %.9f _%s_ liberated from sendbuf %s->%s %s", Scheduler::instance().clock(), net_id.dump(), send_buf[c].p.src.dump(), send_buf[c].p.dest.dump(), send_buf[c].p.route.dump()); sendOutPacketWithRoute(send_buf[c].p, true, delay); /* DSR spread out the rate in order to arp to complete, since we've already optimized ARP to take in MAC address of neighbors in advance, we don't really need to delay any more */ //delay += cbrp_arp_timeout; send_buf[c].p.pkt = NULL; } }}voidCBRP_Agent::processBrokenRouteError(CBRP_Packet& p)// take the error packet and proccess our part of it.// if needed, send the remainder of the errors to the next person// doesn't free p.pkt, mostly taken from DSR's implementation by dmaltz{ hdr_cbrp *cbrph = (hdr_cbrp*)p.pkt->access(off_cbrp_); if (!cbrph->route_error()) return; // what happened?? /* if we hear A->B is dead, should we also run the link B->A through the cache as being dead, since 802.11 requires bidirectional links XXX -dam 4/23/98 */ // since CPU time is cheaper than network time, we'll process // all the dead links in the error packet assert(cbrph->num_route_errors() > 0); int count = cbrph->num_route_errors(); for (int c = 0 ; c < count ; c++) { assert(cbrph->down_links()[c].addr_type == AF_INET); route_cache->noticeDeadLink(ID(cbrph->down_links()[c].from_addr,::IP), ID(cbrph->down_links()[c].to_addr,::IP), Scheduler::instance().clock()); // I'll assume everything's of type AF_INET for the printout... XXX if (verbose_srr) trace("SRR %.9f _%s_ dead-link tell %d %d -> %d", Scheduler::instance().clock(), net_id.dump(), cbrph->down_links()[c].tell_addr, cbrph->down_links()[c].from_addr, cbrph->down_links()[c].to_addr); } ID who = ID(cbrph->down_links()[cbrph->num_route_errors()-1].tell_addr, ::IP); if (who != net_id && who != MAC_id) { // this error packet wasn't meant for us to deal with // since the outer entry doesn't list our name return; } // record this route error data for possible propagation on our next // route request route_error_held = true; err_from = ID(cbrph->down_links()[cbrph->num_route_errors()-1].from_addr,::IP); err_to = ID(cbrph->down_links()[cbrph->num_route_errors()-1].to_addr,::IP); route_error_data_time = Scheduler::instance().clock(); if (1 == cbrph->num_route_errors()) { // this error packet has done its job // it's either for us, in which case we've done what it sez // or it's not for us, in which case we still don't have to forward // it to whoever it is for return; } /* make a copy of the packet and send it to the next tell_addr on the error list. the copy is needed in case there is other data in the packet (such as nested route errors) that need to be delivered */ if (verbose_) trace("Sdebug %.5f _%s_ unwrapping nested route error", Scheduler::instance().clock(), net_id.dump()); CBRP_Packet p_copy = p; p_copy.pkt = p.pkt->copy(); hdr_cbrp *new_cbrph = (hdr_cbrp*)p_copy.pkt->access(off_cbrp_); hdr_ip *new_iph = (hdr_ip*)p_copy.pkt->access(off_ip_); // remove us from the list of errors new_cbrph->num_route_errors() -= 1; new_cbrph->route_request() = 0; //new_cbrph->route_error() = 1; // send the packet to the person listed in what's now the last entry p_copy.dest = ID(new_cbrph->down_links()[new_cbrph->num_route_errors()-1].tell_addr, ::IP); p_copy.src = net_id; new_iph->dst() = p_copy.dest.addr; new_iph->dport() = RT_PORT; new_iph->src() = p_copy.src.addr; new_iph->sport() = RT_PORT; new_iph->ttl() = 255; // an error packet is a first class citizen, so we'll // use handlePktWOSR to obtain a route if needed handlePktWithoutSR(p_copy, false);}/*============================================================== Callback for link layer transmission failures------------------------------------------------------------*/struct filterfailuredata { nsaddr_t dead_next_hop; int off_cmn_; CBRP_Agent *agent;};intCBRP_FilterFailure(Packet *p, void *data){ struct filterfailuredata *ffd = (filterfailuredata *) data; hdr_cmn *cmh = (hdr_cmn*)p->access(ffd->off_cmn_); int remove = cmh->next_hop() == ffd->dead_next_hop; if (remove) ffd->agent->undeliverablePkt(p,1); return remove;}voidCBRP_Agent::undeliverablePkt(Packet *pkt, int mine)/* try our best to save the undeliverable packet using local repair or cache */{ hdr_cbrp *cbrph = (hdr_cbrp*)pkt->access(off_cbrp_); hdr_ip *iph = (hdr_ip*)pkt->access(off_ip_); hdr_cmn *cmh = (hdr_cmn*)pkt->access(off_cmn_); CBRP_Packet p(pkt,cbrph); p.dest = ID(iph->dst(),::IP); p.src = ID(iph->src(),::IP); p.pkt = mine ? pkt : pkt->copy(); cbrph = (hdr_cbrp*)p.pkt->access(off_cbrp_); iph = (hdr_ip*)p.pkt->access(off_ip_); cmh = (hdr_cmn*)p.pkt->access(off_cmn_); if ((cbrph->route_request())) { if (UnicastRREQ(p,iph->dst())) { trace("CBRP %.5f _%d_ salvage-request %d->%d", Scheduler::instance().clock(), myaddr_, iph->src(),cbrph->request_destination()); } return
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -