Skip to content

Commit 544d7ca

Browse files
committed
fix random seeding and add a test to cover it with seeded rng
1 parent 5368fd8 commit 544d7ca

File tree

1 file changed

+30
-11
lines changed
  • quinn-proto/src/congestion/bbr3

1 file changed

+30
-11
lines changed

quinn-proto/src/congestion/bbr3/mod.rs

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -218,8 +218,8 @@ pub struct Bbr3 {
218218
/// equivalent to BBR.DefaultCwndGain: A constant specifying the minimum gain value that allows the sending rate to double each round (2) [BBRStartupCwndGain].
219219
/// Used by default in most phases for BBR.cwnd_gain.
220220
default_cwnd_gain: f64,
221-
/// used to seed the rng needed when deciding how long to wait before probing again
222-
probe_rng_seed: Option<u64>,
221+
/// used to generate random numbers when deciding how long to wait before probing again
222+
probe_rng: Pcg32,
223223
/// cwnd gain used when probing up <https://www.ietf.org/archive/id/draft-ietf-ccwg-bbr-04.html#section-5.6.1>
224224
probe_up_cwnd_gain: f64,
225225
/// cwnd gain used when probing RTT <https://www.ietf.org/archive/id/draft-ietf-ccwg-bbr-04.html#section-5.6.1>
@@ -359,6 +359,12 @@ pub struct Bbr3 {
359359

360360
impl Bbr3 {
361361
fn new(config: Arc<Bbr3Config>, current_mtu: u16) -> Self {
362+
let probe_rng: Pcg32;
363+
if let Some(probe_seed) = config.probe_rng_seed {
364+
probe_rng = Pcg32::seed_from_u64(probe_seed);
365+
} else {
366+
probe_rng = Pcg32::from_os_rng();
367+
}
362368
// rfc9000 making sure maximum datagram size is between acceptable values
363369
// default values come from: https://www.ietf.org/archive/id/draft-ietf-ccwg-bbr-04.txt
364370
let smss = min(
@@ -386,7 +392,7 @@ impl Bbr3 {
386392
pacing_margin_percent: 1.0,
387393
cwnd_gain: 2.0,
388394
default_cwnd_gain: 2.0,
389-
probe_rng_seed: config.probe_rng_seed,
395+
probe_rng,
390396
probe_up_cwnd_gain: 2.25,
391397
state: BbrState::Startup,
392398
round_count: 0,
@@ -556,15 +562,9 @@ impl Bbr3 {
556562
}
557563

558564
fn pick_probe_wait(&mut self) {
559-
let mut rng: Pcg32;
560-
if let Some(probe_seed) = self.probe_rng_seed {
561-
rng = Pcg32::seed_from_u64(probe_seed);
562-
} else {
563-
rng = Pcg32::from_os_rng();
564-
}
565565
// 0 or 1
566-
self.rounds_since_bw_probe = rng.random_bool(0.5) as u64;
567-
self.bw_probe_wait = Duration::from_millis(2000 + rng.random_range(0..=1000));
566+
self.rounds_since_bw_probe = self.probe_rng.random_bool(0.5) as u64;
567+
self.bw_probe_wait = Duration::from_millis(2000 + self.probe_rng.random_range(0..=1000));
568568
}
569569

570570
fn has_elapsed_in_phase(&mut self, interval: Duration, now: Instant) -> bool {
@@ -1442,3 +1442,22 @@ impl ControllerFactory for Bbr3Config {
14421442
Box::new(Bbr3::new(self, current_mtu))
14431443
}
14441444
}
1445+
1446+
#[cfg(test)]
1447+
mod test {
1448+
use super::*;
1449+
1450+
#[test]
1451+
fn test_probe_rng() {
1452+
let seed: u64 = 123456789;
1453+
let mut config = Bbr3Config::default();
1454+
config.probe_rng_seed = Some(seed);
1455+
let mut bbr3 = Bbr3::new(Arc::new(config), 2500);
1456+
bbr3.pick_probe_wait();
1457+
assert_eq!(bbr3.rounds_since_bw_probe, 1);
1458+
assert_eq!(bbr3.bw_probe_wait, Duration::from_millis(2949));
1459+
bbr3.pick_probe_wait();
1460+
assert_eq!(bbr3.rounds_since_bw_probe, 1);
1461+
assert_eq!(bbr3.bw_probe_wait, Duration::from_millis(2590));
1462+
}
1463+
}

0 commit comments

Comments
 (0)