Fix seq_to_transmit incorrectly returning true when a FIN was enqueued.

If there's data queued that doesn't fit into the remote window, we can't
send the FIN either, so seq_to_transmit should return false.
This commit is contained in:
Dario Nieuwenhuis 2020-12-26 03:04:17 +01:00
parent 21deb47bbb
commit 67e03b34b6
1 changed files with 16 additions and 13 deletions

View File

@ -1401,20 +1401,23 @@ impl<'a> TcpSocket<'a> {
}
fn seq_to_transmit(&self) -> bool {
let control;
match self.state {
State::SynSent | State::SynReceived =>
control = TcpControl::Syn,
State::FinWait1 | State::LastAck =>
control = TcpControl::Fin,
_ => control = TcpControl::None
}
// We can send data if we have data that:
// - hasn't been sent before
// - fits in the remote window
let can_data = self.remote_last_seq
< self.local_seq_no + core::cmp::min(self.remote_win_len, self.tx_buffer.len());
self.remote_last_seq <
self.local_seq_no + core::cmp::min(
self.remote_win_len,
self.tx_buffer.len()
) + control.len()
// Do we have to send a FIN?
let want_fin = matches!(self.state, State::FinWait1 | State::LastAck);
// Can we actually send the FIN? We can send it if:
// 1. We have unsent data that fits in the remote window.
// 2. We have no unsent data.
// This condition matches only if #2, because #1 is already covered by can_data and we're ORing them.
let can_fin =
want_fin && self.remote_last_seq == self.local_seq_no + self.tx_buffer.len();
can_data || can_fin
}
fn ack_to_transmit(&self) -> bool {