4 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
5 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
6 // Stefan Bund <g0dil@berlios.de>
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.
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.
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.
23 /** \mainpage RateStuffer: A simple example featuring the Packet Processing Infrastructure
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.
29 \section run Running the example
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 folling commands, each in it's own window
35 The first command listens for incoming UDP packets on port 44345:
40 The next command starts the \c ratestuffer
42 # cd .../Examples/RateStuffer
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.
51 # nc -u localhost 44344
52 < type any text here >
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 seccond, they will still only be forwarded
57 with a speed of 1 packet / seccond. If the kernel UDP buffer overflows, packets would be dropped
58 (however, this buffer is prohibitively large)
60 \image html screenshot.png
62 \section setup Module setup
64 \image html ratestuffer.png
66 Above image depicts the module setup implementing the rate stuffer. A
67 senf::ppi::module::ActiveSocketReader reads the incoming UDP packets and sends them into a
68 senf::ppi::module::PassiveQueue.
70 The \a queue feeds the packets into a senf::ppi::module::PriorityJoin. The CopyPacketGenerator
71 \a generator is fed as second input into the \a join to provide the stuffing packets.
73 The RateFilter \a rateFilter reads packets from it's input at a fixed rate and writes them into
74 the senf::ppi::module::PassiveSocketWriter \a udpWriter. The senf::ppi::module::PriorityJoin
75 ensures that read requests of the RateStuffer's input are always serviced, either from the \a
76 queue or, if the \a queue output is throttled, from the \a generator.
78 \section code Example code
80 \dontinclude ratestuffer.cc
82 The code starts out including the necessary header files
88 We also define some namepsace aliases
93 The RateStuffer application is based on two additional modules.
95 \subsection ratefilter The RateFilter module
97 The RateFilter module simply forwards packets at a fixed rate.
102 Both connectors of the RateFilter module are active. The module is driven by a
103 senf::ppi::IntervalTimer.
107 The event is initialized to fire eery \a interval nanoseconds. The traffic is routed 'accross'
108 the timer which controls the traffic. The timer is then registered to call
109 RateFilter::timeout().
113 The event handler is quite simple: Every \a interval nanoseconds a packet is read from \a input
114 and forwarded to \a output.
116 This is all there is to the RateFilter module. Due to the routing setup, the timer will
117 automatically be disabled if either \a input or \a output become throttled (which is not even
120 \subsection generator The CopyPacketGenerator
122 We need an additional module to provide the stuffing packets. The CopyPacketGenerator provides
123 an unlimited stream of clone's of a template packet.
128 This module is very simple.
132 We save the template packet and initialize the \a output connector to call
133 CopyPacketGenerator::request() whenever a packet is requested.
137 The handler just provides \a packet on each request. This is ok as long as the packets are not
138 changed, in which case we would return <tt>packet->clone()</tt> instead.
140 \subsection main Connecting the modules
142 The applications main() method starts out by initializing the socket handles
147 The \a inputSocket is listening on port 44344 while the \a outputSocket will send packets to
148 port 44345 on localhost. The \a outputSocket uses the senf::ConnectedUDPv4SocketProtocol which
149 is compatible with the senf::ppi::module::PassiveSocketWriter module.
153 Next all the modules are allocated:
155 \li \a udpReader to read the packets from \a inputSocket
156 \li \a queue to convert the active output of senf::ppi::module::ActiveSocketReader into a
158 \li \a generator to provide the stuffing in the form of packets containing <tt>"<idle>\n"</tt>
159 \li \a join to combine the two packet streams (from \a udpReader and from \a generator) into a
161 \li \a rateFilter to generate the fixed rate packet stream of 1 packet every 1000000000
163 \li \a udpWriter to send the packets to \a outputSocket
167 The \ref senf::ppi::connect() calls now setup the necessary connections.
171 The module setup is complete, \ref senf::ppi::run() is called to enter the event loop.
180 // comment-column: 40
181 // c-file-style: "senf"
182 // indent-tabs-mode: nil
183 // ispell-local-dictionary: "american"
184 // compile-command: "scons -u doc"