srm.tex
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:50k
- defc#1{ensuremath{C_{#1}}}
- defd#1{ensuremath{D_{#1}}}
- chapter{Agent/SRM}
- label{chap:agent/srm}
- This chapter describes the internals of the SRM implementation in ns.
- The chapter is in three parts:
- the first part is an overview of a minimal SRM configuration,
- and a ``complete'' description of the configuration parameters
- of the base SRM agent.
- The second part describes the architecture, internals, and the code path
- of the base SRM agent.
- The last part of the chapter is a description of the extensions
- for other types of SRM agents that have been attempted to date.
- The procedures and functions described in this chapter can be found in
- nsf{tcl/mcast/srm.tcl}, nsf{tcl/mcast/srm-adaptive.tcl},
- nsf{tcl/mcast/srm-nam.tcl}, nsf{tcl/mcast/srm-debug.tcl}, and
- nsf{srm.{cc, h}}.
- section{Configuration}
- label{sec:srm-config}
- Running an SRM simulation requires
- creating and configuring the agent,
- attaching an application-level data source (a traffic generator), and
- starting the agent and the traffic generator.
- subsection{Trivial Configuration}
- paragraph{Creating the Agent}
- begin{program}
- set ns [new Simulator] ; preamble initialization;
- $ns enableMcast
- set node [$ns node] ; agent to reside on this node;
- set group [$ns allocaddr] ; multicast group for this agent;
- {bfseries{}set srm [new Agent/SRM]}
- $srm set dst_ $group ; configure the SRM agent;
- {bfseries{}$ns attach-agent $node $srm}
- $srm set fid_ 1 ; optional configuration;
- $srm log [open srmStats.tr w] ; log statistics in this file;
- $srm trace [open srmEvents.tr w] ; trace events for this agent;
- end{program}
- The key steps in configuring a virgin SRM agent are to assign
- its multicast group, and attach it to a node.
- Other useful configuration parameters are
- to assign a separate flow id to traffic originating from this agent,
- to open a log file for statistics, and
- a trace file for trace data%
- footnote{%
- Note that the trace data can also be used
- to gather certain kinds of trace data.
- We will illustrate this later.}.
- The file
- fcnref{code{tcl/mcast/srm-nam.tcl}}{../ns-2/srm-nam.tcl}{Agent/SRM::send}
- contains definitions that overload the agent's code{send} methods;
- this separates control traffic originating from the agent by type.
- Each type is allocated a separate flowID.
- The traffic is separated into session messages (flowid = 40),
- requests (flowid = 41), and repair messages (flowid = 42).
- The base flowid can be changed by setting global variable code{ctrlFid}
- to one less than the desired flowid before sourcing code{srm-nam.tcl}.
- To do this, the simulation script must source code{srm-nam.tcl}
- before creating any SRM agents.
- This is useful for analysis of traffic traces, or
- for visualization in nam.
- paragraph{Application Data Handling}
- The agent does not generate any application data on its own;
- instead, the simulation user can connect any traffic generation
- module to any SRM agent to generate data.
- The following code demonstrates
- how a traffic generation agent can be attached to an SRM agent:
- begin{program}
- set packetSize 210
- set exp0 [new Application/Traffic/Exponential] ; configure traffic generator;
- $exp0 set packetSize_ $packetSize
- $exp0 set burst_time_ 500ms
- $exp0 set idle_time_ 500ms
- $exp0 set rate_ 100k
- {bfseries{}$exp0 attach-agent $srm0} ; attach application to SRM agent;
- {bfseries{}$srm0 set packetSize_ $packetSize} ; to generate repair packets of appropriate size;
- $srm0 set tg_ $exp0 ; pointer to traffic generator object;
- $srm0 set app_fid_ 0 ; fid value for packets generated by traffic generator;
- end{program}
- The user can attach any traffic generator to an SRM agent.
- The SRM agent will add the SRM headers,
- set the destination address to the multicast group, and
- deliver the packet to its target.
- The SRM header contains the type of the message,
- the identity of the sender,
- the sequence number of the message,
- and (for control messages), the round for which this message is being sent.
- Each data unit in SRM is identified as
- tup{sender's id, message sequence number}.
- The SRM agent does not generate its own data;
- it does not also keep track of the data sent,
- except to record the sequence numbers of messages received
- in the event that it has to do error recovery.
- Since the agent has no actual record of past data,
- it needs to know what packet size to use for each repair message.
- Hence, the instance variable code{packetSize_} specifies the size
- of repair messages generated by the agent.
- paragraph{Starting the Agent and Traffic Generator}
- The agent and the traffic generator must be started separately.
- begin{program}
- {bfseries{}fcnref{$srm start}{../ns-2/srm.tcl}{Agent/SRM::start}}
- {bfseries{}fcnref{$exp0 start}{../ns-2/srm.tcl}{Agent/SRM::start-source}}
- end{program}
- Alternatively, the traffic generator can be started from the SRM Agent:
- begin{program}
- {bfseries{}fcnref{$srm0 start-source}{../ns-2/srm.tcl}{Agent/SRM::start-source}}
- end{program}
- At code{start}, the agent joins the multicast group, and
- starts generating session messages.
- The code{start-source} triggers the traffic generator to start sending
- data.
- subsection{Other Configuration Parameters}
- label{sec:config-param}
- In addition to the above parameters,
- the SRM agent supports additional configuration variables.
- Each of the variables described in this section is
- both an OTcl class variable and an OTcl object's instance variable.
- Changing the class variable changes the default value
- for all agents that are created subsequently.
- Changing the instance variable of a particular agent
- only affects the values used by that agent.
- For example,
- begin{program}
- Agent/SRM set D1_ 2.0 ; Changes the class variable;
- $srm set D1_ 2.0 ; Changes D1_ for the particular $srm object only;
- end{program}
- The default request and repair timer parameters cite{Floy95:Reliable}
- for each SRM agent are:
- begin{program}
- Agent/SRM set C1_ 2.0 ; request parameters;
- Agent/SRM set C2_ 2.0
- Agent/SRM set D1_ 1.0 ; repair parameters;
- Agent/SRM set D2_ 1.0
- end{program}
- It is thus possible to trivially obtain two flavors of SRM agents
- based on whether the agents use probabilistic or deterministic
- suppression by using the following definitions:
- begin{program}
- Class Agent/SRM/Deterministic -superclass Agent/SRM
- Agent/SRM/Deterministic set C2_ 0.0
- Agent/SRM/Deterministic set D2_ 0.0
- Class Agent/SRM/Probabilistic -superclass Agent/SRM
- Agent/SRM/Probabilistic set C1_ 0.0
- Agent/SRM/Probabilistic set D1_ 0.0
- end{program}
- In href{a later section}{Section}{sec:extensions},
- we will discuss other ways of extending the SRM agent.
- Timer related functions are handled by separate objects
- belonging to the class SRM.
- Timers are required for loss recovery and sending periodic session messages.
- There are loss recovery objects to send request and repair messages.
- The agent creates a separate request or repair object to handle each loss.
- In contrast, the agent only creates one session object to send
- periodic session messages.
- The default classes the express each of these functions are:
- begin{program}
- Agent/SRM set requestFunction_ "SRM/request"
- Agent/SRM set repairFunction_ "SRM/repair"
- Agent/SRM set sessionFunction_ "SRM/session"
- Agent/SRM set requestBackoffLimit_ 5 ; parameter to requestFunction_;
- Agent/SRM set sessionDelay_ 1.0 ; parameter to sessionFunction_;
- end{program}
- The instance procedures
- fcnref{proc[]{requestFunction}}{../ns-/srm.tcl}{Agent/SRM::requestFunction},
- fcnref{proc[]{repairFunction}}{../ns-/srm.tcl}{Agent/SRM::repairFunction},
- and
- fcnref{proc[]{sessionFunction}}{../ns-/srm.tcl}{Agent/SRM::sessionFunction}
- can be used to change the default function for individual agents.
- The last two lines are specific parameters used by the request
- and session objects.
- The href{following section}{Section}{sec:architecture}
- describes the implementation of theses objects in greater detail.
- subsection{Statistics}
- Each agent tracks two sets of statistics:
- statistics to measure the response to data loss,
- and overall statistics for each request/repair.
- In addition, there are methods to access other
- information from the agent.
- paragraph{Data Loss}
- The statistics to measure the response to data losses
- tracks the duplicate requests (and repairs),
- and the average request (and repair) delay.
- The algorithm used is documented in Floyd etal cite{Floy95:Reliable}.
- In this algorithm,
- each new request (or repair) starts a new request (or repair) period.
- During the request (or repair) period, the agent measures
- the number of first round duplicate requests (or repairs)
- until the round terminates either due to receiving a request (or
- repair), or due to the agent sending one.
- % These statistics are used by the adaptive timer algorithms;
- % we will describe our implementation of these algorithms
- % in the following subsections.
- The following code illustrates how the user can simple retrieve the
- current values in an agent:
- begin{program}
- set statsList [$srm array get statistics_]
- array set statsArray [$srm array get statistics_]
- end{program}
- The first form returns a list of key-value pairs.
- The second form loads the list into the code{statsArray} for further manipulation.
- The keys of the array are
- code{dup-req}, code{ave-dup-req}, code{req-delay}, code{ave-req-delay},
- code{dup-rep}, code{ave-dup-rep}, code{rep-delay}, and code{ave-rep-delay}.
- paragraph{Overall Statistics}
- In addition, each loss recovery and session object keeps track of
- times and statistics.
- In particular, each object records its
- code{startTime}, code{serviceTime}, code{distance}, as are relevant to that object;
- startTime is the time that this object was created,
- serviceTime is the time for this object to complete its task, and the
- distance is the one-way time to reach the remote peer.
- For request objects, startTime is the time a packet loss is detected,
- serviceTime is the time to finally receive that packet,
- and distance is the distance to the original sender of the packet.
- For repair objects, startTime is the time that a request for
- retransmission is received, serviceTime is the time send a repair,
- and the distance is the distance to the original requester.
- For both types of objects, the serviceTime is normalized by the
- distance.
- For the session object,
- startTime is the time that the agent joins the multicast group.
- serviceTime and distance are not relevant.
- Each object also maintains statistics particular to that type of object.
- Request objects track the number of duplicate requests and repairs received,
- the number of requests sent, and the number of times this object
- had to backoff before finally receiving the data.
- Repair objects track the number of duplicate requests and repairs,
- as well as whether or not this object for this agent sent the repair.
- Session objects simply record the number of session messages sent.
- The values of the timers and the statistics for each object are written
- to the log file every time an object completes the error recovery function
- it was tasked to do.
- The format of this trace file is:
- begin{program}
- tup{prefix} tup{id} tup{times} tup{stats}
- {itshape{}where}
- tup{prefix} is tup{time} n tup{node id} m tup{msg id} r tup{round}
- tup{msg id} is expressed as tup{source id:sequence number}
- tup{id} is type tup{of object}
- tup{times} is list of key-value pairs of startTime, serviceTime, distance
- tup{stats} is list of key-value pairs of per object statistics
- code{dupRQST}, code{dupREPR}, code{#sent}, code{backoff} {itshape for request objects}
- code{dupRQST}, code{dupREPR}, code{#sent} {itshape for repair objects}
- code{#sent} {itshape for session objects}
- end{program}
- The following sample output illustrates the output file format (the lines
- have been folded to fit on the page):
- {small
- begin{verbatim}
- 3.6274 n 0 m <1:1> r 1 type repair serviceTime 0.500222
- startTime 3.5853553333333332 distance 0.0105 #sent 1 dupREPR 0 dupRQST 0
- 3.6417 n 1 m <1:1> r 2 type request serviceTime 2.66406
- startTime 3.5542666666666665 distance 0.0105 backoff 1 #sent 1 dupREPR 0 dupRQST 0
- 3.6876 n 2 m <1:1> r 2 type request serviceTime 1.33406
- startTime 3.5685333333333333 distance 0.021 backoff 1 #sent 0 dupREPR 0 dupRQST 0
- 3.7349 n 3 m <1:1> r 2 type request serviceTime 0.876812
- startTime 3.5828000000000002 distance 0.032 backoff 1 #sent 0 dupREPR 0 dupRQST 0
- 3.7793 n 5 m <1:1> r 2 type request serviceTime 0.669063
- startTime 3.5970666666666671 distance 0.042 backoff 1 #sent 0 dupREPR 0 dupRQST 0
- 3.7808 n 4 m <1:1> r 2 type request serviceTime 0.661192
- startTime 3.5970666666666671 distance 0.0425 backoff 1 #sent 0 dupREPR 0 dupRQST 0
- end{verbatim}
- }
- paragraph{Miscellaneous Information}
- Finally, the user can use the following methods to gather
- additional information about the agent:
- begin{list}{textbullet}{}
- item
- fcnref{proc[]{groupSize?}}{../ns-2/srm.tcl.html}{Agent/SRM::groupSize?}
- returns the agent's current estimate of the multicast group size.
- item
- fcnref{proc[]{distances?}}{../ns-2/srm.cc.html}{SRMAgent::command}
- returns a list of key-value pairs of distances;
- the key is the address of the agent,
- the value is the estimate of the distance to that agent.
- The first element is the address of this agent, and the distance of 0.
- item
- fcnref{proc[]{distance?}}{../ns-2/srm.cc.html}{SRMAgent::command}
- returns the distance to the particular agent specified as argument.
- The default distance at the start of any simulation is 1.
- end{list}
- begin{program}
- $srm(i) groupSize? ; returns $srm(i)'s estimate of the group size;
- $srm(i) distances? ; returns list of tup{address, distance} tuples;
- $srm(i) distance? 257 ; returns the distance to agent at address 257;
- end{program}
- subsection{Tracing}
- Each object writes out trace information that can be used to track the
- progress of the object in its error recovery.
- Each trace entry is of the form:
- begin{program}
- tup{prefix} tup{tag} tup{type of entry} tup{values}
- end{program}
- The prefix is as describe in the previous section for statistics.
- The tag is {bf Q} for request objects, {bf P} for repair objects, and
- {bf S} for session objects.
- The following types of trace entries and parameters are written by each
- object:
- centerline{smallrenewcommand{arraystretch}{1.3}
- begin{tabular}{rclp{2in}}hline
- & Type of & & \
- Tag & Object & Other values & Comments\ hline
- Q & DETECT & & \
- Q & INTERVALS & C1 tup{C1_} C2 tup{C2_} dist tup{distance} i tup{backoff_} & \
- Q & NTIMER & at tup{time} & Time the request timer will fire \
- Q & SENDNACK & & \
- Q & NACK & IGNORE-BACKOFF tup{time} & Receive NACK, ignore other NACKs until
- tup{time} \
- Q & REPAIR & IGNORES tup{time} & Receive REPAIR, ignore NACKs until tup{time} \
- Q & DATA & & Agent receives data instead of repair. Possibly indicates out of order arrival of data. \ hline
- P & NACK & from tup{requester} & Receive NACK, initiate repair \
- P & INTERVALS & D1 tup{D1_} D2 tup{D2_} dist tup{distance} & \
- P & RTIMER & at tup{time} & Time the repair timer will fire \
- P & SENDREP & \
- P & REPAIR & IGNORES tup{time} & Receive REPAIR, ignore NACKs until tup{time} \
- P & DATA & & Agent receives data instead of repair. Indicates premature request by an agent. \ hline
- S & SESSION & & logs session message sent \ hline
- end{tabular}}
- The following illustrates a typical trace for a single loss and recovery.
- {small
- begin{verbatim}
- 3.5543 n 1 m <1:1> r 0 Q DETECT
- 3.5543 n 1 m <1:1> r 1 Q INTERVALS C1 2.0 C2 0.0 d 0.0105 i 1
- 3.5543 n 1 m <1:1> r 1 Q NTIMER at 3.57527
- 3.5685 n 2 m <1:1> r 0 Q DETECT
- 3.5685 n 2 m <1:1> r 1 Q INTERVALS C1 2.0 C2 0.0 d 0.021 i 1
- 3.5685 n 2 m <1:1> r 1 Q NTIMER at 3.61053
- 3.5753 n 1 m <1:1> r 1 Q SENDNACK
- 3.5753 n 1 m <1:1> r 2 Q INTERVALS C1 2.0 C2 0.0 d 0.0105 i 2
- 3.5753 n 1 m <1:1> r 2 Q NTIMER at 3.61727
- 3.5753 n 1 m <1:1> r 2 Q NACK IGNORE-BACKOFF 3.59627
- 3.5828 n 3 m <1:1> r 0 Q DETECT
- 3.5828 n 3 m <1:1> r 1 Q INTERVALS C1 2.0 C2 0.0 d 0.032 i 1
- 3.5828 n 3 m <1:1> r 1 Q NTIMER at 3.6468
- 3.5854 n 0 m <1:1> r 0 P NACK from 257
- 3.5854 n 0 m <1:1> r 1 P INTERVALS D1 1.0 D2 0.0 d 0.0105
- 3.5854 n 0 m <1:1> r 1 P RTIMER at 3.59586
- 3.5886 n 2 m <1:1> r 2 Q INTERVALS C1 2.0 C2 0.0 d 0.021 i 2
- 3.5886 n 2 m <1:1> r 2 Q NTIMER at 3.67262
- 3.5886 n 2 m <1:1> r 2 Q NACK IGNORE-BACKOFF 3.63062
- 3.5959 n 0 m <1:1> r 1 P SENDREP
- 3.5959 n 0 m <1:1> r 1 P REPAIR IGNORES 3.62736
- 3.5971 n 4 m <1:1> r 0 Q DETECT
- 3.5971 n 4 m <1:1> r 1 Q INTERVALS C1 2.0 C2 0.0 d 0.0425 i 1
- 3.5971 n 4 m <1:1> r 1 Q NTIMER at 3.68207
- 3.5971 n 5 m <1:1> r 0 Q DETECT
- 3.5971 n 5 m <1:1> r 1 Q INTERVALS C1 2.0 C2 0.0 d 0.042 i 1
- 3.5971 n 5 m <1:1> r 1 Q NTIMER at 3.68107
- 3.6029 n 3 m <1:1> r 2 Q INTERVALS C1 2.0 C2 0.0 d 0.032 i 2
- 3.6029 n 3 m <1:1> r 2 Q NTIMER at 3.73089
- 3.6029 n 3 m <1:1> r 2 Q NACK IGNORE-BACKOFF 3.66689
- 3.6102 n 1 m <1:1> r 2 Q REPAIR IGNORES 3.64171
- 3.6172 n 4 m <1:1> r 2 Q INTERVALS C1 2.0 C2 0.0 d 0.0425 i 2
- 3.6172 n 4 m <1:1> r 2 Q NTIMER at 3.78715
- 3.6172 n 4 m <1:1> r 2 Q NACK IGNORE-BACKOFF 3.70215
- 3.6172 n 5 m <1:1> r 2 Q INTERVALS C1 2.0 C2 0.0 d 0.042 i 2
- 3.6172 n 5 m <1:1> r 2 Q NTIMER at 3.78515
- 3.6172 n 5 m <1:1> r 2 Q NACK IGNORE-BACKOFF 3.70115
- 3.6246 n 2 m <1:1> r 2 Q REPAIR IGNORES 3.68756
- 3.6389 n 3 m <1:1> r 2 Q REPAIR IGNORES 3.73492
- 3.6533 n 4 m <1:1> r 2 Q REPAIR IGNORES 3.78077
- 3.6533 n 5 m <1:1> r 2 Q REPAIR IGNORES 3.77927
- end{verbatim}
- }
- The logging of request and repair traces is done by
- fcnref{proc[]{SRM::evTrace}}{../ns-2/srm.tcl}{SRM::evTrace}.
- However, the routine
- fcnref{proc[]{SRM/Session::evTrace}}{../ns-2/srm.tcl}{SRM/Session::evTrace},
- overrides the base class definition of proc[]{srm::evTrace},
- and writes out nothing.
- Individual simulation scripts can override these methods
- for greater flexibility in logging options.
- One possible reason to override these methods might to
- reduce the amount of data generated;
- the new procedure could then generate compressed and processed output.
- Notice that the trace filoe contains sufficient information and details
- to derive most of the statistics written out in the log file, or
- is stored in the statistics arrays.
- section{Architecture and Internals}
- label{sec:architecture}
- The SRM agent implementation splits the protocol functions
- into packet handling, loss recovery, and session message activity.
- begin{list}{}{}
- item Packet handling consists of forwarding application data messages,
- sending and receipt of control messages.
- These activities are executed by C++ methods.
- item Error detection is done in C++ due to receipt of messages.
- However, the loss recovery is entirely done through
- instance procedures in OTcl.
- item The sending and processing of messages is accomplished in C++;
- the policy about when these messages should be sent is decided
- by instance procedures in OTcl.
- end{list}
- We first describe the C++
- href{processing due to receipt of messages}{Section}{sec:receipt}.
- Loss recovery and the sending of session messages involves
- timer based processing.
- The agent uses a separate clsref{SRM}{../ns-2/srm.tcl}
- to perform the timer based functions.
- For each loss, an agent may do either request or repair processing.
- Each agent will instantiate a separate loss recovery object
- for every loss, as is appropriate for the processing that it has to do.
- In the following section
- href{we describe the basic timer based functions and
- the loss recovery mechanisms}{Section}{sec:recovery}.
- Finally, each agent uses one timer based function
- for href{sending periodic session messages}{Section}{sec:session}.
- section{Packet Handling: Processing received messages}
- label{sec:receipt}
- The
- fcnref{fcn[]{recv}}{../ns-2/srm.cc}{SRMAgent::recv}
- method can receive four type of messages:
- data, request, repair, and session messages.
- paragraph{Data Packets}
- The agent does not generate any data messages.
- The user has to specify an external agent to generate traffic.
- The fcn[]{recv} method must distinguish between
- locally originated data that must be sent to the multicast group,
- and data received from multicast group that must be processed.
- Therefore, the application agent must
- set the packet's destination address to zero.
- For locally originated data,
- the agent adds the appropriate SRM headers,
- sets the destination address to the multicast group,
- and forwards the packet to its target.
- On receiving a data message from the group,
- fcnref{fcn[sender, msgid]{recv_data}}{../ns-2/srm.cc}{SRMAgent::recv_data}
- will update its state marking message tup{sender, msgid} received,
- and possibly trigger requests if it detects losses.
- In addition, if the message was an older message received out of order,
- then there must be a pending request or repair that must be cleared.
- In that case, the compiled object invokes the OTcl instance procedure,
- fcnref{proc[sender, msgid]{recv-data}}{%
- ../ns-2/srm.tcl}{Agent/SRM::recv-data}%
- footnote{Technically,
- fcn[]{recv_data} invokes the instance procedure
- code{recv data tup{sender} tup{msgid}},
- that then invokes proc[]{recv-data}.
- The indirection allows individual simulation scripts to override the
- proc[]{recv} as needed.}.
- Currently, there is no provision for the receivers
- to actually receive any application data.
- The agent does not also store any of the user data.
- It only generates repair messages of the appropriate size,
- defined by the instance variable code{packetSize_}.
- However, the agent assumes that any application data
- is placed in the data portion of the packet,
- pointed to by code{packet->accessdata()}.
- paragraph{Request Packets}
- On receiving a request,
- fcnref{fcn[sender, msgid]{recv_rqst}}{../ns-2/srm.cc}{SRMAgent::recv_rqst}
- will check whether it needs to schedule requests for other missing data.
- If it has received this request
- before it was aware that the source had generated this data message
- (ie, the sequence number of the request is higher than
- the last known sequence number of data from this source),
- then the agent can infer that it is missing this, as well as data
- from the last known sequence number onwards;
- it schedules requests for all of the missing data and returns.
- On the other hand, if the sequence number of the request is less
- than the last known sequence number from the source,
- then the agent can be in one of three states:
- (1) it does not have this data, and has a request pending for it,
- (2) it has the data, and has seen an earlier request,
- upon which it has a repair pending for it, or
- (3) it has the data, and it should instantiate a repair.
- All of these error recovery mechanisms are done in OTcl;
- fcn[]{recv_rqst} invokes the instance procedure
- fcnref{proc[sender, msgid,
- requester]{recv-rqst}}{../ns-2/srm.tcl}{Agent/SRM::recv-rqst}
- for further processing.
- paragraph{Repair Packets}
- On receiving a repair,
- fcnref{fcn[sender, msgid]{recv_repr}}{../ns-2/srm.cc}{SRMAgent::recv_repr}
- will check whether it needs to schedule requests for other missing data.
- If it has received this repair
- before it was aware that the source had generated this data message
- (ie, the sequence number of the repair is higher than
- the last known sequence number of data from this source),
- then the agent can infer that it is missing all
- data between the last known sequence number and that on the repair;
- it schedules requests for all of this data,
- marks this message as received, and returns.
- On the other hand, if the sequence number of the request is less
- than the last known sequence number from the source,
- then the agent can be in one of three states:
- (1) it does not have this data, and has a request pending for it,
- (2) it has the data, and has seen an earlier request,
- upon which it has a repair pending for it, or
- (3) it has the data, and probably scheduled a repair for it at some time;
- after error recovery, its hold down timer (equal to three times its
- distance to some requester) expired, at which time the pending object
- was cleared. In this last situation, the agent will simply ignore
- the repair, for lack of being able to do anything meaningful.
- All of these error recovery mechanisms are done in OTcl;
- fcn[]{recv_repr} invokes the instance procedure
- fcnref{proc[sender, msgid]{recv-repr}}{%
- ../ns-2/srm.tcl}{Agent/SRM::recv-rqst}
- to complete the loss recovery phase for the particular message.
-
- paragraph{Session Packets}
- On receiving a session message,
- the agent updates its sequence numbers for all active sources,
- and computes its instantaneous distance to the sending agent if possible.
- The agent will ignore earlier session messages from a group member,
- if it has received a later one out of order.
-
- Session message processing is done in
- fcnref{fcn[]{recv_sess}}{../ns-2/srm.cc}{SRMAgent::recv_sess}.
- The format of the session message is:
- tup{count of tuples in this message, list of tuples},
- where each tuple indicates the
- tup{sender id, last sequence number from the source, time the last
- session message was received from this sender, time that that message
- was sent}.
- The first tuple is the information about the local agent%
- footnote{Note that this implementation of session message handling
- is subtly different from that used in emph{wb} or described in
- cite{Floy95:Reliable}.
- In principle, an agent disseminates a list of the data it has
- actually received.
- Our implementation, on the other hand, only disseminates
- a count of the last message sequence number per source that the
- agent knows that that the source has sent.
- This is a constraint when studying aspects of loss recovery
- during partition and healing.
- It is reasonable to expect that the maintainer of this code will fix
- this problem during one of his numerous intervals of copious spare time.}.
- section{Loss Detection---The Class SRMinfo}
- label{sec:srminfo}
- A very small encapsulating class, entirely in C++,
- tracks a number of assorted state information.
- Each member of the group, $n_i$, uses one SRMinfo block for every other
- member of the group.
- An SRMinfo object about group member $n_j$ at $n_i$,
- contains information about the session messages
- received by $n_i$ from $n_j$.
- $n_i$ can use this information to compute its distance to $n_j$.
- If $n_j$ sends is active in sending data traffic, then
- the SRMinfo object will also contain information about the
- received data, including a bit vector indicating all packets
- received from $n_j$.
- The agent keeps a list of SRMinfo objects, one per group member,
- in its member variable, code{sip_}.
- Its method, fcn[int sender]{get_state}
- will return the object corresponding to that sender,
- possibly creating that object, if it did not already exist.
- The clsref{SRMinfo}{../ns-2/srm-state.h} has two methods
- to access and set the bit vector, ie,
- begin{alist}
- fcn[int id]{ifReceived} & indicates whether the particular message
- from the appropriate sender, with id code{id}
- was received at $n_i$,\
- fcn[int id]{setReceived} & to set the bit to indicate that the
- particular message from the appropriate sender,
- with id code{id} was received at $n_i$.
- end{alist}
- The session message variables to access timing information are public;
- no encapsulating methods are provided. These are:
- begin{program}
- int lsess_; * # of last session msg received */
- int sendTime_; * Time sess. msg. # sent */
- int recvTime_; * Time sess. msg. # received */
- double distance_;
- /* {cf Data messages} */
- int ldata_; * # of last data msg sent */
- end{program}
- section{Loss Recovery Objects}
- label{sec:recovery}
- In the last section,
- we described the agent behavior when it receives a message.
- Timers are used to control when any particular control message is to be sent.
- The SRM agent uses a separate
- clsref{SRM}{../ns-2/srm.tcl}
- to do the timer based processing.
- In this section, we describe the basics if the class SRM,
- and the loss recovery objects.
- The following section will describe how the class SRM is used
- for sending periodic session messages.
- An SRM agent will instantiate one object to recover from one lost data packet.
- Agents that detect the loss will instantiate an object in the
- clsref{SRM/request}{../ns-2/srm.tcl};
- agents that receive a request and have the required data will
- instantiate an object in the clsref{SRM/repair}{../ns-2/srm.tcl}.
- paragraph{Request Mechanisms}
- SRM agents detect loss when they receive a message, and
- infer the loss based on the sequence number on the message received.
- Since packet reception is handled entirely by the compiled object,
- loss detection occurs in the C++ methods.
- Loss recovery, however, is handled entirely by instance procedures
- of the corresponding interpreted object in OTcl.
- When any of the methods detects new losses, it invokes
- fcnref{proc[]{Agent/SRM::request}}{../ns-2/srm.tcl}{Agent/SRM::request}
- with a list of the message sequence numbers that are missing.
- proc[]{request} will create a new code{requestFunction_}
- object for each message that is missing.
- The agent stores the object handle in its array of code{pending_} objects.
- The key to the array is the message identifier tup{sender}:tup{msgid}.
- begin{list}{}{}
- item
- The default code{requestFunction_} is clsref{SRM/request}.
- The constructor for the class SRM/request
- calls the base class constructor to initialize
- the simulator instance (code{ns_}), the SRM agent (code{agent_}),
- trace file (code{trace_}), and the code{times_} array.
- It then initializes its code{statistics_} array with the pertinent elements.
- item
- A separate call to
- fcnref{proc[]{set-params}}{../ns-2/srm.tcl}{SRM::set-params}
- sets the code{sender_}, code{msgid_}, code{round_} instance variables for
- the request object.
- The object determines code{C1_} and code{C2_} by querying its code{agent_}.
- It sets its distance to the sender (code{times_(distance)})
- and fixes other scheduling parameters:
- the backoff constant (code{backoff_}),
- the current number of backoffs (code{backoffCtr_}),
- and the limit (code{backoffLimit_}) fixed by the agent.
- proc[]{set-params} writes the trace entry ``textsc{q detect}''.
- item
- The final step in proc[]{request} is to schedule the timer
- to send the actual request at the appropriate moment.
- The instance procedure
- fcnref{proc[]{SRM/request::schedule}}{../ns-2/srm.tcl}{%
- SRM/request::schedule}
- uses
- fcnref{proc[]{compute-delay}}{%
- ../ns-2/srm.tcl}{SRM/request::compute-delay}
- and its current backoff constant to determine the delay.
- The object schedules
- fcnref{proc[]{send-request}}{../ns-2/srm.tcl}{SRM/request::send-request}
- to be executed after code{delay_} seconds.
- The instance variable code{eventID_} stores a handle to the scheduled event.
- The default proc[]{compute-delay} function returns a value
- uniformly distributed in the interval $[C_1 d_s, (C_1 + C_2) d_s]$,
- where $d_s$ is twice code{$times_(distance)}.
- The proc[]{schedule} schedules an event to send a request
- after the computed delay.
- The routine writes a trace entry ``textsc{q ntimer } at tup{time}''.
- end{list}
- When the scheduled timer fires, the routine
- fcnref{proc[]{send-request}}{../ns-2/srm.tcl}{SRM/request::send-request}
- sends the appropriate message.
- It invokes ``code{$agent_} send request tup{args}'' to send the request.
- Note that proc[]{send} is an instproc-like,
- executed by the fcn[]{command} method of the compiled object.
- However, it is possible to overload the instproc-like
- with a specific instance procedure proc[]{send}
- for specific configurations.
- As an example, recall that the file code{tcl/mcast/srm-nam.tcl}
- overloads the proc[]{send} command
- to set the flowid based on type of message that is sent.
- proc[]{send-request} updates the statistics, and writes the trace entry
- ``textsc{q sendnack}''.
- When the agent receives a control message for a packet
- for which a pending object exists,
- the agent will hand the message off to the object for processing.
- begin{list}{}{}
- item When a
- fcnref{request for a particular packet is received}{../ns-2/srm.tcl}{%
- SRM/request::recv-request},
- the request object can be in one of two states:
- it is ignoring requests, considering them to be duplicates, or
- it will cancel its send event and re-schedule another one,
- after having backed off its timer.
- If ignoring requests it will update its statistics,
- and write the trace entry ``textsc{q nack } dup''.
- Otherwise, set a time based on its current estimate of the code{delay_},
- until which to ignore further requests.
- This interval is marked by the instance variable code{ignore_}.
- If the object reschedules its timer, it will write the trace entry
- ``textsc{ q nack ignore-backoff } tup{ignore}''.
- Note that this re-scheduling relies on the fact that
- the agent has joined the multicast group, and will therefore
- receive a copy of every message it sends out.
-
- item When the
- fcnref{request object receives a repair for the particular packet}{%
- ../ns-2/srm.tcl}{SRM/request::recv-repair},
- it can be in one of two states:
- either it is still waiting for the repair,
- or it has already received an earlier repair.
- If it is the former, there will be an event pending
- to send a request, and code{eventID_} will point to that event.
- The object will compute its serviceTime, cancel that event,
- and set a hold-down period during which it will ignore
- other requests.
- At the end of the hold-down period, the object will ask its
- agent to clear it.
- It will write the trace entry ``textsc{q repair ignores } tup{ignore}''.
- On the other hand, if this is a duplicate repair,
- the object will update its statistics, and write the trace entry
- ``textsc{q repair } dup''.
- end{list}
- When the loss recovery phase is completed by the object,
- fcnref{proc[]{Agent/SRM::clear}}{../ns-2/srm.tcl}{Agent/SRM::clear}
- will remove the object from its array of code{pending_} objects,
- and place it in its list of code{done_} objects.
- Periodically, the agent will cleanup and delete the code{done_} objects.
- paragraph{Repair Mechanisms}
- The agent will initiate a repair if it receives a request for a packet,
- and it does not have a request object code{pending_} for that packet.
- The default repair object belongs to the
- clsref{SRM/repair}{../ns-2/srm.tcl}.
- Barring minor differences,
- the sequence of events and the instance procedures in this class
- are identical to those for SRM/request.
- Rather than outline every single procedure, we only outline
- the differences from those described earlier for a request object.
- The repair object uses the repair parameters, code{D1_}, code{D2_}.
- A repair object does not repeatedly reschedule is timers;
- therefore, it does not use any of the backoff variables
- such as that used by a request object.
- The repair object ignores all requests for the same packet.
- The repair objet does not use the code{ignore_} variable that
- request objects use.
- The trace entries written by repair objects are marginally different;
- they are ``textsc{p nack } from tup{requester}'',
- ``textsc{p rtimer } at tup{fireTime}'',
- ``textsc{p sendrep}'', ``textsc{p repair ignores } tup{holddown}''.
- Apart from these differences,
- the calling sequence for events in a repair object is similar to that
- of a request object.
- paragraph{Mechanisms for Statistics}
- The agent, in concert with the request and repair objects,
- collect statistics about their response to data loss cite{Floy95:Reliable}.
- Each call to the agent proc[]{request} procedure marks a new period.
- At the start of a new period,
- fcnref{proc[]{mark-period}}{../ns-2/srm.tcl}{Agent/SRM::mark-period}
- computes the moving average of the number of duplicates in the last period.
- Whenever the agent receives a first round request from another agent,
- and it had sent a request in that round, then it considers the request
- as a duplicate request, and increments the appropriate counters.
- A request object does not consider duplicate requests if it did not
- itself send a request in the first round.
- If the agent has a repair object pending, then it does not consider
- the arrival of duplicate requests for that packet.
- The object methods
- fcnref{proc[]{SRM/request::dup-request?}}{../ns-2/srm.tcl}{%
- SRM/request::dup-request?} and
- fcnref{proc[]{SRM/repair::dup-request?}}{../ns-2/srm.tcl}{%
- SRM/repair::dup-request?}
- encode these policies, and return 0 or 1 as required.
- A request object also computes the elapsed time between
- when the loss is detected to when it receives the first request.
- The agent computes a moving average of this elapsed time.
- The object computes the elapsed time (or delay) when it
- fcnref{cancels}{../ns-2/srm.tcl}{SRM/request::cancel}
- its scheduled event for the first round.
- The object invokes
- fcnref{Agent/SRM::update-ave}{../ns-2/srm.tcl}{Agent/SRM::update-ave}
- to compute the moving average of the delay.
- The agent keeps similar statistics of the duplicate repairs,
- and the repair delay.
- The agent stores the number of rounds taken for one loss recovery,
- to ensure that subsequent loss recovery phases for that packet
- that are not definitely not due to data loss
- do not account for these statistics.
- The agent stores the number of routes taken for a phase in
- the array code{old_}.
- When a new loss recovery object is instantiated,
- the object will use the agent's instance procedure
- fcnref{proc[]{round?}}{../ns-2/srm.tcl}{Agent/SRM::round?}
- to determine the number of rounds in a previous loss recovery phase
- for that packet.
- section{Session Objects}
- label{sec:session}
- Session objects,
- href{like the loss recovery objects}{Section}{sec:recovery},
- are derived from the base clsref{SRM}.
- Unlike the loss recovery objects though,
- the agent only creates one session object for the lifetime of the agent.
- The constructor invokes the base class constructor as before;
- it then sets its instance variable code{sessionDelay_}.
- The agent creates the session object when it proc[]{start}s.
- At that time, it also invokes
- fcnref{SRM/session::schedule}{../ns-2/srm.tcl}{SRM/session::schedule},
- to send a session message after code{sessionDelay_} seconds.
- When the object sends a session message,
- it will schedule to send the next one after some interval.
- It will also update its statistics.
- fcnref{proc[]{send-session}}{../ns-2/srm.tcl}{SRM/session::send-session}
- writes out the trace entry ``textsc{s session}''.
- The class overrides the
- proc[]{evTrace} routine that writes out the trace entries.
- fcnref{SRM/session::evTrace}{../ns-2/srm.tcl}{SRM/sesion::evTrace}
- disable writing out the trace entry for session messages.
- Two types of session message scheduling strategies are currently
- available:
- The function in the base class schedules sending session messages at
- fixed intervals of code{sessionDelay_} jittered around a small value
- to avoid synchronization among all the agents at all the nodes.
- clsref{SRM/session/logScaled} schedules sending messages
- at intervals of code{sessionDelay} times $log_2$(code{groupSize_})
- so that the frequency of session messages is inversely proportional to
- the size of the group.
- The base class that sends messages at fixed intervals
- is the default code{sessionFunction_} for the agent.
- section{Extending the Base Class Agent}
- label{sec:extensions}
- In
- href{the earlier section on configuration parameters}{Section}{sec:config-param},
- we had shown how to trivially extend the agent to
- get deterministic and probabilistic protocol behavior.
- In this section, we describe how to derive more complex
- extensions to the protocol for fixed and adaptive timer mechanisms.
- subsection{Fixed Timers}
- The fixed timer mechanism are done in
- the derived clsref{Agent/SRM/Fixed}.
- The main difference with fixed timers is that
- the repair parameters are set to $log$(code{groupSize_}).
- Therefore,
- fcnref{the repair procedure of a fixed timer agent}{../ns-2/srm.tcl}{%
- Agent/SRM/Fixed::repair}
- will set d1 and d2 to be proportional to the group size
- before scheduling the repair object.
- subsection{Adaptive Timers}
- Agents using adaptive timer mechanisms
- modify their request and repair parameters under three conditions
- (1) every time a new loss object is created;
- (2) when sending a message; and
- (3) when they receive a duplicate, if their relative distance to the loss
- is less than that of the agent that sends the duplicate.
- All three changes require extensions to the agent and the loss objects.
- The clsref{Agent/SRM/Adaptive}{../ns-2/srm-adaptive.tcl}
- uses clsref{SRM/request/Adaptive}{../ns-2/srm-adaptive.tcl} and
- clsref{SRM/repair/Adaptive}{../ns-2/srm-adaptive.tcl}
- as the request and repair functions respectively.
- In addition, the last item requires extending the packet headers,
- to advertise their distances to the loss.
- The corresponding compiled class for the agent is the
- clsref{ASRMAgent}{../ns-2/srm.h}.
- paragraph{Recompute for Each New Loss Object}
- Each time a new request object is created,
- fcnref{SRM/request/Adaptive::set-params}{../ns-2/srm-adaptive.tcl}{%
- SRM/request/Adaptive::set-params}
- invokes code{$agent_ recompute-request-params}.
- The agent method
- fcnref{fcn[]{recompute-request-params}}{../ns-2/srm-adaptive.tcl}{%
- Agent/SRM/Adaptive::recompute-request-params}.
- uses the statistics about duplicates and delay
- to modify c1 and c2 for the current and future requests.
- Similarly,
- fcnref{SRM/request/Adaptive::set-params}{../ns-2/srm-adaptive.tcl}{%
- SRM/request/Adaptive::set-params}
- for a new repair object
- invokes code{$agent_ recompute-repair-params}.
- The agent method
- fcnref{fcn[]{recompute-repair-params}}{../ns-2/srm-adaptive.tcl}{%
- Agent/SRM/Adaptive::recompute-repair-params}.
- uses the statistics objects to modify d1 and d2
- for the current and future repairs.
- paragraph{Sending a Message}
- If a loss object
- fcnref{sends a request}{../ns-2/srm-adaptive.tcl}{%
- SRM/request/Adaptive::send-request}
- in its first code{round_},
- then the agent, in the instance procedure
- fcnref{proc[]{sending-request}}{../ns-2/srm-adaptive.tcl}{%
- Agent/SRM/Adaptive::sending-request},
- will lower c1,
- and set its instance variable code{closest_(requestor)} to 1.
- Similarly,
- a loss object that
- fcnref{sends a repair}{../ns-2/srm-adaptive.tcl}{%
- SRM/repair/Adaptive::send-repair}
- in its first code{round_}
- will invoke the agent's instance procedure,
- fcnref{proc[]{sending-repair}}{../ns-2/srm-adaptive.tcl}{%
- Agent/SRM/Adaptive::sending-repair},
- to lower d1 and set code{closest_(repairor)} to 1.
- paragraph{Advertising the Distance}
- Each agent must add additional information to each request/repair
- that it sends out.
- The base clsref{SRMAgent}{../ns-2/srm.cc}
- invokes the virtual method
- fcnref{fcn[]{addExtendedHeaders}}{../ns-2/srm.h}{%
- SRMAgent::addExtendedHeaders}
- for each SRM packet that it sends out.
- The method is invoked after adding the SRM packet headers, and
- before the packet is transmitted.
- The adaptive SRM agent overloads
- fcnref{fcn[]{addExtendedHeaders}}{../ns-2/srm.h}{%
- ASRMAgent::addExtendedHeaders}
- to specify its distances in the additional headers.
- When sending a request, that agent unequivocally knows the
- identity of the sender.
- As an example, the definition of
- fcn[]{addExtendedHeaders} for the adaptive SRM agent is:
- begin{program}
- void addExtendedHeaders(Packet* p) {
- SRMinfo* sp;
- hdr_srm* sh = (hdr_srm*) p->access(off_srm_);
- hdr_asrm* seh = (hdr_asrm*) p->access(off_asrm_);
- switch (sh->type()) {
- case SRM_RQST:
- sp = get_state(sh->sender());
- seh->distance() = sp->distance_;
- break;
- ldots
- }
- }
- end{program}
- Similarly, the method
- fcnref{fcn[]{parseExtendedHeaders}}{../ns-2/srm.h}{%
- ASRMAgent::parseExtendedHeaders}
- is invoked every time an SRM packet is received.
- It sets the agent member variable code{pdistance_}
- to the distance advertised by the peer that sent the message.
- The member variable is bound to an instance variable of the same name,
- so that the peer distance can be accessed
- by the appropriate instance procedures.
- The corresponding fcn[]{parseExtendedHeaders} method for the
- Adaptive SRM agent is simply:
- begin{program}
- void parseExtendedHeaders(Packet* p) {
- hdr_asrm* seh = (hdr_asrm*) p->access(off_asrm_);
- pdistance_ = seh->distance();
- }
- end{program}
- Finally, the adaptive SRM agent's extended headers are defined as
- structref{hdr_asrm}{../ns-2/srm.h}.
- The header declaration is identical to declaring other packet headers in ns.
- % xref external documentation here.
- Unlike most other packet headers,
- these are not automatically available in the packet.
- The
- fcnref{interpreted constructor}{../ns-2/srm-adaptive.tcl}{%
- Agent/SRM/Adaptive::init}
- for the first adaptive agent
- will add the header to the packet format.
- For example, the start of the constructor for the
- code{Agent/SRM/Adaptive} agent is:
- begin{program}
- Agent/SRM/Adaptive set done_ 0
- Agent/SRM/Adaptive instproc init args {
- if ![$class set done_] {
- set pm [[Simulator instance] set packetManager_]
- TclObject set off_asrm_ [$pm allochdr aSRM]
- $class set done_ 1
- }
- eval $self next $args
- ldots
- }
- end{program}
- section{SRM objects}
- label{srmobjects}
- SRM objects are a subclass of agent objects that implement the SRM
- reliable multicast transport protocol. They inherit all of the generic
- agent functionalities. The methods for this object is described in the
- next section ref{sec:srmcommand}. Configuration parameters for this object
- are:
- begin{description}
- item[packetSize_] The data packet size that will be used for repair
- messages. The default value is 1024.
- item[requestFunction_] The algorithm used to produce a retransmission
- request, e.g., setting request timers. The default value is SRM/request.
- Other possible request functions are SRM/request/Adaptive, used by the
- Adaptive SRM code.
- item[repairFunction_]
- The algorithm used to produce a repair, e.g., compute repair timers. The
- default value is SRM/repair. Other possible request functions are
- SRM/repair/Adaptive, used by the Adaptive SRM code.
- item[sessionFunction_]
- The algorithm used to generate session messages. Default is SRM/session
- item[sessionDelay_]
- The basic interval of session messages. Slight random variation is added
- to this interval to avoid global synchronization of session messages. User
- may want to adjust this variable according to their specific simulation.
- Default value is 1.0.
- item[C1_, C2_]
- The parameters which control the request timer. Refer to [8] for detail.
- The default value is C1_ = C2_ = 2.0.
- item[D1_, D2_]
- The parameters which control the repair timer. Refer to [8] for detail.
- The default value is D1_ = D2_ = 1.0.
- item[requestBackoffLimit_]
- The maximum number of exponential backoffs. Default value is 5.
- end{description}
- State Variables are:
- begin{description}
- item[stats_]
- An array containing multiple statistics needed by adaptive SRM agent.
- Including: duplicate requests and repairs in current request/repair
- period, average number of duplicate requests and repairs, request and
- repair delay in current request/repair period, average request and repair
- delay.
- end{description}
- textsc{SRM/Adaptive Objects}
- SRM/Adaptive objects are a subclass of the SRM objects that implement the
- adaptive SRM reliable multicast transport protocol. They inherit all of
- the SRM object functionalities.
- State Variables are: \
- (Refer to the SRM paper by Sally et al [Fall, K., Floyd, S., and
- Henderson, T., Ns Simulator Tests for Reno FullTCP. URL
- ftp://ftp.ee.lbl.gov/papers/fulltcp.ps. July 1997.] for more detail.)
- begin{description}
- item[pdistance_]
- This variable is used to pass the distance estimate provided by the remote
- agent in a request or repair message.
- item[D1_, D2_]
- The same as that in SRM agents, except that they are initialized to
- log10(group size) when generating the first repair.
- item[MinC1_, MaxC1_, MinC2_, MaxC2_]
- The minimum/maximum values of C1_ and C2_. Default initial values are
- defined in [8]. These values define the dynamic range of C1_ and C2_.
- item[MinD1_, MaxD1_, MinD2_, MaxD2_]
- The minimum/maximum values of D1_ and D2_. Default initial values are
- defined in [8]. These values define the dynamic range of D1_ and D2_.
- item[AveDups]
- Higher bound for average duplicates.
- item[AveDelay]
- Higher bound for average delay.
- item[eps AveDups] -dups determines the lower bound of the number of
- duplicates, when we should adjust parameters to decrease delay.
- end{description}
- section{Commands at a glance}
- label{sec:srmcommand}
- The following is a list of commands to create/manipulate srm agents in
- simulations:
- begin{flushleft}
- code{set srm0 [new Agent/SRM]}\
- This creates an instance of the SRM agent. In addition to the base class,
- two extensions of the srm agent have been implemented. They are
- Agent/SRM/Fixed and Agent/SRM/Adaptive. See section ref{sec:extensions}
- for details about these extensions.
- code{ns_ attach-agent <node> <srm-agent>}\
- This attaches the srm agent instance to the given <node>.
- begin{program}
- set grp [Node allocaddr]
- $srm set dst_ $grp
- end{program}
- This assigns the srm agent to a multicast group represented by the mcast
- address <grp>.
- Configuration parameters for srm agent may be set as follows:\
- begin{program}
- $srm set fid_ <flow-id>
- $srm set tg_ <traffic-generator-instance>
- .. etc
- end{program}
- For all possible parameters and their default values please lookup ns/tcl/mcast/srm.tcl
- and ns/tcl/mcast/srm-adaptive.tcl.
- begin{program}
- set exp [new Application/Traffic/Exponential]
- $exp attach-agent $srm
- end{program}
- This command attaches a traffic generator (an exponential one in this example),
- to the srm agent.
- code{$srm start; $exp start}\
- These commands start the srm agent and traffic generator. Note that the srm
- agent and traffic generator have to be started separately. Alternatively, the
- traffic generator may be started through the agent as follows:\
- code{$srm start-source}.
- See ns/tcl/ex/srm.tcl for a simple example of setting up a SRM agent.
- end{flushleft}
- endinput
- ### Local Variables:
- ### mode: latex
- ### comment-column: 60
- ### backup-by-copying-when-linked: t
- ### file-precious-flag: nil
- ### End: