pub struct Sampler(/* private fields */);Expand description
How often a warning a peer can repeat at will is allowed to be loud.
The rules above bound what one line may carry. This bounds how many lines
there are, which is the other half of the same problem and the one an
operator feels first: journald rate limiting counts lines, per unit, so a
peer that can buy one warning per request does not merely fill a disk — it
spends this service’s whole allowance and the genuine lines that follow are
dropped. Suppressing the real signal is the more expensive half of the
attack, and a peer needs no privilege to run it: a refusal is a request that
went nowhere, so the refusals are the cheapest lines there are.
Silencing the repeats is not the answer either. The two warnings this guards are read as evidence — a client probing the private side of the host, a client sitting on its tunnel limit — and evidence that reports “it happened” while hiding “it happened sixty thousand times” is worse than useless.
So the schedule doubles: occurrence 1 is reported, then 2, 4, 8, and so on, each carrying the running total. A scan of every port on a host is 17 lines instead of 65535, the first of them lands as immediately as it does today, and the last one says it was 65536 — which is more than the unsampled version ever told anybody, since counting identical lines was left to whoever read the journal. The cost is that the count between reports is only known to within a factor of two until the next one arrives.
One of these per connection, so a peer cannot use a quiet neighbour’s allowance, and nothing here is ever reset: the schedule is about a connection’s whole life.
Implementations§
Source§impl Sampler
impl Sampler
Sourcepub fn record(&self) -> Option<u64>
pub fn record(&self) -> Option<u64>
Records an occurrence: Some(total) when this one is to be reported.
Relaxed because the only thing ordered against is the counter itself —
two threads racing here get two distinct totals and at most one of them
is a power of two, which is all the schedule asks. Wrapping is
unreachable (a u64 of refusals is longer than the hardware lasts) and
harmless if it happened: zero is not a power of two, so the pass is
quiet rather than wrong.