📄 tora.cc
字号:
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- *//* * Copyright (c) 1997 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the Computer Systems * Engineering Group at Lawrence Berkeley Laboratory. * 4. Neither the name of the University nor of the Laboratory may be used * to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * Ported from CMU/Monarch's code * * $Header: /nfs/jade/vint/CVSROOT/ns-2/tora/tora.cc,v 1.14 2002/03/18 17:32:36 haldar Exp $ */#include <agent.h>#include <random.h>#include <trace.h>#include <ll.h>#include <priqueue.h>#include <tora/tora_packet.h>#include <tora/tora.h>#define LOG(s) \ fprintf(stdout, "%s --- %s (index: %d, time: %f)\n", \ __PRETTY_FUNCTION__, (s), index, Scheduler::instance().clock())// #define DEBUG#define CURRENT_TIME Scheduler::instance().clock()/* sec of spacing inserted between pkts when a bunch of packets are dumped into the link layer all at once. Allows arp time to resolve dst, preventing the dumping of all but the last pkt on the floor */#define ARP_SEPARATION_DELAY 0.030 /* ====================================================================== TCL Hooks ====================================================================== */int hdr_tora::offset_;static class TORAHeaderClass : public PacketHeaderClass {public: TORAHeaderClass() : PacketHeaderClass("PacketHeader/TORA", TORA_HDR_LEN) { bind_offset(&hdr_tora::offset_); } } class_toraAgent_hdr;static class toraAgentclass : public TclClass {public: toraAgentclass() : TclClass("Agent/TORA") {} TclObject* create(int argc, const char*const* argv) { assert(argc == 5); return (new toraAgent((nsaddr_t) atoi(argv[4]))); }} class_toraAgent;/* ====================================================================== toraAgent Class Functions ====================================================================== */toraAgent::toraAgent(nsaddr_t id) : rtAgent(id, PT_TORA), rqueue(){ LIST_INIT(&dstlist); imepagent = 0; logtarget = 0; ifqueue = 0;}voidtoraAgent::reset(){ Packet *p; while((p = rqueue.deque())) { drop(p,DROP_END_OF_SIMULATION); }}inttoraAgent::command(int argc, const char*const* argv){ if(argc == 2) { Tcl& tcl = Tcl::instance(); if(strncasecmp(argv[1], "id", 2) == 0) { tcl.resultf("%d", index); return TCL_OK; } } else if(argc == 3) { if(strcmp(argv[1], "log-target") == 0 || strcmp(argv[1], "tracetarget") == 0 ) { logtarget = (Trace*) TclObject::lookup(argv[2]); if(logtarget == 0) return TCL_ERROR; return TCL_OK; } else if(strcmp(argv[1], "drop-target") == 0) { int stat = rqueue.command(argc,argv); if (stat != TCL_OK) return stat; return Agent::command(argc, argv); } else if(strcmp(argv[1], "if-queue") == 0) { ifqueue = (PriQueue*) TclObject::lookup(argv[2]); if(ifqueue == 0) return TCL_ERROR; return TCL_OK; } else if(strcmp(argv[1], "imep-agent") == 0) { imepagent = (imepAgent*) TclObject::lookup(argv[2]); if(imepagent == 0) return TCL_ERROR; imepagent->imepRegister((rtAgent*) this); return TCL_OK; } } return Agent::command(argc, argv);}/* ====================================================================== Destination Management Functions ====================================================================== */TORADest*toraAgent::dst_find(nsaddr_t id){ TORADest* td = dstlist.lh_first; for( ; td; td = td->link.le_next) { if(td->index == id) return td; } return 0;}TORADest*toraAgent::dst_add(nsaddr_t id){ TORADest *td = new TORADest(id, this); assert(td); LIST_INSERT_HEAD(&dstlist, td, link); int *nblist = 0, nbcnt = 0; imepagent->imepGetBiLinks(nblist, nbcnt); for(int i = 0; i < nbcnt; i++) (void) td->nb_add(nblist[i]); if(nblist) delete[] nblist; return td;}voidtoraAgent::dst_dump(){ TORADest *td = dstlist.lh_first; for( ; td; td = td = td->link.le_next) td->dump();}/* ====================================================================== Route Resolution ====================================================================== */voidtoraAgent::forward(Packet *p, nsaddr_t nexthop, Time delay){ struct hdr_cmn *ch = HDR_CMN(p);#ifdef TORA_DISALLOW_ROUTE_LOOP if(nexthop == ch->prev_hop_) { log_route_loop(ch->prev_hop_, nexthop); drop(p, DROP_RTR_ROUTE_LOOP); return; }#endif ch->next_hop() = nexthop; ch->prev_hop_ = ipaddr(); ch->addr_type() = NS_AF_INET; // change the packet direction to DOWN ch->direction() = hdr_cmn::DOWN; if (0.0 == delay) { tora_output(p); } else { Scheduler::instance().schedule(target_, p, delay); }}voidtoraAgent::rt_resolve(Packet *p){ struct hdr_ip *ih = HDR_IP(p); TORADest *td; TORANeighbor *tn; td = dst_find(ih->daddr()); if(td == 0) { td = dst_add(ih->daddr()); } tn = td->nb_find_next_hop(); if(tn == 0) { rqueue.enque(p); trace("T %.9f _%d_ tora enq %d->%d", Scheduler::instance().clock(), ipaddr(), ih->saddr(), ih->daddr()); if(!td->rt_req) { // if no QRY pending, then send one sendQRY(ih->daddr()); td->time_tx_qry = CURRENT_TIME; td->rt_req = 1; } } else { forward(p, tn->index); }}/* ====================================================================== Incoming Packets ====================================================================== */voidtoraAgent::recv(Packet *p, Handler *){ struct hdr_cmn *ch = HDR_CMN(p); struct hdr_ip *ih = HDR_IP(p); assert(initialized()); if(ch->ptype() == PT_TORA) { recvTORA(p); return; } /* * Must be a packet I'm originating... */ if(ih->saddr() == ipaddr() && ch->num_forwards() == 0) { /* * Add the IP Header. */ ch->size() += IP_HDR_LEN; ih->ttl_ = IP_DEF_TTL; }#ifdef TORA_DISALLOW_ROUTE_LOOP /* * I received a packet that I sent. Probably * a routing loop. */ else if(ih->saddr() == ipaddr()) { drop(p, DROP_RTR_ROUTE_LOOP); return; }#endif /* * Packet I'm forwarding... */ else { /* * Check the TTL. If it is zero, then discard. */ if(--ih->ttl_ == 0) { drop(p, DROP_RTR_TTL); return; } } rt_resolve(p);}voidtoraAgent::recvTORA(Packet *p){ struct hdr_ip *ih = HDR_IP(p); struct hdr_tora *th = HDR_TORA(p); TORADest *td; TORANeighbor *tn; /* * Fix the source IP address. */ assert(ih->sport() == RT_PORT); assert(ih->dport() == RT_PORT); /* * Incoming Packets. */ switch(th->th_type) { case TORATYPE_QRY: recvQRY(p); Packet::free(p); return; // don't add/change routing state case TORATYPE_UPD: log_recv_upd(p); recvUPD(p); break; case TORATYPE_CLR: log_recv_clr(p); recvCLR(p); break; default: fprintf(stderr, "%s: Invalid TORA type (%x)\n", __PRETTY_FUNCTION__, th->th_type); exit(1); } if((td = dst_find(th->th_dst)) == 0) { Packet::free(p); return; } logNextHopChange(td); if((tn = td->nb_find_next_hop())) { Packet *p0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -