瀏覽代碼

Refactor the TCP ACK handling in ESTABLISHED/CLOSE-WAIT states.

whitequark 8 年之前
父節點
當前提交
53feb670e7
共有 1 個文件被更改,包括 48 次插入13 次删除
  1. 48 13
      src/socket/tcp.rs

+ 48 - 13
src/socket/tcp.rs

@@ -630,14 +630,6 @@ impl<'a> TcpSocket<'a> {
                                ack_number, self.local_seq_no, self.local_seq_no + unacknowledged);
                     return Err(Error::Dropped)
                 }
-                // If we got a valid acknowledgement and the transmit half of the connection
-                // is open, reset the retransmit timer.
-                // This primarily matters in the case where the local endpoint keeps sending data
-                // already in its buffer (e.g. if the contents of the buffer exceed the window
-                // of the remote endpoint), and nothing else happens.
-                if self.may_send() {
-                    self.retransmit.reset()
-                }
             }
         }
 
@@ -715,8 +707,10 @@ impl<'a> TcpSocket<'a> {
                 self.retransmit.reset();
             }
 
-            // ACK packets in ESTABLISHED state do nothing.
-            (State::Established, TcpRepr { control: TcpControl::None, .. }) => (),
+            // ACK packets in ESTABLISHED state reset the retransmit timer.
+            (State::Established, TcpRepr { control: TcpControl::None, .. }) => {
+                self.retransmit.reset()
+            },
 
             // FIN packets in ESTABLISHED state indicate the remote side has closed.
             (State::Established, TcpRepr { control: TcpControl::Fin, .. }) => {
@@ -753,8 +747,10 @@ impl<'a> TcpSocket<'a> {
                 self.retransmit.reset();
             }
 
-            // ACK packets in CLOSE-WAIT state do nothing.
-            (State::CloseWait, TcpRepr { control: TcpControl::None, .. }) => (),
+            // ACK packets in CLOSE-WAIT state reset the retransmit timer.
+            (State::CloseWait, TcpRepr { control: TcpControl::None, .. }) => {
+                self.retransmit.reset();
+            }
 
             // ACK packets in LAST-ACK state change it to CLOSED.
             (State::LastAck, TcpRepr { control: TcpControl::None, .. }) => {
@@ -2124,7 +2120,7 @@ mod test {
     }
 
     #[test]
-    fn test_retransmit_reset_after_ack() {
+    fn test_established_retransmit_reset_after_ack() {
         let mut s = socket_established();
         s.remote_win_len = 6;
         s.send_slice(b"abcdef").unwrap();
@@ -2161,4 +2157,43 @@ mod test {
             ..RECV_TEMPL
         }));
     }
+
+    #[test]
+    fn test_close_wait_retransmit_reset_after_ack() {
+        let mut s = socket_close_wait();
+        s.remote_win_len = 6;
+        s.send_slice(b"abcdef").unwrap();
+        s.send_slice(b"123456").unwrap();
+        s.send_slice(b"ABCDEF").unwrap();
+        recv!(s, time 1000, Ok(TcpRepr {
+            seq_number: LOCAL_SEQ + 1,
+            ack_number: Some(REMOTE_SEQ + 1 + 1),
+            payload:    &b"abcdef"[..],
+            ..RECV_TEMPL
+        }));
+        send!(s, time 1005, TcpRepr {
+            seq_number: REMOTE_SEQ + 1 + 1,
+            ack_number: Some(LOCAL_SEQ + 1 + 6),
+            window_len: 6,
+            ..SEND_TEMPL
+        });
+        recv!(s, time 1010, Ok(TcpRepr {
+            seq_number: LOCAL_SEQ + 1 + 6,
+            ack_number: Some(REMOTE_SEQ + 1 + 1),
+            payload:    &b"123456"[..],
+            ..RECV_TEMPL
+        }));
+        send!(s, time 1015, TcpRepr {
+            seq_number: REMOTE_SEQ + 1 + 1,
+            ack_number: Some(LOCAL_SEQ + 1 + 6 + 6),
+            window_len: 6,
+            ..SEND_TEMPL
+        });
+        recv!(s, time 1020, Ok(TcpRepr {
+            seq_number: LOCAL_SEQ + 1 + 6 + 6,
+            ack_number: Some(REMOTE_SEQ + 1 + 1),
+            payload:    &b"ABCDEF"[..],
+            ..RECV_TEMPL
+        }));
+    }
 }