#rate-limiting #limit #dos #fair #throttle

fair-rate-limiter

Detect overload and fairly shed load from diverse IPs, subnets, users, or systems. Mitigate denial-of-service (DoS) attacks.

1 unstable release

0.1.0 May 3, 2022

#2 in #fair

Apache-2.0

23KB
296 lines

fair-rate-limiter

crates.io version license: Apache 2.0 unsafe forbidden pipeline status

Use RateLimiter struct to detect overload and fairly shed load from diverse IP addresses, users, or systems. Mitigate denial-of-service (DoS) attacks.

Use Cases

  • DNS server: DNS servers must send UDP replies without a handshake. Your DNS server could be used in a DNS amplification attacks. Use this crate to prevent that.
  • Server without handshake: If your server sends large responses without a handshake, it could be used in an amplification attack. Use this crate to prevent that.
  • Load balancer: Use this crate in a load balancer to avoid forwarding DoS attacks to backend systems.
  • API server: Shed load from misbehaving clients and keep the API available for other clients.

Features

  • Global throughput limit
  • IPv4 & IPv6
  • forbid(unsafe_code), depends only on crates that are forbid(unsafe_code)
  • 83% test coverage
  • Optimized. Performance on an i5-8259U:
    • Internal service tracking 10 clients: 150ns per check, 7M checks per second
    • Public service tracking 1M clients: 500ns per check, 2M checks per second
    • DDoS mitigation tracking 30M clients: 750ns per check, 1.3M checks per second

Limitations

Alternatives

  • governor
    • Popular
    • Lots of features
    • Good docs
    • Unnecessary unsafe
    • Uses non-standard mutex library parking_lot
  • r8limit
    • Supports a single bucket. Usable for unfair load shedding.
    • No unsafe or deps
  • leaky-bucket
    • Async tasks can wait for their turn to use a resource.
    • Unsuitable for load shedding.

Related Crates

Example

let mut limiter = new_fair_ip_address_rate_limiter(10.0).unwrap();
let mut now = Instant::now();
let key = IpAddrKey::from(Ipv4Addr::new(10,0,0,1));
assert!(limiter.check(key, 4, now));
assert!(limiter.check(key, 4, now));
now += Duration::from_secs(1);
assert!(limiter.check(key, 4, now));
assert!(limiter.check(key, 4, now));
now += Duration::from_secs(1);
assert!(limiter.check(key, 4, now));
assert!(limiter.check(key, 4, now));
now += Duration::from_secs(1);
assert!(limiter.check(key, 4, now));
assert!(limiter.check(key, 4, now));
assert!(!limiter.check(key, 4, now));

Cargo Geiger Safety Report


Metric output format: x/y
    x = unsafe code used by the build
    y = total unsafe code found in the crate

Symbols: 
    🔒  = No `unsafe` usage found, declares #![forbid(unsafe_code)]= No `unsafe` usage found, missing #![forbid(unsafe_code)]
    ☢️  = `unsafe` usage found

Functions  Expressions  Impls  Traits  Methods  Dependency

0/0        0/0          0/0    0/0     0/0      🔒  fair-rate-limiter 0.1.0
0/0        0/0          0/0    0/0     0/0      🔒  └── oorandom 11.1.3

0/0        0/0          0/0    0/0     0/0    

Changelog

  • v0.1.0 - Initial version

TO DO

  • Compare performance with governor
  • Publish
  • Simulate bursty traffic
  • Measure memory consumption, add to Limitations section
  • Replace hash table with skip list and see if performance improves
  • Support concurrent use
  • Allow tracked sources to use unused untracked throughput allocation

License: Apache-2.0

Dependencies

~32KB