Implement the TCP FIN-WAIT-2 state.

This commit is contained in:
whitequark 2016-12-28 04:10:17 +00:00
parent 9dc931dbe2
commit 3e7a1ee575
1 changed files with 39 additions and 20 deletions

View File

@ -514,7 +514,7 @@ impl<'a> TcpSocket<'a> {
let unacknowledged = self.tx_buffer.len() + control_len; let unacknowledged = self.tx_buffer.len() + control_len;
if !(ack_number >= self.local_seq_no && if !(ack_number >= self.local_seq_no &&
ack_number <= (self.local_seq_no + unacknowledged)) { ack_number <= (self.local_seq_no + unacknowledged)) {
net_trace!("tcp:{}:{}: unacceptable ACK ({} not in {}..{})", net_trace!("tcp:{}:{}: unacceptable ACK ({} not in {}...{})",
self.local_endpoint, self.remote_endpoint, self.local_endpoint, self.remote_endpoint,
ack_number, self.local_seq_no, self.local_seq_no + unacknowledged); ack_number, self.local_seq_no, self.local_seq_no + unacknowledged);
return Err(Error::Malformed) return Err(Error::Malformed)
@ -608,12 +608,19 @@ impl<'a> TcpSocket<'a> {
} }
// FIN packets in FIN-WAIT-1 state change it to CLOSING. // FIN packets in FIN-WAIT-1 state change it to CLOSING.
(State::FinWait1, TcpRepr { control: TcpControl::Fin, .. }) => { (State::FinWait1, TcpRepr { control: TcpControl::Fin, .. }) => {
self.remote_seq_no += 1; self.remote_seq_no += 1;
self.set_state(State::Closing); self.set_state(State::Closing);
self.retransmit.reset(); self.retransmit.reset();
} }
// FIN packets in FIN-WAIT-2 state change it to TIME-WAIT.
(State::FinWait2, TcpRepr { control: TcpControl::Fin, .. }) => {
self.remote_seq_no += 1;
self.set_state(State::TimeWait);
self.retransmit.reset();
}
// ACK packets in CLOSE-WAIT state do nothing. // ACK packets in CLOSE-WAIT state do nothing.
(State::CloseWait, TcpRepr { control: TcpControl::None, .. }) => (), (State::CloseWait, TcpRepr { control: TcpControl::None, .. }) => (),
@ -1347,6 +1354,18 @@ mod test {
s s
} }
#[test]
fn test_fin_wait_2_fin() {
let mut s = socket_fin_wait_2();
send!(s, [TcpRepr {
control: TcpControl::Fin,
seq_number: REMOTE_SEQ + 1,
ack_number: Some(LOCAL_SEQ + 1 + 1),
..SEND_TEMPL
}]);
assert_eq!(s.state, State::TimeWait);
}
#[test] #[test]
fn test_fin_wait_2_close() { fn test_fin_wait_2_close() {
let mut s = socket_fin_wait_2(); let mut s = socket_fin_wait_2();
@ -1372,6 +1391,24 @@ mod test {
assert_eq!(s.state, State::Closing); assert_eq!(s.state, State::Closing);
} }
// =========================================================================================//
// Tests for the TIME-WAIT state.
// =========================================================================================//
fn socket_time_wait() -> TcpSocket<'static> {
let mut s = socket_fin_wait_2();
s.state = State::TimeWait;
s.remote_seq_no = REMOTE_SEQ + 1 + 1;
s.remote_last_ack = REMOTE_SEQ + 1 + 1;
s
}
#[test]
fn test_time_wait_close() {
let mut s = socket_time_wait();
s.close();
assert_eq!(s.state, State::TimeWait);
}
// =========================================================================================// // =========================================================================================//
// Tests for the CLOSE-WAIT state. // Tests for the CLOSE-WAIT state.
// =========================================================================================// // =========================================================================================//
@ -1441,24 +1478,6 @@ mod test {
assert_eq!(s.state, State::LastAck); assert_eq!(s.state, State::LastAck);
} }
// =========================================================================================//
// Tests for the TIME-WAIT state.
// =========================================================================================//
fn socket_time_wait() -> TcpSocket<'static> {
let mut s = socket_fin_wait_2();
s.state = State::TimeWait;
s.remote_seq_no = REMOTE_SEQ + 1 + 1;
s.remote_last_ack = REMOTE_SEQ + 1 + 1;
s
}
#[test]
fn test_time_wait_close() {
let mut s = socket_time_wait();
s.close();
assert_eq!(s.state, State::TimeWait);
}
// =========================================================================================// // =========================================================================================//
// Tests for transitioning through multiple states. // Tests for transitioning through multiple states.
// =========================================================================================// // =========================================================================================//