📄 dsragent.cc
字号:
} else if(strcasecmp(argv[1], "mac-addr") == 0) { MAC_id = ID(atoi(argv[2]), ::MAC); route_cache->MAC_id = MAC_id; return TCL_OK; } if( (obj = TclObject::lookup(argv[2])) == 0) { fprintf(stderr, "DSRAgent: %s lookup of %s failed\n", argv[1], argv[2]); return TCL_ERROR; } if (strcasecmp(argv[1], "log-target") == 0) { logtarget = (Trace*) obj; return route_cache->command(argc, argv); } else if (strcasecmp(argv[1], "install-tap") == 0) { Mac *m = (Mac*) obj; m->installTap(this); return TCL_OK; } } else if (argc == 4) { if (strcasecmp(argv[1], "add-ll") == 0) { if( (obj = TclObject::lookup(argv[2])) == 0) { fprintf(stderr, "DSRAgent: %s lookup of %s failed\n", argv[1], argv[2]); return TCL_ERROR; } ll = (NsObject*) obj; if( (obj = TclObject::lookup(argv[3])) == 0) { fprintf(stderr, "DSRAgent: %s lookup of %s failed\n", argv[1], argv[3]); return TCL_ERROR; } ifq = (PriQueue *) obj; return TCL_OK; } } return Agent::command(argc, argv);}voidDSRAgent::recv(Packet* packet, Handler*) /* handle packets with a MAC destination address of this host, or the MAC broadcast addr */{ hdr_sr *srh = (hdr_sr*)packet->access(off_sr_); hdr_ip *iph = (hdr_ip*)packet->access(off_ip_); hdr_cmn *cmh = (hdr_cmn*)packet->access(off_cmn_); assert(cmh->size() >= 0); SRPacket p(packet, srh); p.dest = ID(iph->dst(),::IP); p.src = ID(iph->src(),::IP); assert(logtarget != 0); if (!srh->valid()) { // this must be an outgoing packet, it doesn't have a SR header on it srh->init(); // give packet an SR header now cmh->size() += IP_HDR_LEN; // add on IP header size if (verbose) trace("S %.9f _%s_ originating %s -> %s", Scheduler::instance().clock(), net_id.dump(), p.src.dump(), p.dest.dump()); handlePktWithoutSR(p, false); goto done; } else if (p.dest == net_id || p.dest == IP_broadcast) { // this packet is intended for us handlePacketReceipt(p); goto done; } // should we check to see if it's an error packet we're handling // and if so call processBrokenRouteError to snoop if (dsragent_snoop_forwarded_errors && srh->route_error()) { processBrokenRouteError(p); } if (srh->route_request()) { // propagate a route_request that's not for us handleRouteRequest(p); } else { // we're not the intended final recpt, but we're a hop handleForwarding(p); }done: assert(p.pkt == 0); p.pkt = 0; return;}/*=========================================================================== handlers for each class of packet---------------------------------------------------------------------------*/voidDSRAgent::handlePktWithoutSR(SRPacket& p, bool retry) /* obtain a source route to p's destination and send it off. this should be a retry if the packet is already in the sendbuffer */{ hdr_sr *srh = (hdr_sr*)p.pkt->access(off_sr_); assert(srh->valid()); if (p.dest == net_id) { // it doesn't need a source route, 'cause it's for us handlePacketReceipt(p); return; } if (route_cache->findRoute(p.dest, p.route, 1)) { // we've got a route... if (verbose) trace("S$hit %.5f _%s_ %s -> %s %s", Scheduler::instance().clock(), net_id.dump(), p.src.dump(), p.dest.dump(), p.route.dump()); sendOutPacketWithRoute(p, true); return; } // end if we have a route else { // we don't have a route... if (verbose) trace("S$miss %.5f _%s_ %s -> %s", Scheduler::instance().clock(), net_id.dump(), net_id.dump(), p.dest.dump()); getRouteForPacket(p, retry); return; } // end of we don't have a route}voidDSRAgent::handlePacketReceipt(SRPacket& p) /* Handle a packet destined to us */{ hdr_cmn *cmh = (hdr_cmn*)p.pkt->access(off_cmn_); hdr_sr *srh = (hdr_sr*)p.pkt->access(off_sr_); if (srh->route_reply()) { // we got a route_reply piggybacked on a route_request // accept the new source route before we do anything else // (we'll send off any packet's we have queued and waiting) acceptRouteReply(p); } if (srh->route_request()) { if (dsragent_reply_only_to_first_rtreq && ignoreRouteRequestp(p)) { //we only respond to the first route request // we receive from a host Packet::free(p.pkt); // drop silently p.pkt = 0; return; } else { // we're going to process this request now, so record the req_num request_table.insert(p.src, p.src, srh->rtreq_seq()); returnSrcRouteToRequestor(p); } } if (srh->route_error()) { // register the dead route processBrokenRouteError(p); } /* give the data in the packet to our higher layer (our port dmuxer, most likely) */ assert(p.dest == net_id || p.dest == MAC_id); cmh->size() -= srh->size(); // cut off the SR header 4/7/99 -dam srh->valid() = 0; cmh->size() -= IP_HDR_LEN; // cut off IP header size 4/7/99 -dam target_->recv(p.pkt, (Handler*)0); p.pkt = 0;}voidDSRAgent::handleForwarding(SRPacket &p) /* forward packet on to next host in source route, snooping as appropriate */{ hdr_sr *srh = (hdr_sr*)p.pkt->access(off_sr_); hdr_cmn *cmh = (hdr_cmn*)p.pkt->access(off_cmn_); trace("SF %.9f _%s_ --- %d [%s -> %s] %s", Scheduler::instance().clock(), net_id.dump(), cmh->uid(), p.src.dump(), p.dest.dump(), srh->dump()); // first make sure we are the ``current'' host along the source route. // if we're not, the previous node set up the source route incorrectly. assert(p.route[p.route.index()] == net_id || p.route[p.route.index()] == MAC_id); if (p.route.index() >= p.route.length()) { fprintf(stderr,"dfu: ran off the end of a source route\n"); trace("SDFU: ran off the end of a source route\n"); drop(p.pkt, DROP_RTR_ROUTE_LOOP); p.pkt = 0; // maybe we should send this packet back as an error... return; } // if there's a source route, maybe we should snoop it too if (dsragent_snoop_source_routes) route_cache->noticeRouteUsed(p.route, Scheduler::instance().clock(), net_id); // sendOutPacketWithRoute will add in the size of the src hdr, so // we have to subtract it out here struct hdr_cmn *ch = HDR_CMN(p.pkt); ch->size() -= srh->size(); // now forward the packet... sendOutPacketWithRoute(p, false);}voidDSRAgent::handleRouteRequest(SRPacket &p) /* process a route request that isn't targeted at us */{ hdr_sr *srh = (hdr_sr*)p.pkt->access(off_sr_); assert (srh->route_request()); if (ignoreRouteRequestp(p)) { if (verbose_srr) trace("SRR %.5f _%s_ dropped %s #%d (ignored)", Scheduler::instance().clock(), net_id.dump(), p.src.dump(), srh->rtreq_seq()); Packet::free(p.pkt); // pkt is a route request we've already processed p.pkt = 0; return; // drop silently } // we're going to process this request now, so record the req_num request_table.insert(p.src, p.src, srh->rtreq_seq()); /* - if it's a Ring 0 search, check the rt$ for a reply and use it if possible. There's not much point in doing Ring 0 search if you're not going to check the cache. See the comment about turning off all reply from cache behavior near the definition of d_r_f_c_o_p (if your workload had really good spatial locality, it might still make sense 'cause your target is probably sitting next to you) - if reply from cache is on, check the cache and reply if possible - otherwise, just propagate if possible. */ if ((srh->max_propagation() == 0 || dsragent_reply_from_cache_on_propagating) && replyFromRouteCache(p)) return; // all done // does the orginator want us to propagate? if (p.route.length() > srh->max_propagation()) { // no propagation if (verbose_srr) trace("SRR %.5f _%s_ dropped %s #%d (prop limit exceeded)", Scheduler::instance().clock(), net_id.dump(), p.src.dump(), srh->rtreq_seq()); Packet::free(p.pkt); // pkt isn't for us, and isn't data carrying p.pkt = 0; return; } // can we propagate? if (p.route.full()) { // no propagation trace("SRR %.5f _%s_ dropped %s #%d (SR full)", Scheduler::instance().clock(), net_id.dump(), p.src.dump(), srh->rtreq_seq()); /* pkt is a rt req, even if data carrying, we don't want to log the drop using drop() since many nodes could be dropping the packet in this fashion */ Packet::free(p.pkt); p.pkt = 0; return; } // add ourselves to the source route p.route.appendToPath(net_id); if (verbose_srr) trace("SRR %.5f _%s_ rebroadcast %s #%d ->%s %s", Scheduler::instance().clock(), net_id.dump(), p.src.dump(), srh->rtreq_seq(), p.dest.dump(), p.route.dump()); sendOutPacketWithRoute(p, false); return; }/*=========================================================================== Helpers---------------------------------------------------------------------------*/boolDSRAgent::ignoreRouteRequestp(SRPacket &p)// should we ignore this route request?{ hdr_sr *srh = (hdr_sr*)p.pkt->access(off_sr_); if (request_table.get(p.src) >= srh->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()) { // there won't be room for us to put our address into // the route // so drop silently - sigh, so close, and yet so far... // Note that since we don't record the req_id of this message yet, // we'll process the request if it gets to us on a shorter path return true; } return false;}boolDSRAgent::replyFromRouteCache(SRPacket &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 */{ Path rest_of_route; Path complete_route = p.route; /* we shouldn't yet be on on the pkt's current source route */ assert(!p.route.member(net_id, MAC_id)); // 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 */ 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() + p.route.length() > MAX_SR_LEN) return false; // too long to work with... // add our suggested completion to the route so far complete_route.appendPath(rest_of_route); // call compressPath to remove any double backs ::compressPath(complete_route); if (!complete_route.member(net_id, MAC_id)) { // we're not on the suggested route, so we can't return it return false; } // if there is any other information piggybacked into the // route request pkt, we need to forward it on to the dst hdr_cmn *cmh = (hdr_cmn*)p.pkt->access(off_cmn_); hdr_sr *srh = (hdr_sr*)p.pkt->access(off_sr_); int request_seqnum = srh->rtreq_seq(); if (PT_DSR != cmh->ptype() // there's data
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -