updated RateStuffer documentation
[senf.git] / Examples / RateStuffer / Mainpage.dox
1 // $Id$
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \mainpage Example introducing the Packet Processing Infrastructure
24
25     This example application implements a simple PPI application: It will read UDP packets from an
26     input port and will forward them to another port at a fixed packet rate. If the input stream
27     does not provide enough packets, empty UDP packets will be sent instead.
28     
29     \section run Running the example
30
31     Running the example is a little bit more complicated since we need to provide example UDP
32     packets so we can see the application at work. We do this using \c netcat. We open several shell
33     windows and run the following commands, each in it's own window
34
35     The first command listens for incoming UDP packets on port 44345:
36     <pre>
37     # nc -u -l -p 44345
38     </pre>
39     
40     The next command starts the \c ratestuffer
41     <pre>
42     # cd .../Examples/RateStuffer
43     # scons -u
44     # ./ratestuffer
45     </pre>
46
47     We should now see '<idle>' messages arriving in the first window once per second. We now can
48     start another \c netcat to send packets to the input port.
49
50     <pre>
51     # nc -u localhost 44344
52     < type any text here >
53     </pre>
54
55     Whenever we send out a packet with CR in the last window we should see it appear in the first
56     one. If we send out packets faster than 1 packet per second, they will start to be discarded if
57     more than two packets are in flight.
58
59     \image html screenshot.png
60
61     \section setup Module setup
62
63     <div class="diamap" name="ratestuffer">
64         <span coords="101,139,220,206">\ref senf::ppi::module::ThrottleBarrier</span>
65         <span coords="241,152,365,219">\ref senf::ppi::module::PassiveQueue</span>
66         <span coords="606,346,748,400">\ref senf::ppi::module::PassiveSocketSink<></span>
67         <span coords="528,190,647,257">\ref RateFilter</span>
68         <span coords="387,165,511,245">\ref senf::ppi::module::PriorityJoin</span>
69         <span coords="0,0,149,53">\ref senf::ppi::module::ActiveSocketSource<></span>
70         <span coords="241,235,365,289">\ref senf::ppi::module::CloneSource</span>
71     </div>
72     \htmlonly <img src="ratestuffer.png" border="0" alt="ratestuffer" usemap="#ratestuffer"> \endhtmlonly
73
74     Above image depicts the module setup implementing the rate stuffer. A
75     senf::ppi::module::ActiveSocketSource reads the incoming UDP packets and sends them into a
76     senf::ppi::module::PassiveQueue (via a senf::ppi::module::ThrottleBarrier).
77
78     The \a queue feeds the packets into a senf::ppi::module::PriorityJoin. The CloneSource
79     \a generator is fed as second input into the \a join to provide the stuffing packets.
80
81     The RateFilter \a rateFilter reads packets from it's input at a fixed rate and writes them into
82     the senf::ppi::module::PassiveSocketSink \a udpSink. The senf::ppi::module::PriorityJoin
83     ensures that read requests of the RateStuffer's input are always serviced, either from the \a
84     queue or, if the \a queue output is throttled, from the \a generator.
85
86     The \a barrier is not strictly necessary. However, it makes the behavior of the RateStuffer
87     predictable in the case where packets need to be dropped. Without the
88     senf::ppi::module::ThrottleBarrier, the packets will be left in the kernel socket queue. Packets
89     will only start to be dropped when that queue fills up. The size of this queue cannot be easily
90     manipulated and it's initial size is immense. So to stop the kernel queue from filling up with
91     increasingly out-of-date packets, we add the \a barrier which will explicitly read and drop
92     excess packets.
93
94     \section code Example code
95
96     \dontinclude ratestuffer.cc
97
98     The code starts out including the necessary header files
99
100     \skip Custom
101     \skip #include
102     \until PPI
103
104     We also define some namespace aliases
105
106     \skip namespace
107     \until senf::ppi;
108
109     The RateStuffer application is based on one additional application module.
110
111     \subsection ratefilter The RateFilter module
112
113     The RateFilter module simply forwards packets at a fixed rate.
114
115     \skip class
116     \until };
117
118     Both connectors of the RateFilter module are active. The module is driven by a
119     senf::ppi::IntervalTimer.
120
121     \until }
122
123     The event is initialized to fire every \a interval nanoseconds.  The traffic is routed 'across'
124     the timer which controls the traffic. This routing lets the module automatically handle
125     throttling events. The timer is registered to call RateFilter::timeout().
126
127     \until }
128
129     The event handler is quite simple: Every \a interval nanoseconds a packet is read from \a input
130     and forwarded to \a output.
131
132     This is all there is to the RateFilter module. Due to the routing setup, the timer will
133     automatically be disabled should either \a input or \a output become throttled. However, in this
134     specific case this should never happen: The \a input is connected (via the \a join) to the
135     senf::ppi::module::CloneSource, which will never throttle. The \a output is connected to a UDP
136     socket which also never throttles.
137
138     \subsection ratestuffer The RateStuffer subnet
139
140     We decide to implement the RateStuffer as a subnet or collection. This is a simple struct or
141     class which contains all the modules necessary for a specific functionality. The modules are
142     initialized and connected in the class's constructor. External connectors are exported as
143     references to the corresponding module connectors:
144
145     \skip class
146     \until rateFilter
147     
148     First the needed modules are declared. We have 
149     - the \a barrier to discard incoming packets sent to fast
150     - the \a queue to receive incoming packets and create throttling notifications
151     - the \a generator to create the stuffing packets
152     - the \a join to combine the input stream from the \a queue with the stuffing packet stream
153     - the \a rateFilter to generate the fixed rate output stream
154
155     \until output
156
157     Here we declare the external connectors. The subnetwork exports a single input and output
158     connector. The external connectors are declared as \e references.
159
160     \until output
161
162     The constructor now initializes all the local objects. We pass the template \a packet to the \a
163     generator and set the timing \a interval of the \a rateFilter.
164     
165     The \a input and \a output connector references are bound to the corresponding connectors we
166     want to expose: \a input to the \a barrier's \a input and \a output to the \a rateFilter's \a
167     output.
168
169     \until };
170
171     The constructor body sets up the connections within the subnetwork. Finally, we set the queueing
172     discipline of the \a queue. This Completes the RateStuffer. This subnetwork can now be used like
173     a module.
174
175     \subsection main Application setup
176
177     The applications main() method starts out by initializing the socket handles
178
179     \skip main
180     \until 44345
181
182     The \a inputSocket is listening on port 44344 while the \a outputSocket will send packets to
183     port 44345 on localhost. The \a outputSocket uses the senf::ConnectedUDPv4SocketProtocol which
184     is compatible with the senf::ppi::module::PassiveSocketSink module.
185
186     \until udpSink
187
188     Here we allocate the components:
189
190     - \a udpSource to read the packets from \a inputSocket
191     - \a stuffer for the real work and
192     - \a udpSink to send the packets to \a outputSocket
193
194     \until udpSink
195
196     The \ref senf::ppi::connect() calls setup the necessary connections.
197     
198     The module setup is complete, \ref senf::ppi::run() is called to enter the event loop.
199
200     \until }
201  */
202
203 \f
204 // Local Variables:
205 // mode: c++
206 // fill-column: 100
207 // comment-column: 40
208 // c-file-style: "senf"
209 // indent-tabs-mode: nil
210 // ispell-local-dictionary: "american"
211 // compile-command: "scons -u doc"
212 // mode: flyspell
213 // mode: auto-fill
214 // End: