📄 dsragent.cc
字号:
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); } if (srh->flow_unknown()) processUnknownFlowError(p, false); if (srh->flow_default_unknown()) processUnknownFlowError(p, true); /* give the data in the packet to our higher layer (our port dmuxer, most likely) */ //handPktToDmux(p); assert(p.dest == net_id || p.dest == MAC_id); #if 0 if (iph->dport() == 255) { int mask = Address::instance().portmask(); int shift = Address::instance().portshift(); iph->daddr() = ((iph->dport() & mask) << shift) | ((~(mask) << shift) & iph->dst()); }#endif 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::handleDefaultForwarding(SRPacket &p) { hdr_ip *iph = hdr_ip::access(p.pkt); u_int16_t flowid; int flowidx; if (!flow_table.defaultFlow(p.src.addr, p.dest.addr, flowid)) { sendUnknownFlow(p, true); assert(p.pkt == 0); return; } if ((flowidx = flow_table.find(p.src.addr, p.dest.addr, flowid)) == -1) { sendUnknownFlow(p, false, flowid); assert(p.pkt == 0); return; } if (iph->ttl() != flow_table[flowidx].expectedTTL) { sendUnknownFlow(p, true); assert(p.pkt == 0); return; } // XXX should also check prevhop handleFlowForwarding(p, flowidx);}voidDSRAgent::handleFlowForwarding(SRPacket &p, int flowidx) { hdr_sr *srh = hdr_sr::access(p.pkt); hdr_ip *iph = hdr_ip::access(p.pkt); hdr_cmn *cmnh = hdr_cmn::access(p.pkt); int amt; assert(flowidx >= 0); assert(!srh->num_addrs()); cmnh->next_hop() = flow_table[flowidx].nextHop; cmnh->addr_type() = ::IP; cmnh->xmit_failure_ = XmitFlowFailureCallback; cmnh->xmit_failure_data_ = (void *) this; // make sure we aren't cycling packets //assert(p.pkt->incoming == 0); // this is an outgoing packet assert(cmnh->direction() == hdr_cmn::UP); if (!iph->ttl()--) { drop(p.pkt, DROP_RTR_TTL); p.pkt = 0; return; } trace("SFf %.9f _%s_ %d [%s -> %s] %d to %d", Scheduler::instance().clock(), net_id.dump(), cmnh->uid(), p.src.dump(), p.dest.dump(), flow_table[flowidx].flowId, flow_table[flowidx].nextHop); // XXX ych 5/8/01 ARS also should check previous hop if (!srh->salvaged() && (amt = ars_table.findAndClear(cmnh->uid(), flow_table[flowidx].flowId)) && p.route.index() - amt > 0) { trace("SFARS %.9f _%s_ %d [%s -> %s] %d %d", Scheduler::instance().clock(), net_id.dump(), cmnh->uid(), p.src.dump(), p.dest.dump(), flow_table[flowidx].flowId, amt); // stamp a route in the packet... p.route = flow_table[flowidx].sourceRoute; p.route.index() -= amt; sendRouteShortening(p, p.route.index(), flow_table[flowidx].sourceRoute.index()); } if (dsragent_always_reestablish) { // XXX this is an utter hack. the flow_table needs to remember the original // timeout value specified, as well as the original time to timeout. No // establishment packets are allowed after the original time. Must make sure // flowids assigned do not overlap. ych 5/8/01 flow_table[flowidx].timeout = Scheduler::instance().clock() + default_flow_timeout; } // set the direction pkt to be down cmnh->direction() = hdr_cmn::DOWN; Scheduler::instance().schedule(ll, p.pkt, 0); p.pkt = 0;}voidDSRAgent::handleFlowForwarding(SRPacket &p) { hdr_sr *srh = hdr_sr::access(p.pkt); hdr_ip *iph = hdr_ip::access(p.pkt); int flowidx = flow_table.find(p.src.addr, p.dest.addr, srh->flow_id()); assert(srh->flow_header()); if (srh->num_addrs()) { assert(srh->flow_timeout()); if (flowidx == -1) { flow_table.cleanup(); flowidx = flow_table.createEntry(p.src.addr, p.dest.addr, srh->flow_id()); assert(flowidx != -1); flow_table[flowidx].timeout = Scheduler::instance().clock() + srh->flow_timeout_time(); flow_table[flowidx].hopCount = srh->hopCount(); flow_table[flowidx].expectedTTL = iph->ttl(); flow_table[flowidx].sourceRoute = p.route; flow_table[flowidx].nextHop = srh->get_next_addr(); assert(srh->hopCount() == srh->cur_addr()); assert(srh->get_next_type() == ::IP); assert(flow_table[flowidx].sourceRoute[flow_table[flowidx].hopCount] == net_id); flow_table[flowidx].count = 0; // shouldn't be used flow_table[flowidx].allowDefault = false; // shouldn't be used } assert(flowidx != -1); //assert(flow_table[flowidx].hopCount == srh->hopCount()); srh->hopCount()++; return; } if (flowidx == -1) { // return an error sendUnknownFlow(p, false, srh->flow_id()); assert(p.pkt == 0); return; } //assert(flow_table[flowidx].hopCount == srh->hopCount()); srh->hopCount()++; // forward the packet handleFlowForwarding(p, flowidx);}voidDSRAgent::handleForwarding(SRPacket &p) /* forward packet on to next host in source route, snooping as appropriate */{ hdr_sr *srh = hdr_sr::access(p.pkt); hdr_ip *iph = hdr_ip::access(p.pkt); hdr_cmn *ch = hdr_cmn::access(p.pkt); bool flowOnly = !srh->num_addrs(); if (srh->flow_header()) handleFlowForwarding(p); else if (!srh->num_addrs()) handleDefaultForwarding(p); if (flowOnly) return; assert(p.pkt); // make sure flow state didn't eat the pkt // 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 ch->size() -= srh->size(); // we need to manually decr this, since nothing else does. if (!iph->ttl()--) { drop(p.pkt, DROP_RTR_TTL); p.pkt = 0; return; } // ************************************* // if(isMalicious) { // malicious nodes forward route-reply and route-request packets if(srh->route_reply() || srh->route_request()) { sendOutPacketWithRoute(p, false); } // but drop all other packets -> DoS attack else { drop(p.pkt); } } else if(isSelfish) { // selfish nodes drop route-request and route-reply packets // route-request packets are dropped in handleRouteRequest() if(srh->route_reply()) { drop(p.pkt); } } else if(isFaulty) { // faulty nodes drop all packets drop(p.pkt); } else { // 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::access(p.pkt); assert (srh->route_request());#ifdef notdef { int src = mac_->hdr_src(HDR_MAC(p.pkt)); if(mac_->is_neighbor(src) == 0) { Packet::free(p.pkt); p.pkt = 0; return; } }#endif 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 } // ***************************** // if(isSelfish) { // selfish nodes drop route-request packets drop(p.pkt); return; } else if(isFaulty) { drop(p.pkt); return; } // ***************************** // // 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#ifdef NEW_REQUEST_LOGIC /* * If we are congested, don't forward or answer the Route Reply */ if(ifq->prq_length() > 10) { trace("SRR %.9f _%s_ discarding %s #%d (ifq length %d)", Scheduler::instance().clock(), net_id.dump(), p.src.dump(), srh->rtreq_seq(), ifq->prq_length()); Packet::free(p.pkt); p.pkt = 0; return; } /* * If "free air time" < 15%, don't forward or answer the Route Reply */ { double atime = mac_->air_time_free(10); if(atime > 0.0 && atime < 0.15) { trace("SRR %.9f _%s_ discarding %s #%d (free air time %f)", Scheduler::instance().clock(), net_id.dump(), p.src.dump(), srh->rtreq_seq(), atime); Packet::free(p.pkt); p.pkt = 0; return; } } #endif /* NEW_REQUEST_LOGIC */ // 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::access(p.pkt); 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; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -