-
Notifications
You must be signed in to change notification settings - Fork 429
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(socket/tcp): add congestion controllers
- add CongestionController trait - implement Cubic and NoControl Signed-off-by: Yuuki Takano <[email protected]> feat(socket/tcp): add congestion_controller.rs Signed-off-by: Yuuki Takano <[email protected]> feat(cubic): add test for TCP Cubic Signed-off-by: Yuuki Takano <[email protected]> feat(cubic): do not update congestion as much as possible If the last update time of the cwnd was less than 100ms ago, don't update the congestion window. Signed-off-by: Yuuki Takano <[email protected]> feat(cubic): implement slow start for TCP Cubic Signed-off-by: Yuuki Takano <[email protected]> fix(cubic): use MSS as the minimum cwnd Signed-off-by: Yuuki Takano <[email protected]> feat(tcp): add "socket-tcp-cubic" and "socket-tcp-reno" features - "socket-tcp-cubic": use Cubic as a default congestion controller - "socket-tcp-reno": use Reno as a default congestion controller Signed-off-by: Yuuki Takano <[email protected]> fix(tcp): prepare new() for Socket<'a, DefaultCC> All tests are passed because of this fix. $ cargo test $ cargo test --features socket-tcp-cubic Signed-off-by: Yuuki Takano <[email protected]> feat(tcp, reno): add Reno of a congestion controller Signed-off-by: Yuuki Takano <[email protected]> feat(cubic): do not use cbrt() and powi() for no_std Signed-off-by: Yuuki Takano <[email protected]> fix(tcp): update for coverage test Signed-off-by: Yuuki Takano <[email protected]> fix(cubic): do not use `abs()` for no_std Signed-off-by: Yuuki Takano <[email protected]> fix(tcp): make some types regading congestion control private Signed-off-by: Yuuki Takano <[email protected]> fix(tcp): make `CongestionController` `pub(super)` Signed-off-by: Yuuki Takano <[email protected]> fix(tcp): make modules of congestion controllers private - `cubic`, `reno` and `no_control` modules are now private. - `ActiveCC` is now `pub(super)` Signed-off-by: Yuuki Takano <[email protected]> fix: typo Signed-off-by: Yuuki Takano <[email protected]> fix(tcp): use `defmt::Format` if `defmt` feature is specified Signed-off-by: Yuuki Takano <[email protected]> fix(tcp): introduce `GenericController` for congestion control Remove `socket-tcp-cubic` and `socket-tcp-reno` features for congestion control. Instead of the features, `set_congestion_control()` is defined to set an algorithm of congestion control. Signed-off-by: Yuuki Takano <[email protected]> feat(tcp): add a test for `(set|get)_congestion_control()` Signed-off-by: Yuuki Takano <[email protected]> fix: restore unessesory change Signed-off-by: Yuuki Takano <[email protected]> fix(tcp): rename congestion_controller to congestion Signed-off-by: Yuuki Takano <[email protected]> fix(tcp): update the document about `Cubic` Signed-off-by: Yuuki Takano <[email protected]> fix(tcp): do not use `Default` trait for congestion controller Because `Default` trait requires `Size`, returning `&dyn Trait` is rejected by the Rust compiler. Signed-off-by: Yuuki Takano <[email protected]> chore(tcp): `#[allow(unused_variables)]` is moved on the trait Signed-off-by: Yuuki Takano <[email protected]> feat(tcp): add `socket-tcp-cubic` feature for Cubic Cubic uses f64 and it is inefficient on some platforms like STM32. So, Cubic is disabled by default. Signed-off-by: Yuuki Takano <[email protected]> fix: typo Signed-off-by: Yuuki Takano <[email protected]> Update src/socket/tcp.rs Co-authored-by: Catherine <[email protected]> feat(tcp): add `socket-tcp-reno` feature for Reno Signed-off-by: Yuuki Takano <[email protected]> feat(tcp): use GenericController::inner_*() methods Signed-off-by: Yuuki Takano <[email protected]> fix(tcp): choose the best congestion controller If Cubic is enabled, it is used as a default controller. If Reno is enabled, it is used as a default controller. If Cubic and Reno are eanabled, Cubic is a default controlerr, but it can be specified by `set_congestion_control()` method. Signed-off-by: Yuuki Takano <[email protected]> fix(tcp): rename CongestionController to Controller Signed-off-by: Yuuki Takano <[email protected]> fix(tcp): rename GenericController to AnyController Signed-off-by: Yuuki Takano <[email protected]> fix(tcp): add a document to `AnyController::new()` Signed-off-by: Yuuki Takano <[email protected]> fix(tcp): use Controller instead of CongestionController CongestionController has been renamed. Signed-off-by: Yuuki Takano <[email protected]>
- Loading branch information
Showing
7 changed files
with
693 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
use crate::time::Instant; | ||
|
||
use super::RttEstimator; | ||
|
||
pub(super) mod no_control; | ||
|
||
#[cfg(feature = "socket-tcp-cubic")] | ||
pub(super) mod cubic; | ||
|
||
#[cfg(feature = "socket-tcp-reno")] | ||
pub(super) mod reno; | ||
|
||
#[allow(unused_variables)] | ||
pub(super) trait Controller { | ||
/// Returns the number of bytes that can be sent. | ||
fn window(&self) -> usize; | ||
|
||
/// Set the remote window size. | ||
fn set_remote_window(&mut self, remote_window: usize) {} | ||
|
||
fn on_ack(&mut self, now: Instant, len: usize, rtt: &RttEstimator) {} | ||
|
||
fn on_retransmit(&mut self, now: Instant) {} | ||
|
||
fn on_duplicate_ack(&mut self, now: Instant) {} | ||
|
||
fn pre_transmit(&mut self, now: Instant) {} | ||
|
||
fn post_transmit(&mut self, now: Instant, len: usize) {} | ||
|
||
/// Set the maximum segment size. | ||
fn set_mss(&mut self, mss: usize) {} | ||
} | ||
|
||
#[derive(Debug)] | ||
#[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
pub(super) enum AnyController { | ||
None(no_control::NoControl), | ||
|
||
#[cfg(feature = "socket-tcp-reno")] | ||
Reno(reno::Reno), | ||
|
||
#[cfg(feature = "socket-tcp-cubic")] | ||
Cubic(cubic::Cubic), | ||
} | ||
|
||
impl AnyController { | ||
/// Create a new congestion controller. | ||
/// `AnyController::new()` selects the best congestion controller based on the features. | ||
/// | ||
/// - If `socket-tcp-cubic` feature is enabled, it will use `Cubic`. | ||
/// - If `socket-tcp-reno` feature is enabled, it will use `Reno`. | ||
/// - If both `socket-tcp-cubic` and `socket-tcp-reno` features are enabled, it will use `Cubic`. | ||
/// - `Cubic` is more efficient regarding throughput. | ||
/// - `Reno` is more conservative and is suitable for low-power devices. | ||
/// - If no congestion controller is available, it will use `NoControl`. | ||
/// | ||
/// Users can also select a congestion controller manually by [`super::Socket::set_congestion_control()`] | ||
/// method at run-time. | ||
#[allow(unreachable_code)] | ||
#[inline] | ||
pub fn new() -> Self { | ||
#[cfg(feature = "socket-tcp-cubic")] | ||
{ | ||
return AnyController::Cubic(cubic::Cubic::new()); | ||
} | ||
|
||
#[cfg(feature = "socket-tcp-reno")] | ||
{ | ||
return AnyController::Reno(reno::Reno::new()); | ||
} | ||
|
||
AnyController::None(no_control::NoControl) | ||
} | ||
|
||
#[inline] | ||
pub fn inner_mut(&mut self) -> &mut dyn Controller { | ||
match self { | ||
AnyController::None(n) => n, | ||
|
||
#[cfg(feature = "socket-tcp-reno")] | ||
AnyController::Reno(r) => r, | ||
|
||
#[cfg(feature = "socket-tcp-cubic")] | ||
AnyController::Cubic(c) => c, | ||
} | ||
} | ||
|
||
#[inline] | ||
pub fn inner(&self) -> &dyn Controller { | ||
match self { | ||
AnyController::None(n) => n, | ||
|
||
#[cfg(feature = "socket-tcp-reno")] | ||
AnyController::Reno(r) => r, | ||
|
||
#[cfg(feature = "socket-tcp-cubic")] | ||
AnyController::Cubic(c) => c, | ||
} | ||
} | ||
} |
Oops, something went wrong.