📄 dsdv.cc
字号:
} else { // If the first thing we hear from a node is a triggered update // that doesn't list the node sending the update as the first // thing in the packet (which is disrecommended by the paper) // we won't have a route to that node already. In order to timeout // the routes we just learned, we need a harmless route to keep the // timeout metadata straight. // Hi there, nice to meet you. I'll make a fake advertisement bzero(&rte, sizeof(rte)); rte.dst = Address::instance().get_nodeaddr(iph->saddr()); rte.hop = Address::instance().get_nodeaddr(iph->saddr()); rte.metric = 1; rte.seqnum = 0; rte.advertise_ok_at = now + 604800; // check back next week... :) rte.changed_at = now; rte.new_seqnum_at = now; rte.wst = wst0_; rte.timeout_event = new Event (); rte.q = 0; updateRoute(NULL, &rte); s.schedule(helper_, rte.timeout_event, min_update_periods_ * perup_); } /* * Freeing a routing layer packet --> don't need to * call drop here. */ Packet::free (p);}int DSDV_Agent::diff_subnet(int dst) { char* dstnet = Address::instance().get_subnetaddr(dst); if (subnet_ != NULL) { if (dstnet != NULL) { if (strcmp(dstnet, subnet_) != 0) { delete [] dstnet; return 1; } delete [] dstnet; } } //assert(dstnet == NULL); return 0;}voidDSDV_Agent::forwardPacket (Packet * p){ hdr_ip *iph = HDR_IP(p); Scheduler & s = Scheduler::instance (); double now = s.clock (); hdr_cmn *hdrc = HDR_CMN (p); int dst; rtable_ent *prte; // We should route it. //printf("(%d)-->forwardig pkt\n",myaddr_); // set direction of pkt to -1 , i.e downward hdrc->direction() = hdr_cmn::DOWN; // if the destination is outside mobilenode's domain // forward it to base_stn node // Note: pkt is not buffered if route to base_stn is unknown dst = Address::instance().get_nodeaddr(iph->daddr()); if (diff_subnet(iph->daddr())) { prte = table_->GetEntry (dst); if (prte && prte->metric != BIG) goto send; //int dst = (node_->base_stn())->address(); dst = node_->base_stn(); prte = table_->GetEntry (dst); if (prte && prte->metric != BIG) goto send; else { //drop pkt with warning fprintf(stderr, "warning: Route to base_stn not known: dropping pkt\n"); Packet::free(p); return; } } prte = table_->GetEntry (dst); // trace("VDEBUG-RX %d %d->%d %d %d 0x%08x 0x%08x %d %d", // myaddr_, iph->src(), iph->dst(), hdrc->next_hop_, hdrc->addr_type_, // hdrc->xmit_failure_, hdrc->xmit_failure_data_, // hdrc->num_forwards_, hdrc->opt_num_forwards); if (prte && prte->metric != BIG) { //printf("(%d)-have route for dst\n",myaddr_); goto send; } else if (prte) { /* must queue the packet */ //printf("(%d)-no route, queue pkt\n",myaddr_); if (!prte->q) { prte->q = new PacketQueue (); } prte->q->enque(p); if (verbose_) trace ("VBP %.5f _%d_ %d:%d -> %d:%d", now, myaddr_, iph->saddr(), iph->sport(), iph->daddr(), iph->dport()); while (prte->q->length () > MAX_QUEUE_LENGTH) drop (prte->q->deque (), DROP_RTR_QFULL); return; } else { // Brand new destination rtable_ent rte; double now = s.clock(); bzero(&rte, sizeof(rte)); rte.dst = dst; rte.hop = dst; rte.metric = BIG; rte.seqnum = 0; rte.advertise_ok_at = now + 604800; // check back next week... :) rte.changed_at = now; rte.new_seqnum_at = now; // was now + wst0_, why??? XXX -dam rte.wst = wst0_; rte.timeout_event = 0; rte.q = new PacketQueue(); rte.q->enque(p); assert (rte.q->length() == 1 && 1 <= MAX_QUEUE_LENGTH); table_->AddEntry(rte); if (verbose_) trace ("VBP %.5f _%d_ %d:%d -> %d:%d", now, myaddr_, iph->saddr(), iph->sport(), iph->daddr(), iph->dport()); return; } send: hdrc->addr_type_ = NS_AF_INET; hdrc->xmit_failure_ = mac_callback; hdrc->xmit_failure_data_ = this; if (prte->metric > 1) hdrc->next_hop_ = prte->hop; else hdrc->next_hop_ = dst; if (verbose_) trace ("Routing pkts outside domain: \VFP %.5f _%d_ %d:%d -> %d:%d", now, myaddr_, iph->saddr(), iph->sport(), iph->daddr(), iph->dport()); assert (!HDR_CMN (p)->xmit_failure_ || HDR_CMN (p)->xmit_failure_ == mac_callback); target_->recv(p, (Handler *)0); return; }void DSDV_Agent::sendOutBCastPkt(Packet *p){ Scheduler & s = Scheduler::instance (); // send out bcast pkt with jitter to avoid sync s.schedule (target_, p, jitter(DSDV_BROADCAST_JITTER, be_random_));}voidDSDV_Agent::recv (Packet * p, Handler *){ hdr_ip *iph = HDR_IP(p); hdr_cmn *cmh = HDR_CMN(p); int src = Address::instance().get_nodeaddr(iph->saddr()); /* * Must be a packet I'm originating... */ if(src == myaddr_ && cmh->num_forwards() == 0) { /* * Add the IP Header */ cmh->size() += IP_HDR_LEN; iph->ttl_ = IP_DEF_TTL; } /* * I received a packet that I sent. Probably * a routing loop. */ else if(src == myaddr_) { drop(p, DROP_RTR_ROUTE_LOOP); return; } /* * Packet I'm forwarding... */ else { /* * Check the TTL. If it is zero, then discard. */ if(--iph->ttl_ == 0) { drop(p, DROP_RTR_TTL); return; } } if ((src != myaddr_) && (iph->dport() == ROUTER_PORT)) { // XXX disable this feature for mobileIP where // the MH and FA (belonging to diff domains) // communicate with each other. // Drop pkt if rtg update from some other domain: // if (diff_subnet(iph->src())) // drop(p, DROP_OUTSIDE_SUBNET); //else processUpdate(p); } else if (iph->daddr() == ((int)IP_BROADCAST) && (iph->dport() != ROUTER_PORT)) { if (src == myaddr_) { // handle brdcast pkt sendOutBCastPkt(p); } else { // hand it over to the port-demux port_dmux_->recv(p, (Handler*)0); } } else { forwardPacket(p); }}static class DSDVClass:public TclClass{ public: DSDVClass ():TclClass ("Agent/DSDV") { } TclObject *create (int, const char *const *) { return (new DSDV_Agent ()); }} class_dsdv;DSDV_Agent::DSDV_Agent (): Agent (PT_MESSAGE), ll_queue (0), seqno_ (0), myaddr_ (0), subnet_ (0), node_ (0), port_dmux_(0), periodic_callback_ (0), be_random_ (1), use_mac_ (0), verbose_ (1), trace_wst_ (0), lasttup_ (-10), alpha_ (0.875), wst0_ (6), perup_ (15), min_update_periods_ (3) // constants { table_ = new RoutingTable (); helper_ = new DSDV_Helper (this); trigger_handler = new DSDVTriggerHandler(this); bind_time ("wst0_", &wst0_); bind_time ("perup_", &perup_); bind ("use_mac_", &use_mac_); bind ("be_random_", &be_random_); bind ("alpha_", &alpha_); bind ("min_update_periods_", &min_update_periods_); bind ("verbose_", &verbose_); bind ("trace_wst_", &trace_wst_); //DEBUG address = 0; }voidDSDV_Agent::startUp(){ Time now = Scheduler::instance().clock(); subnet_ = Address::instance().get_subnetaddr(myaddr_); //DEBUG address = Address::instance().print_nodeaddr(myaddr_); //printf("myaddress: %d -> %s\n",myaddr_,address); rtable_ent rte; bzero(&rte, sizeof(rte)); rte.dst = myaddr_; rte.hop = myaddr_; rte.metric = 0; rte.seqnum = seqno_; seqno_ += 2; rte.advertise_ok_at = 0.0; // can always advert ourselves rte.advert_seqnum = true; rte.advert_metric = true; rte.changed_at = now; rte.new_seqnum_at = now; rte.wst = 0; rte.timeout_event = 0; // Don't time out our localhost :) rte.q = 0; // Don't buffer pkts for self! table_->AddEntry (rte); // kick off periodic advertisments periodic_callback_ = new Event (); Scheduler::instance ().schedule (helper_, periodic_callback_, jitter (DSDV_STARTUP_JITTER, be_random_));}int DSDV_Agent::command (int argc, const char *const *argv){ if (argc == 2) { if (strcmp (argv[1], "start-dsdv") == 0) { startUp(); return (TCL_OK); } else if (strcmp (argv[1], "dumprtab") == 0) { Packet *p2 = allocpkt (); hdr_ip *iph2 = HDR_IP(p2); rtable_ent *prte; printf ("Table Dump %d[%d]\n----------------------------------\n", iph2->saddr(), iph2->sport()); trace ("VTD %.5f %d:%d\n", Scheduler::instance ().clock (), iph2->saddr(), iph2->sport()); /* * Freeing a routing layer packet --> don't need to * call drop here. */ Packet::free (p2); for (table_->InitLoop (); (prte = table_->NextLoop ());) output_rte ("\t", prte, this); printf ("\n"); return (TCL_OK); } else if (strcasecmp (argv[1], "ll-queue") == 0) { if (!(ll_queue = (PriQueue *) TclObject::lookup (argv[2]))) { fprintf (stderr, "DSDV_Agent: ll-queue lookup of %s failed\n", argv[2]); return TCL_ERROR; } return TCL_OK; } } else if (argc == 3) { if (strcasecmp (argv[1], "addr") == 0) { int temp; temp = Address::instance().str2addr(argv[2]); myaddr_ = temp; return TCL_OK; } TclObject *obj; if ((obj = TclObject::lookup (argv[2])) == 0) { fprintf (stderr, "%s: %s lookup of %s failed\n", __FILE__, argv[1], argv[2]); return TCL_ERROR; } if (strcasecmp (argv[1], "tracetarget") == 0) { tracetarget = (Trace *) obj; 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; } } return (Agent::command (argc, argv));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -