Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework of PfRingDevice capture thread implementation. #1668

Open
wants to merge 15 commits into
base: dev
Choose a base branch
from
Open
4 changes: 3 additions & 1 deletion Pcap++/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ add_library(
$<$<BOOL:${PCAPPP_USE_PF_RING}>:src/PfRingDeviceList.cpp>
$<$<BOOL:${PCAPPP_USE_XDP}>:src/XdpDevice.cpp>
src/RawSocketDevice.cpp
src/StopToken.cpp
$<$<BOOL:${WIN32}>:src/WinPcapLiveDevice.cpp>
# Force light pcapng to be link fully static
$<TARGET_OBJECTS:light_pcapng>)
Expand All @@ -32,7 +33,8 @@ set(public_headers
header/PcapFilter.h
header/PcapLiveDevice.h
header/PcapLiveDeviceList.h
header/RawSocketDevice.h)
header/RawSocketDevice.h
header/StopToken.h)

if(PCAPPP_USE_DPDK)
list(
Expand Down
15 changes: 8 additions & 7 deletions Pcap++/header/PfRingDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
#include "MacAddress.h"
#include "SystemUtils.h"
#include "Packet.h"
#include <array>
#include <thread>
#include <condition_variable>
#include "StopToken.h"

/// @file

Expand Down Expand Up @@ -53,18 +54,18 @@ namespace pcpp
int m_InterfaceIndex;
MacAddress m_MacAddress;
int m_DeviceMTU;
CoreConfiguration m_CoreConfiguration[MAX_NUM_OF_CORES];
bool m_StopThread;
OnPfRingPacketsArriveCallback m_OnPacketsArriveCallback;
void* m_OnPacketsArriveUserCookie;

std::array<CoreConfiguration, MAX_NUM_OF_CORES> m_CoreConfiguration;
// An empty stop token source is used to indicate that no capture is running
internal::StopTokenSource m_StopTokenSource{ internal::NoStopStateTag{} };

bool m_ReentrantMode;
bool m_HwClockEnabled;
bool m_IsFilterCurrentlySet;

PfRingDevice(const char* deviceName);

bool initCoreConfigurationByCoreMask(CoreMask coreMask);
void captureThreadMain(std::condition_variable* startCond, std::mutex* startMutex, const int* startState);

int openSingleRxChannel(const char* deviceName, pfring** ring);

Expand Down Expand Up @@ -246,7 +247,7 @@ namespace pcpp
* Gets the core used in the current thread context
* @return The system core used in the current thread context
*/
SystemCore getCurrentCoreId() const;
static SystemCore getCurrentCoreId();

/**
* Get the statistics of a specific thread/core (=RX channel)
Expand Down
90 changes: 90 additions & 0 deletions Pcap++/header/StopToken.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#pragma once

#include <memory>

namespace pcpp
{
namespace internal
{
class StopToken;

/// Tag type used to construct a StopTokenSource without a shared state.
struct NoStopStateTag
{
};

/// @class StopTokenSource
/// @brief A source that can be used to request a stop operation.
class StopTokenSource
{
friend class StopToken;

public:
/// Creates a new StopTokenSource.
StopTokenSource();
/// Creates a new StopTokenSource without a shared state.
explicit StopTokenSource(NoStopStateTag) noexcept : m_SharedState(nullptr)
{}

/// Returns a StopToken that is associated with this source.
/// @return A StopToken associated with this StopTokenSource.
StopToken getToken() const noexcept;

/// Requests a stop operation. This will notify all associated StopTokens
/// that a stop has been requested.
/// @return True if the stop request was successful, false otherwise.
bool requestStop() noexcept;

/// Checks if a stop has been requested for this StopTokenSource.
/// @return True if a stop has been requested, false otherwise.
bool stopRequested() const noexcept;

/// Checks if a stop can be requested for this StopTokenSource.
/// @return True if a stop can be requested, false otherwise.
bool stopPossible() const noexcept;

private:
struct SharedState;

std::shared_ptr<SharedState> m_SharedState;
};

/// @class StopToken
/// @brief A token that can be used to check if a stop has been requested.
///
/// The StopToken class is used to check if a stop has been requested by a StopTokenSource.
/// It holds a shared state with the StopTokenSource to determine if a stop has been requested.
class StopToken
{
friend class StopTokenSource;

public:
/// @brief Default constructor for StopToken.
/// Constructs a StopToken with no associated shared state.
StopToken() noexcept = default;

/// @brief Checks if a stop has been requested.
/// @return True if a stop has been requested, false otherwise.
bool stopRequested() const noexcept;

/// @brief Checks if a stop can be requested.
/// @return True if a stop can be requested, false otherwise.
bool stopPossible() const noexcept;

private:
/// @brief Constructs a StopToken with the given shared state.
/// @param sharedState The shared state associated with this StopToken.
explicit StopToken(std::shared_ptr<StopTokenSource::SharedState> sharedState) noexcept
: m_SharedState(std::move(sharedState))
{}

/// @brief The shared state associated with this StopToken.
std::shared_ptr<StopTokenSource::SharedState> m_SharedState;
};

inline StopToken StopTokenSource::getToken() const noexcept
{
return StopToken(m_SharedState);
}
} // namespace internal
} // namespace pcpp
Loading
Loading