📄 dsragent.cc
字号:
}intDSRAgent::command(int argc, const char*const* argv){ TclObject *obj; if (argc == 2) { if (strcasecmp(argv[1], "testinit") == 0) { testinit(); return TCL_OK; } if (strcasecmp(argv[1], "reset") == 0) { Terminate(); return Agent::command(argc, argv); } if (strcasecmp(argv[1], "check-cache") == 0) { return route_cache->command(argc, argv); } if (strcasecmp(argv[1], "startdsr") == 0) { if (ID(1,::IP) == net_id) { // log the configuration parameters of the dsragent trace("Sconfig %.5f tap: %s snoop: rts? %s errs? %s", Scheduler::instance().clock(), dsragent_use_tap ? "on" : "off", dsragent_snoop_source_routes ? "on" : "off", dsragent_snoop_forwarded_errors ? "on" : "off"); trace("Sconfig %.5f salvage: %s !bd replies? %s", Scheduler::instance().clock(), dsragent_salvage_with_cache ? "on" : "off", dsragent_dont_salvage_bad_replies ? "on" : "off"); trace("Sconfig %.5f grat error: %s grat reply: %s", Scheduler::instance().clock(), dsragent_propagate_last_error ? "on" : "off", dsragent_send_grat_replies ? "on" : "off"); trace("Sconfig %.5f $reply for props: %s ring 0 search: %s", Scheduler::instance().clock(), dsragent_reply_from_cache_on_propagating ? "on" : "off", dsragent_ring_zero_search ? "on" : "off"); } // cheap source of jitter send_buf_timer.sched(BUFFER_CHECK + BUFFER_CHECK * Random::uniform(1.0)); return route_cache->command(argc,argv); } } else if(argc == 3) { if (strcasecmp(argv[1], "addr") == 0) { int temp; temp = Address::instance().str2addr(argv[2]); net_id = ID(temp, ::IP); flow_table.setNetAddr(net_id.addr); route_cache->net_id = net_id; return TCL_OK; } else if(strcasecmp(argv[1], "mac-addr") == 0) { MAC_id = ID(atoi(argv[2]), ::MAC); route_cache->MAC_id = MAC_id; return TCL_OK; } else if(strcasecmp(argv[1], "rt_rq_max_period") == 0) { rt_rq_max_period = strtod(argv[2],NULL); return TCL_OK; } else if(strcasecmp(argv[1], "rt_rq_period") == 0) { rt_rq_period = strtod(argv[2],NULL); return TCL_OK; } else if(strcasecmp(argv[1], "send_timeout") == 0) { send_timeout = strtod(argv[2],NULL); 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], "tracetarget") == 0 ) { logtarget = (Trace*) obj; return route_cache->command(argc, argv); } else if (strcasecmp(argv[1], "install-tap") == 0) { mac_ = (Mac*) obj; mac_->installTap(this); return TCL_OK; } else if (strcasecmp(argv[1], "node") == 0) { node_ = (MobileNode *) obj; return TCL_OK; } else if (strcasecmp (argv[1], "port-dmux") == 0) { port_dmux_ = (NsObject *) obj; 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 = (CMUPriQueue *) obj; return TCL_OK; } } return Agent::command(argc, argv);}voidDSRAgent::sendOutBCastPkt(Packet *p){ hdr_cmn *cmh = hdr_cmn::access(p); if(cmh->direction() == hdr_cmn::UP) cmh->direction() = hdr_cmn::DOWN; // no jitter required Scheduler::instance().schedule(ll, p, 0.0);}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::access(packet); hdr_ip *iph = hdr_ip::access(packet); hdr_cmn *cmh = hdr_cmn::access(packet); // special process for GAF if (cmh->ptype() == PT_GAF) { if (iph->daddr() == (int)IP_BROADCAST) { if(cmh->direction() == hdr_cmn::UP) cmh->direction() = hdr_cmn::DOWN; Scheduler::instance().schedule(ll,packet,0); return; } else { target_->recv(packet, (Handler*)0); return; } } assert(cmh->size() >= 0); SRPacket p(packet, srh); //p.dest = ID(iph->dst(),::IP); //p.src = ID(iph->src(),::IP); p.dest = ID((Address::instance().get_nodeaddr(iph->daddr())),::IP); p.src = ID((Address::instance().get_nodeaddr(iph->saddr())),::IP); assert(logtarget != 0); if (srh->valid() != 1) { unsigned int dst = cmh->next_hop(); if (dst == IP_BROADCAST) { // extensions for mobileIP --Padma, 04/99. // Brdcast pkt - treat differently if (p.src == net_id) // I have originated this pkt sendOutBCastPkt(packet); else //hand it over to port-dmux port_dmux_->recv(packet, (Handler*)0); } else { // 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 (srh->valid() == 1) { 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); } } else { // some invalid pkt has reached here fprintf(stderr,"dsragent: Error-received Invalid pkt!\n"); Packet::free(p.pkt); p.pkt =0; // drop silently } 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 */{ assert(HDR_SR (p.pkt)->valid()); if (p.dest == net_id) { // it doesn't need a source route, 'cause it's for us handlePacketReceipt(p); return; } // Extensions for wired cum wireless simulation mode //if pkt dst outside my subnet, route to base_stn ID dest; if (diff_subnet(p.dest,net_id)) { dest = ID(node_->base_stn(),::IP); p.dest = dest; } 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::access(p.pkt); hdr_sr *srh = hdr_sr::access(p.pkt); 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)) &&
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -