A pit full of rusty nails
1use std::time::Duration;
2
3use nailconfig::{DropBehavior, RateLimitingConfig};
4
5use crate::PeerState;
6
7#[derive(Debug, Clone, PartialEq, Eq)]
8pub enum LimitModes {
9 None,
10 Soft {
11 limit: u64,
12 delay: u64,
13 },
14 Hard {
15 limit: u64,
16 spicy: bool,
17 },
18 SoftHard {
19 soft_limit: u64,
20 hard_limit: u64,
21 delay: u64,
22 spicy: bool,
23 },
24}
25
26impl LimitModes {
27 pub(crate) fn limit(&self, visits: &u64) -> PeerState {
28 match *self {
29 LimitModes::Soft { limit, delay } if (limit..).contains(visits) => {
30 PeerState::Delay(Duration::from_millis(delay))
31 }
32 LimitModes::Hard { limit, spicy } if (limit..).contains(visits) => {
33 if spicy {
34 PeerState::SpicyDrop
35 } else {
36 PeerState::Drop
37 }
38 }
39 LimitModes::SoftHard {
40 soft_limit,
41 hard_limit,
42 delay,
43 ..
44 } if (soft_limit..hard_limit).contains(visits) => {
45 PeerState::Delay(Duration::from_millis(delay))
46 }
47 LimitModes::SoftHard {
48 hard_limit, spicy, ..
49 } if (hard_limit..).contains(visits) => {
50 if spicy {
51 PeerState::SpicyDrop
52 } else {
53 PeerState::Drop
54 }
55 }
56 _ => PeerState::Ready,
57 }
58 }
59}
60
61impl From<&RateLimitingConfig> for LimitModes {
62 #[inline]
63 fn from(value: &RateLimitingConfig) -> Self {
64 match value {
65 RateLimitingConfig::NoLimit => Self::None,
66 &RateLimitingConfig::SoftLimit {
67 soft_limit: limit,
68 soft_delay: delay,
69 } => Self::Soft { limit, delay },
70 RateLimitingConfig::HardLimit {
71 hard_limit: limit,
72 drop_behavior,
73 } => Self::Hard {
74 limit: *limit,
75 spicy: matches!(drop_behavior, DropBehavior::Spicy { .. }),
76 },
77 RateLimitingConfig::SoftWithHardLimit {
78 soft_limit,
79 hard_limit,
80 soft_delay: delay,
81 drop_behavior,
82 } => Self::SoftHard {
83 soft_limit: *soft_limit,
84 hard_limit: *hard_limit,
85 delay: *delay,
86 spicy: matches!(drop_behavior, DropBehavior::Spicy { .. }),
87 },
88 }
89 }
90}