TCP: retransmit ACK when receiving duplicate SEQ.
This commit is contained in:
parent
64a8c36118
commit
818e98f47a
|
@ -122,7 +122,7 @@ impl<T: Device> Device for FaultInjector<T>
|
|||
fn transmit(&mut self, length: usize) -> Result<Self::TxBuffer, Error> {
|
||||
let buffer;
|
||||
if check_rng(&mut self.state, self.config.drop_pct) {
|
||||
net_trace!("rx: dropping a packet");
|
||||
net_trace!("tx: dropping a packet");
|
||||
buffer = None;
|
||||
} else {
|
||||
buffer = Some(try!(self.lower.transmit(length)));
|
||||
|
|
|
@ -542,6 +542,9 @@ impl<'a> TcpSocket<'a> {
|
|||
net_trace!("tcp:{}:{}: duplicate SEQ ({} in ..{})",
|
||||
self.local_endpoint, self.remote_endpoint,
|
||||
seq_number, next_remote_seq);
|
||||
// If we've seen this sequence number already but the remote end is not aware
|
||||
// of that, make sure we send the acknowledgement again.
|
||||
self.remote_last_ack = next_remote_seq - 1;
|
||||
return Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -1656,4 +1659,42 @@ mod test {
|
|||
assert_eq!(s.state, State::TimeWait);
|
||||
recv!(s, []);
|
||||
}
|
||||
|
||||
// =========================================================================================//
|
||||
// Tests for retransmission on packet loss.
|
||||
// =========================================================================================//
|
||||
fn socket_recved() -> TcpSocket<'static> {
|
||||
let mut s = socket_established();
|
||||
send!(s, [TcpRepr {
|
||||
seq_number: REMOTE_SEQ + 1,
|
||||
ack_number: Some(LOCAL_SEQ + 1),
|
||||
payload: &b"abcdef"[..],
|
||||
..SEND_TEMPL
|
||||
}]);
|
||||
recv!(s, [TcpRepr {
|
||||
seq_number: LOCAL_SEQ + 1,
|
||||
ack_number: Some(REMOTE_SEQ + 1 + 6),
|
||||
window_len: 58,
|
||||
..RECV_TEMPL
|
||||
}]);
|
||||
s
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_duplicate_seq_ack() {
|
||||
let mut s = socket_recved();
|
||||
// remote retransmission
|
||||
send!(s, [TcpRepr {
|
||||
seq_number: REMOTE_SEQ + 1,
|
||||
ack_number: Some(LOCAL_SEQ + 1),
|
||||
payload: &b"abcdef"[..],
|
||||
..SEND_TEMPL
|
||||
}]);
|
||||
recv!(s, [TcpRepr {
|
||||
seq_number: LOCAL_SEQ + 1,
|
||||
ack_number: Some(REMOTE_SEQ + 1 + 6),
|
||||
window_len: 58,
|
||||
..RECV_TEMPL
|
||||
}]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,17 @@ impl ops::Add<usize> for SeqNumber {
|
|||
}
|
||||
}
|
||||
|
||||
impl ops::Sub<usize> for SeqNumber {
|
||||
type Output = SeqNumber;
|
||||
|
||||
fn sub(self, rhs: usize) -> SeqNumber {
|
||||
if rhs > i32::MAX as usize {
|
||||
panic!("attempt to subtract to sequence number with unsigned overflow")
|
||||
}
|
||||
SeqNumber(self.0.wrapping_sub(rhs as i32))
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::AddAssign<usize> for SeqNumber {
|
||||
fn add_assign(&mut self, rhs: usize) {
|
||||
*self = *self + rhs;
|
||||
|
|
Loading…
Reference in New Issue