Skip to content

Commit 4c42b1f

Browse files
bors[bot]mbirtwell
andauthored
Merge #665
665: Send incomplete fin packets even if nagle enabled r=Dirbaio a=mbirtwell 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. I think this is strictly only an optimisation, but when I wrote the code I thought it was necessary. If there is no packet loss this change saves you a RTT before sending the final packet in the stream (plus any ack delay). If there is incoming packet loss so that you've missed an ACK, this change might additionally save you from having to do some retransmission. Once the far end has received the FIN/ACK it can drive retransmission if that gets dropped. Co-authored-by: Michael Birtwell <michael.birtwell@oxionics.com>
2 parents 69f1aad + f9f3ab8 commit 4c42b1f

File tree

1 file changed

+29
-1
lines changed

1 file changed

+29
-1
lines changed

src/socket/tcp.rs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1898,7 +1898,12 @@ impl<'a> Socket<'a> {
18981898
_ => false,
18991899
};
19001900

1901-
if self.nagle && data_in_flight && !can_send_full {
1901+
// If we're applying the Nagle algorithm we don't want to send more
1902+
// until one of:
1903+
// * There's no data in flight
1904+
// * We can send a full packet
1905+
// * We have all the data we'll ever send (we're closing send)
1906+
if self.nagle && data_in_flight && !can_send_full && !want_fin {
19021907
can_send = false;
19031908
}
19041909

@@ -6847,6 +6852,29 @@ mod test {
68476852
);
68486853
}
68496854

6855+
#[test]
6856+
fn test_final_packet_in_stream_doesnt_wait_for_nagle() {
6857+
let mut s = socket_established();
6858+
s.remote_mss = 6;
6859+
s.send_slice(b"abcdef0").unwrap();
6860+
s.socket.close();
6861+
6862+
recv!(s, time 0, Ok(TcpRepr {
6863+
control: TcpControl::None,
6864+
seq_number: LOCAL_SEQ + 1,
6865+
ack_number: Some(REMOTE_SEQ + 1),
6866+
payload: &b"abcdef"[..],
6867+
..RECV_TEMPL
6868+
}), exact);
6869+
recv!(s, time 0, Ok(TcpRepr {
6870+
control: TcpControl::Fin,
6871+
seq_number: LOCAL_SEQ + 1 + 6,
6872+
ack_number: Some(REMOTE_SEQ + 1),
6873+
payload: &b"0"[..],
6874+
..RECV_TEMPL
6875+
}), exact);
6876+
}
6877+
68506878
// =========================================================================================//
68516879
// Tests for packet filtering.
68526880
// =========================================================================================//

0 commit comments

Comments
 (0)