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 127 128 129 130 131 132
//! Edge rate limiter and supporting functions.
//!
pub(crate) mod handle;
use std::time::Duration;
pub use handle::ERLError;
use handle::{ERLHandle, PenaltyboxHandle, RateCounterHandle};
/// An edge rate limiter which includes a ratecounter and a penaltybox.
///
pub struct ERL {
handle: ERLHandle,
}
/// A rate counter that can be used with a edge rate limiter or stand alone for counting and rate calculations
///
pub struct RateCounter {
handle: RateCounterHandle,
}
/// To be used for picking the window in a rate counter lookup_rate or a ERL check_rate
///
#[repr(u32)]
pub enum RateWindow {
/// A one secound rate window
OneSec = 1,
/// A ten secound rate window
TenSecs = 10,
/// A sixty secound rate window
SixtySecs = 60,
}
/// To be used for picking the duration in a rate counter lookup_count call
///
#[repr(u32)]
pub enum CounterDuration {
/// A one second counter window
TenSec = 10,
/// A twenty second counter window
TwentySecs = 20,
/// A thirty second counter window
ThirtySecs = 30,
/// A forty second counter window
FortySecs = 40,
/// A fifty second counter window
FiftySecs = 50,
/// A sixty second counter window
SixtySecs = 60,
}
/// A penaltybox that can be used with the edge rate limiter or stand alone for adding and checking if some entry is in the data set.
///
pub struct Penaltybox {
handle: PenaltyboxHandle,
}
impl ERL {
/// Open a ERL with the given ratecounter and penaltybox.
///
pub fn open(ratecounter: RateCounter, penaltybox: Penaltybox) -> Self {
Self {
handle: ERLHandle::open(ratecounter, penaltybox),
}
}
/// Increment an entry in a rate counter and check if the client has exceeded some average number of requests per second (RPS) over the window.
/// If the client is over the rps limit for the window, add to the penaltybox for ttl.
/// Valid ttl span is 1m to 1h and TTL value is truncated to the nearest minute.
///
pub fn check_rate(
&self,
entry: &str,
delta: u32,
window: RateWindow,
limit: u32,
ttl: Duration,
) -> Result<bool, ERLError> {
self.handle.check_rate(entry, delta, window, limit, ttl)
}
}
impl RateCounter {
/// Open a RateCounter with the given name for a ratecounter.
///
pub fn open(ratecounter_name: &str) -> Self {
Self {
handle: RateCounterHandle::open(ratecounter_name),
}
}
/// Increment an entry in the ratecounter by delta.
///
pub fn increment(&self, entry: &str, delta: u32) -> Result<(), ERLError> {
self.handle.increment(entry, delta)
}
/// Lookup the current rate for entry in the ratecounter for a window.
///
pub fn lookup_rate(&self, entry: &str, window: RateWindow) -> Result<u32, ERLError> {
self.handle.lookup_rate(entry, window)
}
/// Lookup the current count for entry in the ratecounter for duration.
///
pub fn lookup_count(&self, entry: &str, duration: CounterDuration) -> Result<u32, ERLError> {
self.handle.lookup_count(entry, duration)
}
}
impl Penaltybox {
/// Open a Penaltybox identified by the given name.
///
pub fn open(penaltybox_name: &str) -> Self {
Self {
handle: PenaltyboxHandle::open(penaltybox_name),
}
}
/// Add entry to a the penaltybox for the duration of ttl.
/// Valid ttl span is 1m to 1h and TTL value is truncated to the nearest minute.
///
pub fn add(&self, entry: &str, ttl: Duration) -> Result<(), ERLError> {
self.handle.add(entry, ttl)
}
/// Check if entry is in the penaltybox.
///
pub fn has(&self, entry: &str) -> Result<bool, ERLError> {
self.handle.has(entry)
}
}