Do not send window updates in states that shouldn't do so.
Previously, the window update was sent anytime it changed. This is not desirable for 2 reasons: - It would send window updates in TimeWait or Closed states, which is incorrect. - It would send window updates in states where we've already received the remote side's FIN, such as CloseWait. This is not necessarily incorrect, but is useless, since the remote side is not going to send us more data, therefore it's not interested in our window size anymore.v0.7.x
parent
f6a55fa3c7
commit
4cfe8dafdb
|
@ -1417,8 +1417,11 @@ impl<'a> TcpSocket<'a> {
|
|||
}
|
||||
|
||||
fn window_to_update(&self) -> bool {
|
||||
(self.rx_buffer.window() >> self.remote_win_shift) as u16 >
|
||||
self.remote_last_win
|
||||
match self.state {
|
||||
State::SynSent | State::SynReceived | State::Established | State::FinWait1 | State::FinWait2 =>
|
||||
(self.rx_buffer.window() >> self.remote_win_shift) as u16 > self.remote_last_win,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn dispatch<F>(&mut self, timestamp: Instant, caps: &DeviceCapabilities,
|
||||
|
@ -4083,6 +4086,60 @@ mod test {
|
|||
}));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_close_wait_no_window_update() {
|
||||
let mut s = socket_established();
|
||||
send!(s, TcpRepr {
|
||||
control: TcpControl::Fin,
|
||||
seq_number: REMOTE_SEQ + 1,
|
||||
ack_number: Some(LOCAL_SEQ + 1),
|
||||
payload: &[1,2,3,4],
|
||||
..SEND_TEMPL
|
||||
});
|
||||
assert_eq!(s.state, State::CloseWait);
|
||||
|
||||
// we ack the FIN, with the reduced window size.
|
||||
recv!(s, Ok(TcpRepr {
|
||||
seq_number: LOCAL_SEQ + 1,
|
||||
ack_number: Some(REMOTE_SEQ + 6),
|
||||
window_len: 60,
|
||||
..RECV_TEMPL
|
||||
}));
|
||||
|
||||
let rx_buf = &mut [0; 32];
|
||||
assert_eq!(s.recv_slice(rx_buf), Ok(4));
|
||||
|
||||
// check that we do NOT send a window update even if it has changed.
|
||||
recv!(s, Err(Error::Exhausted));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_time_wait_no_window_update() {
|
||||
let mut s = socket_fin_wait_2();
|
||||
send!(s, TcpRepr {
|
||||
control: TcpControl::Fin,
|
||||
seq_number: REMOTE_SEQ + 1,
|
||||
ack_number: Some(LOCAL_SEQ + 2),
|
||||
payload: &[1,2,3,4],
|
||||
..SEND_TEMPL
|
||||
});
|
||||
assert_eq!(s.state, State::TimeWait);
|
||||
|
||||
// we ack the FIN, with the reduced window size.
|
||||
recv!(s, Ok(TcpRepr {
|
||||
seq_number: LOCAL_SEQ + 2,
|
||||
ack_number: Some(REMOTE_SEQ + 6),
|
||||
window_len: 60,
|
||||
..RECV_TEMPL
|
||||
}));
|
||||
|
||||
let rx_buf = &mut [0; 32];
|
||||
assert_eq!(s.recv_slice(rx_buf), Ok(4));
|
||||
|
||||
// check that we do NOT send a window update even if it has changed.
|
||||
recv!(s, Err(Error::Exhausted));
|
||||
}
|
||||
|
||||
// =========================================================================================//
|
||||
// Tests for flow control.
|
||||
// =========================================================================================//
|
||||
|
|
Loading…
Reference in New Issue