Initial PPI documentation
g0dil [Wed, 25 Apr 2007 15:33:33 +0000 (15:33 +0000)]
git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@235 270642c3-0616-0410-b53a-bc976706d245

PPI/Doxyfile [new file with mode: 0644]
PPI/Mainpage.dox [new file with mode: 0644]
PPI/SConscript [new file with mode: 0644]
PPI/scenario.dia [new file with mode: 0644]

diff --git a/PPI/Doxyfile b/PPI/Doxyfile
new file mode 100644 (file)
index 0000000..ae7a8ae
--- /dev/null
@@ -0,0 +1,4 @@
+@INCLUDE = "$(TOPDIR)/doclib/Doxyfile.global"
+
+PROJECT_NAME = libPPI
+GENERATE_TAGFILE = doc/ppi.tag
diff --git a/PPI/Mainpage.dox b/PPI/Mainpage.dox
new file mode 100644 (file)
index 0000000..bb234bb
--- /dev/null
@@ -0,0 +1,247 @@
+// Copyright (C) 2007 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     Stefan Bund <g0dil@berlios.de>
+//
+// 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.
+//
+// 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.
+//
+// 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.
+
+/** \mainpage libPPI : The Packet Processing Infrastructure
+
+    The PPI provides an infrastructure to create packet oriented network processin
+    applications. A PPI application is built by combining processing modules in a very flexible
+    manner.
+
+    \image html scenario.png Target Scenario
+    
+    The PPI concept is built around some key concepts
+
+    \li The PPI is based on processing \e packets. It does not handle stream oriented channels.
+    \li The PPI is built around reusable \e modules. Each module is completely independent.
+    \li Each module has an arbitrary number of \e connectors, inputs and outputs.
+    \li The modules are connected to each other using flexible \e connections.
+    \li Data flow throughout the network is governed via flexible automatic or manual \e throttling.
+    \li Modules may register additional external \e events (file descriptor events or timers).
+    
+    The PPI thereby builds on the facilities provided by the other components of the SENF
+    framework. 
+
+    Modules are divided roughly in to two categories: I/O modules provide packet sources and sinks
+    (network connection, writing packets to disk, generating new packets) whereas processing modules
+    process packets internally.  The target scenario above depicts a diffserv capable UDLR/ULE
+    router including performance optimizations for TCP traffic (PEP). This router is built by
+    combining several modules. In this scenario, <em>TAP</em>, <em>ASI Out</em>, <em>Raw Socket</em>
+    and in a limited way <em>Generator</em> are I/O modules whereas <em>PEP</em>, <em>DiffServ</em>,
+    <em>DVB Enc</em>, <em>GRE/UDLR</em>, <em>TCP Filter</em> and <em>Stuffer</em>are processing
+    modules. <em>ASI/MPEG</em> and <em>Net</em> are external I/O ports which are integrated via the
+    <em>TAP</em>, <em>ASI Out</em> and <em>Raw Sock</em> modules using external events.
+
+    \section packets Packets
+
+    The PPI processes packets and uses the <a href="@TOPDIR@/Packets/doc/html/index.html">Packet
+    library</a> to handle them. All packets are passed around as generic Packet::ptr's, the PPI
+    does not enforce any packet type restrictions.
+
+    \section modules Modules
+
+    A module is represented by a class type. Each module has several components:
+
+    \li It may have any number of connectors (inputs and outputs)
+    \li Each module declares flow information which details the route packets take within the
+        module. This information does not define how the information is processed, it only tells,
+        where data arriving on some input will be directed at.
+    \li The module might take additional parameters.
+    \li The module might also register additional events.
+
+    \code
+      class RateStuffer 
+          : public senf::ppi::Module
+      {
+      public:
+          ActiveInput payload;
+          ActiveInput stuffing;
+          ActiveOutput output;
+
+          RateStuffer(unsigned packetsPerSecond)
+          {
+              route(payload, output);
+              route(stuffing, output);
+
+              registerEvent(&RateStuffer::tick, IntervalTimer(1000u, packetsPerSecond));
+          }
+
+      private:
+          void tick()
+          {
+              if (payload)
+                  output(payload());
+              else
+                  output(stuffing());
+          }
+      };
+    \endcode
+
+    This module declares three I/O connectors (see below): <tt>payload</tt>, <tt>stuffing</tt> and
+    <tt>output</tt>. These connectors are defined as <em>public</em> data members so they can be
+    accessed from the outside. This is important as we will see below.
+
+    On module instantiation, it will declare it's flow information with <tt>route</tt> (which
+    is inherited from <tt>senf::ppi::Module</tt>). Then the module registers an interval timer which
+    will fire <tt>packetsPerSecond</tt> times every <tt>1000</tt> milliseconds.
+
+    The processing of the module is very simple: Whenever a timer tick arrives a packet is sent. If
+    the <tt>payload</tt> input is ready (see throttling below), a payload packet is sent, otherwise
+    a stuffing packet is sent. The module will therefore provide a constant stream of packets at a
+    fixed rate on <tt>output</tt>
+    
+    An example module to generate the stuffing packets could be
+
+    \code
+      class CopyPacketGenerator
+          : public senf::ppi::Module
+      {
+      public:
+          PassiveOutput output;
+
+          CopyPacketGenerator(Packet::ptr template)
+              : template_ (template)
+          {
+              noroute(output);
+              output.onRequest(&CopyPacketGenerator::makePacket);
+          }
+
+      private:
+          Packet::ptr template_;
+
+          void makePacket()
+          {
+              output(template_.clone());
+          }
+      };
+    \endcode
+
+    This module just produces a copy of a given packet whenever output is requested.
+
+    \subsection connectors Connectors
+    
+    Inputs and Outputs can be active and passive. An \e active I/O is <em>activated by the
+    module</em> to send data or to poll for available packets. A \e passive I/O is <em>signaled by
+    the framework</em> to fetch data from the module or to pass data into the module.
+
+    To send or receive a packet (either actively or after packet reception has been signaled), the
+    module just calls the connector. This allows to generate or process multiple packets in one
+    iteration. However, reading will only succeed, as long as packets are available from the
+    connection.
+
+    A module might want to queue incoming packets within a passive input or outgoing packets within
+    an active output. This is possible by either not reading any packet even though a new packet has
+    been scheduled on the input or by writing to the output while it is still throttled. To
+    facilitate this use, the connectors provide accessors to access the attached connection and it's
+    queue. This allows to analyze all packets available in the queue and act accordingly.
+
+    \section connections Connections
+
+    To make use of the modules, they have to be instantiated and connections have to be created
+    between the I/O connectors. It is possible to connect any pair of input/output connectors as
+    long as at least one of them is active
+
+    Every connection contains an internal packet queue. Under normal operating conditions (without
+    throttling) the queue will mostly be empty since packets will be processed directly. If a
+    connection is throttled, it can still receive new packets on it's input which will then be
+    queued. This is necessary even though the throttling will be propagated backwards (so no new
+    packets should arrive) since a module may produce more then one result packet from a single
+    incoming packet.
+
+    To complete our simplified example: Lets say we have a <tt>UdpInput</tt> module and a
+    <tt>UdpOutput</tt> module. We can then use our <tt>RateStuffer</tt> module to build an
+    application which will create a fixed-rate UDP stream:
+
+    \code
+      RateStuffer rateStuffer (10);
+      CopyPacketGenerator generator (some_packet_ptr);
+      senf::UDPv4ClientSocketHandle inputSocket (1111);
+      senf::ppi::SocketInput udpInput (inputSocket);
+      senf::UDPv4ClientSocketHandle outputSocket ("2.3.4.5:2222");
+      senf::ppi::SocketOutput udpOutput (outputSocket);
+
+      senf::ppi::connect(udpInput.output, rateStuffer.payload)
+          .bufferHighThresh(10)
+          .bufferLowThresh(5);
+      senf::ppi::connect(generator.output, rateStuffer.stuffing);
+      senf::ppi::connect(rateStuffer.output, udpOutput.input);
+
+      senf::ppi::run();
+    \endcode
+
+    First all necessary modules are created. Then the connections between these modules are set
+    up. The buffering of the udpInput <-> rateStuffer connection is changed so the queue will begin
+    to throttle only if more than 10 packets are in the queue. The connection will be unthrottled as
+    soon as there are no more than 5 packets left in the queue. This application will read
+    udp-packts coming in on port 1111 and will forward them to port 2222 on host 2.3.4.5 with a
+    fixed rate of 10 packets / second. 
+
+    \section throttling Throttling
+
+    If a connection cannot pass packets in it's current state, the connection is \e throttled. In
+    simple cases, throttling is handled automatically by
+    \li the connection if the queue is exceeds the buffering threshold
+    \li I/O modules whenever the external source or sink of the module is not ready
+
+    Throttling is handled separately in each direction:
+    \li Forward throttling will throttle in the direction of the data flow. Example: No new packets
+        are available from an input. This will activate forward throttling until new data arrives
+    \li Backward throttling will throttle in the direction to the data source. Example: an output
+        device (e.g. serial interface) has no more room for data. This event will activate backward
+        throttling so no new data will arrive until the device can send data again
+
+    The throttling state is managed within the Connection. Automatic throttling utilizes the routing
+    information (provided in the modules constructor) to forward throttling events across
+    modules. However, automatic throttling can be disabled for each connector. Modules may also
+    register event handlers whenever a throttling event occurs.
+
+    Whenever a connection is throttled (in the corresponding direction), passive connectors will \e
+    not be called by the framework. This may lead to packets being accumulated in the connection
+    queue. These packets will be sent as soon as the connection is unthrottled. The unthrottle event
+    will hoewever only be forwarded when the queue is empty (or has reached it's lower buffering
+    threshold).
+    
+    \code
+      passiveConnector.autoForwardThrottling(false);
+      passiveConnector.autoBackwardThrotttling(true);
+      passiveConnector.onForwardThrottle(...);
+      passiveConnector.onBackwardUnthrottle(...);
+    \endcode
+
+    Throttling is <em>not</em> enforced: especially a throttled output may still be called, the
+    excessive packets will be queued in the connection queue.
+
+    \section events Events
+
+    Modules may register additional events. These external events are very important since the drive
+    the PPI framework. Possible event sources are
+    \li time based events
+    \li file descriptors.
+ */
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// mode: flyspell
+// mode: auto-fill
+// End:
diff --git a/PPI/SConscript b/PPI/SConscript
new file mode 100644 (file)
index 0000000..a1b65ae
--- /dev/null
@@ -0,0 +1,10 @@
+Import('env')
+import SENFSCons
+
+###########################################################################
+
+SENFSCons.StandardTargets(env)
+
+SENFSCons.Doxygen(env, extra_sources=[
+    env.Dia2Png('scenario.dia'),
+])
diff --git a/PPI/scenario.dia b/PPI/scenario.dia
new file mode 100644 (file)
index 0000000..ab85acd
Binary files /dev/null and b/PPI/scenario.dia differ