Do not try to retransmit SYN as if it was in data stream.

This commit is contained in:
whitequark 2017-01-14 11:22:19 +00:00
parent 62883a6e0b
commit a864157feb
1 changed files with 61 additions and 9 deletions

View File

@ -760,9 +760,13 @@ impl<'a> TcpSocket<'a> {
}; };
if self.retransmit.may_send_old(timestamp) { if self.retransmit.may_send_old(timestamp) {
// The retransmit timer has expired, so assume all in-flight packets that // The retransmit timer has expired, so assume all in-flight data that
// have not been acknowledged are lost. // has not been acknowledged is lost.
self.remote_last_seq = self.local_seq_no; match self.state {
// Retransmission of SYN is handled elsewhere.
State::SynReceived => (),
_ => self.remote_last_seq = self.local_seq_no
}
} else if self.retransmit.may_send_new(timestamp) { } else if self.retransmit.may_send_new(timestamp) {
// The retransmit timer has reset, and we can send something new. // The retransmit timer has reset, and we can send something new.
} else { } else {
@ -1121,16 +1125,33 @@ mod test {
s.local_endpoint = LOCAL_END; s.local_endpoint = LOCAL_END;
s.remote_endpoint = REMOTE_END; s.remote_endpoint = REMOTE_END;
s.local_seq_no = LOCAL_SEQ; s.local_seq_no = LOCAL_SEQ;
s.remote_seq_no = REMOTE_SEQ; s.remote_seq_no = REMOTE_SEQ + 1;
s.remote_last_seq = LOCAL_SEQ + 1;
s s
} }
#[test]
fn test_syn_received_syn_ack() {
let mut s = socket_syn_received();
recv!(s, [TcpRepr {
control: TcpControl::Syn,
seq_number: LOCAL_SEQ,
ack_number: Some(REMOTE_SEQ + 1),
..RECV_TEMPL
}]);
send!(s, TcpRepr {
seq_number: REMOTE_SEQ + 1,
ack_number: Some(LOCAL_SEQ + 1),
..SEND_TEMPL
});
}
#[test] #[test]
fn test_syn_received_rst() { fn test_syn_received_rst() {
let mut s = socket_syn_received(); let mut s = socket_syn_received();
send!(s, TcpRepr { send!(s, TcpRepr {
control: TcpControl::Rst, control: TcpControl::Rst,
seq_number: REMOTE_SEQ, seq_number: REMOTE_SEQ + 1,
ack_number: Some(LOCAL_SEQ), ack_number: Some(LOCAL_SEQ),
..SEND_TEMPL ..SEND_TEMPL
}); });
@ -1760,6 +1781,20 @@ mod test {
recv!(s, []); recv!(s, []);
} }
#[test]
fn test_fin_with_data() {
let mut s = socket_established();
s.send_slice(b"abcdef").unwrap();
s.close();
recv!(s, [TcpRepr {
control: TcpControl::Fin,
seq_number: LOCAL_SEQ + 1,
ack_number: Some(REMOTE_SEQ + 1),
payload: &b"abcdef"[..],
..RECV_TEMPL
}])
}
// =========================================================================================// // =========================================================================================//
// Tests for retransmission on packet loss. // Tests for retransmission on packet loss.
// =========================================================================================// // =========================================================================================//
@ -1818,16 +1853,33 @@ mod test {
} }
#[test] #[test]
fn test_fin_with_data() { fn test_send_data_after_syn_ack_retransmit() {
let mut s = socket_established(); let mut s = socket_syn_received();
recv!(s, time 50, Ok(TcpRepr {
control: TcpControl::Syn,
seq_number: LOCAL_SEQ,
ack_number: Some(REMOTE_SEQ + 1),
..RECV_TEMPL
}));
recv!(s, time 150, Ok(TcpRepr { // retransmit
control: TcpControl::Syn,
seq_number: LOCAL_SEQ,
ack_number: Some(REMOTE_SEQ + 1),
..RECV_TEMPL
}));
send!(s, TcpRepr {
seq_number: REMOTE_SEQ + 1,
ack_number: Some(LOCAL_SEQ + 1),
..SEND_TEMPL
});
assert_eq!(s.state(), State::Established);
s.send_slice(b"abcdef").unwrap(); s.send_slice(b"abcdef").unwrap();
s.close();
recv!(s, [TcpRepr { recv!(s, [TcpRepr {
control: TcpControl::Fin,
seq_number: LOCAL_SEQ + 1, seq_number: LOCAL_SEQ + 1,
ack_number: Some(REMOTE_SEQ + 1), ack_number: Some(REMOTE_SEQ + 1),
payload: &b"abcdef"[..], payload: &b"abcdef"[..],
..RECV_TEMPL ..RECV_TEMPL
}]) }])
} }
} }