📄 dsragent.cc
字号:
|| srh->route_reply() || (srh->route_error() && srh->down_links()[srh->num_route_errors()-1].tell_addr != GRAT_ROUTE_ERROR)) { // must forward the packet on SRPacket p_copy = p; p.pkt = 0; srh->route_request() = 0; p_copy.route = complete_route; p_copy.route.setIterator(p.route.length()); assert(p.route[p.route.index()] == net_id); if (verbose) trace("Sdebug %.9f _%s_ splitting %s to %s", Scheduler::instance().clock(), net_id.dump(), p.route.dump(), p_copy.route.dump()); sendOutPacketWithRoute(p_copy,false); } else { Packet::free(p.pkt); // free the rcvd rt req before making rt reply p.pkt = 0; } // make up and send out a route reply p.route.appendToPath(net_id); p.route.reverseInPlace(); route_cache->addRoute(p.route, Scheduler::instance().clock(), net_id); p.dest = p.src; p.src = net_id; p.pkt = allocpkt(); hdr_ip *iph = (hdr_ip*)p.pkt->access(off_ip_); iph->src() = p.src.addr; iph->sport() = RT_PORT; iph->dst() = p.dest.addr; iph->dport() = RT_PORT; iph->ttl() = 255; srh = (hdr_sr*)p.pkt->access(off_sr_); srh->init(); for (int i = 0 ; i < complete_route.length() ; i++) complete_route[i].fillSRAddr(srh->reply_addrs()[i]); srh->route_reply_len() = complete_route.length(); srh->route_reply() = 1; // propagate the request sequence number in the reply for analysis purposes srh->rtreq_seq() = request_seqnum; hdr_cmn *cmnh = (hdr_cmn*)p.pkt->access(off_cmn_); cmnh->ptype() = PT_DSR; cmnh->size() = IP_HDR_LEN; if (verbose_srr) trace("SRR %.9f _%s_ cache-reply-sent %s -> %s #%d (len %d) %s", Scheduler::instance().clock(), net_id.dump(), p.src.dump(), p.dest.dump(), request_seqnum, complete_route.length(), complete_route.dump()); sendOutPacketWithRoute(p, true); return true;}voidDSRAgent::sendOutPacketWithRoute(SRPacket& p, bool fresh, Time delay = 0.0) // take packet and send it out, packet must a have a route in it // return value is not very meaningful // 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_sr *srh = (hdr_sr*)p.pkt->access(off_sr_); hdr_cmn *cmnh = (hdr_cmn*)p.pkt->access(off_cmn_); assert(srh->valid()); assert(cmnh->size() > 0); if (p.dest == net_id) { // 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 && !srh->route_request()) { trace("SO %.9f _%s_ originating %s %s", Scheduler::instance().clock(), net_id.dump(), packet_names[cmnh->ptype()], p.route.dump()); } } p.route.fillSR(srh); cmnh->size() += srh->size(); if (srh->route_request()) { // broadcast forward cmnh->xmit_failure_ = 0; cmnh->next_hop() = MAC_BROADCAST; cmnh->addr_type() = AF_LINK; } else { // forward according to source route cmnh->xmit_failure_ = XmitFailureCallback; cmnh->xmit_failure_data_ = (void *) this; cmnh->next_hop() = srh->get_next_addr(); cmnh->addr_type() = srh->get_next_type(); srh->cur_addr() = srh->cur_addr() + 1; } /* put route errors at the head of the ifq somehow? -dam 4/13/98 */ // make sure we aren't cycling packets assert(p.pkt->incoming == 0); // this is an outgoing packet if (ifq->prq_length() > 25) trace("SIFQ %.5f _%s_ len %d", Scheduler::instance().clock(), net_id.dump(), ifq->prq_length()); // off it goes! if (srh->route_request()) { // route requests need to be jittered a bit Scheduler::instance().schedule(ll, p.pkt, Random::uniform(RREQ_JITTER) + delay); } else { // no jitter required Scheduler::instance().schedule(ll, p.pkt, delay); } p.pkt = NULL; /* packet sent off */}voidDSRAgent::getRouteForPacket(SRPacket &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 */{ // since we'll commonly be only one hop away, we should // arp first before route discovery as an optimization... Entry *e = request_table.getEntry(p.dest); Time time = Scheduler::instance().clock(); /* for now, no piggybacking at all, queue all pkts */ if (!retry) { stickPacketInSendBuffer(p); p.pkt = 0; // pkt is handled for now (it's in sendbuffer) }#if 0 /* pre 4/13/98 logic -dam removed b/c it seemed more complicated than needed since we're not doing piggybacking and we're returning route replies via a reversed route (the copy in this code is critical if we need to piggyback route replies on the route request to discover the return path) */ /* make the route request packet */ SRPacket rrp = p; rrp.pkt = p.pkt->copy(); hdr_sr *srh = (hdr_sr*)rrp.pkt->access(off_sr_); hdr_ip *iph = (hdr_ip*)rrp.pkt->access(off_ip_); hdr_cmn *cmnh = (hdr_cmn*)rrp.pkt->access(off_cmn_); iph->dst() = p.dest.getNSAddr_t(); iph->dport() = RT_PORT; iph->src() = net_id.getNSAddr_t(); iph->sport() = RT_PORT; cmnh->ptype() = PT_DSR; cmnh->size() = size_; cmnh->num_forwards() = 0;#endif /* make the route request packet */ SRPacket rrp; rrp.dest = p.dest; rrp.src = net_id; rrp.pkt = allocpkt(); hdr_sr *srh = (hdr_sr*)rrp.pkt->access(off_sr_); hdr_ip *iph = (hdr_ip*)rrp.pkt->access(off_ip_); hdr_cmn *cmnh = (hdr_cmn*)rrp.pkt->access(off_cmn_); iph->dst() = p.dest.getNSAddr_t(); iph->dport() = RT_PORT; iph->src() = net_id.getNSAddr_t(); iph->sport() = RT_PORT; cmnh->ptype() = PT_DSR; cmnh->size() = size_ + IP_HDR_LEN; // add in IP header cmnh->num_forwards() = 0; srh->init(); if (BackOffTest(e, time)) { // it's time to start another route request cycle if (dsragent_ring_zero_search) { // do a ring zero search e->last_type = LIMIT0; sendOutRtReq(rrp, 0); } else { // do a propagating route request right now e->last_type = UNLIMIT; sendOutRtReq(rrp, MAX_SR_LEN); } e->last_arp = time; } else if (LIMIT0 == e->last_type && (time - e->last_arp) > arp_timeout) { // try propagating rt req since we haven't heard back from limited one e->last_type = UNLIMIT; sendOutRtReq(rrp, 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(), rrp.src.dump(), rrp.dest.dump()); Packet::free(rrp.pkt); // dump the route request packet we made up rrp.pkt = 0; return; }}voidDSRAgent::sendOutRtReq(SRPacket &p, int max_prop) // turn p into a route request and launch it, max_prop of request is // set as specified // p.pkt is freed or handed off{ hdr_sr *srh = (hdr_sr*)p.pkt->access(off_sr_); assert(srh->valid()); srh->route_request() = 1; srh->rtreq_seq() = route_request_num++; srh->max_propagation() = max_prop; p.route.reset(); p.route.appendToPath(net_id); if (dsragent_propagate_last_error && route_error_held && Scheduler::instance().clock() - route_error_data_time < max_err_hold) { assert(srh->num_route_errors() < MAX_ROUTE_ERRORS); srh->route_error() = 1; link_down *deadlink = &(srh->down_links()[srh->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; srh->num_route_errors() += 1; /* * Make sure that the Route Error gets on a propagating request. */ if(max_prop > 0) route_error_held = false; } if (verbose_srr) trace("SRR %.5f _%s_ new-request %d %s #%d -> %s", Scheduler::instance().clock(), net_id.dump(), max_prop, p.src.dump(), srh->rtreq_seq(), p.dest.dump()); sendOutPacketWithRoute(p, false);}voidDSRAgent::returnSrcRouteToRequestor(SRPacket &p) // take the route in p, add us to the end of it and return the // route to the sender of p // doesn't free p.pkt{ hdr_sr *old_srh = (hdr_sr*)p.pkt->access(off_sr_); if (p.route.full()) return; // alas, the route would be to long once we add ourselves SRPacket p_copy = p; p_copy.pkt = allocpkt(); p_copy.dest = p.src; p_copy.src = net_id; p_copy.route.appendToPath(net_id); hdr_ip *new_iph = (hdr_ip*)p_copy.pkt->access(off_ip_); 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; hdr_sr *new_srh = (hdr_sr*)p_copy.pkt->access(off_sr_); new_srh->init(); for (int i = 0 ; i < p_copy.route.length() ; i++) p_copy.route[i].fillSRAddr(new_srh->reply_addrs()[i]); new_srh->route_reply_len() = p_copy.route.length(); new_srh->route_reply() = 1; // propagate the request sequence number in the reply for analysis purposes new_srh->rtreq_seq() = old_srh->rtreq_seq(); hdr_cmn *new_cmnh = (hdr_cmn*)p_copy.pkt->access(off_cmn_); new_cmnh->ptype() = PT_DSR; new_cmnh->size() = IP_HDR_LEN; if (verbose_srr) trace("SRR %.9f _%s_ reply-sent %s -> %s #%d (len %d) %s", Scheduler::instance().clock(), net_id.dump(), p_copy.src.dump(), p_copy.dest.dump(), old_srh->rtreq_seq(), p_copy.route.length(), p_copy.route.dump()); // flip the route around for the return to the requestor, and // cache the route for future use p_copy.route.reverseInPlace(); route_cache->addRoute(p_copy.route, Scheduler::instance().clock(), net_id); p_copy.route.resetIterator(); p_copy.route.fillSR(new_srh); new_cmnh->size() += new_srh->size(); /* we now want to jitter when we first originate route replies, since they are a transmission we make in response to a broadcast packet -dam 4/23/98 sendOutPacketWithRoute(p_copy, true); */ Scheduler::instance().schedule(this, p_copy.pkt, Random::uniform(RREQ_JITTER));}voidDSRAgent::acceptRouteReply(SRPacket &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 */{ hdr_sr *srh = (hdr_sr*)p.pkt->access(off_sr_); Path reply_route(srh->reply_addrs(), srh->route_reply_len()); if (!srh->route_reply()) { // somethings wrong... trace("SDFU non route containing packet given to acceptRouteReply"); fprintf(stderr, "dfu: non route containing packet given to acceptRouteReply\n"); } /* 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; } if (verbose_srr) trace("SRR %.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(), srh->rtreq_seq(), reply_route[reply_route.length()-1].dump(), reply_route.dump()); // add the new route into our cache route_cache->addRoute(reply_route, Scheduler::instance().clock(), p.src); // 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 DEBUG struct hdr_cmn *ch = HDR_CMN(send_buf[c].p.pkt); if(ch->size() < 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -