소스 검색

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 년 전
부모
커밋
e51e7509b3
1개의 변경된 파일29개의 추가작업 그리고 1개의 파일을 삭제
  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.
     // =========================================================================================//