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