agents.tex
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:40k
源码类别:

通讯编程

开发平台:

Visual C++

  1. %
  2. % personal commentary:
  3. %        handlers and how they are used are confusing
  4. %        Connector::send is needed, but so is just send()... confusing
  5. %        default handler in Connector::recv is confusing
  6. %        this is a DRAFT DRAFT DRAFT
  7. %        - KFALL
  8. %
  9. chapter{Agents}
  10. label{sec:agents}
  11. Agents represent endpoints where network-layer
  12. packets are constructed or consumed, and are used in the implementation
  13. of protocols at various layers.
  14. %Generally, a user wishing to create a new
  15. %source or sink for network-layer packets
  16. %will create a class derived from {tt Agent}.
  17. The clsref{Agent}{../ns-2/agent.h} has an implementation partly in
  18. OTcl and partly in C++.
  19. The C++ implementation is contained in nsf{agent.cc} and
  20. nsf{agent.h}, and the OTcl support is in
  21. nsf{tcl/lib/ns-agent.tcl}.
  22. section{Agent state}
  23. label{sec:agentstate}
  24. The C++ clsref{Agent}{../ns-2/agent.h} includes enough internal state
  25. to assign various fields to a simulated packet before
  26. it is sent.
  27. This state includes the following:
  28. begin{tabularx}{linewidth}{rX}
  29. code{addr_} & node address of myself (source address in packets) \
  30. code{dst_} & where I am sending packets to \
  31. code{size_} & packet size in bytes (placed into the common packet header) \
  32. code{type_} & type of packet (in the common header, see packet.h) \
  33. code{fid_} & the IP flow identifier (formerly {em class} in ns-1) \
  34. code{prio_} & the IP priority field \
  35. code{flags_} & packet flags (similar to ns-1) \
  36. code{defttl_} & default IP ttl value \
  37. end{tabularx}
  38. These variables may be modified by any class derived from code{Agent},
  39. although not all of them may be needed by any particular agent.
  40. section{Agent methods}
  41. label{sec:agentmethods}
  42. The clsref{Agent}{../ns-2/agent.h} supports packet generation and reception.
  43. The following member functions are implemented by the C++ Agent class, and are
  44. generally {em not} over-ridden by derived classes:
  45. begin{tabularx}{linewidth}{rX}
  46. fcn[]{Packet* allocpkt} & allocate new packet and assign its fields \
  47. fcn[int]{Packet* allocpkt} & allocate new packet with a data payload of n bytes and assign its fields \
  48. end{tabularx}
  49. The following member functions are also defined by the class Agent,
  50. but {em are} intended to be over-ridden by classes deriving from Agent:
  51. begin{tabularx}{linewidth}{rX}
  52.   fcn[timeout number]{void timeout} & subclass-specific time out method \
  53.   fcn[Packet*, Handler*]{void recv} & receiving agent main receive path \
  54. end{tabularx}
  55. The fcn[]{allocpkt} method is used by derived classes
  56. to create packets to send.
  57. The function fills in the following fields
  58. href{in the common packet header}{Section}{chap:pformat}:
  59. {tt uid, ptype, size}, and the following fields in the IP header:
  60. {tt src, dst, flowid, prio, ttl}.
  61. It also zero-fills in the following fields of the Flags header:
  62. {tt ecn, pri, usr1, usr2}.
  63. Any packet header information not included in these lists must
  64. be must be handled in the classes derived from code{Agent}.
  65. The fcn[]{recv} method is the main entry point for an
  66. Agent which receives packets, and
  67. is invoked by upstream nodes when sending a packet.
  68. In most cases, Agents make no use of the second argument (the handler
  69. defined by upstream nodes).
  70. section{Protocol Agents}
  71. label{sec:protoagents}
  72. There are several agents supported in the simulator.
  73. These are their names in OTcl:
  74. begin{longtable}{rl}
  75.   TCP & a ``Tahoe'' TCP sender (cwnd = 1 on any loss)   \
  76.   TCP/Reno & a ``Reno'' TCP sender  (with fast recovery)        \
  77.   TCP/Newreno & a modified Reno TCP sender (changes fast recovery)      \
  78.   TCP/Sack1 & a SACK TCP sender \
  79.   TCP/Fack & a ``forward'' SACK sender TCP      \
  80.   TCP/FullTcp & a more full-functioned TCP with 2-way traffic   \
  81.   TCP/Vegas & a ``Vegas'' TCP sender    \
  82.   TCP/Vegas/RBP & a Vegas TCP with ``rate based pacing''        \
  83.   TCP/Vegas/RBP & a Reno TCP with ``rate based pacing'' \
  84.   TCP/Asym & an experimental Tahoe TCP for asymmetric links     \
  85.   TCP/Reno/Asym & an experimental Reno TCP for asymmetric links \
  86.   TCP/Newreno/Asym & an experimental Newreno TCP for asymmetric links   \
  87.   TCPSink & a Reno or Tahoe TCP receiver (not used for FullTcp) \
  88.   TCPSink/DelAck & a TCP delayed-ACK receiver   \
  89.   TCPSink/Asym & an experimental  TCP sink for asymmetric links \
  90.   TCPSink/Sack1 & a SACK TCP receiver   \
  91.   TCPSink/Sack1/DelAck & a delayed-ACK SACK TCP receiver        \
  92.         \
  93.   UDP & a basic UDP agent\
  94. \
  95.   RTP & an RTP sender and receiver  \
  96.   RTCP & an RTCP sender and receiver    \
  97.         \
  98.   LossMonitor & a packet sink which checks for losses   \
  99.         \
  100.   IVS/Source & an IVS source    \
  101.   IVS/Receiver & an IVS receiver        \
  102.         \
  103.   CtrMcast/Encap & a ``centralised multicast'' encapsulator     \
  104.   CtrMcast/Decap & a ``centralised multicast'' de-encapsulator  \
  105.   Message & a protocol to carry textual messages        \
  106.   Message/Prune & processes multicast routing prune messages    \
  107.         \
  108.   SRM & an SRM agent with non-adaptive timers   \
  109.   SRM/Adaptive & an SRM agent with adaptive timers      \
  110.         \
  111.   Tap & interfaces the simulator to a live network      \
  112.         \
  113.   Null & a degenerate agent which discards packets      \
  114.         \
  115.   rtProto/DV & distance-vector routing protocol agent   \
  116. end{longtable}
  117. Agents are used in the implementation of protocols at various layers.
  118. Thus, for some transport protocols (e.g.~UDP) the distribution
  119. of packet sizes and/or inter-departure times
  120. may be dictated by some separate
  121. object representing the demands of an application.  To this end, agents
  122. expose an application programming interface (API) to the application.
  123. For agents used in the implementation of lower-layer protocols
  124. (e.g. routing agents), size and departure timing is generally dictated
  125. by the agent's own processing of protocol messages.
  126. section{OTcl Linkage}
  127. label{sec:agentotcl}
  128. Agents may be created within OTcl and an agent's internal
  129. state can be modified by use of Tcl's code{set} function and
  130. any Tcl functions an Agent (or its base classes) implements.
  131. Note that some of an Agent's internal state may exist
  132. only within OTcl, and is thus is not directly accessible from C++.
  133. subsection{Creating and Manipulating Agents}
  134. label{sec:agentcreateotcl}
  135. The following example illustrates the creation and modification
  136. of an Agent in OTcl:
  137. begin{program}
  138.         set newtcp [new Agent/TCP] ; create new object (and C++ shadow object);
  139.         $newtcp set window_ 20 ; sets the tcp agent's window to 20;
  140.         $newtcp target $dest ; target is implemented in Connector class;
  141.         $newtcp set portID_ 1 ; exists only in OTcl, not in C++;
  142. end{program}
  143. subsection{Default Values}
  144. label{sec:agentdefaults}
  145. Default values for member variables, those visible in OTcl only and those
  146. linked between OTcl and C++ with code{bind} are initialized
  147. in the nsf{tcl/lib/ns-default.tcl} file.  For example,
  148. code{Agent} is initialized as follows:
  149. begin{program}
  150.         Agent set fid_ 0
  151.         Agent set prio_ 0
  152.         Agent set addr_ 0
  153.         Agent set dst_ 0
  154.         Agent set flags_ 0
  155. end{program}
  156. Generally these initializations are placed in the OTcl namespace
  157. before any objects of these types are created.
  158. Thus, when an code{Agent} object
  159. is created, the calls to code{bind}
  160. in the objects' constructors will causes the corresponding member variables
  161. to be set to these specified defaults.
  162. subsection{OTcl Methods}
  163. label{sec:agentmethodsotcl}
  164. The instance procedures defined for the OTcl code{Agent} class are
  165. currently found in nsf{tcl/lib/ns-agent.tcl}.
  166. They are as follows:
  167. begin{tabularx}{linewidth}{rX}
  168. code{port} & the agent's port identifier \
  169. code{dst-port} & the destination's port identifier \
  170. code{attach-source tup{stype}} & create and attach a Source object to an agent \
  171. end{tabularx}
  172. section{Examples: Tcp, TCP Sink Agents}
  173. label{sec:agentexample}
  174. The clsref{TCP}{../ns-2/tcp.h} represents a simplified TCP sender.
  175. It sends data to a code{TCPSink} agent and processes its acknowledgments.
  176. It has a separate object associated with it which represents
  177. an application's demand.
  178. By looking at the clsref{TCPAgent}{../ns-2/tcp.h} and
  179.  clsref{TCPSinkAgent}{../ns-2/tcp-sink.h},
  180. we may see how relatively complex agents are constructed.
  181. An example from the Tahoe TCP agent code{TCPAgent} is also given
  182. to illustrate the use of timers.
  183. subsection{Creating the Agent}
  184. label{sec:createtcpsimple}
  185. The following OTcl code fragment creates a code{TCP} agent
  186. and sets it up:
  187. begin{program}
  188.         set tcp [new Agent/TCP]         ; create sender agent;
  189.         $tcp set fid_ 2                 ; set IP-layer flow ID;
  190.         set sink [new Agent/TCPSink]    ; create receiver agent;
  191.         $ns attach-agent $n0 $tcp       ; put sender on node $n0;
  192.         $ns attach-agent $n3 $sink      ; put receiver on node $n3;
  193.         $ns connect $tcp $sink          ; establish TCP connection;
  194.         set ftp [new Application/FTP]        ; create an FTP source "application";
  195.         $ftp attach-agent $tcp            ; associate FTP with the TCP sender;
  196.         $ns at 1.2 "$ftp start"  ;arrange for FTP to start at time 1.2 sec;
  197. end{program}
  198. The OTcl instruction code{new Agent/TCP} results in the
  199. creation of a C++ code{TcpAgent} class object.
  200. Its constructor first invokes the constructor of the
  201. code{Agent} base class and then performs its own bindings.
  202. These two constructors appear as follows:
  203. begin{program}
  204. {rm The TcpSimpleAgent constructor (nsf{tcp.cc}):}
  205.         TcpAgent::TcpAgent() : Agent(PT_TCP), rtt_active_(0), rtt_seq_(-1),
  206.                         rtx_timer_(this), delsnd_timer_(this)
  207.         {
  208.                 bind("window_", &wnd_);
  209.                 bind("windowInit_", &wnd_init_);
  210.                 bind("windowOption_", &wnd_option_);
  211.                 bind("windowConstant_", &wnd_const_);
  212.                 ldots
  213.                 bind("off_ip_", &off_ip_);
  214.                 bind("off_tcp_", &off_tcp_);
  215.                 ldots
  216.         }
  217. {rm The Agent constructor (nsf{agent.cc}):}
  218.         Agent::Agent(int pkttype) : 
  219.                 addr_(-1), dst_(-1), size_(0), type_(pkttype), fid_(-1),
  220.                 prio_(-1), flags_(0)
  221.         {
  222.                 memset(pending_, 0, sizeof(pending_)); * timers */
  223.                 // {cf this is really an IP agent, so set up}
  224.                 // {cf for generating the appropriate IP fieldsldots}
  225.                 bind("addr_", (int*)&addr_);
  226.                 bind("dst_", (int*)&dst_);
  227.                 bind("fid_", (int*)&fid_);
  228.                 bind("prio_", (int*)&prio_);
  229.                 bind("flags_", (int*)&flags_);
  230.                 ldots
  231.         }
  232. end{program}
  233. These code fragments illustrate the common case where an agent's
  234. constructor passes a packet type identifier to the code{Agent}
  235. constructor.
  236. The values for the various packet types are
  237. href{used by the packet tracing facility}{Section}{sec:traceptype}
  238. and are defined in nsf{trace.h}.
  239. The variables which are bound in the code{TcpAgent} constructor
  240. are ordinary instance/member variables for the class
  241. with the exception of the special integer values code{off_tcp_}
  242. and code{off_ip_}.
  243. These are needed in order to access a TCP header and IP header, respectively.
  244. href{Additional details are in the section on packet headers}{Section}{sec:ppackethdr}.
  245. Note that the code{TcpAgent} constructor contains initializations for
  246. two timers, code{rtx_timer_} and code{delsnd_timer_}.
  247. code{TimerHandler} 
  248. objects are initialized by providing a pointer (the code{this} pointer) to
  249. the relevant agent.
  250. subsection{Starting the Agent}
  251. label{sec:starttcp}
  252. The code{TcpAgent} agent is started in the example when its
  253. FTP source receives the code{start} directive at time 1.2.
  254. The code{start} operation is an instance procedure defined on the
  255. href{class Application/FTP}{Section}{sec:simapps}.
  256. It is defined in nsf{tcl/lib/ns-source.tcl} as follows:
  257. begin{program}
  258.         Application/FTP instproc start {} {
  259.                 [$self agent] send -1
  260.         }
  261. end{program}
  262. In this case, code{agent} refers to our simple TCP agent and
  263. code{send -1} is analogous to sending an arbitrarily large file.
  264. The call to code{send} eventually results in the simple TCP sender
  265. generating packets.
  266. The following function code{output} performs this:
  267. begin{program}
  268.         void TcpAgent::output(int seqno, int reason)
  269.         {
  270.                 Packet* p = allocpkt();
  271.                 hdr_tcp *tcph = (hdr_tcp*)p->access(off_tcp_);
  272.                 double now = Scheduler::instance().clock();
  273.                 tcph->seqno() = seqno;
  274.                 tcph->ts() = now;
  275.                 tcph->reason() = reason;
  276.                 Connector::send(p, 0);
  277.                 ldots
  278.                 if (!(rtx_timer_.status() == TIMER_PENDING))
  279.                         /* {cf No timer pending.  Schedule one.} */
  280.                         set_rtx_timer();
  281.         }
  282. end{program}
  283. Here we see an illustration of the use of the fcn[]{Agent::allocpkt} method.
  284. This output routine first allocates a new packet
  285. (with its common and IP headers already filled in), but then must fill
  286. in the appropriate TCP-layer header fields.
  287. To find the TCP header in a packet 
  288. (href{assuming it has been enabled}{Section}{sec:packethdrmgr})
  289. the code{off_tcp_} must be properly initialized,
  290. as illustrated in the constructor.
  291. The packet fcn[]{access} method returns a pointer to the TCP header,
  292. its sequence number and time stamp fields are filled in,
  293. and the fcn[]{send} method of the class Connector is called
  294. to send the packet downstream one hop.
  295. Note that the C++ code{::} scoping operator is used here to avoid
  296. calling fcn[]{TcpSimpleAgent::send} (which is also defined).
  297. The check for a pending timer uses the timer method fcn[]{status} which
  298. is defined in the base class TimerHandler.
  299. It is used here to set a retransmission timer if one is not already set
  300. (a TCP sender only sets one timer per window of packets on each connection).
  301. subsection{Processing Input at Receiver}
  302. label{sec:tcpsink}
  303. Many of the TCP agents can be used with the
  304. clsref{TCPSink}{../ns-2/tcp-sink.h} as the peer.
  305. This class defines the fcn[]{recv} and fcn[]{ack} methods as follows:
  306. begin{program}
  307.         void TcpSink::recv(Packet* pkt, Handler*)
  308.         {
  309.                 hdr_tcp *th = (hdr_tcp*)pkt->access(off_tcp_);
  310.                 acker_->update(th->seqno());
  311.                 ack(pkt);
  312.                 Packet::free(pkt);
  313.         }
  314.         void TcpSink::ack(Packet* opkt)
  315.         {
  316.                 Packet* npkt = allocpkt();
  317.         
  318.                 hdr_tcp *otcp = (hdr_tcp*)opkt->access(off_tcp_);
  319.                 hdr_tcp *ntcp = (hdr_tcp*)npkt->access(off_tcp_);
  320.                 ntcp->seqno() = acker_->Seqno();
  321.                 ntcp->ts() = otcp->ts();
  322.         
  323.                 hdr_ip* oip = (hdr_ip*)opkt->access(off_ip_);
  324.                 hdr_ip* nip = (hdr_ip*)npkt->access(off_ip_);
  325.                 nip->flowid() = oip->flowid();
  326.         
  327.                 hdr_flags* of = (hdr_flags*)opkt->access(off_flags_);
  328.                 hdr_flags* nf = (hdr_flags*)npkt->access(off_flags_);
  329.                 nf->ecn_ = of->ecn_;
  330.         
  331.                 acker_->append_ack((hdr_cmn*)npkt->access(off_cmn_),
  332.                                    ntcp, otcp->seqno());
  333.                 send(npkt, 0);
  334.         }
  335. end{program}
  336. The fcn[]{recv} method overrides the fcn[]{Agent::recv} method
  337. (which merely discards the received packet).
  338. It updates some internal state with the sequence number of the
  339. received packet (and therefore requires the code{off_tcp_} variable
  340. to be properly initialized.
  341. It then generates an acknowledgment for the received packet.
  342. The fcn[]{ack} method makes liberal use of access to packet header
  343. fields including separate accesses to the TCP header, IP header,
  344. Flags header, and common header.
  345. The call to fcn[]{send} invokes the fcn[]{Connector::send} method.
  346. subsection{Processing Responses at the Sender}
  347. label{sec:tcpsimpleack}
  348. Once the simple TCP's peer receives data and generates an ACK, the
  349. sender must (usually) process the ACK.
  350. In the code{TcpAgent} agent, this is done as follows:
  351. begin{program}
  352.         /*
  353.          * {cf main reception path - should only see acks, otherwise the}
  354.          * {cf network connections are misconfigured}
  355.          */
  356.         void TcpAgent::recv(Packet *pkt, Handler*)
  357.         {
  358.                 hdr_tcp *tcph = (hdr_tcp*)pkt->access(off_tcp_);
  359.                 hdr_ip* iph = (hdr_ip*)pkt->access(off_ip_);
  360.                 ...
  361.                 if (((hdr_flags*)pkt->access(off_flags_))->ecn_)
  362.                         quench(1);
  363.                 if (tcph->seqno() > last_ack_) {
  364.                         newack(pkt);
  365.                         opencwnd();
  366.                 } else if (tcph->seqno() == last_ack_) {
  367.                         if (++dupacks_ == NUMDUPACKS) {
  368.                                 ldots
  369.                         }
  370.                 }
  371.                 Packet::free(pkt);
  372.                 send(0, 0, maxburst_);
  373.        }
  374. end{program}
  375. This routine is invoked when an ACK arrives at the sender.
  376. In this case, once the information in the ACK is processed (by code{newack})
  377. the packet is no longer needed and is returned to the packet memory
  378. allocator.
  379. In addition, the receipt of the ACK indicates the possibility of sending
  380. additional data, so the fcn[]{TcpSimpleAgent::send} method is
  381. invoked which attempts to send more data if the TCP window allows.
  382. subsection{Implementing Timers}
  383. label{sec:tcptimer}
  384. As described in 
  385. href{the following chapter}{Chapter}{chap:timers}, specific
  386. timer classes must be derived from an abstract base
  387. clsref{TimerHandler}{../ns-2/timer-handler.h}
  388. defined in nsf{timer-handler.h}.  Instances of these
  389. subclasses can then be used as various agent timers.
  390. An agent may wish to override the fcn[]{Agent::timeout} method
  391. (which does nothing).
  392. In the case of the Tahoe TCP agent, two timers are used:
  393. a delayed send timer code{delsnd_timer_} 
  394. and a retransmission timer code{rtx_timer_}.
  395. href{We describe the retransmission timer in TCP}{Section}{sec:timerexample}
  396. as an example of timer usage.  
  397. section{Creating a New Agent}
  398. label{sec:createagent}
  399. To create a new agent, one has to do the following:
  400. begin{enumerate}itemsep0pt
  401.         item href{decide its inheritance structure}{Section}{sec:pingexample},
  402.                 and create the appropriate class definitions,
  403.         item href{define the fcn[]{recv} and fcn[]{timeout} methods}{%
  404.                 Section}{sec:agents:exmethods},
  405.         item define any necessary timer classes,
  406.         item href{define OTcl linkage functions}{Section}{sec:agents:exlinkage},
  407.         item href{write the necessary OTcl code to access the agent}{Section}{sec:agents:exotclcode}.
  408. end{enumerate}
  409. The action required to create and agent can be illustrated
  410. by means of a very simple example.
  411. Suppose we wish to construct an agent which performs
  412. the ICMP ECHO REQUEST/REPLY (or ``ping'') operations.
  413. subsection{Example: A ``ping'' requestor (Inheritance Structure)}
  414. label{sec:pingexample}
  415. Deciding on the inheritance structure is a matter of personal choice, but is
  416. likely to be related to the layer at which the agent will operate
  417. and its assumptions on lower layer functionality.
  418. The simplest type of Agent, connectionless datagram-oriented transport, is
  419. the code{Agent/UDP} base class.  Traffic generators can easily be connected
  420. to UDP Agents.
  421. For protocols wishing to use a connection-oriented stream transport
  422. (like TCP), the various TCP Agents could be used.
  423. Finally, if a new transport or ``sub-transport'' protocol
  424. is to be developed, using code{Agent}
  425. as the base class would likely be the best choice.
  426. In our example, we'll use Agent as the base class, given that
  427. we are constructing an agent logically belonging to the IP layer
  428. (or just above it).
  429. We may use the following class definitions:
  430. begin{program}
  431.         class ECHO_Timer;
  432.  
  433.         class ECHO_Agent : public Agent {
  434.          public:
  435.                 ECHO_Agent();
  436.                 int command(int argc, const char*const* argv);
  437.          protected:
  438.                 void timeout(int);
  439.                 void sendit();
  440.                 double interval_;
  441.                 ECHO_Timer echo_timer_;
  442.         };
  443.         class ECHO_Timer : public TimerHandler {
  444.         public:
  445.                 ECHO_Timer(ECHO_Agent *a) : TimerHandler() { a_ = a; }
  446.         protected:
  447.                 virtual void expire(Event *e);
  448.                 ECHO_Agent *a_;
  449.         }; 
  450. end{program}
  451. subsection{The texttt{recv}() and texttt{timeout}() Methods}
  452. label{sec:agents:exmethods}
  453. The fcn[]{recv} method is not defined here, as this agent
  454. represents a request function and will generally not be receiving
  455. events or packetsfootnote{This is perhaps unrealistically simple.
  456. An ICMP ECHO REQUEST agent would likely wish to process
  457. ECHO REPLY messages.}.
  458. By not defining the fcn[]{recv} method, the base class version
  459. of fcn[]{recv} (ie, fcn[]{Connector::recv}) is used.
  460. The fcn[]{timeout} method is used to periodically send request packets.
  461. The following fcn[]{timeout} method is used, along with a helper
  462. method, fcn[]{sendit}:
  463. begin{program}
  464.         void ECHO_Agent::timeout(int)
  465.         {
  466.                 sendit();
  467.                 echo_timer_.resched(interval_);
  468.         }
  469.         void ECHO_Agent::sendit()
  470.         {
  471.                 Packet* p = allocpkt();
  472.                 ECHOHeader *eh = ECHOHeader::access(p->bits());
  473.                 eh->timestamp() = Scheduler::instance().clock();
  474.                 send(p, 0);     // {cf Connector::send()}
  475.         }
  476.         void ECHO_Timer::expire(Event *e)
  477.         {
  478.                 a_->timeout(0);
  479.         }
  480. end{program}
  481. The fcn[]{timeout} method simply arranges for fcn[]{sendit} to be
  482. executed every code{interval_} seconds.
  483. The fcn[]{sendit} method creates a new packet with most of its
  484. header fields already set up by fcn[]{allocpkt}.
  485. The packet is only lacks the current time stamp. 
  486. The call to fcn[]{access} provides for a structured interface to the
  487. packet header fields, and is used to set the timestamp field.
  488. Note that this agent uses its own special header (``ECHOHeader'').
  489. The 
  490. href{creation and use of packet headers is described in
  491. later chapter}{Chapter}{chap:pformat};
  492. to send the packet to the next downstream node, fcn[]{Connector::send}
  493. is invoked without a handler.
  494. subsection{Linking the ``ping'' Agent with OTcl}
  495. label{sec:agents:exlinkage}
  496. We have the 
  497. href{methods and mechanisms for establishing OTcl Linkage earlier}{%
  498.         Chapter}{chap:otcl:intro}.
  499. This section is a brief review of the essential features of that
  500. earlier chapter, and describes the minimum functionality required to 
  501. create the ping agent.
  502. There are three items we must handle to properly link our agent
  503. with Otcl.
  504. First we need to establish a mapping between the OTcl name
  505. for our class and the actual object created when an
  506. instantiation of the class is requested in OTcl.
  507. This is done as follows:
  508. begin{program}
  509.         static class ECHOClass : public TclClass {
  510.         public:
  511.                 ECHOClass() : TclClass("Agent/ECHO") {}
  512.                 TclObject* create(int argc, const char*const* argv) {
  513.                         return (new ECHO_Agent());
  514.                 }
  515.         } class_echo;
  516. end{program}
  517. Here, a {em static} object ``class_echo'' is created. It's constructor
  518. (executed immediately when the simulator is executed) places the class name
  519. ``Agent/ECHO'' into the OTcl name space.
  520. The mixing of case is by convention;
  521. recall from Section~ref{sec:TclClass} in the earlier chapters that
  522. the ``/'' character is a hierarchy delimiter for the interpreted hierarchy.
  523. The definition of the fcn[]{create} method specifies how a C++
  524. shadow object should be created when
  525. the OTcl interpreter is instructed to create an
  526. object of class ``Agent/ECHO''.  In this case, a dynamically-allocated
  527. object is returned.  This is the normal way new C++ shadow objects
  528. are created.
  529. % Note that arguments could have been passed to our constructor
  530. % via OTcl through the conventional code{argc/argv} pairs of the
  531. % fcn[]{create} method, although this is rare.
  532. Once we have the object creation set up, we will want to link
  533. C++ member variables with corresponding variables in the OTcl
  534. nname space, so that accesses to OTcl variables are actually
  535. backed by member variables in C++.
  536. Assume we would like OTcl to be able to adjust the sending
  537. interval and the packet size.
  538. This is accomplished in the class's constructor:
  539. begin{program}
  540.         ECHO_Agent::ECHO_Agent() : Agent(PT_ECHO)
  541.         {
  542.                 bind_time("interval_", &interval_);
  543.                 bind("packetSize_", &size_);
  544.         }
  545. end{program}
  546. Here, the C++ variables code{interval_} and code{size_} are
  547. linked to the OTcl instance variables code{interval_} and
  548. code{packetSize_}, respectively.
  549. Any read or modify operation to the Otcl variables will result
  550. in a corresponding access to the underlying C++ variables.
  551. The href{details of the fcn[]{bind} methods are described elsewhere}{%
  552.         Section}{sec:VarBinds}.
  553. The defined constant code{PT_ECHO} is passed to the fcn[]{Agent}
  554. constuctor so that the fcn[]{Agent::allocpkt} method may set
  555. the href{packet type field used by the trace support}{%
  556.         Section}{sec:traceptype}.
  557. In this case, code{PT_ECHO} 
  558. href{represents a new packet type and must be defined in nsf{trace.h}}{%
  559.         Section}{sec:traceformat}.
  560. Once object creation and variable binding is set up, we may
  561. want to href{create methods implemented in C++ but which can
  562. be invoked from OTcl}{Section}{sec:Commands}.
  563. These are often control functions that initiate, terminate or
  564. modify behavior.
  565. In our present example, we may wish to be able to start the
  566. ping query agent from OTcl using a ``start'' directive.
  567. This may be implemented as follows:
  568. begin{program}
  569.         int ECHO_Agent::command(int argc, const char*const* argv)
  570.         {
  571.                 if (argc == 2) {
  572.                         if (strcmp(argv[1], "start") == 0) {
  573.                                 timeout(0);
  574.                                 return (TCL_OK);
  575.                         }
  576.                 }
  577.                 return (Agent::command(argc, argv));
  578.         }
  579. end{program}
  580. Here, the fcn[]{start} method available to OTcl simply calls
  581. the C++ member function fcn[]{timeout} which initiates the
  582. first packet generation and schedules the next.
  583. Note this class is so simple it does not even include a
  584. way to be stopped.
  585. subsection{Using the agent through OTcl}
  586. label{sec:agents:exotclcode}
  587. The agent we have created will have to be instantiated and attached
  588. to a node.
  589. Note that a node and simulator object is assumed to have
  590. already been created.
  591. % (Section ref{tcllink} describes how this is done).
  592. The following OTcl code performs these functions:
  593. begin{program}
  594.         set echoagent [new Agent/ECHO]
  595.         $simulator attach-agent $node $echoagent
  596. end{program}
  597. To set the interval and packet size, and start packet generation,
  598. the following OTcl code is executed:
  599. begin{program}
  600.         $echoagent set dst_ $dest
  601.         $echoagent set fid_ 0
  602.         $echoagent set prio_ 0
  603.         $echoagent set flags_ 0
  604.         $echoagent set interval_ 1.5
  605.         $echoagent set packetSize_ 1024
  606.         $echoagent start
  607. end{program}
  608. This will cause our agent to generate one 1024-byte packet destined for
  609. node code{$dest} every 1.5 seconds.
  610. section{The Agent API}
  611. label{sec:agents:api}
  612. Simulated applications may be implemented on top of protocol agents.  Chapter
  613. ref{chap:applications} describes the API used by applications to  access the 
  614. services provided by the protocol agent.
  615. section{Different agent objects}
  616. label{sec:agentobjects}
  617. Class Agent forms the base class from which different types of objects
  618. like Nullobject, TCP etc are derived. The methods for Agent class are
  619. described in the next section. Configuration parameters for:
  620. begin{description}
  621. item[fid_] Flowid.
  622. item[prio_] Priority. 
  623. item[agent_addr_] Address of this agent. 
  624. item[agent_port_] Port adress of this agent. 
  625. item[dst_addr_ ] Destination address for the agent.
  626. item[dst_port_] Destination port address for the agent.
  627. item[flags_]
  628. item[ttl_] TTL defaults to 32.
  629. end{description}
  630. There are no state variables specific to the generic agent class. Other
  631. objects derived from Agent are given below:
  632. begin{description}
  633. item[Null Objects]
  634. Null objects are a subclass of agent objects that implement a traffic
  635. sink. They inherit all of the generic agent object functionality. There
  636. are no methods specific to this object. The state variables are:
  637. begin{itemize}
  638. item sport_
  639. item dport_
  640. end{itemize}
  641. item[LossMonitor Objects]
  642. LossMonitor objects are a subclass of agent objects that implement a
  643. traffic sink which also maintains some statistics about the received data
  644. e.g., number of bytes received, number of packets lost etc. They inherit
  645. all of the generic agent object functionality. 
  646. code{$lossmonitor clear}\
  647. Resets the expected sequence number to -1. 
  648. State Variables are:
  649. begin{description}
  650. item[nlost_] Number of packets lost. 
  651. item[npkts_] Number of packets received. 
  652. item[bytes_] Number of bytes received. 
  653. item[lastPktTime_] Time at which the last packet was received. 
  654. item[expected_] The expected sequence number of the next packet. 
  655. end{description}
  656. item[TCP objects]
  657. TCP objects are a subclass of agent objects that implement the BSD Tahoe
  658. TCP transport protocol as described in paper: "Fall, K., and Floyd, S.
  659. Comparisons of Tahoe, Reno, and Sack TCP. December 1995." URL ftp://
  660. ftp.ee.lbl.gov/papers/sacks.ps.Z. They inherit
  661. all of the generic agent functionality. Configuration Parameters are:
  662. begin{description}
  663. item[window_] The upper bound on the advertised window for the TCP
  664. connection. 
  665. item[maxcwnd_]
  666. The upper bound on the congestion window for the TCP connection. Set to
  667. zero to ignore. (This is the default.) 
  668. item[windowInit_]
  669. The initial size of the congestion window on slow-start. 
  670. item[windowOption_]
  671. The algorithm to use for managing the congestion window. 
  672. item[windowThresh_]
  673. Gain constant to exponential averaging filter used to compute awnd (see
  674. below). For investigations of different window-increase algorithms. 
  675. item[overhead_]
  676. The range of a uniform random variable used to delay each output packet.
  677. The idea is to insert random delays at the source in order to avoid phase
  678. effects, when desired [see Floyd, S., and Jacobson, V. On Traffic Phase
  679. Effects in Packet-Switched Gateways. Internetworking: Research and
  680. Experience, V.3 N.3, September 1992. pp. 115-156 ]. This has only been
  681. implemented for the Tahoe ("tcp") version of tcp, not for tcp-reno. This
  682. is not intended to be a realistic model of CPU processing overhead. 
  683. item[ecn_] Set to true to use explicit congestion notification in
  684. addition to packet drops to signal congestion. This allows a Fast
  685. Retransmit after a quench() due to an ECN (explicit congestion
  686. notification) bit. 
  687. item[packetSize_]
  688. The size in bytes to use for all packets from this source. 
  689. item[tcpTick_]
  690. The TCP clock granularity for measuring roundtrip times. Note that it is
  691. set by default to the non-standard value of 100ms. 
  692. item[bugFix_]
  693. Set to true to remove a bug when multiple fast retransmits are allowed for
  694. packets dropped in a single window of data. 
  695. item[maxburst_]
  696. Set to zero to ignore. Otherwise, the maximum number of packets that the
  697. source can send in response to a single incoming ACK. 
  698. item[slow_start_restart_]
  699. Set to 1 to slow-start after the connection goes idle. On by default. 
  700. end{description}
  701. Defined Constants are:
  702. begin{description}
  703. item[MWS] The Maximum Window Size in packets for a TCP connection. MWS
  704. determines the size of an array in tcp-sink.cc. The default for MWS is
  705. 1024 packets. For Tahoe TCP, the "window" parameter, representing the
  706. receiver's advertised window, should be less than MWS-1. For Reno TCP, the
  707. "window" parameter should be less than (MWS-1)/2. 
  708. end{description}
  709. State Variables are:
  710. begin{description}
  711. item[dupacks_]
  712. Number of duplicate acks seen since any new data was acknowledged. 
  713. item[seqno_]
  714. Highest sequence number for data from data source to TCP. 
  715. item[t_seqno_]
  716. Current transmit sequence number. 
  717. item[ack_] Highest acknowledgment seen from receiver. cwnd_
  718. Current value of the congestion window. 
  719. item[awnd_]
  720. Current value of a low-pass filtered version of the congestion window. For
  721. investigations of different window-increase algorithms. 
  722. item[ssthresh_]
  723. Current value of the slow-start threshold. 
  724. item[rtt_] Round-trip time estimate. 
  725. item[srtt_]
  726. Smoothed round-trip time estimate. 
  727. item[rttvar_]
  728. Round-trip time mean deviation estimate. 
  729. item[backoff_]
  730. Round-trip time exponential backoff constant. 
  731. end{description}
  732. item[TCP/Reno Objects]
  733. TCP/Reno objects are a subclass of TCP objects that implement the Reno TCP
  734. transport protocol described in paper: "Fall, K., and Floyd, S.
  735. Comparisons of Tahoe, Reno, and Sack TCP. December 1995." URL ftp://
  736. ftp.ee.lbl.gov/papers/sacks.ps.Z. There are no methods,
  737. configuration parameters or state variables specific to this object. 
  738. item[TCP/Newreno Objects]
  739. TCP/Newreno objects are a subclass of TCP objects that implement a
  740. modified version of the BSD Reno TCP transport protocol. 
  741. There are no methods or state variables specific to this object. 
  742. Configuration Parameters are:
  743. begin{description}
  744. item[newreno_changes_]
  745. Set to zero for the default New Reno described in "Fall, K., and Floyd, S.
  746. Comparisons of Tahoe, Reno, and Sack TCP. December 1995". Set to 1 for
  747. additional New Reno algorithms [see Hoe, J., Improving the Start-up
  748. Behavior of a Congestion Control Scheme for TCP. in SIGCOMM 96, August
  749. 1996, pp. 270-280. URL 
  750. http://www.acm.org/sigcomm/sigcomm96/papers/hoe.html.]; this includes the
  751. estimation of the ssthresh parameter during slow-start. 
  752. end{description}
  753. item[TCP/Vegas Objects]
  754. There are no methods or configuration parameters specific to this
  755. object. State variables are:
  756. begin{itemize}
  757. item v_alpha_
  758. item v_beta_
  759. item v_gamma_
  760. item v_rtt_
  761. end{itemize}
  762. item[TCP/Sack1 Objects]
  763. TCP/Sack1 objects are a subclass of TCP objects that implement the BSD
  764. Reno TCP transport protocol with Selective Acknowledgement Extensions
  765. described in "Fall, K., and Floyd, S. Comparisons of Tahoe, Reno, and
  766. Sack TCP. December 1995". URL ftp:// ftp.ee.lbl.gov/papers/sacks.ps.Z. 
  767. They inherit all of the TCP object functionality. There are no methods,
  768. configuration parameters or state variables specific to this object. 
  769. item[TCP/FACK Objects]
  770. TCP/Fack objects are a subclass of TCP objects that implement the BSD Reno
  771. TCP transport protocol with Forward Acknowledgement congestion control. 
  772. They inherit all of the TCP object functionality. There are no methods or
  773. state variables specific to this object. 
  774. Configuration Parameters are:
  775. begin{description}
  776. item[ss-div4]
  777. Overdamping algorithm. Divides ssthresh by 4 (instead of 2) if congestion
  778. is detected within 1/2 RTT of slow-start. (1=Enable, 0=Disable) 
  779. item[rampdown]
  780. Rampdown data smoothing algorithm. Slowly reduces congestion window rather
  781. than instantly halving it. (1=Enable, 0=Disable) 
  782. end{description}
  783. item[TCP/FULLTCP Objects]
  784. This section has not yet been added here. The implementation
  785. and the configuration parameters are described in paper: "Fall, K.,
  786. Floyd, S., and Henderson, T., Ns Simulator Tests for Reno FullTCP.
  787. July, 1997." URL ftp://ftp.ee.lbl.gov/papers/fulltcp.ps. 
  788. item[TCPSINK Objects]
  789. TCPSink objects are a subclass of agent objects that implement a receiver
  790. for TCP packets. The simulator only implements "one-way" TCP connections,
  791. where the TCP source sends data packets and the TCP sink sends ACK
  792. packets. TCPSink objects inherit all of the generic agent functionality.
  793. There are no methods or state variables specific to the TCPSink object. 
  794. Configuration Parameters are
  795. begin{description}
  796. item[packetSize_]
  797. The size in bytes to use for all acknowledgment packets. 
  798. item[maxSackBlocks_]
  799. The maximum number of blocks of data that can be acknowledged in a SACK
  800. option. For a receiver that is also using the time stamp option [RFC
  801. 1323], the SACK option specified in RFC 2018 has room to include three
  802. SACK blocks. This is only used by the TCPSink/Sack1 subclass. This value
  803. may not be increased within any particular TCPSink object after that
  804. object has been allocated. (Once a TCPSink object has been allocated, the
  805. value of this parameter may be decreased but not increased). 
  806. end{description}
  807. item[TCPSINK/DELACK Objects]
  808. DelAck objects are a subclass of TCPSink that implement a delayed-ACK
  809. receiver for TCP packets. They inherit all of the TCPSink object
  810. functionality. There are no methods or state variables specific to the
  811. DelAck object. 
  812. Configuration Parameters are:
  813. begin{description}
  814. item[interval_]
  815. The amount of time to delay before generating an acknowledgment for a
  816. single packet. If another packet arrives before this time expires,
  817. generate an acknowledgment immediately. 
  818. end{description}
  819. item[TCPSINK/SACK1 Objects]
  820. TCPSink/Sack1 objects are a subclass of TCPSink that implement a SACK
  821. receiver for TCP packets. They inherit all of the TCPSink object
  822. functionality. There are no methods, configuration parameters or state
  823. variables specific to this object. 
  824. item[TCPSINK/SACK1/DELACK Objects]
  825. TCPSink/Sack1/DelAck objects are a subclass of TCPSink/Sack1 that
  826. implement a delayed-SACK receiver for TCP packets. They inherit all of the
  827. TCPSink/Sack1 object functionality. There are no methods or state
  828. variables specific to this object. 
  829. Configuration Parameters are:
  830. begin{description}
  831. item[interval_]
  832. The amount of time to delay before generating an acknowledgment for a
  833. single packet. If another packet arrives before this time expires,
  834. generate an acknowledgment immediately. 
  835. end{description}
  836. end{description}
  837. section{Commands at a glance}
  838. label{sec:agentscommand}
  839. Following are the agent related commands used in simulation scripts:
  840. begin{flushleft}
  841. code{ns_ attach-agent <node> <agent>}\
  842. This command attaches the <agent> to the <node>. We assume here that the
  843. <agent> has already been created. An agent is typically created by
  844. code{set agent [new Agent/AgentType]}
  845. where Agent/AgentType defines the class definiton of the specified agent
  846. type.
  847. code{$agent port}\
  848. This returns the port number to which the agent is attached.
  849. code{$agent dst-port}\
  850. This returns the port number of the destination.
  851. When any connection is setup between 2 nodes, each agent stores the 
  852. destination port in its instance variable called code{dst_port_}.
  853. code{$agent attach-app <s_type>}\
  854. This commands attaches an application of type code{<s_type>} to the agent.
  855. A handle to the application object is returned. Also note that the application
  856. type must be defined as a packet type in packet.h.
  857. code{$agent attach-source <s_type>}\
  858. This used to be the procedure to attach source of type code{<s_type>} to
  859. the agent. But this is obsolete now. Use attach-app (described above)
  860. instead.
  861. code{$agent attach-tbf <tbf>}\
  862. Attaches a token bucket filter (tbf) to the agent.
  863. code{$ns_ connect <src> <dst>}\
  864. Sets up a connection between the src and dst agents. 
  865. code{$ns_ create-connection <srctype> <src> <dsttype> <dst> <pktclass>}\
  866. This sets up a complete connection between two agents. First creates a source
  867. of type <srctype> and binds it to <src>. Then creates a destination of type
  868. <dsttype> and binds it to <dst>. Finally connects the src and dst agents and
  869. returns a handle to the source agent.
  870. code{$ns_ create-connection-list <srctype> <src> <dsttype> <dst> <pktclass>}\
  871. This command is exactly similar to create-connection described above. But
  872. instead of returning only the source-agent, this returns a list of source and
  873. destination agents.
  874. Internal procedures:
  875. code{$ns_ simplex-connect <src> <dst>}\
  876. This is an internal method that actually sets up an unidirectional connection
  877. between the <src> agent and <dst> agent. It simply sets the destination address
  878. and destination port of the <src> as <dst>'s agent-address and agent-port.
  879. The "connect" described above calls this method twice to set up a bi-directional
  880. connection between the src and dst.
  881. code{$agent set <args>}\
  882. This is an internal procedure used to inform users of the backward compatibility
  883. issues resulting from the upgrade to 32-bit addressing space currently used
  884. in ns.
  885. code{$agent attach-trace <file>}\
  886. This attaches the <file> to the agent to allow nam-tracing of the agent
  887. events.
  888. In addition to the agent related procedures described here, there are additional
  889. methods that support different type of agents like Agent/Null, Agent/TCP,
  890. Agent/CBR, Agent/TORA, Agent/mcast etc. These additional methods along
  891. with the procedures described here can be found in ns/tcl/lib/(ns-agent.tcl,
  892. ns-lib.tcl, ns-mip.tcl, ns-mobilenode.tcl, ns-namsupp.tcl, ns-queue.tcl,
  893. ns-route.tcl, ns-sat.tcl, ns-source.tcl). They are also described in the
  894. previous section.
  895. end{flushleft} 
  896. endinput