Skip to content

Commit 44db3a8

Browse files
EwecaBcDBobAnkh
andauthored
feat(cell): add token bucket cell (#96)
Resolves: #85 Co-authored-by: BobAnkh <[email protected]>
1 parent ce0384a commit 44db3a8

File tree

10 files changed

+1440
-0
lines changed

10 files changed

+1440
-0
lines changed

config.example.toml

+26
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,32 @@ interface_id = 1
279279
prefix = "10.2.0.0/16"
280280
# no interface_id, meaning drop
281281

282+
# Token Bucket Cell Example
283+
[cells.token_bucket]
284+
type = "TokenBucket"
285+
286+
# Token Bucket configuration
287+
# We have 5 fields for TokenBucket:
288+
# "limit" : Size of the queue of TokenBucket cell in bytes.
289+
# Default: Unlimited
290+
limit = 1024
291+
292+
# "burst" : Size of the bucket in bytes.
293+
# Default: Unlimited
294+
burst = "5KB"
295+
296+
# "rate" : The rate limit of the bucket in bytes per second.
297+
# Default: Unlimited
298+
rate = "500Kbps"
299+
300+
# - "minburst" : Specifies the size of the peakrate bucket.
301+
# Default: Unlimited
302+
minburst = "1540B"
303+
304+
# - "peakrate" : Maximum depletion rate of the bucket.
305+
# Default: Unlimited
306+
peakrate = "1Mbps"
307+
282308
# ----- Cells Section End -----
283309

284310

rattan-core/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ async-trait = "0.1.68"
1313
axum = { version = "0.7.5", optional = true }
1414
backon = "1.2.0"
1515
bandwidth = "0.3.0"
16+
bytesize = "1.3.0"
1617
figment = { workspace = true }
1718
camellia = { git = "https://github.com/minhuw/camellia.git", optional = true }
1819
etherparse = "0.16.0"
@@ -74,6 +75,7 @@ serde = [
7475
"dep:serde",
7576
"dep:serde_json",
7677
"bandwidth/serde",
78+
"bytesize/serde",
7779
]
7880
camellia = ["dep:camellia"]
7981

rattan-core/src/cells/bandwidth/queue.rs

+99
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,19 @@ where
2828

2929
// If the queue is empty, return `None`
3030
fn dequeue(&mut self) -> Option<P>;
31+
32+
fn is_empty(&self) -> bool;
33+
34+
// If the queue is empty, return `None`
35+
fn get_front_size(&self) -> Option<usize>;
36+
37+
fn length(&self) -> usize;
38+
39+
fn retain<F>(&mut self, _f: F)
40+
where
41+
F: FnMut(&P) -> bool,
42+
{
43+
}
3144
}
3245

3346
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
@@ -81,6 +94,25 @@ where
8194
fn dequeue(&mut self) -> Option<P> {
8295
self.queue.pop_front()
8396
}
97+
98+
fn is_empty(&self) -> bool {
99+
self.queue.is_empty()
100+
}
101+
102+
fn get_front_size(&self) -> Option<usize> {
103+
self.queue.front().map(|packet| packet.l3_length())
104+
}
105+
106+
fn length(&self) -> usize {
107+
self.queue.len()
108+
}
109+
110+
fn retain<F>(&mut self, mut f: F)
111+
where
112+
F: FnMut(&P) -> bool,
113+
{
114+
self.queue.retain(|packet| f(packet));
115+
}
84116
}
85117

86118
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
@@ -137,6 +169,10 @@ impl<P> DropTailQueue<P> {
137169
now_bytes: 0,
138170
}
139171
}
172+
173+
pub fn get_extra_length(&self) -> usize {
174+
self.bw_type.extra_length()
175+
}
140176
}
141177

142178
impl<P> Default for DropTailQueue<P> {
@@ -186,6 +222,27 @@ where
186222
None => None,
187223
}
188224
}
225+
226+
fn is_empty(&self) -> bool {
227+
self.queue.is_empty()
228+
}
229+
230+
fn get_front_size(&self) -> Option<usize> {
231+
self.queue
232+
.front()
233+
.map(|packet| packet.l3_length() + self.bw_type.extra_length())
234+
}
235+
236+
fn length(&self) -> usize {
237+
self.queue.len()
238+
}
239+
240+
fn retain<F>(&mut self, mut f: F)
241+
where
242+
F: FnMut(&P) -> bool,
243+
{
244+
self.queue.retain(|packet| f(packet));
245+
}
189246
}
190247

191248
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
@@ -291,6 +348,27 @@ where
291348
None => None,
292349
}
293350
}
351+
352+
fn is_empty(&self) -> bool {
353+
self.queue.is_empty()
354+
}
355+
356+
fn get_front_size(&self) -> Option<usize> {
357+
self.queue
358+
.front()
359+
.map(|packet| packet.l3_length() + self.bw_type.extra_length())
360+
}
361+
362+
fn length(&self) -> usize {
363+
self.queue.len()
364+
}
365+
366+
fn retain<F>(&mut self, mut f: F)
367+
where
368+
F: FnMut(&P) -> bool,
369+
{
370+
self.queue.retain(|packet| f(packet));
371+
}
294372
}
295373

296374
// CoDel Queue Implementation Reference:
@@ -558,4 +636,25 @@ where
558636
}
559637
}
560638
}
639+
640+
fn is_empty(&self) -> bool {
641+
self.queue.is_empty()
642+
}
643+
644+
fn get_front_size(&self) -> Option<usize> {
645+
self.queue
646+
.front()
647+
.map(|packet| packet.l3_length() + self.config.bw_type.extra_length())
648+
}
649+
650+
fn length(&self) -> usize {
651+
self.queue.len()
652+
}
653+
654+
fn retain<F>(&mut self, mut f: F)
655+
where
656+
F: FnMut(&P) -> bool,
657+
{
658+
self.queue.retain(|packet| f(packet));
659+
}
561660
}

rattan-core/src/cells/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ pub mod external;
1313
pub mod loss;
1414
pub mod router;
1515
pub mod shadow;
16+
pub mod token_bucket;
1617

1718
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1819
#[derive(Debug, Clone, Hash, Eq, PartialEq)]

0 commit comments

Comments
 (0)