From 3e7a1ee575235394fd98cfd23989a9d4b569b478 Mon Sep 17 00:00:00 2001 From: whitequark Date: Wed, 28 Dec 2016 04:10:17 +0000 Subject: [PATCH] Implement the TCP FIN-WAIT-2 state. --- src/socket/tcp.rs | 59 +++++++++++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 20 deletions(-) diff --git a/src/socket/tcp.rs b/src/socket/tcp.rs index e85e518..db4a9d5 100644 --- a/src/socket/tcp.rs +++ b/src/socket/tcp.rs @@ -514,7 +514,7 @@ impl<'a> TcpSocket<'a> { let unacknowledged = self.tx_buffer.len() + control_len; if !(ack_number >= self.local_seq_no && 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, ack_number, self.local_seq_no, self.local_seq_no + unacknowledged); return Err(Error::Malformed) @@ -608,12 +608,19 @@ impl<'a> TcpSocket<'a> { } // 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.set_state(State::Closing); 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. (State::CloseWait, TcpRepr { control: TcpControl::None, .. }) => (), @@ -1347,6 +1354,18 @@ mod test { 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] fn test_fin_wait_2_close() { let mut s = socket_fin_wait_2(); @@ -1372,6 +1391,24 @@ mod test { 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. // =========================================================================================// @@ -1441,24 +1478,6 @@ mod test { 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. // =========================================================================================//