Skip to content

Commit

Permalink
Merge pull request #1465 from microsoft/ab-tcp-handle-rst-packet
Browse files Browse the repository at this point in the history
[inetstack] Handle RST packet from peer endpoint
  • Loading branch information
anandbonde authored Nov 25, 2024
2 parents 38b7fdf + 5cd112f commit d866a2a
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 16 deletions.
3 changes: 1 addition & 2 deletions src/rust/inetstack/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,15 +88,14 @@ impl SharedInetStack {
runtime: runtime.clone(),
layer4_endpoint,
}));
runtime.insert_background_coroutine("bgc::inetstack::poll_recv", Box::pin(me.clone().poll().fuse()))?;
runtime.insert_background_coroutine("bgc::inetstack::poll", Box::pin(me.clone().poll().fuse()))?;
Ok(me)
}

/// Scheduler will poll all futures that are ready to make progress.
/// Then ask the runtime to receive new data which we will forward to the engine to parse and
/// route to the correct protocol.
pub async fn poll(mut self) {
timer!("inetstack::poll");
loop {
for _ in 0..MAX_RECV_ITERS {
self.layer4_endpoint.poll_once();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,11 @@ impl SharedControlBlock {
pub fn get_state(&self) -> State {
self.state
}

pub fn set_state(&mut self, state: State) {
self.state = state;
}

// This coroutine runs the close protocol.
pub async fn close(&mut self) -> Result<(), Fail> {
// Assert we are in a valid state and move to new state.
Expand Down
24 changes: 10 additions & 14 deletions src/rust/inetstack/protocols/layer4/tcp/established/receiver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ impl Receiver {
&mut seg_len,
&mut cb,
)?;
self.check_rst(&header)?;
self.check_and_process_rst(&header, &mut cb)?;
self.check_syn(&header)?;
self.process_ack(&header, &mut cb, now)?;

Expand Down Expand Up @@ -374,20 +374,16 @@ impl Receiver {
Ok(())
}

// Check the RST bit.
fn check_rst(&mut self, header: &TcpHeader) -> Result<(), Fail> {
if header.rst {
// TODO: RFC 5961 "Blind Reset Attack Using the RST Bit" prevention would have us ACK and drop if the new
// segment doesn't start precisely on RCV.NXT.

// Our peer has given up. Shut the connection down hard.
info!("Received RST");
// TODO: Schedule a close coroutine.
let cause: String = format!("remote reset connection");
info!("check_rst(): {}", cause);
return Err(Fail::new(libc::ECONNRESET, &cause));
// TODO: RFC 5961 "Blind Reset Attack Using the RST Bit" prevention would have us ACK and drop if the new segment
// doesn't start precisely on RCV.NXT.
fn check_and_process_rst(&mut self, header: &TcpHeader, cb: &mut SharedControlBlock) -> Result<(), Fail> {
if !header.rst {
return Ok(());
}
Ok(())
info!("Received RST: remote reset connection");
cb.set_state(State::Closed);
self.push_fin();
return Err(Fail::new(libc::ECONNRESET, "remote reset connection"));
}

// Check the SYN bit.
Expand Down

0 comments on commit d866a2a

Please sign in to comment.