📄 dsragent.cc
字号:
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; } /* 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) }}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::access(p.pkt); 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 = NS_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::access(p.pkt); 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::access(p_copy.pkt); //new_iph->daddr() = p_copy.dest.addr; new_iph->daddr() = Address::instance().create_ipaddr(p_copy.dest.getNSAddr_t(),RT_PORT); new_iph->dport() = RT_PORT; //new_iph->saddr() = p_copy.src.addr; new_iph->saddr() = Address::instance().create_ipaddr(p_copy.src.getNSAddr_t(),RT_PORT); new_iph->sport() = RT_PORT; new_iph->ttl() = 255; hdr_sr *new_srh = hdr_sr::access(p_copy.pkt); 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::access(p_copy.pkt); 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); */ { double d = Random::uniform(RREQ_JITTER);#if 0 fprintf(stderr, "Random Delay: %f\n", d);#endif Scheduler::instance().schedule(this, p_copy.pkt, d); }}intDSRAgent::diff_subnet(ID dest, ID myid) { int dst = dest.addr; int id = myid.addr; char* dstnet = Address::instance().get_subnetaddr(dst); char * subnet = Address::instance().get_subnetaddr(id); if (subnet != NULL) { if (dstnet != NULL) { if (strcmp(dstnet, subnet) != 0) { delete [] dstnet; return 1; } delete [] dstnet; } delete [] subnet; } assert(dstnet == NULL); return 0;}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::access(p.pkt); 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"); } bool good_reply = true; //#ifdef USE_GOD_FEEDBACK /* check to see if this reply is valid or not using god info */ int i; 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; } //#endif //GOD_FEEDBACK 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; ID dest; for (int c = 0; c < SEND_BUF_SIZE; c++) { if (send_buf[c].p.pkt == NULL) continue; // check if pkt is destined to outside domain if (diff_subnet(send_buf[c].p.dest,net_id)) { dest = ID(node_->base_stn(),::IP); send_buf[c].p.dest = dest; } 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) { 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()); /* we need to spread out the rate at which we send packets in to the link layer to give ARP time to complete. If we dump all the packets in at once, all but the last one will be dropped. XXX THIS IS A MASSIVE HACK -dam 4/14/98 */ sendOutPacketWithRoute(send_buf[c].p, true, delay); delay += arp_timeout; send_buf[c].p.pkt = NULL; } }}voidDSRAgent::processUnknownFlowError(SRPacket &p, bool asDefault) { hdr_sr *srh = hdr_sr::access(p.pkt); int flowidx = -1; struct flow_error *fe; u_int16_t flowid; if (asDefault) { assert (srh->flow_default_unknown() && srh->num_default_unknown()); fe = &srh->unknown_defaults()[srh->num_default_unknown()-1]; } else { assert (srh->flow_unknown() && srh->num_flow_unknown()); fe = &srh->unknown_flows()[srh->num_flow_unknown()-1]; if (!flow_table.defaultFlow(fe->flow_src, fe->flow_dst, flowid)) goto skip_proc; } /* not for us; hope it gets the right place... */ if (fe->flow_src != (int) net_id.addr) return; if (-1 != (flowidx = flow_table.find(fe->flow_src, fe->flow_dst, asDefault ? flowid : fe->flow_id))) flow_table[flowidx].count = 0;skip_proc: trace("SFEr %.9f _%s_ from %d re %d : %d [%d]", Scheduler::instance().clock(), net_id.dump(), p.src.addr, fe->flow_dst, asDefault ? -1 : fe->flow_id, flowidx != -1 ? flow_table[flowidx].count : -1); if ((asDefault ? srh->num_default_unknown() : srh->num_flow_unknown()) == 1) return; SRPacket p_copy = p; p_copy.pkt = p.pkt->copy(); hdr_sr *new_srh = hdr_sr::access(p_copy.pkt); hdr_ip *new_iph = hdr_ip::access(p_copy.pkt); // remove us from the list of errors if (asDefault) new_srh->num_default_unknown()--; else new_srh->num_flow_unknown()--; // send the packet to the person listed in what's now the last entry p_copy.dest = ID(fe[-1].flow_src, ::IP); p_copy.src = net_id; //new_iph->daddr() = p_copy.dest.addr; new_iph->daddr() = Address::instance().create_ipaddr(p_copy.dest.getNSAddr_t(),RT_PORT); new_iph->dport() = RT_PORT; //new_iph->saddr() = p_copy.src.addr; new_iph->saddr() = Address::instance().create_ipaddr(p_copy.src.getNSAddr_t(),RT_PORT); new_iph->sport() = RT_PORT; new_iph->ttl() = 255; new_srh->flow_header() = 0; new_srh->flow_timeout() = 0; // an error packet is a first class citizen, so we'll // use handlePktWOSR to obtain a route if needed handlePktWithoutSR(p_copy, false);}voidDSRAgent::processBrokenRouteError(SRPacket& 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{ hdr_sr *srh = hdr_sr::access(p.pkt); if (!srh->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(srh->num_route_errors() > 0); for (int c = 0 ; c < srh->num_route_errors() ; c++) { assert(srh->down_links()[c].addr_type == NS_AF_INET); route_cache->noticeDeadLink(ID(srh->down_links()[c].from_addr,::IP), ID(srh->down_links()[c].to_addr,::IP), Scheduler::instance().clock()); flow_table.noticeDeadLink(ID(srh->down_links()[c].from_addr,::IP), ID(srh->down_links()[c].to_addr,::IP)); // I'll assume everything's of type NS_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(), srh->down_links()[c].tell_addr, srh->down_links()[c].from_addr, srh->down_links()[c].to_addr); } ID who = ID(srh->down_links()[srh->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(srh->down_links()[srh->num_route_errors()-1].from_addr,::IP); err_to = ID(srh->down_links()[srh->num_route_errors()-1].to_addr,::IP); route_error_data_time = Scheduler::instance().clock(); if (1 == srh->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()); SRPacket p_copy = p; p_copy.pkt = p.pkt->copy(); hdr_sr *new_srh = hdr_sr::access(p_copy.pkt); hdr_ip *new_iph = hdr_ip::access(p_copy.pkt); // remove us from the list of errors new_srh->num_route_errors() -= 1; // send the packet to the person listed in what's now the last entry p_copy.dest = ID(new_srh->down_links()[new_srh->num_route_errors()-1].tell_addr, ::IP); p_copy.src = net_id; //new_iph->daddr() = p_copy.dest.addr; new_iph->daddr() = Address::instance().create_ipaddr(p_copy.dest.getNSAddr_t(),RT_PORT); new_iph->dport() = RT_PORT; //new_iph->saddr() = p_copy.src.addr; new_iph->saddr() = Address::instance().create_ipaddr(p_copy.src.getNSAddr_t(),RT_PORT); new_iph->sport() = RT_PORT; new_iph->ttl() = 255; new_srh->flow_header() = 0; new_srh->flow_timeout() = 0; // an error packet is a first class citizen, so we'll // use handlePktWOSR to obtain a route if needed handlePktWithoutSR(p_copy, false);}#ifdef DSR_FILTER_TAPint64_t dsr_tap = 0;int64_t dsr_tap_skip = 0;#endif// Process flow state Automatic Route ShorteningvoidDSRAgent::processFlowARS(const Packet *packet) { hdr_sr *srh = hdr_sr::access(packet); hdr_ip *iph = hdr_ip::access(packet); hdr_cmn *cmh = hdr_cmn::access(packet); //hdr_sr *srh = (hdr_sr*) ((Packet *)packet)->access(off_sr_); //hdr_ip *iph = (hdr_ip*) ((Packet *)packet)->access(off_ip_); //hdr_cmn *cmh = (hdr_cmn*)((Packet *)packet)->access(off_cmn_); u_int16_t flowid; int flowidx; int shortamt; assert(!srh->num_addrs()); if (srh->flow_header()) { flowid = srh->flow_id(); // do I know about this flow? if (-1 == (flowidx = flow_table.find(iph->saddr(), iph->daddr(), flowid))) return; shortamt = flow_table[flowidx].hopCount - srh->hopCount(); } else { // do I know which flow is default? if (!flow_table.defaultFlow(iph->saddr(), iph->daddr(), flowid)) return; // do I know about t
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -