Selaa lähdekoodia

Don't send TCP FIN flag yet if next segment will also have data.

whitequark 8 vuotta sitten
vanhempi
commit
d57b42ca93
1 muutettua tiedostoa jossa 19 lisäystä ja 1 poistoa
  1. 19 1
      src/socket/tcp.rs

+ 19 - 1
src/socket/tcp.rs

@@ -901,8 +901,12 @@ impl<'a> TcpSocket<'a> {
                     self.remote_last_seq += data.len();
                     should_send = true;
                 }
+                // The FIN control flag occupies the place in the sequence space after
+                // the data in the current segment. If we still have some data left for the next
+                // segment (e.g. the receiver window is too small), then don't send FIN just yet.
+                let all_data_sent = self.tx_buffer.len() == offset + size;
                 match self.state {
-                    State::FinWait1 | State::LastAck => {
+                    State::FinWait1 | State::LastAck if all_data_sent => {
                         // We should notify the other side that we've closed the transmit half
                         // of the connection.
                         net_trace!("[{}]{}:{}: sending FIN|ACK",
@@ -1619,6 +1623,20 @@ mod test {
         sanity!(s, socket_closing());
     }
 
+    #[test]
+    fn test_fin_wait_1_fin_with_data_queued() {
+        let mut s = socket_established();
+        s.remote_win_len = 6;
+        s.send_slice(b"abcdef123456").unwrap();
+        s.close();
+        recv!(s, [TcpRepr {
+            seq_number: LOCAL_SEQ + 1,
+            ack_number: Some(REMOTE_SEQ + 1),
+            payload:    &b"abcdef"[..],
+            ..RECV_TEMPL
+        }]);
+    }
+
     #[test]
     fn test_fin_wait_1_close() {
         let mut s = socket_fin_wait_1();