File: agents.tex

package info (click to toggle)
ns2 2.35%2Bdfsg-2.1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 78,780 kB
  • ctags: 27,490
  • sloc: cpp: 172,923; tcl: 107,130; perl: 6,391; sh: 6,143; ansic: 5,846; makefile: 816; awk: 525; csh: 355
file content (1065 lines) | stat: -rw-r--r-- 42,063 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
\%
% 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 fields\ldots}
                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 packets\footnote{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. 

\item[syn\_]
Set to false to disable modeling the initial SYN/SYNACK exchange. On by default.
Note: if this is set to false and the DelAck sink is used, it's advisable to also disable the sink's ``SYN\_immediate\_ack\_'' flag.
\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. 

\item[RFC2581\_immediate\_ack\_]
A boolean flag. If true, conforms to RFC2581 (section 4.2) and only delays
the ACK if we know we're not doing recovery, i.e. not gap-filling.
Otherwise all ACKs are delayed. The default value is true.

\item[SYN\_immediate\_ack\_]
A boolean flag. If true, the first packet in sequence (seqno == 0) is
always ACKed immediately. This simulates the behavior of the FullTCP
agent, which ACKs a SYN immediately. The default value is true.
See also the ``syn\_'' flag of the one-way TcpAgent.
\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