<!doctype linuxdoc system>

<article>

<title>
cflowd-2-0 design
</title>
<author>Daniel W. McRobb
<date>Sept 1998

<abstract>
This document contains a description of the design and architecture
of <tt>cflowd-2-0</tt>.

</abstract>

<toc>

<sect>System Overview
<p>

<tt>cflowd</tt> is divided into three distinct high-level modules,
which map directly to three distinct programs.  

The first program is responsible for handling raw flow data from Cisco
routers and making it available to clients on the local host.  The name of
this program is <tt>cflowdmux</tt>.

The second program is responsible for maintaining per-input-interface
tabular data for each Cisco, and passing it back to a central collector.
This program is called <tt>cflowd</tt>.

The third program is responsible for retrieving tabular data from
instances of <tt>cflowd</tt>.  This program is called <tt>cfdcollect</tt>.

A diagram of the relationships of different programs in the system
is shown in <bf>Figure 1</bf>.

<figure loc="ht">
<eps file="./dataflow2.ps" height="5in">
<img src="./dataflow2.gif">
<caption>
<label id="figure1">
<#if output="html">
Figure 1: cflowd data flow detail
</#if>
<#if output="ps|dvi|latex2e|latex">
cflowd data flow detail
</#if>
</caption>
</figure>

<sect>cflowdmux
<p>

<tt>cflowdmux</tt> accepts Cisco flow-export packets arriving
on UDP sockets and saves the packets in shared memory buffers.
<tt>cflowdmux</tt> toggles between two packet buffers when writing
packets, and clients may read the buffer that is not currently being
written.  A semaphore is used as the read/write mutex for each buffer,
so that clients can avoid reading a buffer while it's being written
by <tt>cflowdmux</tt>.  <bf>Figure 2</bf> is a diagram of the
basic functions of <tt>cflowdmux</tt>.

<figure loc="ht">
<eps file="./cflowdmux1.ps" height="5in">
<img src="./cflowdmux1.gif">
<caption>
<label id="figure2">
<#if output="html">
Figure 2: cflowdmux
</#if>
<#if output="ps|dvi|latex2e|latex">
cflowdmux
</#if>
</caption>
</figure>

As UDP flow-export packets arrive, <tt>cflowdmux</tt> writes them into
one of the shared memory packet buffers.  Before writing into a share
memory buffer, <tt>cflowdmux</tt> gets the semaphore for the buffer to
prevent writing a buffer that's being read by a client like
<tt>cflowd</tt>.  When <tt>cflowdmux</tt> reaches the end of the buffer
or 2 seconds transpires without coming to the end of the buffer, it
releases the semaphore for the buffer and toggles to the other buffer.

The motivation for the use of shared memory for inter-process
communication: performance.  A bottleneck at this interface in the
system is important to avoid because it will affect all downstream
processing.

Currently <tt>cflowdmux</tt> is a standalone program, and can be run
alone without clients.  There's no particularly good reason to do
so, since <tt>cflowdmux</tt> does not analyze the contents of the data.
However, it does mean that it's fairly safe to start <tt>cflowdmux</tt> 
at boot time even if you will not be running clients all of the time.

<sect>cflowd
<p>

<tt>cflowd</tt> watches the shared memory packet buffer semaphores and
reads a packet buffer when it becomes available.  <tt>cflowd</tt> uses
the <tt>CflowdRawFlow</tt> class to convert the flow-export packets into
<tt>CflowdRawFlow</tt> objects, and uses the <tt>CflowdRawFlow</tt>
objects to populate tables for which it is configured (the AS matrix,
net matrix, etc.).  <tt>cflowd</tt> does not yet write raw flow data to
disk.  This facility will be provided soon (but obviously be a bottleneck
in most cases since disk I/O is generally slow).

<tt>cflowd</tt> will <tt>listen()</tt> for local client connections on a
UNIX domain socket.  If a client connects, <tt>cflowd</tt> will accept()
and fork(), read the client request, then send the client the data they
requested.  This IPC channel is used for clients like <tt>cfdases</tt>,
<tt>cfdnets</tt>, et. al.  The data sent is current data, and
<tt>cflowd</tt> does not clear any tables.

<tt>cflowd</tt> will also listen for remote client connections on a TCP
socket.  When a client connects, <tt>cflowd</tt> checks to see if the
client is allowed to connect.  If not, it closes the socket with
prejudice.  If allowed, <tt>cflowd</tt> will <tt>fork()</tt> and the
child will send all of the tabular data to the client.  The child
simply exits when done (or if it gets a SIGPIPE while writing to the
client), while the parent clears its tables, updates some timestamp
information, then continues collecting data.

<sect>cfdcollect
<p>

<tt>cfdcollect</tt> is used to retrieve and archive tabular data from
instances of <tt>cflowd</tt> at regular intervals.  This is how we
generate time series data for the tabular information (AS matrix, net
matrix, protocol table and port matrix).  <tt>cfdcollect</tt> uses a
<tt>CflowdServer</tt> class as an interface to instances of
<tt>cflowd</tt>.  <tt>cfdcollect</tt> writes data in ARTS files, using
the ARTS C++ class library (from the arts++ package).  A simple picture
of tabular data collection via <tt>cfdcollect</tt> is shown in 
<bf>Figure 3</bf>.

<figure loc="ht">
<eps file="./cfdcollect1.ps" height="5in">
<img src="./cfdcollect1.gif">
<caption>
<label id="figure3">
<#if output="html">
Figure 3: tabular data collection via cfdcollect
</#if>
<#if output="ps|dvi|latex2e|latex">
tabular data collection via cfdcollect
</#if>
</caption>
</figure>

</article>
