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

通讯编程

开发平台:

Visual C++

  1. %
  2. % personal commentary:
  3. %        DRAFT DRAFT DRAFT
  4. %        - KFALL
  5. %
  6. section{shdr{Trace and Monitoring Support}{trace.h}{sec:trace}}
  7. There are a number of ways of collecting output or
  8. trace data on a simulation.
  9. Generally, trace data is either displayed directly during execution
  10. of the simulation, or (more commonly) stored in a file to be
  11. post-processed and analyzed.
  12. There are two primary but distinct types of monitoring capabilities
  13. currently supported by the simulator.
  14. The first, called {em traces}, record each individual packet
  15. as it arrives, departs, or is dropped at a link or queue.
  16. Trace objects are configured into a simulation as nodes in the
  17. network topology, usually with a Tcl ``Channel'' object
  18. hooked to them, representing the destination of collected data
  19. (typically a trace file in the current directory).
  20. The other types of objects, called {em monitors}, record counts
  21. of various interesting quantities such as packet and byte arrivals,
  22. departures, etc.
  23. Monitors can monitor counts associated with all packets,
  24. or on a per-flow basis using a {em flow monitor}
  25. (see section ref{flowmon} below).
  26. To support traces, there is a special {em common} header
  27. included in each packet (this format is defined in code{packet.h}
  28. as {tt hdr_cmn}).
  29. It presently includes a unique identifier on each packet, a
  30. packet type field (set by agents when they generate packets),
  31. a packet size field (in bytes, used to determine the transmission
  32. time for packets), and an interface label (used for computing
  33. multicast distribution trees).
  34. Monitors are supported by a separate
  35. set of objects that are created and inserted into the network topology
  36. around queues.
  37. They provide a place where
  38. arrival statistics and times are gathered and make
  39. use of the code{Integrator} class (see ref{sec:integclass}) to
  40. compute statistics over time intervals.
  41. subsection{shdr{Trace Support}{ns-lib.tcl}{sec:otcltrace}}
  42. The trace support in OTcl consists of a number of specialized
  43. classes visible in OTcl but implemented in C++, combined
  44. with a set of Tcl helper procedures and classes defined in the ns library.
  45. All following OTcl classes are supported by underlying C++
  46. classes defined in code{trace.cc}.
  47. Objects of the following types are inserted directly in-line in the
  48. network topology:
  49. begin{quote}
  50. begin{itemize}
  51. item [Trace/Hop] - trace a ``hop'' (XXX what does this mean exactly; it is not really used XXX)
  52. item [Trace/Enque] - a packet arrival (usually at a queue)
  53. item [Trace/Deque] - a packet departure (usually at a queue)
  54. item [Trace/Drop] - packet drop (packet delivered to drop-target)
  55. item [SnoopQueue/In] - on input, collect a time/size sample (pass packet on)
  56. item [SnoopQueue/Out] - on output, collect a time/size sample (pass packet on)
  57. item [SnoopQueue/Drop] - on drop, collect a time/size sample (pass packet on)
  58. item [SnoopQueue/EDrop] - on an "early" drop, collect a time/size sample (pass packet on)
  59. end{itemize}
  60. end{quote}
  61. Objects of the following types are added in the simulation and a referenced
  62. by the objects listed above.  They are used to aggregate statistics collected
  63. by the SnoopQueue objects:
  64. begin{quote}
  65. begin{itemize}
  66. item [QueueMonitor] - receive and aggregate collected samples from snoopers
  67. item [QueueMonitor/ED] - queue-monitor capable of distinguishing between ``early'' and standard packet drops
  68. item [QueueMonitor/ED/Flowmon] - per-flow statistics monitor (manager)
  69. item [QueueMonitor/ED/Flow] - per-flow statistics container
  70. item [QueueMonitor/Compat] - a replacement for a standard QueueMonitor when ns-1 compatibility is in use
  71. end{itemize}
  72. end{quote}
  73. subsubsection{shdr{otcl helper functions}{ns-lib.tcl}{sec:helptrace}}
  74. The following helper functions may be used within simulation
  75. scripts to help in attaching trace elements (see code{ns-lib.tcl}):
  76. begin{small}
  77. begin{itemize}
  78. item[Simulator instproc flush-trace {}] - flush buffers for all
  79. trace objects in simulation
  80. item[Simulator instproc create-trace { type file src dst }] - create a
  81. trace object of type {em type} betweek the given src and dest nodes.
  82. If {em file} is non-null, it is interpreted as a Tcl channel and is
  83. attached to the newly-created trace object.
  84. item[Simulator instproc trace-queue { n1 n2 file }] - arrange for
  85. tracing on the link between nodes {em n1} and {em n2}.  This function
  86. calls create-trace, so the same rules apply with respect to the {em file}
  87. argument.
  88. item[DOES TRACE-ALL REALLY BELONG HERE] - XXXX
  89. item[Simulator instproc monitor-queue { n1 n2 }] - this function
  90. calls the {tt init-monitor} function on the link between nodes {em n1}
  91. and {em n2}.
  92. item[Simulator instproc drop-trace { n1 n2 trace }] - the given {em trace}
  93. object is made the drop-target of the queue associated with the link
  94. between nodes {em n1} and {em n2}.
  95. end{itemize}
  96. end{small}
  97. The code{create-trace} procedure is used to create a new code{Trace}
  98. object of the appropriate kind and attach an Tcl I/O channel to it
  99. (typically a file handle).
  100. The code{src_} and code{dst_} fields are are used by the underlying C++
  101. object for producing the trace output file so that trace output
  102. can include the node addresses defining the endpoints of the link which
  103. is being traced.
  104. Note that they are not used for {em matching}.  Specifically, these
  105. values in no way relate to the packet header code{src} and code{dst}
  106. fields, which are also displayed when tracing.
  107. See the description of the code{Trace}
  108. class below (ref{sec:traceclass}).
  109. The code{trace-queue} function enables
  110. code{Enque}, code{Deque}, and code{Drop} tracing on the link
  111. between nodes code{n1} and code{n2}.
  112. The Link code{trace} procedure is described below (ref{sec:libexam}).
  113. The code{monitor-queue} function is constructed similarly to
  114. code{trace-queue}.
  115. By calling the link's code{init-monitor} procedure, it arranges
  116. for the creation of objects (code{SnoopQueue} and code{QueueMonitor}
  117. objects) which can, in turn, be used to ascertain time-aggregated
  118. queue statistics.
  119. The code{drop-trace} function provides a way to specify a
  120. code{Queue}'s drop target without having a direct handle of
  121. the queue.
  122. subsection{shdr{Library support and examples}{ns-lib.tcl}{sec:libexam}}
  123. The code{Simulator} procedures described above require the code{trace}
  124. and code{init-monitor} methods associated with the OTcl code{Link} class.
  125. Several subclasses of link are defined, the most common of which
  126. is called code{SimpleLink}.  Thus, the code{trace} and code{init-monitor}
  127. methods are actually part of the code{SimpleLink} class rather than
  128. the code{Link} base class.
  129. The code{trace} function is defined as follows (in code{ns-link.tcl}):
  130. begin{small}
  131. begin{verbatim}
  132. #
  133. # Build trace objects for this link and
  134. # update the object linkage
  135. #
  136. SimpleLink instproc trace { ns f } {
  137.         $self instvar enqT_ deqT_ drpT_ queue_ link_ head_ fromNode_ toNode_
  138.         set enqT_ [$ns create-trace Enque $f $fromNode_ $toNode_]
  139.         set deqT_ [$ns create-trace Deque $f $fromNode_ $toNode_]
  140.         set drpT_ [$ns create-trace Drop $f $fromNode_ $toNode_]
  141.         $drpT_ target [$queue_ drop-target]
  142.         $queue_ drop-target $drpT_
  143.         $deqT_ target [$queue_ target]
  144.         $queue_ target $deqT_
  145.         if { [$head_ info class] == "networkinterface" } {
  146.             $enqT_ target [$head_ target]
  147.             $head_ target $enqT_
  148.             # puts "head is i/f"
  149.         } else {
  150.             $enqT_ target $head_
  151.             set head_ $enqT_
  152.             # puts "head is not i/f"
  153.         }
  154.         $self instvar dynamics_
  155.         if [info exists dynamics_] {
  156.                 $self trace-dynamics $ns $f
  157.         }
  158. }
  159. end{verbatim}
  160. end{small}
  161. This function establishes code{Enque}, code{Deque}, and code{Drop}
  162. traces in the simulator code{$ns} and directs their
  163. output to I/O handle code{$f}.
  164. The function assumes a queue has been associated with the link.
  165. It operates by first creating three new trace objects
  166. and inserting the code{Enque} object before the queue, the
  167. code{Deque} object after the queue, and the code{Drop} object
  168. between the queue and its previous drop target.
  169. Note that all trace output is directed to the same I/O handle.
  170. This function also performs two additional tasks.
  171. It checks to see if a link contains a network interface,
  172. and if so, leaves it as the first object in the chain of objects
  173. in the link, but otherwise inserts the code{Enque} object as
  174. the first one.
  175. The second additional task check to see if link dynamics
  176. (see ref{linkdynamics}) are enabled for links in the simulation
  177. and if so, enables tracing of the link's up/down status.
  178. The following functions, code{init-monitor} and
  179. code{attach-monitor}, are used to create a set of
  180. objects used to monitor queue sizes of a queue associated
  181. with a link.
  182. They are defined as follows:
  183. begin{small}
  184. begin{verbatim}
  185. #
  186. # like init-monitor, but allows for specification of more of the items
  187. # attach-monitors $insnoop $inqm $outsnoop $outqm $dropsnoop $dropqm
  188. #
  189. SimpleLink instproc attach-monitors { insnoop outsnoop dropsnoop qmon } {
  190. $self instvar drpT_ queue_ head_ snoopIn_ snoopOut_ snoopDrop_
  191. $self instvar qMonitor_
  192. set snoopIn_ $insnoop
  193. set snoopOut_ $outsnoop
  194. set snoopDrop_ $dropsnoop
  195. $snoopIn_ target $head_
  196. set head_ $snoopIn_
  197. $snoopOut_ target [$queue_ target]
  198. $queue_ target $snoopOut_
  199. if [info exists drpT_] {
  200. $snoopDrop_ target [$drpT_ target]
  201. $drpT_ target $snoopDrop_
  202. $queue_ drop-target $drpT_
  203. } else {
  204. $snoopDrop_ target [[Simulator instance] set nullAgent_]
  205. $queue_ drop-target $snoopDrop_
  206. }
  207. $snoopIn_ set-monitor $qmon
  208. $snoopOut_ set-monitor $qmon
  209. $snoopDrop_ set-monitor $qmon
  210. set qMonitor_ $qmon
  211. }
  212. # Insert objects that allow us to monitor the queue size
  213. # of this link.  Return the name of the object that
  214. # can be queried to determine the average queue size.
  215. #
  216. SimpleLink instproc init-monitor { ns qtrace sampleInterval} {
  217. $self instvar qMonitor_ ns_ qtrace_ sampleInterval_
  218. set ns_ $ns
  219. set qtrace_ $qtrace
  220. set sampleInterval_ $sampleInterval
  221. set qMonitor_ [new QueueMonitor]
  222. $self attach-monitors [new SnoopQueue/In] 
  223. [new SnoopQueue/Out] [new SnoopQueue/Drop] $qMonitor_
  224. set bytesInt_ [new Integrator]
  225. $qMonitor_ set-bytes-integrator $bytesInt_
  226. set pktsInt_ [new Integrator]
  227. $qMonitor_ set-pkts-integrator $pktsInt_
  228. return $qMonitor_
  229. }
  230. end{verbatim}
  231. end{small}
  232. These functions establish queue monitoring on the code{SimpleLink} object
  233. in the simulator code{ns}.
  234. Queue monitoring is implemented by constructing three code{SnoopQueue}
  235. objects and one code{QueueMonitor} object.
  236. The code{SnoopQueue} objects are linked in around a code{Queue} in a way
  237. similar to code{Trace} objects.
  238. The code{SnoopQueue/In(Out)} object monitors packet arrivals(departures)
  239. and reports them to an associated code{QueueMonitor} agent.
  240. In addition, a code{SnoopQueue/Out} object is also used to accumulate
  241. packet drop statistics to an associated code{QueueMonitor} object.
  242. For code{init-monitor} the same code{QueueMonitor} object is used
  243. in all cases.
  244. The C++ definitions of the code{SnoopQueue} and code{QueueMonitor}
  245. classes are described below.
  246. subsection{shdr{The C++ Trace Class}{trace.cc}{sec:tracemoncplus}}
  247. Underlying C++ objects are created in support of the interface specified
  248. in Sectionref{sec:traceclass} and are linked into the network topology
  249. as network elements.
  250. The single C++ code{Trace} class is used to implement the OTcl
  251. classes code{Trace/Hop}, code{Trace/Enque}, code{Trace/Deque},
  252. and code{Trace/Drop}.
  253. The code{type_} field is used to differentiate among the
  254. various types of
  255. traces any particular code{Trace} object might implement.
  256. Currently, this field may contain one of the following symbolic characters:
  257. {bf +} for enque, {bf -} for deque, {bf h} for hop, and
  258. {bf d} for drop.
  259. The overall class is defined as follows in code{trace.cc}:
  260. begin{small}
  261. begin{verbatim}
  262.         class Trace : public Connector {
  263.          protected:
  264.                 int type_;
  265.                 nsaddr_t src_;
  266.                 nsaddr_t dst_;
  267.                 Tcl_Channel channel_;
  268.                 int callback_;
  269.                 char wrk_[256];
  270.                 void format(int tt, int s, int d, Packet* p);
  271.                 void annotate(const char* s);
  272.                 int show_tcphdr_;  // bool flags; backward compat
  273.          public:
  274.                 Trace(int type);
  275.                 ~Trace();
  276.                 int command(int argc, const char*const* argv);
  277.                 void recv(Packet* p, Handler*);
  278.                 void dump();
  279.                 inline char* buffer() { return (wrk_); }
  280.         };
  281. end{verbatim}
  282. end{small}
  283. The code{src_}, and code{dst_} internal state is used
  284. to label trace output and is independent of the corresponding field
  285. names in packet headers.
  286. The main code{recv} method is defined as follows:
  287. begin{small}
  288. begin{verbatim}
  289.         void Trace::recv(Packet* p, Handler* h)
  290.         {
  291.                 format(type_, src_, dst_, p);
  292.                 dump();
  293.                 /* hack: if trace object not attached to anything free packet */
  294.                 if (target_ == 0)
  295.                         Packet::free(p);
  296.                 else
  297.                         send(p, h); /* Connector::send() */
  298.         }
  299. end{verbatim}
  300. end{small}
  301. The function merely formats a trace entry using the source, destination,
  302. and particular trace type character.
  303. The code{dump} function writes the formatted entry out to the
  304. I/O handle associated with code{channel_}.
  305. The code{format} function, in effect, dictates the trace file format.
  306. subsection{shdr{trace file format}{trace.cc}{sec:traceformat}}
  307. The code{Trace::format} function defines the trace file format used
  308. in trace files produced by the code{Trace} class.
  309. It is constructed to maintain backward compatibility with output files
  310. in earlier versions of the simulator (i.e. {em ns-1}) so that ns-1
  311. post-processing scripts continue to operate.
  312. The important pieces of its implementation are as follows:
  313. begin{small}
  314. begin{verbatim}
  315. // this function should retain some backward-compatibility, so that
  316. // scripts don't break.
  317. void Trace::format(int tt, int s, int d, Packet* p)
  318. {
  319. hdr_cmn *th = (hdr_cmn*)p->access(off_cmn_);
  320. hdr_ip *iph = (hdr_ip*)p->access(off_ip_);
  321. hdr_tcp *tcph = (hdr_tcp*)p->access(off_tcp_);
  322. hdr_rtp *rh = (hdr_rtp*)p->access(off_rtp_);
  323. int t = th->ptype();
  324. const char* name = pt_names[t];
  325. if (name == 0)
  326. abort();
  327. int seqno;
  328. /* XXX */
  329. /* CBR's now have seqno's too */
  330. if (t == PT_RTP || t == PT_CBR)
  331. seqno = rh->seqno();
  332. else if (t == PT_TCP || t == PT_ACK)
  333. seqno = tcph->seqno();
  334. else
  335. seqno = -1;
  336.                 ....
  337. if (!show_tcphdr_) {
  338. sprintf(wrk_, "%c %g %d %d %s %d %s %d %d.%d %d.%d %d %d",
  339. tt,
  340. Scheduler::instance().clock(),
  341. s,
  342. d,
  343. name,
  344. th->size(),
  345. flags,
  346. iph->flowid() /* was p->class_ */,
  347. iph->src() >> 8, iph->src() & 0xff,     // XXX
  348. iph->dst() >> 8, iph->dst() & 0xff,     // XXX
  349. seqno,
  350. th->uid() /* was p->uid_ */);
  351. } else {
  352. sprintf(wrk_, "%c %g %d %d %s %d %s %d %d.%d %d.%d %d %d %d 0x%x
  353.  %d",
  354. tt,
  355. Scheduler::instance().clock(),
  356. s,
  357. d,
  358. name,
  359. th->size(),
  360. flags,
  361. iph->flowid() /* was p->class_ */,
  362. iph->src() >> 8, iph->src() & 0xff,     // XXX
  363. iph->dst() >> 8, iph->dst() & 0xff,     // XXX
  364. seqno,
  365. th->uid(), /* was p->uid_ */
  366. tcph->ackno(),
  367. tcph->flags(),
  368. tcph->hlen());
  369. }
  370. end{verbatim}
  371. end{small}
  372. This function is somewhat unelegant, primarily due to the desire
  373. to maintain backward compatibility.
  374. It formats the source, destination, and type fields defined in the
  375. trace object ({em not in the packet headers}), the current time,
  376. along with various packet header fields including,
  377. type of packet (as a name), size, flags (symbolically),
  378. flow identifier, source and destination packet header fields,
  379. sequence number (if present), and unique identifier.
  380. The {tt show_tcphdr_} variable indicates whether the trace
  381. output should append tcp header information (ack number, flags, header length)
  382. at the end of each output line.  This is especially useful for simulations
  383. using FullTCP agents (ref{fulltcp}).
  384. An example of a trace file (without the tcp header fields) migh
  385. appear as follows: 
  386. begin{small}
  387. begin{verbatim}
  388.         + 1.45176 2 3 tcp 1000 ---- 1 256 769 27 48
  389.         + 1.45276 2 3 tcp 1000 ---- 1 256 769 28 49
  390.         - 1.46176 2 3 tcp 1000 ---- 1 256 769 22 43
  391.         + 1.46176 2 3 tcp 1000 ---- 1 256 769 29 50
  392.         + 1.46276 2 3 tcp 1000 ---- 1 256 769 30 51
  393.         d 1.46276 2 3 tcp 1000 ---- 1 256 769 30 51
  394.         - 1.47176 2 3 tcp 1000 ---- 1 256 769 23 44
  395.         + 1.47176 2 3 tcp 1000 ---- 0 0 768 3 52
  396.         + 1.47276 2 3 tcp 1000 ---- 0 0 768 4 53
  397.         d 1.47276 2 3 tcp 1000 ---- 0 0 768 4 53
  398. end{verbatim}
  399. end{small}
  400. Here we see ten trace entries, 6 enque operations (indicated by ``+''
  401. in the first column), 2 deque operations (indicated by ``-''),
  402. and 2 packet drops (indicated by ``d'').
  403. (this had better be a trace fragment, or 2 packets would have just vanished!).
  404. The simulated time (in seconds) at which each event occurred is listed
  405. in the second column.
  406. The next two fields indicate between which two nodes tracing is happening.
  407. The next field is a descriptive name for the the type of packet seen
  408. (see ref{sec:traceptype} below).
  409. The next field is the packet's size, as encoded in its IP header.
  410. The next four characters represent special flag bits which may be
  411. enabled.  Presently only one such bit exists (explicit congestion
  412. notification, or {sf ECN}).  In this example, {sf ECN} is not used.
  413. The next field gives the IP {em flow identifier} field as defined
  414. for IP version 6.footnote{In ns-1, each packet included a code{class}
  415. field, which was used by CBQ to classify packets.
  416. It then found additional use to differentiate between
  417. ``flows'' at one trace point.  In ns-2, the flow ID field is available
  418. for this purpose, but any additional information (which was commonly overloaded
  419. into the class field in ns-1) should be placed in its own separate field,
  420. possibly in some other header}.
  421. The subsequent two fields indicate the packet's source and destination
  422. node addresses, respectively.
  423. The following field indicates the sequence number.footnote{In ns-1,
  424. all packets contained a sequence number, whereas in ns-2 only those
  425. Agents interested in providing sequencing will generate sequence numbers.
  426. Thus, this field may not be useful in ns-2 for packets generated by
  427. agents that have not filled in a sequence number.  It is used here
  428. to remain backward compatible with ns-1.}
  429. The last field is a unique packet identifier.  Each new packet
  430. created in the simulation is assigned a new, unique identifier.
  431. subsection{shdr{packet types}{trace.h}{sec:traceptype}}
  432. Each packet contains a packet type field used by code{Trace::format}
  433. to print out the type of packet encountered.
  434. The type field is defined in the code{TraceHeader} class, and is considered
  435. to be part of the trace support; it is not interpreted
  436. elsewhere in the simulator.
  437. Initialization of the type field in packets is performed by the
  438. code{Agent::allocpkt()} function.
  439. The type field is set to integer values associated with the
  440. definition passed to the code{Agent} constructor.
  441. See Section~ref{sec:agentmethodsotcl} for more details.
  442. The currently-supported definitions, their values, and their
  443. associated symblic names are as follows
  444. (defined in code{packet.h}):
  445. begin{small}
  446. begin{verbatim}
  447. #define PT_TCP          0
  448. #define PT_TELNET       1
  449. #define PT_CBR          2
  450. #define PT_AUDIO        3
  451. #define PT_VIDEO        4
  452. #define PT_ACK          5
  453. #define PT_START        6
  454. #define PT_STOP         7
  455. #define PT_PRUNE        8
  456. #define PT_GRAFT        9
  457. #define PT_MESSAGE      10
  458. #define PT_RTCP         11
  459. #define PT_RTP          12
  460. #define PT_RTPROTO_DV   13
  461. #define PT_CtrMcast_Encap 14
  462. #define PT_CtrMcast_Decap 15
  463. #define PT_SRM          16
  464. #define PT_NTYPE        17
  465. #define PT_NAMES "tcp", "telnet", "cbr", "audio", "video", "ack", 
  466. "start", "stop", "prune", "graft", "message", "rtcp", "rtp", 
  467. "rtProtoDV", "CtrMcast_Encap", "CtrMcast_Decap", "SRM"
  468. end{verbatim}
  469. end{small}
  470. The definition of code{PT_NAMES} is used to initialize the
  471. code{pt_names} array as indicated above;
  472. code{PT_NTYPE} is not presently used.
  473. subsection{shdr{Queue Monitoring}{queue-monitor.cc}{sec:qmonitor}}
  474. Queue monitoring refers to the capability of tracking the
  475. dynamics of packets at a queue (or other object).
  476. A queue monitor tracks packet arrival/departure/drop statistics,
  477. and may optionally compute averages of these values.
  478. Monitoring may be applied all packets (aggregate statistics), or
  479. per-flow statistics (using a Flow Monitor).
  480. Several classes are used in supporting queue monitoring.
  481. When a packet arrives at a link where queue monitoring is enabled,
  482. it generally passes through a code{SnoopQueue} object when it
  483. arrives and leaves (or is dropped).
  484. These objects contain a reference to a code{QueueMonitor} object.
  485. A code{QueueMonitor} is defined as follows (code{queue-monitor.cc}):
  486. begin{small}
  487. begin{verbatim}
  488. class QueueMonitor : public TclObject {
  489.  public: 
  490. QueueMonitor() : bytesInt_(NULL), pktsInt_(NULL), delaySamp_(NULL),
  491.   size_(0), pkts_(0),
  492.   parrivals_(0), barrivals_(0),
  493.   pdepartures_(0), bdepartures_(0),
  494.   pdrops_(0), bdrops_(0),
  495.   srcId_(0), dstId_(0), channel_(0) {
  496. bind("size_", &size_);
  497. bind("pkts_", &pkts_);
  498. bind("parrivals_", &parrivals_);
  499. bind("barrivals_", &barrivals_);
  500. bind("pdepartures_", &pdepartures_);
  501. bind("bdepartures_", &bdepartures_);
  502. bind("pdrops_", &pdrops_);
  503. bind("bdrops_", &bdrops_);
  504. bind("off_cmn_", &off_cmn_);
  505. };
  506. int size() const { return (size_); }
  507. int pkts() const { return (pkts_); }
  508. int parrivals() const { return (parrivals_); }
  509. int barrivals() const { return (barrivals_); }
  510. int pdepartures() const { return (pdepartures_); }
  511. int bdepartures() const { return (bdepartures_); }
  512. int pdrops() const { return (pdrops_); }
  513. int bdrops() const { return (bdrops_); }
  514. void printStats();
  515. virtual void in(Packet*);
  516. virtual void out(Packet*);
  517. virtual void drop(Packet*);
  518. virtual void edrop(Packet*) { abort(); }; // not here
  519. virtual int command(int argc, const char*const* argv);
  520.                 .....
  521. // packet arrival to a queue
  522. void QueueMonitor::in(Packet* p)
  523. {
  524. hdr_cmn* hdr = (hdr_cmn*)p->access(off_cmn_);
  525. double now = Scheduler::instance().clock();
  526. int pktsz = hdr->size();
  527. barrivals_ += pktsz;
  528. parrivals_++;
  529. size_ += pktsz;
  530. pkts_++;
  531. if (bytesInt_)
  532. bytesInt_->newPoint(now, double(size_));
  533. if (pktsInt_)
  534. pktsInt_->newPoint(now, double(pkts_));
  535. if (delaySamp_)
  536. hdr->timestamp() = now;
  537. if (channel_)
  538. printStats();
  539. }
  540.         ... in(), out(), drop() are all defined similarly ...
  541. end{verbatim}
  542. end{small}
  543. It addition to the packet and byte counters, a queue monitor
  544. may optionally refer to objects that keep an integral
  545. of the queue size over time using
  546. code{Integrator} objects, which are defined in Sectionref{sec:mathinteg}.
  547. The code{Integrator} class provides a simple implementation of
  548. integral approximation by discrete sums.
  549. All bound variables beginning with {bf p} refer to packet counts, and
  550. all variables beginning with {bf b} refer to byte counts.
  551. The variable {tt size_} records the instantaneous queue size in bytes,
  552. and the variable {tt pkts_} records the same value in packets.
  553. When a code{QueueMonitor} is configured to include the integral
  554. functions (on bytes or packets or both), it
  555. computes the approximate integral of the
  556. queue size (in bytes)
  557. with respect to time over the interval $[t_0, now]$, where
  558. $t_0$ is either the start of the simulation or the last time the
  559. code{sum_} field of the underlying code{Integrator} class was reset.
  560. The code{QueueMonitor} class is not derived from code{Connector}, and
  561. is not linked directly into the network topology.
  562. Rather, objects of the code{SnoopQueue} class (or its derived classes)
  563. are inserted into the network topology, and these objects contain references
  564. to an associated queue monitor.
  565. Ordinarily, multiple code{SnoopQueue} objects will refer to the same
  566. queue monitor.
  567. Objects constructed out of these classes are linked in the simulation
  568. topology as described above and call code{QueueMonitor}
  569. code{out}, code{in}, or code{drop} procedures,
  570. depending on the particular type of snoopy queue.
  571. subsection{shdr{Per-Flow Monitoring}{flowmon.cc}{sec:flowmon}}
  572. A collection of specialized classes are used to to implement
  573. per-flow statistics gathering.
  574. These classes include: code{QueueMonitor/ED/Flowmon},
  575. code{QueueMonitor/ED/Flow}, and code{Classifier/Hash}.
  576. Typically, an arriving packet is inspected to determine
  577. to which flow it belongs.
  578. This inspection and flow mapping is performed by a {em classifier}
  579. object (described in section ref{sec:hashclass}).
  580. Once the correct flow is determined, the packet is passed to
  581. a {em flow monitor}, which is responsible for collecting per-flow
  582. state.
  583. Per-flow state is contained in {em flow} objects in a one-to-one
  584. relationship to the flows known by the flow monitor.
  585. Typically, a flow monitor will create flow objects on-demand when
  586. packets arrive that cannot be mapped to an already-known flow.
  587. subsubsection{shdr{the flow monitor}{flowmon.cc}{sec:flowclass}}
  588. The code{QueueMonitor/ED/Flowmon} class is responsible for managing
  589. the creation of new flow objects when packets arrive on previously
  590. unknown flows and for updating existing flow objects.
  591. Because it is a subclass of code{QueueMonitor}, each flow monitor
  592. contains an aggregate count of packet and byte arrivals, departures, and
  593. drops.
  594. Thus, it is not necessary to create a separate queue monitor to record
  595. aggregate statistics.
  596. It provides the following OTcl interface:
  597. begin{quote}
  598. begin{itemize}
  599. item[classifier] - get(set) classifier to map packets to flows
  600. item[attach] - attach a Tcl I/O channel to this monitor
  601. item[dump] - dump contents of flow monitor to Tcl channel
  602. item[flows] - return string of flow object names known to this monitor
  603. end{itemize}
  604. end{quote}
  605. The {tt classifier} function sets or gets the name of the previously-allocated
  606. object which will perform packet-to-flow mapping for the flow monitor.
  607. Typically, the type of classifier used will have to do with the notion of
  608. ``flow'' held by the user.
  609. One of the hash based classifiers that inspect various IP-level header
  610. fields is typically used here (e.g. fid, src/dst, src/dst/fid).
  611. Note that while classifiers usually receive packets and forward them
  612. on to downstream objects, the flow monitor uses the classifier only for
  613. its packet mapping capability, so the flow monitor acts as a passive
  614. monitor only and does not actively forward packets.
  615. The {tt attach} and {tt dump} functions are used to
  616. associate a Tcl I/O stream with the
  617. flow monitor, and dump its contents on-demand.
  618. The file format used by the {tt dump} command is described below.
  619. The {tt flows} function returns a list of the names of flows known
  620. by the flow monitor in a way understandable to Tcl.
  621. This allows tcl code to interrogate a flow monitor in order
  622. to obtain handles to the individual flows it maintains.
  623. subsubsection{shdr{flow monitor trace format}{flowmon.cc}{sec:flowmonclass}}
  624. The flow monitor defines a trace format which may be used by post-processing
  625. scripts to determine various counts on a per-flow basis.
  626. The format is defined by the folling code in code{flowmon.cc}:
  627. begin{small}
  628. begin{verbatim}
  629. void
  630. FlowMon::fformat(Flow* f)
  631. {   
  632.         double now = Scheduler::instance().clock();
  633.         sprintf(wrk_, "%8.3f %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d 
  634. %d", 
  635.                 now,    
  636.                 f->flowid(),    // flowid
  637.                 0,              // category
  638.                 f->ptype(),     // type (from common header) 
  639.                 f->flowid(),    // flowid (formerly class)
  640.                 f->src(),
  641.                 f->dst(),
  642.                 f->parrivals(), // arrivals this flow (pkts)
  643.                 f->barrivals(), // arrivals this flow (bytes) 
  644.                 f->epdrops(),   // early drops this flow (pkts)
  645.                 f->ebdrops(),   // early drops this flow (bytes) 
  646.                 parrivals(),    // all arrivals (pkts)
  647.                 barrivals(),    // all arrivals (bytes) 
  648.                 epdrops(),      // total early drops (pkts)
  649.                 ebdrops(),      // total early drops (bytes) 
  650.                 pdrops(),       // total drops (pkts)
  651.                 bdrops(),       // total drops (bytes) 
  652.                 f->pdrops(),    // drops this flow (pkts) [includes edrops] 
  653.                 f->bdrops()     // drops this flow (bytes) [includes edrops]
  654.         );
  655. };  
  656. end{verbatim}
  657. end{small}
  658. Most of the fields are explained in the code comments.
  659. The ``category'' is historical, but is used to maintain loose backward-
  660. compatibility with the flow manager format in ns version 1.
  661. subsubsection{shdr{the flow class}{flowmon.cc}{sec:flowclass}}
  662. The class code{QueueMonitor/ED/Flow} is used by the flow monitor
  663. for containing per-flow counters.
  664. As a subclass of code{QueueMonitor}, it inherits the standard
  665. counters for arrivals, departures, and drops, both in packets and
  666. bytes.
  667. In addition, because each flow is typically identified by
  668. some combination of the packet source, destination, and flow
  669. identifier fields, these objects contain such fields.
  670. It's OTcl interface contains only bound variables:
  671. begin{quote}
  672. begin{itemize}
  673. item[src_] - source address on packets for this flow
  674. item[dst_] - desination address on packets for this flow
  675. item[flowid_] - flow id on packets for this flow
  676. end{itemize}
  677. end{quote}
  678. Note that packets may be mapped to flows (by classifiers) using
  679. criteria other than a src/dst/flowid triple.
  680. In such circumstances, only those fields actually used by
  681. the classifier in performing the packet-flow mapping should be
  682. considered reliable.