1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
//! `flowscope::correlate` — generic helpers for cross-flow
//! correlation patterns.
//!
//! Three small, composable primitives that consumers stitch into
//! detectors:
//!
//! - [`TimeBucketedCounter`] — windowed rate counting per key
//! (DDoS rate-limits, SYN-flood thresholds, "did key K cross N
//! in W seconds").
//! - [`KeyIndexed`] — TTL'd LRU cache with monotonic-timestamp
//! eviction (DNS query/response correlation, ICMP error tying
//! back to original flow, generic request/response matching).
//! - [`SequencePattern`] / [`KeylessSequencePattern`] — generic
//! FSM trait for event-stream pattern detectors (port scans,
//! "auth failure → success", retry storms).
//!
//! These are tracker-clock aware: `now: Timestamp` is the packet
//! timestamp, not wall clock, so live and offline pipelines
//! produce identical detector output for identical inputs.
//!
//! # Hashing
//!
//! Hash-consuming primitives default to the std
//! [`RandomState`](std::hash::RandomState) (SipHash-1-3,
//! HashDoS-resistant, randomly seeded per instance). The
//! hasher-generic types ([`BloomFilter`], [`CountMinSketch`],
//! [`HyperLogLog`], [`EwmaVar`]) accept an alternative
//! `BuildHasher` via their `with_hasher` /
//! `with_*_and_hasher` constructors: pass `ahash::RandomState`
//! (already a `tracker`-feature dependency) for throughput on
//! trusted keys, or a **fixed-seed** builder when
//! [`Mergeable`] shards must agree on hash positions
//! (issue #134).
//!
//! # Quick start: bucketed counter
//!
//! ```
//! use flowscope::correlate::TimeBucketedCounter;
//! use flowscope::Timestamp;
//! use std::time::Duration;
//!
//! let mut c: TimeBucketedCounter<u32> =
//! TimeBucketedCounter::new(Duration::from_secs(60), Duration::from_secs(10), 1024);
//!
//! c.bump(42, Timestamp::new(0, 0));
//! c.bump(42, Timestamp::new(1, 0));
//! c.bump(42, Timestamp::new(2, 0));
//! assert_eq!(c.count(&42, Timestamp::new(3, 0)), 3);
//! ```
//!
//! # Quick start: KeyIndexed
//!
//! ```
//! use flowscope::correlate::KeyIndexed;
//! use flowscope::Timestamp;
//! use std::time::Duration;
//!
//! let mut q: KeyIndexed<u16, String> = KeyIndexed::new(Duration::from_secs(5), 1024);
//! q.insert(0x1234, "example.com".to_string(), Timestamp::new(0, 0));
//! assert_eq!(q.get(&0x1234, Timestamp::new(1, 0)).map(|s| s.as_str()), Some("example.com"));
//!
//! // Past TTL — entry is logically expired.
//! q.evict_expired(Timestamp::new(10, 0));
//! assert!(q.get(&0x1234, Timestamp::new(10, 0)).is_none());
//! ```
// Issue #141 (0.22): throughput grouped by an opaque owner key.
// Issue #134 (0.21): sequential change-point detectors (CUSUM /
// Page-Hinkley).
// Issue #134 (0.21): delete-capable counting-Bloom membership.
// Issue #134 (0.21): DdSketch relative-error quantiles + windowed.
// Issue #134 (0.21): per-key EWMA mean + variance.
// Issue #134 (0.21): bounded TTL first-seen / newly-observed set.
// FlowStateMap defaults its key type to `crate::extract::FiveTupleKey`,
// which only exists under the `extractors` feature. Gate the module
// here so consumers running with `--no-default-features` (no extractors)
// still get the rest of `correlate`.
pub use ;
pub use BloomFilter;
pub use TimeBucketedCounter;
pub use ;
pub use ;
pub use CountMinSketch;
pub use CountingBloomFilter;
pub use ;
pub use Ewma;
pub use ;
pub use FirstSeen;
pub use FlowStateMap;
pub use ;
pub use KeyIndexed;
pub use Mergeable;
pub use ArpTable;
pub use ;
pub use ;
pub use ;
pub use TimeBucketedSet;
pub use TopK;
pub use WelfordStats;
pub use BitStore;