X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Examples%2FRateStuffer%2FMainpage.dox;h=6d034ebb56300a5f4c0186e85d9ff606f78aacc8;hb=ab7ff164ab5ae711ec09ce2b24228510f1ffdcff;hp=85bbd9beb2f49f0432bc47447a3cfb0c16ad21be;hpb=3d16600678b948ff3bd0e4fd2a1a800fcc629a03;p=senf.git diff --git a/Examples/RateStuffer/Mainpage.dox b/Examples/RateStuffer/Mainpage.dox index 85bbd9b..6d034eb 100644 --- a/Examples/RateStuffer/Mainpage.dox +++ b/Examples/RateStuffer/Mainpage.dox @@ -1,42 +1,49 @@ // $Id$ // -// Copyright (C) 2007 -// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) -// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) -// Stefan Bund +// Copyright (C) 2007 +// Fraunhofer Institute for Open Communication Systems (FOKUS) // -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. +// The contents of this file are subject to the Fraunhofer FOKUS Public License +// Version 1.0 (the "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// http://senf.berlios.de/license.html // -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// The Fraunhofer FOKUS Public License Version 1.0 is based on, +// but modifies the Mozilla Public License Version 1.1. +// See the full license text for the amendments. // -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the -// Free Software Foundation, Inc., -// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// Software distributed under the License is distributed on an "AS IS" basis, +// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +// for the specific language governing rights and limitations under the License. +// +// The Original Code is Fraunhofer FOKUS code. +// +// The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. +// (registered association), Hansastraße 27 c, 80686 Munich, Germany. +// +// Contributor(s): +// Stefan Bund + -/** \mainpage RateStuffer: A simple example featuring the Packet Processing Infrastructure +using namespace senf::ppi::module; + +/** \mainpage Example introducing the Packet Processing Infrastructure This example application implements a simple PPI application: It will read UDP packets from an input port and will forward them to another port at a fixed packet rate. If the input stream does not provide enough packets, empty UDP packets will be sent instead. - + \section run Running the example Running the example is a little bit more complicated since we need to provide example UDP packets so we can see the application at work. We do this using \c netcat. We open several shell - windows and run the folling commands, each in it's own window + windows and run the following commands, each in it's own window The first command listens for incoming UDP packets on port 44345:
     # nc -u -l -p 44345
     
- + The next command starts the \c ratestuffer
     # cd .../Examples/RateStuffer
@@ -53,28 +60,35 @@
     
Whenever we send out a packet with CR in the last window we should see it appear in the first - one. If we send out packets faster than 1 packet per seccond, they will still only be forwarded - with a speed of 1 packet / seccond. If the kernel UDP buffer overflows, packets would be dropped - (however, this buffer is prohibitively large) + one. If we send out packets faster than 1 packet per second, they will start to be discarded if + more than two packets are in flight. \image html screenshot.png \section setup Module setup - \image html ratestuffer.png + \diaimage ratestuffer.dia Above image depicts the module setup implementing the rate stuffer. A - senf::ppi::module::ActiveSocketReader reads the incoming UDP packets and sends them into a - senf::ppi::module::PassiveQueue. + senf::ppi::module::ActiveSocketSource reads the incoming UDP packets and sends them into a + senf::ppi::module::PassiveQueue (via a senf::ppi::module::ThrottleBarrier). - The \a queue feeds the packets into a senf::ppi::module::PriorityJoin. The CopyPacketGenerator + The \a queue feeds the packets into a senf::ppi::module::PriorityJoin. The CloneSource \a generator is fed as second input into the \a join to provide the stuffing packets. The RateFilter \a rateFilter reads packets from it's input at a fixed rate and writes them into - the senf::ppi::module::PassiveSocketWriter \a udpWriter. The senf::ppi::module::PriorityJoin + the senf::ppi::module::PassiveSocketSink \a udpSink. The senf::ppi::module::PriorityJoin ensures that read requests of the RateStuffer's input are always serviced, either from the \a queue or, if the \a queue output is throttled, from the \a generator. + The \a barrier is not strictly necessary. However, it makes the behavior of the RateStuffer + predictable in the case where packets need to be dropped. Without the + senf::ppi::module::ThrottleBarrier, the packets will be left in the kernel socket queue. Packets + will only start to be dropped when that queue fills up. The size of this queue cannot be easily + manipulated and it's initial size is immense. So to stop the kernel queue from filling up with + increasingly out-of-date packets, we add the \a barrier which will explicitly read and drop + excess packets. + \section code Example code \dontinclude ratestuffer.cc @@ -83,14 +97,14 @@ \skip Custom \skip #include - \until Setup + \until PPI - We also define some namepsace aliases + We also define some namespace aliases \skip namespace \until senf::ppi; - The RateStuffer application is based on two additional modules. + The RateStuffer application is based on one additional application module. \subsection ratefilter The RateFilter module @@ -104,9 +118,9 @@ \until } - The event is initialized to fire eery \a interval nanoseconds. The traffic is routed 'accross' - the timer which controls the traffic. The timer is then registered to call - RateFilter::timeout(). + The event is initialized to fire every \a interval nanoseconds. The traffic is routed 'across' + the timer which controls the traffic. This routing lets the module automatically handle + throttling events. The timer is registered to call RateFilter::timeout(). \until } @@ -114,30 +128,49 @@ and forwarded to \a output. This is all there is to the RateFilter module. Due to the routing setup, the timer will - automatically be disabled if either \a input or \a output become throttled (which is not even - needed here). + automatically be disabled should either \a input or \a output become throttled. However, in this + specific case this should never happen: The \a input is connected (via the \a join) to the + senf::ppi::module::CloneSource, which will never throttle. The \a output is connected to a UDP + socket which also never throttles. - \subsection generator The CopyPacketGenerator + \subsection ratestuffer The RateStuffer subnet - We need an additional module to provide the stuffing packets. The CopyPacketGenerator provides - an unlimited stream of clone's of a template packet. + We decide to implement the RateStuffer as a subnet or collection. This is a simple struct or + class which contains all the modules necessary for a specific functionality. The modules are + initialized and connected in the class's constructor. External connectors are exported as + references to the corresponding module connectors: \skip class - \until }; + \until rateFilter - This module is very simple. + First the needed modules are declared. We have + - the \a barrier to discard incoming packets sent to fast + - the \a queue to receive incoming packets and create throttling notifications + - the \a generator to create the stuffing packets + - the \a join to combine the input stream from the \a queue with the stuffing packet stream + - the \a rateFilter to generate the fixed rate output stream - \until } + \until output - We save the template packet and initialize the \a output connector to call - CopyPacketGenerator::request() whenever a packet is requested. + Here we declare the external connectors. The subnetwork exports a single input and output + connector. The external connectors are declared as \e references. - \until } + \until output + + The constructor now initializes all the local objects. We pass the template \a packet to the \a + generator and set the timing \a interval of the \a rateFilter. + + The \a input and \a output connector references are bound to the corresponding connectors we + want to expose: \a input to the \a barrier's \a input and \a output to the \a rateFilter's \a + output. + + \until }; - The handler just provides \a packet on each request. This is ok as long as the packets are not - changed, in which case we would return packet->clone() instead. + The constructor body sets up the connections within the subnetwork. Finally, we set the queueing + discipline of the \a queue. This Completes the RateStuffer. This subnetwork can now be used like + a module. - \subsection main Connecting the modules + \subsection main Application setup The applications main() method starts out by initializing the socket handles @@ -146,27 +179,19 @@ The \a inputSocket is listening on port 44344 while the \a outputSocket will send packets to port 44345 on localhost. The \a outputSocket uses the senf::ConnectedUDPv4SocketProtocol which - is compatible with the senf::ppi::module::PassiveSocketWriter module. + is compatible with the senf::ppi::module::PassiveSocketSink module. - \until udpWriter + \until udpSink - Next all the modules are allocated: + Here we allocate the components: - \li \a udpReader to read the packets from \a inputSocket - \li \a queue to convert the active output of senf::ppi::module::ActiveSocketReader into a - passive output - \li \a generator to provide the stuffing in the form of packets containing "\n" - \li \a join to combine the two packet streams (from \a udpReader and from \a generator) into a - single stream - \li \a rateFilter to generate the fixed rate packet stream of 1 packet every 1000000000 - nanoseconds and - \li \a udpWriter to send the packets to \a outputSocket + - \a udpSource to read the packets from \a inputSocket + - \a stuffer for the real work and + - \a udpSink to send the packets to \a outputSocket - \until udpWriter + \until udpSink - The \ref senf::ppi::connect() calls now setup the necessary connections. - - \until run + The \ref senf::ppi::connect() calls setup the necessary connections. The module setup is complete, \ref senf::ppi::run() is called to enter the event loop.