Skip to content

Commit

Permalink
[inetstack] Bug Fix: Implement MSL
Browse files Browse the repository at this point in the history
  • Loading branch information
iyzhang committed May 8, 2024
1 parent b7ee223 commit 0ec985e
Show file tree
Hide file tree
Showing 6 changed files with 23 additions and 15 deletions.
1 change: 1 addition & 0 deletions src/rust/inetstack/protocols/tcp/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ pub use crate::runtime::network::consts::{
MAX_MSS,
MAX_WINDOW_SCALE,
MIN_MSS,
MSL,
};
20 changes: 9 additions & 11 deletions src/rust/inetstack/protocols/tcp/established/ctrlblk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use crate::{
ip::IpProtocol,
ipv4::Ipv4Header,
tcp::{
constants::MSL,
established::{
congestion_control::{
self,
Expand All @@ -49,6 +50,7 @@ use crate::{
types::MacAddress,
NetworkRuntime,
},
yield_with_timeout,
SharedDemiRuntime,
SharedObject,
},
Expand Down Expand Up @@ -1125,10 +1127,10 @@ impl<N: NetworkRuntime> SharedControlBlock<N> {
}

// This coroutine runs the close protocol.
pub async fn close(&mut self) -> Result<(), Fail> {
pub async fn close(&mut self, linger: Option<Duration>) -> Result<(), Fail> {
// Assert we are in a valid state and move to new state.
match self.state {
State::Established => self.local_close().await,
State::Established => self.local_close(linger).await,
State::CloseWait => self.remote_already_closed().await,
_ => {
let cause: String = format!("socket is already closing");
Expand All @@ -1138,12 +1140,13 @@ impl<N: NetworkRuntime> SharedControlBlock<N> {
}
}

async fn local_close(&mut self) -> Result<(), Fail> {
async fn local_close(&mut self, linger: Option<Duration>) -> Result<(), Fail> {
// 0. Set state.
self.state = State::FinWait1;
// 1. Send FIN.
self.send_fin();

// 2. TIME_WAIT
while self.state != State::TimeWait {
// Wait for next packet.
let (_, header, _) = self.recv_queue.pop(None).await?;
Expand Down Expand Up @@ -1178,14 +1181,9 @@ impl<N: NetworkRuntime> SharedControlBlock<N> {
}
}

// TODO: Get 2MSL value or linger option if set.
// TODO: Turn this on when our tests support it.
// let timeout_yielder: Yielder = Yielder::new();
// self.runtime
// .get_timer()
// .wait(Duration::from_secs(1), &timeout_yielder)
// .await?;

// 3. TIMED_WAIT
let timeout: Duration = linger.unwrap_or(MSL * 2);
yield_with_timeout(timeout).await;
self.state = State::Closed;
Ok(())
}
Expand Down
4 changes: 2 additions & 2 deletions src/rust/inetstack/protocols/tcp/established/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,8 @@ impl<N: NetworkRuntime> EstablishedSocket<N> {
self.cb.pop(size).await
}

pub async fn close(&mut self) -> Result<(), Fail> {
self.cb.close().await
pub async fn close(&mut self, linger: Option<Duration>) -> Result<(), Fail> {
self.cb.close(linger).await
}

pub fn remote_mss(&self) -> usize {
Expand Down
4 changes: 3 additions & 1 deletion src/rust/inetstack/protocols/tcp/socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,10 +245,12 @@ impl<N: NetworkRuntime> SharedTcpSocket<N> {
}

pub async fn close(&mut self) -> Result<Option<SocketId>, Fail> {
let linger: Option<Duration> = self.tcp_options.get_linger();

match self.state {
// Closing an active socket.
SocketState::Established(ref mut socket) => {
socket.close().await?;
socket.close(linger).await?;
Ok(Some(SocketId::Active(socket.endpoints().0, socket.endpoints().1)))
},
// Closing a listening socket.
Expand Down
4 changes: 4 additions & 0 deletions src/rust/runtime/network/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ pub const MIN_MSS: usize = FALLBACK_MSS;
/// Maximum MSS Parameter for TCP
pub const MAX_MSS: usize = u16::max_value() as usize;

/// Maximum Segment Lifetime
/// See: https://www.rfc-editor.org/rfc/rfc793.txt
pub const MSL: Duration = Duration::from_secs(2);

/// Delay timeout for TCP ACKs.
/// See: https://www.rfc-editor.org/rfc/rfc5681#section-4.2
pub const TCP_ACK_DELAY_TIMEOUT: Duration = Duration::from_millis(500);
Expand Down
5 changes: 4 additions & 1 deletion src/rust/runtime/network/socket/option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ impl TcpSocketOptions {

impl Default for TcpSocketOptions {
fn default() -> Self {
Self { linger: None }
Self {
// Setting this to zero by default.
linger: Some(Duration::ZERO),
}
}
}

0 comments on commit 0ec985e

Please sign in to comment.