Send a TCP ACK after window increases from zero to non-zero.

This commit is contained in:
whitequark 2017-08-30 23:09:31 +00:00
parent 6324d3384a
commit 5e48567297
1 changed files with 31 additions and 0 deletions

View File

@ -624,6 +624,12 @@ impl<'a> TcpSocket<'a> {
// another (stale) SYN.
if !self.may_recv() { return Err(Error::Illegal) }
// If we advertised a zero window, make sure to send an ACK so that the peer
// can resume sending data.
if self.rx_buffer.window() == 0 {
self.remote_last_ack = None;
}
#[cfg(any(test, feature = "verbose"))]
let old_length = self.rx_buffer.len();
let buffer = self.rx_buffer.dequeue(size);
@ -2962,4 +2968,29 @@ mod test {
..RECV_TEMPL
})));
}
#[test]
fn test_zero_window_ack_on_window_growth() {
let mut s = socket_established();
s.rx_buffer = SocketBuffer::new(vec![0; 6]);
send!(s, TcpRepr {
seq_number: REMOTE_SEQ + 1,
ack_number: Some(LOCAL_SEQ + 1),
payload: &b"abcdef"[..],
..SEND_TEMPL
}, Ok(Some(TcpRepr {
seq_number: LOCAL_SEQ + 1,
ack_number: Some(REMOTE_SEQ + 1 + 6),
window_len: 0,
..RECV_TEMPL
})));
recv!(s, time 0, Err(Error::Exhausted));
assert_eq!(s.recv(6), Ok(&b"abcdef"[..]));
recv!(s, time 0, Ok(TcpRepr {
seq_number: LOCAL_SEQ + 1,
ack_number: Some(REMOTE_SEQ + 1 + 6),
window_len: 6,
..RECV_TEMPL
}));
}
}