agents.tex
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:40k
- %
- % personal commentary:
- % handlers and how they are used are confusing
- % Connector::send is needed, but so is just send()... confusing
- % default handler in Connector::recv is confusing
- % this is a DRAFT DRAFT DRAFT
- % - KFALL
- %
- chapter{Agents}
- label{sec:agents}
- Agents represent endpoints where network-layer
- packets are constructed or consumed, and are used in the implementation
- of protocols at various layers.
- %Generally, a user wishing to create a new
- %source or sink for network-layer packets
- %will create a class derived from {tt Agent}.
- The clsref{Agent}{../ns-2/agent.h} has an implementation partly in
- OTcl and partly in C++.
- The C++ implementation is contained in nsf{agent.cc} and
- nsf{agent.h}, and the OTcl support is in
- nsf{tcl/lib/ns-agent.tcl}.
- section{Agent state}
- label{sec:agentstate}
- The C++ clsref{Agent}{../ns-2/agent.h} includes enough internal state
- to assign various fields to a simulated packet before
- it is sent.
- This state includes the following:
- begin{tabularx}{linewidth}{rX}
- code{addr_} & node address of myself (source address in packets) \
- code{dst_} & where I am sending packets to \
- code{size_} & packet size in bytes (placed into the common packet header) \
- code{type_} & type of packet (in the common header, see packet.h) \
- code{fid_} & the IP flow identifier (formerly {em class} in ns-1) \
- code{prio_} & the IP priority field \
- code{flags_} & packet flags (similar to ns-1) \
- code{defttl_} & default IP ttl value \
- end{tabularx}
- These variables may be modified by any class derived from code{Agent},
- although not all of them may be needed by any particular agent.
- section{Agent methods}
- label{sec:agentmethods}
- The clsref{Agent}{../ns-2/agent.h} supports packet generation and reception.
- The following member functions are implemented by the C++ Agent class, and are
- generally {em not} over-ridden by derived classes:
- begin{tabularx}{linewidth}{rX}
- fcn[]{Packet* allocpkt} & allocate new packet and assign its fields \
- fcn[int]{Packet* allocpkt} & allocate new packet with a data payload of n bytes and assign its fields \
- end{tabularx}
- The following member functions are also defined by the class Agent,
- but {em are} intended to be over-ridden by classes deriving from Agent:
- begin{tabularx}{linewidth}{rX}
- fcn[timeout number]{void timeout} & subclass-specific time out method \
- fcn[Packet*, Handler*]{void recv} & receiving agent main receive path \
- end{tabularx}
- The fcn[]{allocpkt} method is used by derived classes
- to create packets to send.
- The function fills in the following fields
- href{in the common packet header}{Section}{chap:pformat}:
- {tt uid, ptype, size}, and the following fields in the IP header:
- {tt src, dst, flowid, prio, ttl}.
- It also zero-fills in the following fields of the Flags header:
- {tt ecn, pri, usr1, usr2}.
- Any packet header information not included in these lists must
- be must be handled in the classes derived from code{Agent}.
- The fcn[]{recv} method is the main entry point for an
- Agent which receives packets, and
- is invoked by upstream nodes when sending a packet.
- In most cases, Agents make no use of the second argument (the handler
- defined by upstream nodes).
- section{Protocol Agents}
- label{sec:protoagents}
- There are several agents supported in the simulator.
- These are their names in OTcl:
- begin{longtable}{rl}
- TCP & a ``Tahoe'' TCP sender (cwnd = 1 on any loss) \
- TCP/Reno & a ``Reno'' TCP sender (with fast recovery) \
- TCP/Newreno & a modified Reno TCP sender (changes fast recovery) \
- TCP/Sack1 & a SACK TCP sender \
- TCP/Fack & a ``forward'' SACK sender TCP \
- TCP/FullTcp & a more full-functioned TCP with 2-way traffic \
- TCP/Vegas & a ``Vegas'' TCP sender \
- TCP/Vegas/RBP & a Vegas TCP with ``rate based pacing'' \
- TCP/Vegas/RBP & a Reno TCP with ``rate based pacing'' \
- TCP/Asym & an experimental Tahoe TCP for asymmetric links \
- TCP/Reno/Asym & an experimental Reno TCP for asymmetric links \
- TCP/Newreno/Asym & an experimental Newreno TCP for asymmetric links \
- TCPSink & a Reno or Tahoe TCP receiver (not used for FullTcp) \
- TCPSink/DelAck & a TCP delayed-ACK receiver \
- TCPSink/Asym & an experimental TCP sink for asymmetric links \
- TCPSink/Sack1 & a SACK TCP receiver \
- TCPSink/Sack1/DelAck & a delayed-ACK SACK TCP receiver \
- \
- UDP & a basic UDP agent\
- \
- RTP & an RTP sender and receiver \
- RTCP & an RTCP sender and receiver \
- \
- LossMonitor & a packet sink which checks for losses \
- \
- IVS/Source & an IVS source \
- IVS/Receiver & an IVS receiver \
- \
- CtrMcast/Encap & a ``centralised multicast'' encapsulator \
- CtrMcast/Decap & a ``centralised multicast'' de-encapsulator \
- Message & a protocol to carry textual messages \
- Message/Prune & processes multicast routing prune messages \
- \
- SRM & an SRM agent with non-adaptive timers \
- SRM/Adaptive & an SRM agent with adaptive timers \
- \
- Tap & interfaces the simulator to a live network \
- \
- Null & a degenerate agent which discards packets \
- \
- rtProto/DV & distance-vector routing protocol agent \
- end{longtable}
- Agents are used in the implementation of protocols at various layers.
- Thus, for some transport protocols (e.g.~UDP) the distribution
- of packet sizes and/or inter-departure times
- may be dictated by some separate
- object representing the demands of an application. To this end, agents
- expose an application programming interface (API) to the application.
- For agents used in the implementation of lower-layer protocols
- (e.g. routing agents), size and departure timing is generally dictated
- by the agent's own processing of protocol messages.
- section{OTcl Linkage}
- label{sec:agentotcl}
- Agents may be created within OTcl and an agent's internal
- state can be modified by use of Tcl's code{set} function and
- any Tcl functions an Agent (or its base classes) implements.
- Note that some of an Agent's internal state may exist
- only within OTcl, and is thus is not directly accessible from C++.
- subsection{Creating and Manipulating Agents}
- label{sec:agentcreateotcl}
- The following example illustrates the creation and modification
- of an Agent in OTcl:
- begin{program}
- set newtcp [new Agent/TCP] ; create new object (and C++ shadow object);
- $newtcp set window_ 20 ; sets the tcp agent's window to 20;
- $newtcp target $dest ; target is implemented in Connector class;
- $newtcp set portID_ 1 ; exists only in OTcl, not in C++;
- end{program}
- subsection{Default Values}
- label{sec:agentdefaults}
- Default values for member variables, those visible in OTcl only and those
- linked between OTcl and C++ with code{bind} are initialized
- in the nsf{tcl/lib/ns-default.tcl} file. For example,
- code{Agent} is initialized as follows:
- begin{program}
- Agent set fid_ 0
- Agent set prio_ 0
- Agent set addr_ 0
- Agent set dst_ 0
- Agent set flags_ 0
- end{program}
- Generally these initializations are placed in the OTcl namespace
- before any objects of these types are created.
- Thus, when an code{Agent} object
- is created, the calls to code{bind}
- in the objects' constructors will causes the corresponding member variables
- to be set to these specified defaults.
- subsection{OTcl Methods}
- label{sec:agentmethodsotcl}
- The instance procedures defined for the OTcl code{Agent} class are
- currently found in nsf{tcl/lib/ns-agent.tcl}.
- They are as follows:
- begin{tabularx}{linewidth}{rX}
- code{port} & the agent's port identifier \
- code{dst-port} & the destination's port identifier \
- code{attach-source tup{stype}} & create and attach a Source object to an agent \
- end{tabularx}
- section{Examples: Tcp, TCP Sink Agents}
- label{sec:agentexample}
- The clsref{TCP}{../ns-2/tcp.h} represents a simplified TCP sender.
- It sends data to a code{TCPSink} agent and processes its acknowledgments.
- It has a separate object associated with it which represents
- an application's demand.
- By looking at the clsref{TCPAgent}{../ns-2/tcp.h} and
- clsref{TCPSinkAgent}{../ns-2/tcp-sink.h},
- we may see how relatively complex agents are constructed.
- An example from the Tahoe TCP agent code{TCPAgent} is also given
- to illustrate the use of timers.
- subsection{Creating the Agent}
- label{sec:createtcpsimple}
- The following OTcl code fragment creates a code{TCP} agent
- and sets it up:
- begin{program}
- set tcp [new Agent/TCP] ; create sender agent;
- $tcp set fid_ 2 ; set IP-layer flow ID;
- set sink [new Agent/TCPSink] ; create receiver agent;
- $ns attach-agent $n0 $tcp ; put sender on node $n0;
- $ns attach-agent $n3 $sink ; put receiver on node $n3;
- $ns connect $tcp $sink ; establish TCP connection;
- set ftp [new Application/FTP] ; create an FTP source "application";
- $ftp attach-agent $tcp ; associate FTP with the TCP sender;
- $ns at 1.2 "$ftp start" ;arrange for FTP to start at time 1.2 sec;
- end{program}
- The OTcl instruction code{new Agent/TCP} results in the
- creation of a C++ code{TcpAgent} class object.
- Its constructor first invokes the constructor of the
- code{Agent} base class and then performs its own bindings.
- These two constructors appear as follows:
- begin{program}
- {rm The TcpSimpleAgent constructor (nsf{tcp.cc}):}
- TcpAgent::TcpAgent() : Agent(PT_TCP), rtt_active_(0), rtt_seq_(-1),
- rtx_timer_(this), delsnd_timer_(this)
- {
- bind("window_", &wnd_);
- bind("windowInit_", &wnd_init_);
- bind("windowOption_", &wnd_option_);
- bind("windowConstant_", &wnd_const_);
- ldots
- bind("off_ip_", &off_ip_);
- bind("off_tcp_", &off_tcp_);
- ldots
- }
- {rm The Agent constructor (nsf{agent.cc}):}
- Agent::Agent(int pkttype) :
- addr_(-1), dst_(-1), size_(0), type_(pkttype), fid_(-1),
- prio_(-1), flags_(0)
- {
- memset(pending_, 0, sizeof(pending_)); * timers */
- // {cf this is really an IP agent, so set up}
- // {cf for generating the appropriate IP fieldsldots}
- bind("addr_", (int*)&addr_);
- bind("dst_", (int*)&dst_);
- bind("fid_", (int*)&fid_);
- bind("prio_", (int*)&prio_);
- bind("flags_", (int*)&flags_);
- ldots
- }
- end{program}
- These code fragments illustrate the common case where an agent's
- constructor passes a packet type identifier to the code{Agent}
- constructor.
- The values for the various packet types are
- href{used by the packet tracing facility}{Section}{sec:traceptype}
- and are defined in nsf{trace.h}.
- The variables which are bound in the code{TcpAgent} constructor
- are ordinary instance/member variables for the class
- with the exception of the special integer values code{off_tcp_}
- and code{off_ip_}.
- These are needed in order to access a TCP header and IP header, respectively.
- href{Additional details are in the section on packet headers}{Section}{sec:ppackethdr}.
- Note that the code{TcpAgent} constructor contains initializations for
- two timers, code{rtx_timer_} and code{delsnd_timer_}.
- code{TimerHandler}
- objects are initialized by providing a pointer (the code{this} pointer) to
- the relevant agent.
- subsection{Starting the Agent}
- label{sec:starttcp}
- The code{TcpAgent} agent is started in the example when its
- FTP source receives the code{start} directive at time 1.2.
- The code{start} operation is an instance procedure defined on the
- href{class Application/FTP}{Section}{sec:simapps}.
- It is defined in nsf{tcl/lib/ns-source.tcl} as follows:
- begin{program}
- Application/FTP instproc start {} {
- [$self agent] send -1
- }
- end{program}
- In this case, code{agent} refers to our simple TCP agent and
- code{send -1} is analogous to sending an arbitrarily large file.
- The call to code{send} eventually results in the simple TCP sender
- generating packets.
- The following function code{output} performs this:
- begin{program}
- void TcpAgent::output(int seqno, int reason)
- {
- Packet* p = allocpkt();
- hdr_tcp *tcph = (hdr_tcp*)p->access(off_tcp_);
- double now = Scheduler::instance().clock();
- tcph->seqno() = seqno;
- tcph->ts() = now;
- tcph->reason() = reason;
- Connector::send(p, 0);
- ldots
- if (!(rtx_timer_.status() == TIMER_PENDING))
- /* {cf No timer pending. Schedule one.} */
- set_rtx_timer();
- }
- end{program}
- Here we see an illustration of the use of the fcn[]{Agent::allocpkt} method.
- This output routine first allocates a new packet
- (with its common and IP headers already filled in), but then must fill
- in the appropriate TCP-layer header fields.
- To find the TCP header in a packet
- (href{assuming it has been enabled}{Section}{sec:packethdrmgr})
- the code{off_tcp_} must be properly initialized,
- as illustrated in the constructor.
- The packet fcn[]{access} method returns a pointer to the TCP header,
- its sequence number and time stamp fields are filled in,
- and the fcn[]{send} method of the class Connector is called
- to send the packet downstream one hop.
- Note that the C++ code{::} scoping operator is used here to avoid
- calling fcn[]{TcpSimpleAgent::send} (which is also defined).
- The check for a pending timer uses the timer method fcn[]{status} which
- is defined in the base class TimerHandler.
- It is used here to set a retransmission timer if one is not already set
- (a TCP sender only sets one timer per window of packets on each connection).
- subsection{Processing Input at Receiver}
- label{sec:tcpsink}
- Many of the TCP agents can be used with the
- clsref{TCPSink}{../ns-2/tcp-sink.h} as the peer.
- This class defines the fcn[]{recv} and fcn[]{ack} methods as follows:
- begin{program}
- void TcpSink::recv(Packet* pkt, Handler*)
- {
- hdr_tcp *th = (hdr_tcp*)pkt->access(off_tcp_);
- acker_->update(th->seqno());
- ack(pkt);
- Packet::free(pkt);
- }
- void TcpSink::ack(Packet* opkt)
- {
- Packet* npkt = allocpkt();
-
- hdr_tcp *otcp = (hdr_tcp*)opkt->access(off_tcp_);
- hdr_tcp *ntcp = (hdr_tcp*)npkt->access(off_tcp_);
- ntcp->seqno() = acker_->Seqno();
- ntcp->ts() = otcp->ts();
-
- hdr_ip* oip = (hdr_ip*)opkt->access(off_ip_);
- hdr_ip* nip = (hdr_ip*)npkt->access(off_ip_);
- nip->flowid() = oip->flowid();
-
- hdr_flags* of = (hdr_flags*)opkt->access(off_flags_);
- hdr_flags* nf = (hdr_flags*)npkt->access(off_flags_);
- nf->ecn_ = of->ecn_;
-
- acker_->append_ack((hdr_cmn*)npkt->access(off_cmn_),
- ntcp, otcp->seqno());
- send(npkt, 0);
- }
- end{program}
- The fcn[]{recv} method overrides the fcn[]{Agent::recv} method
- (which merely discards the received packet).
- It updates some internal state with the sequence number of the
- received packet (and therefore requires the code{off_tcp_} variable
- to be properly initialized.
- It then generates an acknowledgment for the received packet.
- The fcn[]{ack} method makes liberal use of access to packet header
- fields including separate accesses to the TCP header, IP header,
- Flags header, and common header.
- The call to fcn[]{send} invokes the fcn[]{Connector::send} method.
- subsection{Processing Responses at the Sender}
- label{sec:tcpsimpleack}
- Once the simple TCP's peer receives data and generates an ACK, the
- sender must (usually) process the ACK.
- In the code{TcpAgent} agent, this is done as follows:
- begin{program}
- /*
- * {cf main reception path - should only see acks, otherwise the}
- * {cf network connections are misconfigured}
- */
- void TcpAgent::recv(Packet *pkt, Handler*)
- {
- hdr_tcp *tcph = (hdr_tcp*)pkt->access(off_tcp_);
- hdr_ip* iph = (hdr_ip*)pkt->access(off_ip_);
- ...
- if (((hdr_flags*)pkt->access(off_flags_))->ecn_)
- quench(1);
- if (tcph->seqno() > last_ack_) {
- newack(pkt);
- opencwnd();
- } else if (tcph->seqno() == last_ack_) {
- if (++dupacks_ == NUMDUPACKS) {
- ldots
- }
- }
- Packet::free(pkt);
- send(0, 0, maxburst_);
- }
- end{program}
- This routine is invoked when an ACK arrives at the sender.
- In this case, once the information in the ACK is processed (by code{newack})
- the packet is no longer needed and is returned to the packet memory
- allocator.
- In addition, the receipt of the ACK indicates the possibility of sending
- additional data, so the fcn[]{TcpSimpleAgent::send} method is
- invoked which attempts to send more data if the TCP window allows.
- subsection{Implementing Timers}
- label{sec:tcptimer}
- As described in
- href{the following chapter}{Chapter}{chap:timers}, specific
- timer classes must be derived from an abstract base
- clsref{TimerHandler}{../ns-2/timer-handler.h}
- defined in nsf{timer-handler.h}. Instances of these
- subclasses can then be used as various agent timers.
- An agent may wish to override the fcn[]{Agent::timeout} method
- (which does nothing).
- In the case of the Tahoe TCP agent, two timers are used:
- a delayed send timer code{delsnd_timer_}
- and a retransmission timer code{rtx_timer_}.
- href{We describe the retransmission timer in TCP}{Section}{sec:timerexample}
- as an example of timer usage.
- section{Creating a New Agent}
- label{sec:createagent}
- To create a new agent, one has to do the following:
- begin{enumerate}itemsep0pt
- item href{decide its inheritance structure}{Section}{sec:pingexample},
- and create the appropriate class definitions,
- item href{define the fcn[]{recv} and fcn[]{timeout} methods}{%
- Section}{sec:agents:exmethods},
- item define any necessary timer classes,
- item href{define OTcl linkage functions}{Section}{sec:agents:exlinkage},
- item href{write the necessary OTcl code to access the agent}{Section}{sec:agents:exotclcode}.
- end{enumerate}
- The action required to create and agent can be illustrated
- by means of a very simple example.
- Suppose we wish to construct an agent which performs
- the ICMP ECHO REQUEST/REPLY (or ``ping'') operations.
- subsection{Example: A ``ping'' requestor (Inheritance Structure)}
- label{sec:pingexample}
- Deciding on the inheritance structure is a matter of personal choice, but is
- likely to be related to the layer at which the agent will operate
- and its assumptions on lower layer functionality.
- The simplest type of Agent, connectionless datagram-oriented transport, is
- the code{Agent/UDP} base class. Traffic generators can easily be connected
- to UDP Agents.
- For protocols wishing to use a connection-oriented stream transport
- (like TCP), the various TCP Agents could be used.
- Finally, if a new transport or ``sub-transport'' protocol
- is to be developed, using code{Agent}
- as the base class would likely be the best choice.
- In our example, we'll use Agent as the base class, given that
- we are constructing an agent logically belonging to the IP layer
- (or just above it).
- We may use the following class definitions:
- begin{program}
- class ECHO_Timer;
-
- class ECHO_Agent : public Agent {
- public:
- ECHO_Agent();
- int command(int argc, const char*const* argv);
- protected:
- void timeout(int);
- void sendit();
- double interval_;
- ECHO_Timer echo_timer_;
- };
- class ECHO_Timer : public TimerHandler {
- public:
- ECHO_Timer(ECHO_Agent *a) : TimerHandler() { a_ = a; }
- protected:
- virtual void expire(Event *e);
- ECHO_Agent *a_;
- };
- end{program}
- subsection{The texttt{recv}() and texttt{timeout}() Methods}
- label{sec:agents:exmethods}
- The fcn[]{recv} method is not defined here, as this agent
- represents a request function and will generally not be receiving
- events or packetsfootnote{This is perhaps unrealistically simple.
- An ICMP ECHO REQUEST agent would likely wish to process
- ECHO REPLY messages.}.
- By not defining the fcn[]{recv} method, the base class version
- of fcn[]{recv} (ie, fcn[]{Connector::recv}) is used.
- The fcn[]{timeout} method is used to periodically send request packets.
- The following fcn[]{timeout} method is used, along with a helper
- method, fcn[]{sendit}:
- begin{program}
- void ECHO_Agent::timeout(int)
- {
- sendit();
- echo_timer_.resched(interval_);
- }
- void ECHO_Agent::sendit()
- {
- Packet* p = allocpkt();
- ECHOHeader *eh = ECHOHeader::access(p->bits());
- eh->timestamp() = Scheduler::instance().clock();
- send(p, 0); // {cf Connector::send()}
- }
- void ECHO_Timer::expire(Event *e)
- {
- a_->timeout(0);
- }
- end{program}
- The fcn[]{timeout} method simply arranges for fcn[]{sendit} to be
- executed every code{interval_} seconds.
- The fcn[]{sendit} method creates a new packet with most of its
- header fields already set up by fcn[]{allocpkt}.
- The packet is only lacks the current time stamp.
- The call to fcn[]{access} provides for a structured interface to the
- packet header fields, and is used to set the timestamp field.
- Note that this agent uses its own special header (``ECHOHeader'').
- The
- href{creation and use of packet headers is described in
- later chapter}{Chapter}{chap:pformat};
- to send the packet to the next downstream node, fcn[]{Connector::send}
- is invoked without a handler.
- subsection{Linking the ``ping'' Agent with OTcl}
- label{sec:agents:exlinkage}
- We have the
- href{methods and mechanisms for establishing OTcl Linkage earlier}{%
- Chapter}{chap:otcl:intro}.
- This section is a brief review of the essential features of that
- earlier chapter, and describes the minimum functionality required to
- create the ping agent.
- There are three items we must handle to properly link our agent
- with Otcl.
- First we need to establish a mapping between the OTcl name
- for our class and the actual object created when an
- instantiation of the class is requested in OTcl.
- This is done as follows:
- begin{program}
- static class ECHOClass : public TclClass {
- public:
- ECHOClass() : TclClass("Agent/ECHO") {}
- TclObject* create(int argc, const char*const* argv) {
- return (new ECHO_Agent());
- }
- } class_echo;
- end{program}
- Here, a {em static} object ``class_echo'' is created. It's constructor
- (executed immediately when the simulator is executed) places the class name
- ``Agent/ECHO'' into the OTcl name space.
- The mixing of case is by convention;
- recall from Section~ref{sec:TclClass} in the earlier chapters that
- the ``/'' character is a hierarchy delimiter for the interpreted hierarchy.
- The definition of the fcn[]{create} method specifies how a C++
- shadow object should be created when
- the OTcl interpreter is instructed to create an
- object of class ``Agent/ECHO''. In this case, a dynamically-allocated
- object is returned. This is the normal way new C++ shadow objects
- are created.
- % Note that arguments could have been passed to our constructor
- % via OTcl through the conventional code{argc/argv} pairs of the
- % fcn[]{create} method, although this is rare.
- Once we have the object creation set up, we will want to link
- C++ member variables with corresponding variables in the OTcl
- nname space, so that accesses to OTcl variables are actually
- backed by member variables in C++.
- Assume we would like OTcl to be able to adjust the sending
- interval and the packet size.
- This is accomplished in the class's constructor:
- begin{program}
- ECHO_Agent::ECHO_Agent() : Agent(PT_ECHO)
- {
- bind_time("interval_", &interval_);
- bind("packetSize_", &size_);
- }
- end{program}
- Here, the C++ variables code{interval_} and code{size_} are
- linked to the OTcl instance variables code{interval_} and
- code{packetSize_}, respectively.
- Any read or modify operation to the Otcl variables will result
- in a corresponding access to the underlying C++ variables.
- The href{details of the fcn[]{bind} methods are described elsewhere}{%
- Section}{sec:VarBinds}.
- The defined constant code{PT_ECHO} is passed to the fcn[]{Agent}
- constuctor so that the fcn[]{Agent::allocpkt} method may set
- the href{packet type field used by the trace support}{%
- Section}{sec:traceptype}.
- In this case, code{PT_ECHO}
- href{represents a new packet type and must be defined in nsf{trace.h}}{%
- Section}{sec:traceformat}.
- Once object creation and variable binding is set up, we may
- want to href{create methods implemented in C++ but which can
- be invoked from OTcl}{Section}{sec:Commands}.
- These are often control functions that initiate, terminate or
- modify behavior.
- In our present example, we may wish to be able to start the
- ping query agent from OTcl using a ``start'' directive.
- This may be implemented as follows:
- begin{program}
- int ECHO_Agent::command(int argc, const char*const* argv)
- {
- if (argc == 2) {
- if (strcmp(argv[1], "start") == 0) {
- timeout(0);
- return (TCL_OK);
- }
- }
- return (Agent::command(argc, argv));
- }
- end{program}
- Here, the fcn[]{start} method available to OTcl simply calls
- the C++ member function fcn[]{timeout} which initiates the
- first packet generation and schedules the next.
- Note this class is so simple it does not even include a
- way to be stopped.
- subsection{Using the agent through OTcl}
- label{sec:agents:exotclcode}
- The agent we have created will have to be instantiated and attached
- to a node.
- Note that a node and simulator object is assumed to have
- already been created.
- % (Section ref{tcllink} describes how this is done).
- The following OTcl code performs these functions:
- begin{program}
- set echoagent [new Agent/ECHO]
- $simulator attach-agent $node $echoagent
- end{program}
- To set the interval and packet size, and start packet generation,
- the following OTcl code is executed:
- begin{program}
- $echoagent set dst_ $dest
- $echoagent set fid_ 0
- $echoagent set prio_ 0
- $echoagent set flags_ 0
- $echoagent set interval_ 1.5
- $echoagent set packetSize_ 1024
- $echoagent start
- end{program}
- This will cause our agent to generate one 1024-byte packet destined for
- node code{$dest} every 1.5 seconds.
- section{The Agent API}
- label{sec:agents:api}
- Simulated applications may be implemented on top of protocol agents. Chapter
- ref{chap:applications} describes the API used by applications to access the
- services provided by the protocol agent.
- section{Different agent objects}
- label{sec:agentobjects}
- Class Agent forms the base class from which different types of objects
- like Nullobject, TCP etc are derived. The methods for Agent class are
- described in the next section. Configuration parameters for:
- begin{description}
- item[fid_] Flowid.
- item[prio_] Priority.
- item[agent_addr_] Address of this agent.
- item[agent_port_] Port adress of this agent.
- item[dst_addr_ ] Destination address for the agent.
- item[dst_port_] Destination port address for the agent.
- item[flags_]
- item[ttl_] TTL defaults to 32.
- end{description}
- There are no state variables specific to the generic agent class. Other
- objects derived from Agent are given below:
- begin{description}
- item[Null Objects]
- Null objects are a subclass of agent objects that implement a traffic
- sink. They inherit all of the generic agent object functionality. There
- are no methods specific to this object. The state variables are:
- begin{itemize}
- item sport_
- item dport_
- end{itemize}
- item[LossMonitor Objects]
- LossMonitor objects are a subclass of agent objects that implement a
- traffic sink which also maintains some statistics about the received data
- e.g., number of bytes received, number of packets lost etc. They inherit
- all of the generic agent object functionality.
- code{$lossmonitor clear}\
- Resets the expected sequence number to -1.
- State Variables are:
- begin{description}
- item[nlost_] Number of packets lost.
- item[npkts_] Number of packets received.
- item[bytes_] Number of bytes received.
- item[lastPktTime_] Time at which the last packet was received.
- item[expected_] The expected sequence number of the next packet.
- end{description}
- item[TCP objects]
- TCP objects are a subclass of agent objects that implement the BSD Tahoe
- TCP transport protocol as described in paper: "Fall, K., and Floyd, S.
- Comparisons of Tahoe, Reno, and Sack TCP. December 1995." URL ftp://
- ftp.ee.lbl.gov/papers/sacks.ps.Z. They inherit
- all of the generic agent functionality. Configuration Parameters are:
- begin{description}
- item[window_] The upper bound on the advertised window for the TCP
- connection.
- item[maxcwnd_]
- The upper bound on the congestion window for the TCP connection. Set to
- zero to ignore. (This is the default.)
- item[windowInit_]
- The initial size of the congestion window on slow-start.
- item[windowOption_]
- The algorithm to use for managing the congestion window.
- item[windowThresh_]
- Gain constant to exponential averaging filter used to compute awnd (see
- below). For investigations of different window-increase algorithms.
- item[overhead_]
- The range of a uniform random variable used to delay each output packet.
- The idea is to insert random delays at the source in order to avoid phase
- effects, when desired [see Floyd, S., and Jacobson, V. On Traffic Phase
- Effects in Packet-Switched Gateways. Internetworking: Research and
- Experience, V.3 N.3, September 1992. pp. 115-156 ]. This has only been
- implemented for the Tahoe ("tcp") version of tcp, not for tcp-reno. This
- is not intended to be a realistic model of CPU processing overhead.
- item[ecn_] Set to true to use explicit congestion notification in
- addition to packet drops to signal congestion. This allows a Fast
- Retransmit after a quench() due to an ECN (explicit congestion
- notification) bit.
- item[packetSize_]
- The size in bytes to use for all packets from this source.
- item[tcpTick_]
- The TCP clock granularity for measuring roundtrip times. Note that it is
- set by default to the non-standard value of 100ms.
- item[bugFix_]
- Set to true to remove a bug when multiple fast retransmits are allowed for
- packets dropped in a single window of data.
- item[maxburst_]
- Set to zero to ignore. Otherwise, the maximum number of packets that the
- source can send in response to a single incoming ACK.
- item[slow_start_restart_]
- Set to 1 to slow-start after the connection goes idle. On by default.
- end{description}
- Defined Constants are:
- begin{description}
- item[MWS] The Maximum Window Size in packets for a TCP connection. MWS
- determines the size of an array in tcp-sink.cc. The default for MWS is
- 1024 packets. For Tahoe TCP, the "window" parameter, representing the
- receiver's advertised window, should be less than MWS-1. For Reno TCP, the
- "window" parameter should be less than (MWS-1)/2.
- end{description}
- State Variables are:
- begin{description}
- item[dupacks_]
- Number of duplicate acks seen since any new data was acknowledged.
- item[seqno_]
- Highest sequence number for data from data source to TCP.
- item[t_seqno_]
- Current transmit sequence number.
- item[ack_] Highest acknowledgment seen from receiver. cwnd_
- Current value of the congestion window.
- item[awnd_]
- Current value of a low-pass filtered version of the congestion window. For
- investigations of different window-increase algorithms.
- item[ssthresh_]
- Current value of the slow-start threshold.
- item[rtt_] Round-trip time estimate.
- item[srtt_]
- Smoothed round-trip time estimate.
- item[rttvar_]
- Round-trip time mean deviation estimate.
- item[backoff_]
- Round-trip time exponential backoff constant.
- end{description}
- item[TCP/Reno Objects]
- TCP/Reno objects are a subclass of TCP objects that implement the Reno TCP
- transport protocol described in paper: "Fall, K., and Floyd, S.
- Comparisons of Tahoe, Reno, and Sack TCP. December 1995." URL ftp://
- ftp.ee.lbl.gov/papers/sacks.ps.Z. There are no methods,
- configuration parameters or state variables specific to this object.
- item[TCP/Newreno Objects]
- TCP/Newreno objects are a subclass of TCP objects that implement a
- modified version of the BSD Reno TCP transport protocol.
- There are no methods or state variables specific to this object.
- Configuration Parameters are:
- begin{description}
- item[newreno_changes_]
- Set to zero for the default New Reno described in "Fall, K., and Floyd, S.
- Comparisons of Tahoe, Reno, and Sack TCP. December 1995". Set to 1 for
- additional New Reno algorithms [see Hoe, J., Improving the Start-up
- Behavior of a Congestion Control Scheme for TCP. in SIGCOMM 96, August
- 1996, pp. 270-280. URL
- http://www.acm.org/sigcomm/sigcomm96/papers/hoe.html.]; this includes the
- estimation of the ssthresh parameter during slow-start.
- end{description}
- item[TCP/Vegas Objects]
- There are no methods or configuration parameters specific to this
- object. State variables are:
- begin{itemize}
- item v_alpha_
- item v_beta_
- item v_gamma_
- item v_rtt_
- end{itemize}
- item[TCP/Sack1 Objects]
- TCP/Sack1 objects are a subclass of TCP objects that implement the BSD
- Reno TCP transport protocol with Selective Acknowledgement Extensions
- described in "Fall, K., and Floyd, S. Comparisons of Tahoe, Reno, and
- Sack TCP. December 1995". URL ftp:// ftp.ee.lbl.gov/papers/sacks.ps.Z.
- They inherit all of the TCP object functionality. There are no methods,
- configuration parameters or state variables specific to this object.
- item[TCP/FACK Objects]
- TCP/Fack objects are a subclass of TCP objects that implement the BSD Reno
- TCP transport protocol with Forward Acknowledgement congestion control.
- They inherit all of the TCP object functionality. There are no methods or
- state variables specific to this object.
- Configuration Parameters are:
- begin{description}
- item[ss-div4]
- Overdamping algorithm. Divides ssthresh by 4 (instead of 2) if congestion
- is detected within 1/2 RTT of slow-start. (1=Enable, 0=Disable)
- item[rampdown]
- Rampdown data smoothing algorithm. Slowly reduces congestion window rather
- than instantly halving it. (1=Enable, 0=Disable)
- end{description}
- item[TCP/FULLTCP Objects]
- This section has not yet been added here. The implementation
- and the configuration parameters are described in paper: "Fall, K.,
- Floyd, S., and Henderson, T., Ns Simulator Tests for Reno FullTCP.
- July, 1997." URL ftp://ftp.ee.lbl.gov/papers/fulltcp.ps.
- item[TCPSINK Objects]
- TCPSink objects are a subclass of agent objects that implement a receiver
- for TCP packets. The simulator only implements "one-way" TCP connections,
- where the TCP source sends data packets and the TCP sink sends ACK
- packets. TCPSink objects inherit all of the generic agent functionality.
- There are no methods or state variables specific to the TCPSink object.
- Configuration Parameters are
- begin{description}
- item[packetSize_]
- The size in bytes to use for all acknowledgment packets.
- item[maxSackBlocks_]
- The maximum number of blocks of data that can be acknowledged in a SACK
- option. For a receiver that is also using the time stamp option [RFC
- 1323], the SACK option specified in RFC 2018 has room to include three
- SACK blocks. This is only used by the TCPSink/Sack1 subclass. This value
- may not be increased within any particular TCPSink object after that
- object has been allocated. (Once a TCPSink object has been allocated, the
- value of this parameter may be decreased but not increased).
- end{description}
- item[TCPSINK/DELACK Objects]
- DelAck objects are a subclass of TCPSink that implement a delayed-ACK
- receiver for TCP packets. They inherit all of the TCPSink object
- functionality. There are no methods or state variables specific to the
- DelAck object.
- Configuration Parameters are:
- begin{description}
- item[interval_]
- The amount of time to delay before generating an acknowledgment for a
- single packet. If another packet arrives before this time expires,
- generate an acknowledgment immediately.
- end{description}
- item[TCPSINK/SACK1 Objects]
- TCPSink/Sack1 objects are a subclass of TCPSink that implement a SACK
- receiver for TCP packets. They inherit all of the TCPSink object
- functionality. There are no methods, configuration parameters or state
- variables specific to this object.
- item[TCPSINK/SACK1/DELACK Objects]
- TCPSink/Sack1/DelAck objects are a subclass of TCPSink/Sack1 that
- implement a delayed-SACK receiver for TCP packets. They inherit all of the
- TCPSink/Sack1 object functionality. There are no methods or state
- variables specific to this object.
- Configuration Parameters are:
- begin{description}
- item[interval_]
- The amount of time to delay before generating an acknowledgment for a
- single packet. If another packet arrives before this time expires,
- generate an acknowledgment immediately.
- end{description}
- end{description}
- section{Commands at a glance}
- label{sec:agentscommand}
- Following are the agent related commands used in simulation scripts:
- begin{flushleft}
- code{ns_ attach-agent <node> <agent>}\
- This command attaches the <agent> to the <node>. We assume here that the
- <agent> has already been created. An agent is typically created by
- code{set agent [new Agent/AgentType]}
- where Agent/AgentType defines the class definiton of the specified agent
- type.
- code{$agent port}\
- This returns the port number to which the agent is attached.
- code{$agent dst-port}\
- This returns the port number of the destination.
- When any connection is setup between 2 nodes, each agent stores the
- destination port in its instance variable called code{dst_port_}.
- code{$agent attach-app <s_type>}\
- This commands attaches an application of type code{<s_type>} to the agent.
- A handle to the application object is returned. Also note that the application
- type must be defined as a packet type in packet.h.
- code{$agent attach-source <s_type>}\
- This used to be the procedure to attach source of type code{<s_type>} to
- the agent. But this is obsolete now. Use attach-app (described above)
- instead.
- code{$agent attach-tbf <tbf>}\
- Attaches a token bucket filter (tbf) to the agent.
- code{$ns_ connect <src> <dst>}\
- Sets up a connection between the src and dst agents.
- code{$ns_ create-connection <srctype> <src> <dsttype> <dst> <pktclass>}\
- This sets up a complete connection between two agents. First creates a source
- of type <srctype> and binds it to <src>. Then creates a destination of type
- <dsttype> and binds it to <dst>. Finally connects the src and dst agents and
- returns a handle to the source agent.
- code{$ns_ create-connection-list <srctype> <src> <dsttype> <dst> <pktclass>}\
- This command is exactly similar to create-connection described above. But
- instead of returning only the source-agent, this returns a list of source and
- destination agents.
- Internal procedures:
- code{$ns_ simplex-connect <src> <dst>}\
- This is an internal method that actually sets up an unidirectional connection
- between the <src> agent and <dst> agent. It simply sets the destination address
- and destination port of the <src> as <dst>'s agent-address and agent-port.
- The "connect" described above calls this method twice to set up a bi-directional
- connection between the src and dst.
- code{$agent set <args>}\
- This is an internal procedure used to inform users of the backward compatibility
- issues resulting from the upgrade to 32-bit addressing space currently used
- in ns.
- code{$agent attach-trace <file>}\
- This attaches the <file> to the agent to allow nam-tracing of the agent
- events.
- In addition to the agent related procedures described here, there are additional
- methods that support different type of agents like Agent/Null, Agent/TCP,
- Agent/CBR, Agent/TORA, Agent/mcast etc. These additional methods along
- with the procedures described here can be found in ns/tcl/lib/(ns-agent.tcl,
- ns-lib.tcl, ns-mip.tcl, ns-mobilenode.tcl, ns-namsupp.tcl, ns-queue.tcl,
- ns-route.tcl, ns-sat.tcl, ns-source.tcl). They are also described in the
- previous section.
- end{flushleft}
- endinput