pub enum FlowSide {
Initiator,
Responder,
}tracker only.Expand description
Which side of a flow a packet belongs to — the logical role direction axis (who started the conversation).
Derived from the crate::Orientation reported by the extractor:
- The first orientation seen for a flow becomes the
Initiatordirection. - Packets matching that orientation are
Initiator, packets in the opposite orientation areResponder.
§First-seen is arrival-order-relative — not deterministic
Initiator binds to whichever endpoint flowscope saw first,
which is usually the SYN sender but is ultimately “first packet
of this flow to reach the tracker”. On a single capture point that
is reliable. Across a tap-merge (two NICs / two queues feeding
one tracker, with a scheduling race) the first-seen packet can be
the response, so Initiator may bind to the server on some flows
and the client on others — non-deterministically.
For TCP specifically you can make the role axis itself
race-robust: set
FlowTrackerConfig::infer_tcp_initiator
and the tracker derives the initiator from the handshake (a
SYN+ACK-first flow is flipped so the SYN sender stays
Initiator), recording FlowStats::direction_flipped when it
corrected one (issue #122).
When you need a direction label two independent captures of the
same flow will agree on, use crate::Orientation (deterministic,
address-sorted) instead. flowscope keeps both: the
FlowEvent::Started / FlowEvent::Packet events carry both
side (this axis) and orientation (the canonical axis), and
FlowStats::initiator_orientation records which Orientation the
initiator’s first packet had so you can translate between them on a
finished flow. See docs/concepts.md →
“Direction, orientation, and capture leg”.
Maps to IPFIX biflowDirection (IE 239, RFC 5103): Initiator ≈
initiator (value 1), Responder ≈ reverseInitiator (value 2).
Variants§
Trait Implementations§
impl Copy for FlowSide
Source§impl<'de> Deserialize<'de> for FlowSide
impl<'de> Deserialize<'de> for FlowSide
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
impl Eq for FlowSide
impl StructuralPartialEq for FlowSide
Auto Trait Implementations§
impl Freeze for FlowSide
impl RefUnwindSafe for FlowSide
impl Send for FlowSide
impl Sync for FlowSide
impl Unpin for FlowSide
impl UnsafeUnpin for FlowSide
impl UnwindSafe for FlowSide
Blanket Implementations§
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.