From: g0dil Date: Wed, 25 Apr 2007 15:33:33 +0000 (+0000) Subject: Initial PPI documentation X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=ed51531b908d57d1e0a820678bfec41659a0ad4a;p=senf.git Initial PPI documentation git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@235 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/PPI/Doxyfile b/PPI/Doxyfile new file mode 100644 index 0000000..ae7a8ae --- /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 0000000..bb234bb --- /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 +// +// 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, TAP, ASI Out, Raw Socket + and in a limited way Generator are I/O modules whereas PEP, DiffServ, + DVB Enc, GRE/UDLR, TCP Filter and Stufferare processing + modules. ASI/MPEG and Net are external I/O ports which are integrated via the + TAP, ASI Out and Raw Sock modules using external events. + + \section packets Packets + + The PPI processes packets and uses the Packet + library 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): payload, stuffing and + output. These connectors are defined as public 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 route (which + is inherited from senf::ppi::Module). Then the module registers an interval timer which + will fire packetsPerSecond times every 1000 milliseconds. + + The processing of the module is very simple: Whenever a timer tick arrives a packet is sent. If + the payload 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 output + + 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 activated by the + module to send data or to poll for available packets. A \e passive I/O is signaled by + the framework 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 UdpInput module and a + UdpOutput module. We can then use our RateStuffer 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 not 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 0000000..a1b65ae --- /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 0000000..ab85acd Binary files /dev/null and b/PPI/scenario.dia differ