dfx 0.1.0
Linux-based dynamic dataflow executor
Loading...
Searching...
No Matches
dfx::Pcapng::PipeSink Class Reference

PCAPNG sink that streams capture bytes to a named FIFO (pipe) for live consumption. More...

#include <dfx-pcapng/sinks/PipeSink.hpp>

Inheritance diagram for dfx::Pcapng::PipeSink:
[legend]
Collaboration diagram for dfx::Pcapng::PipeSink:
[legend]

Public Member Functions

 PipeSink (fs::path path, uint32_t mode=0600)
 Create a named FIFO at path.
 ~PipeSink ()
 Destroy the sink and remove the FIFO from the filesystem.
void init (std::vector< uint8_t > initialHeader) override
 Initialize the sink and write the initial PCAPNG header into the FIFO.
void setMaxQueueSize (std::size_t maxQueueSize)
 Set the maximum number of queued blocks when the FIFO is not writable.
std::size_t maxQueueSize () const noexcept
 Current maximum number of queued blocks.
void write (std::vector< uint8_t > data) override
 Write serialized PCAPNG bytes to the FIFO.
Public Member Functions inherited from dfx::Pcapng::Sink
 Sink () noexcept=default
 Construct a sink.
 DISABLE_COPY_AND_MOVE (Sink)
 Sinks are not copyable and not movable.
virtual ~Sink ()=default
 Virtual destructor for polymorphic use.
void setPoller (FdWatch::Poller *poller)
 Provide a poller that the sink may use for event-driven I/O.

Additional Inherited Members

Protected Attributes inherited from dfx::Pcapng::Sink
FdWatch::Poller_poller = nullptr
 Borrowed poller pointer for event-driven sink implementations.

Detailed Description

PCAPNG sink that streams capture bytes to a named FIFO (pipe) for live consumption.

PipeSink implements Sink by writing PCAPNG bytes to a named pipe (FIFO). The typical use-case is live capture into Wireshark: a consumer opens the FIFO for reading while dfx streams PCAPNG blocks into it.

This sink is less trivial than "just write to a pipe" because FIFOs have sharp edges:

  • opening a FIFO for write-only can fail with ENXIO if no reader is present (in non-blocking mode). But in our case the writer is necessarily present before the reader,
  • writes can fail with EPIPE when the reader disconnects,
  • the pipe buffer is finite, so writers must handle backpressure (EAGAIN).

PipeSink addresses these by integrating with a FdWatch::Poller :

  • The FIFO is opened non-blocking and attached to the poller via FdWatch::PollerFd.
  • When the pipe is not currently writable, PipeSink queues data and resumes writing when the poller signals write readiness.
FIFO creation and cleanup
Construction performs filesystem setup:
  • parent directories are created if needed,
  • any existing file at the path is removed,
  • the FIFO is created with mkfifo(path, mode).

Destruction removes (unlinks) the FIFO path if it had been opened successfully.

When the pipe buffer is full (EAGAIN) or the reader is absent/closed (EPIPE), the sink marks itself as "not write ready" and defers further writes until the poller signals write readiness again.

To prevent unbounded memory growth, the queue size is capped by maxQueueSize(). When the limit is reached, the oldest queued data is dropped (with a warning).

Write granularity
Writes are performed in chunks of up to PIPE_BUF bytes to preserve atomicity guarantees where applicable and to behave well with FIFO semantics.
Note
All writes are non-blocking. If the consumer is slow, PipeSink buffers up to the configured limit and then drops oldest data.

Constructor & Destructor Documentation

◆ PipeSink()

dfx::Pcapng::PipeSink::PipeSink ( fs::path path,
uint32_t mode = 0600 )

Create a named FIFO at path.

  • Creates parent directories if needed.
  • Removes an existing file at the same path.
  • Creates the FIFO with mkfifo().
Parameters
pathFilesystem path of the FIFO to create.
modeFIFO permissions passed to mkfifo() (default: 0600).
Exceptions
dfx::Utils::ExceptionThrown if directory creation, file removal, or FIFO creation fails.

◆ ~PipeSink()

dfx::Pcapng::PipeSink::~PipeSink ( )

Destroy the sink and remove the FIFO from the filesystem.

If the FIFO FD was opened/attached successfully, the FIFO path is unlinked. Failures to remove the FIFO are logged.

Member Function Documentation

◆ init()

void dfx::Pcapng::PipeSink::init ( std::vector< uint8_t > initialHeader)
overridevirtual

Initialize the sink and write the initial PCAPNG header into the FIFO.

  • Opens the FIFO in non-blocking mode with O_RDWR | O_NONBLOCK.

Opening as O_RDWR (even though this sink only writes) is intentional: opening O_WRONLY in non-blocking mode can fail with ENXIO when no reader is present.

Parameters
initialHeaderSerialized bytes that must start the PCAPNG stream.

Implements dfx::Pcapng::Sink.

◆ maxQueueSize()

std::size_t dfx::Pcapng::PipeSink::maxQueueSize ( ) const
inlinenoexcept

Current maximum number of queued blocks.

◆ setMaxQueueSize()

void dfx::Pcapng::PipeSink::setMaxQueueSize ( std::size_t maxQueueSize)

Set the maximum number of queued blocks when the FIFO is not writable.

If the queue currently exceeds the new limit, the oldest queued blocks are dropped immediately until the queue fits.

Parameters
maxQueueSizeMaximum number of queued blocks.

◆ write()

void dfx::Pcapng::PipeSink::write ( std::vector< uint8_t > data)
overridevirtual

Write serialized PCAPNG bytes to the FIFO.

If the pipe is currently writable, the sink attempts to write immediately:

  • On partial write or EAGAIN, the remaining bytes are stored and the sink waits for a poller write-ready notification.
  • On EPIPE, the read side is closed; the sink stops attempting to write until the poller indicates readiness again.

If the pipe is not currently writable, data is saved internally. When the queue reaches maxQueueSize(), the oldest block is dropped.

Parameters
dataBytes to write (moved into internal storage as needed).

Implements dfx::Pcapng::Sink.


The documentation for this class was generated from the following file: