📄 trace.tex
字号:
if (!show_tcphdr_) { sprintf(wrk_, "%c %g %d %d %s %d %s %d %d.%d %d.%d %d %d", tt, Scheduler::instance().clock(), s, d, name, th->size(), flags, iph->flowid() /* was p->class_ */, iph->src() >> 8, iph->src() & 0xff, // XXX iph->dst() >> 8, iph->dst() & 0xff, // XXX seqno, th->uid() /* was p->uid_ */); } else { sprintf(wrk_, "%c %g %d %d %s %d %s %d %d.%d %d.%d %d %d %d 0x%x %d", tt, Scheduler::instance().clock(), s, d, name, th->size(), flags, iph->flowid() /* was p->class_ */, iph->src() >> 8, iph->src() & 0xff, // XXX iph->dst() >> 8, iph->dst() & 0xff, // XXX seqno, th->uid(), /* was p->uid_ */ tcph->ackno(), tcph->flags(), tcph->hlen()); }\end{verbatim}\end{small}This function is somewhat unelegant, primarily due to the desireto maintain backward compatibility.It formats the source, destination, and type fields defined in thetrace object ({\em not in the packet headers}), the current time,along with various packet header fields including,type of packet (as a name), size, flags (symbolically),flow identifier, source and destination packet header fields,sequence number (if present), and unique identifier.The {\tt show\_tcphdr\_} variable indicates whether the traceoutput should append tcp header information (ack number, flags, header length)at the end of each output line. This is especially useful for simulationsusing FullTCP agents (\ref{fulltcp}).An example of a trace file (without the tcp header fields) mighappear as follows: \begin{small}\begin{verbatim} + 1.45176 2 3 tcp 1000 ---- 1 256 769 27 48 + 1.45276 2 3 tcp 1000 ---- 1 256 769 28 49 - 1.46176 2 3 tcp 1000 ---- 1 256 769 22 43 + 1.46176 2 3 tcp 1000 ---- 1 256 769 29 50 + 1.46276 2 3 tcp 1000 ---- 1 256 769 30 51 d 1.46276 2 3 tcp 1000 ---- 1 256 769 30 51 - 1.47176 2 3 tcp 1000 ---- 1 256 769 23 44 + 1.47176 2 3 tcp 1000 ---- 0 0 768 3 52 + 1.47276 2 3 tcp 1000 ---- 0 0 768 4 53 d 1.47276 2 3 tcp 1000 ---- 0 0 768 4 53\end{verbatim}\end{small}Here we see ten trace entries, 6 enque operations (indicated by ``+''in the first column), 2 deque operations (indicated by ``-''),and 2 packet drops (indicated by ``d'').(this had better be a trace fragment, or 2 packets would have just vanished!).The simulated time (in seconds) at which each event occurred is listedin the second column.The next two fields indicate between which two nodes tracing is happening.The next field is a descriptive name for the the type of packet seen(see \ref{sec:traceptype} below).The next field is the packet's size, as encoded in its IP header.The next four characters represent special flag bits which may beenabled. Presently only one such bit exists (explicit congestionnotification, or {\sf ECN}). In this example, {\sf ECN} is not used.The next field gives the IP {\em flow identifier} field as definedfor IP version 6.\footnote{In ns-1, each packet included a \code{class}field, which was used by CBQ to classify packets.It then found additional use to differentiate between``flows'' at one trace point. In ns-2, the flow ID field is availablefor this purpose, but any additional information (which was commonly overloadedinto the class field in ns-1) should be placed in its own separate field,possibly in some other header}.The subsequent two fields indicate the packet's source and destinationnode addresses, respectively.The following field indicates the sequence number.\footnote{In ns-1,all packets contained a sequence number, whereas in ns-2 only thoseAgents interested in providing sequencing will generate sequence numbers.Thus, this field may not be useful in ns-2 for packets generated byagents that have not filled in a sequence number. It is used hereto remain backward compatible with ns-1.}The last field is a unique packet identifier. Each new packetcreated in the simulation is assigned a new, unique identifier.\subsection{\shdr{packet types}{trace.h}{sec:traceptype}}Each packet contains a packet type field used by \code{Trace::format}to print out the type of packet encountered.The type field is defined in the \code{TraceHeader} class, and is consideredto be part of the trace support; it is not interpretedelsewhere in the simulator.Initialization of the type field in packets is performed by the\code{Agent::allocpkt()} function.The type field is set to integer values associated with thedefinition passed to the \code{Agent} constructor.See Section~\ref{sec:agentmethodsotcl} for more details.The currently-supported definitions, their values, and theirassociated symblic names are as follows(defined in \code{packet.h}):\begin{small}\begin{verbatim} #define PT_TCP 0 #define PT_TELNET 1 #define PT_CBR 2 #define PT_AUDIO 3 #define PT_VIDEO 4 #define PT_ACK 5 #define PT_START 6 #define PT_STOP 7 #define PT_PRUNE 8 #define PT_GRAFT 9 #define PT_MESSAGE 10 #define PT_RTCP 11 #define PT_RTP 12 #define PT_RTPROTO_DV 13 #define PT_CtrMcast_Encap 14 #define PT_CtrMcast_Decap 15 #define PT_SRM 16 #define PT_NTYPE 17 #define PT_NAMES "tcp", "telnet", "cbr", "audio", "video", "ack", \ "start", "stop", "prune", "graft", "message", "rtcp", "rtp", \ "rtProtoDV", "CtrMcast_Encap", "CtrMcast_Decap", "SRM"\end{verbatim}\end{small}The definition of \code{PT_NAMES} is used to initialize the\code{pt_names} array as indicated above;\code{PT_NTYPE} is not presently used.\subsection{\shdr{Queue Monitoring}{queue-monitor.cc}{sec:qmonitor}}Queue monitoring refers to the capability of tracking thedynamics of packets at a queue (or other object).A queue monitor tracks packet arrival/departure/drop statistics,and may optionally compute averages of these values.Monitoring may be applied all packets (aggregate statistics), orper-flow statistics (using a Flow Monitor).Several classes are used in supporting queue monitoring.When a packet arrives at a link where queue monitoring is enabled,it generally passes through a \code{SnoopQueue} object when itarrives and leaves (or is dropped).These objects contain a reference to a \code{QueueMonitor} object.A \code{QueueMonitor} is defined as follows (\code{queue-monitor.cc}):\begin{small}\begin{verbatim} class QueueMonitor : public TclObject { public: QueueMonitor() : bytesInt_(NULL), pktsInt_(NULL), delaySamp_(NULL), size_(0), pkts_(0), parrivals_(0), barrivals_(0), pdepartures_(0), bdepartures_(0), pdrops_(0), bdrops_(0), srcId_(0), dstId_(0), channel_(0) { bind("size_", &size_); bind("pkts_", &pkts_); bind("parrivals_", &parrivals_); bind("barrivals_", &barrivals_); bind("pdepartures_", &pdepartures_); bind("bdepartures_", &bdepartures_); bind("pdrops_", &pdrops_); bind("bdrops_", &bdrops_); bind("off_cmn_", &off_cmn_); }; int size() const { return (size_); } int pkts() const { return (pkts_); } int parrivals() const { return (parrivals_); } int barrivals() const { return (barrivals_); } int pdepartures() const { return (pdepartures_); } int bdepartures() const { return (bdepartures_); } int pdrops() const { return (pdrops_); } int bdrops() const { return (bdrops_); } void printStats(); virtual void in(Packet*); virtual void out(Packet*); virtual void drop(Packet*); virtual void edrop(Packet*) { abort(); }; // not here virtual int command(int argc, const char*const* argv); ..... // packet arrival to a queue void QueueMonitor::in(Packet* p) { hdr_cmn* hdr = (hdr_cmn*)p->access(off_cmn_); double now = Scheduler::instance().clock(); int pktsz = hdr->size(); barrivals_ += pktsz; parrivals_++; size_ += pktsz; pkts_++; if (bytesInt_) bytesInt_->newPoint(now, double(size_)); if (pktsInt_) pktsInt_->newPoint(now, double(pkts_)); if (delaySamp_) hdr->timestamp() = now; if (channel_) printStats(); } ... in(), out(), drop() are all defined similarly ...\end{verbatim}\end{small}It addition to the packet and byte counters, a queue monitormay optionally refer to objects that keep an integralof the queue size over time using\code{Integrator} objects, which are defined in Section\ref{sec:mathinteg}.The \code{Integrator} class provides a simple implementation ofintegral approximation by discrete sums.All bound variables beginning with {\bf p} refer to packet counts, andall variables beginning with {\bf b} refer to byte counts.The variable {\tt size\_} records the instantaneous queue size in bytes,and the variable {\tt pkts\_} records the same value in packets.When a \code{QueueMonitor} is configured to include the integralfunctions (on bytes or packets or both), itcomputes the approximate integral of thequeue size (in bytes)with respect to time over the interval $[t_0, now]$, where$t_0$ is either the start of the simulation or the last time the\code{sum\_} field of the underlying \code{Integrator} class was reset.The \code{QueueMonitor} class is not derived from \code{Connector}, andis not linked directly into the network topology.Rather, objects of the \code{SnoopQueue} class (or its derived classes)are inserted into the network topology, and these objects contain referencesto an associated queue monitor.Ordinarily, multiple \code{SnoopQueue} objects will refer to the samequeue monitor.Objects constructed out of these classes are linked in the simulationtopology as described above and call \code{QueueMonitor}\code{out}, \code{in}, or \code{drop} procedures,depending on the particular type of snoopy queue.\subsection{\shdr{Per-Flow Monitoring}{flowmon.cc}{sec:flowmon}}A collection of specialized classes are used to to implementper-flow statistics gathering.These classes include: \code{QueueMonitor/ED/Flowmon},\code{QueueMonitor/ED/Flow}, and \code{Classifier/Hash}.Typically, an arriving packet is inspected to determineto which flow it belongs.This inspection and flow mapping is performed by a {\em classifier}object (described in section \ref{sec:hashclass}).Once the correct flow is determined, the packet is passed toa {\em flow monitor}, which is responsible for collecting per-flowstate.Per-flow state is contained in {\em flow} objects in a one-to-onerelationship to the flows known by the flow monitor.Typically, a flow monitor will create flow objects on-demand whenpackets arrive that cannot be mapped to an already-known flow.\subsubsection{\shdr{the flow monitor}{flowmon.cc}{sec:flowclass}}The \code{QueueMonitor/ED/Flowmon} class is responsible for managingthe creation of new flow objects when packets arrive on previouslyunknown flows and for updating existing flow objects.Because it is a subclass of \code{QueueMonitor}, each flow monitorcontains an aggregate count of packet and byte arrivals, departures, anddrops.Thus, it is not necessary to create a separate queue monitor to recordaggregate statistics.It provides the following OTcl interface:\begin{quote}\begin{itemize} \item[classifier] - get(set) classifier to map packets to flows \item[attach] - attach a Tcl I/O channel to this monitor \item[dump] - dump contents of flow monitor to Tcl channel \item[flows] - return string of flow object names known to this monitor\end{itemize}\end{quote}The {\tt classifier} function sets or gets the name of the previously-allocatedobject which will perform packet-to-flow mapping for the flow monitor.Typically, the type of classifier used will have to do with the notion of``flow'' held by the user.One of the hash based classifiers that inspect various IP-level headerfields is typically used here (e.g. fid, src/dst, src/dst/fid).Note that while classifiers usually receive packets and forward themon to downstream objects, the flow monitor uses the classifier only forits packet mapping capability, so the flow monitor acts as a passivemonitor only and does not actively forward packets.The {\tt attach} and {\tt dump} functions are used toassociate a Tcl I/O stream with theflow monitor, and dump its contents on-demand.The file format used by the {\tt dump} command is described below.The {\tt flows} function returns a list of the names of flows knownby the flow monitor in a way understandable to Tcl.This allows tcl code to interrogate a flow monitor in orderto obtain handles to the individual flows it maintains.\subsubsection{\shdr{flow monitor trace format}{flowmon.cc}{sec:flowmonclass}}The flow monitor defines a trace format which may be used by post-processingscripts to determine various counts on a per-flow basis.The format is defined by the folling code in \code{flowmon.cc}:\begin{small}\begin{verbatim}voidFlowMon::fformat(Flow* f){ double now = Scheduler::instance().clock(); sprintf(wrk_, "%8.3f %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d", now, f->flowid(), // flowid 0, // category f->ptype(), // type (from common header) f->flowid(), // flowid (formerly class) f->src(), f->dst(), f->parrivals(), // arrivals this flow (pkts) f->barrivals(), // arrivals this flow (bytes) f->epdrops(), // early drops this flow (pkts) f->ebdrops(), // early drops this flow (bytes) parrivals(), // all arrivals (pkts) barrivals(), // all arrivals (bytes) epdrops(), // total early drops (pkts) ebdrops(), // total early drops (bytes) pdrops(), // total drops (pkts) bdrops(), // total drops (bytes) f->pdrops(), // drops this flow (pkts) [includes edrops] f->bdrops() // drops this flow (bytes) [includes edrops] );}; \end{verbatim}\end{small}Most of the fields are explained in the code comments.The ``category'' is historical, but is used to maintain loose backward-compatibility with the flow manager format in ns version 1.\subsubsection{\shdr{the flow class}{flowmon.cc}{sec:flowclass}}The class \code{QueueMonitor/ED/Flow} is used by the flow monitorfor containing per-flow counters.As a subclass of \code{QueueMonitor}, it inherits the standardcounters for arrivals, departures, and drops, both in packets andbytes.In addition, because each flow is typically identified bysome combination of the packet source, destination, and flowidentifier fields, these objects contain such fields.It's OTcl interface contains only bound variables:\begin{quote}\begin{itemize} \item[src\_] - source address on packets for this flow \item[dst\_] - desination address on packets for this flow \item[flowid\_] - flow id on packets for this flow\end{itemize}\end{quote}Note that packets may be mapped to flows (by classifiers) usingcriteria other than a src/dst/flowid triple.In such circumstances, only those fields actually used bythe classifier in performing the packet-flow mapping should beconsidered reliable.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -