Răsfoiți Sursa

Send incomplete fin packets even if nagle enabled

If we have an incomplete packet to send and the socket has been closed
then send it. Without this change (with nagle enabled) we wait for the
penultimate packet in the stream to be acked before sending the final
packet even if there's plenty of space in the window.
Michael Birtwell 2 ani în urmă
părinte
comite
e51e7509b3
1 a modificat fișierele cu 29 adăugiri și 1 ștergeri
  1. 29 1
      src/socket/tcp.rs

+ 29 - 1
src/socket/tcp.rs

@@ -2002,7 +2002,12 @@ impl<'a> TcpSocket<'a> {
             _ => false,
         };
 
-        if self.nagle && data_in_flight && !can_send_full {
+        // If we're applying the Nagle algorithm we don't want to send more
+        // until one of:
+        // * There's no data in flight
+        // * We can send a full packet
+        // * We have all the data we'll ever send (we're closing send)
+        if self.nagle && data_in_flight && !can_send_full && !want_fin {
             can_send = false;
         }
 
@@ -7000,6 +7005,29 @@ mod test {
         );
     }
 
+    #[test]
+    fn test_final_packet_in_stream_doesnt_wait_for_nagle() {
+        let mut s = socket_established();
+        s.remote_mss = 6;
+        s.send_slice(b"abcdef0").unwrap();
+        s.socket.close();
+
+        recv!(s, time 0, Ok(TcpRepr {
+            control:    TcpControl::None,
+            seq_number: LOCAL_SEQ + 1,
+            ack_number: Some(REMOTE_SEQ + 1),
+            payload:    &b"abcdef"[..],
+            ..RECV_TEMPL
+        }), exact);
+        recv!(s, time 0, Ok(TcpRepr {
+            control:    TcpControl::Fin,
+            seq_number: LOCAL_SEQ + 1 + 6,
+            ack_number: Some(REMOTE_SEQ + 1),
+            payload:    &b"0"[..],
+            ..RECV_TEMPL
+        }), exact);
+    }
+
     // =========================================================================================//
     // Tests for packet filtering.
     // =========================================================================================//