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