From dc455eda3c0dd5cc8b6ca79ca01e85e536518cca Mon Sep 17 00:00:00 2001 From: g0dil <g0dil@wiback.org> Date: Wed, 25 Apr 2007 15:33:33 +0000 Subject: [PATCH] Initial PPI documentation --- PPI/Doxyfile | 4 + PPI/Mainpage.dox | 247 +++++++++++++++++++++++++++++++++++++++++++++++ PPI/SConscript | 10 ++ PPI/scenario.dia | Bin 0 -> 2924 bytes 4 files changed, 261 insertions(+) create mode 100644 PPI/Doxyfile create mode 100644 PPI/Mainpage.dox create mode 100644 PPI/SConscript create mode 100644 PPI/scenario.dia diff --git a/PPI/Doxyfile b/PPI/Doxyfile new file mode 100644 index 000000000..ae7a8ae20 --- /dev/null +++ b/PPI/Doxyfile @@ -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 index 000000000..bb234bb1b --- /dev/null +++ b/PPI/Mainpage.dox @@ -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. + */ + + +// 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 index 000000000..a1b65aed6 --- /dev/null +++ b/PPI/SConscript @@ -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 index 0000000000000000000000000000000000000000..ab85acdc3047e854216f84420644a1e00f18c593 GIT binary patch literal 2924 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 WpnM^JXIXH4eDHst*7MqHw*UY&g_`OB literal 0 HcmV?d00001 -- GitLab