diff --git a/quinn-proto/src/tests/mod.rs b/quinn-proto/src/tests/mod.rs index 7e64cd72e..08bbadbce 100644 --- a/quinn-proto/src/tests/mod.rs +++ b/quinn-proto/src/tests/mod.rs @@ -3074,3 +3074,32 @@ fn gso_truncation() { ); } } + +/// Verify that a large application datagram is sent successfully when an ACK frame too large to fit +/// alongside it is also queued, in exactly 2 UDP datagrams. +#[test] +fn large_datagram_with_acks() { + let _guard = subscribe(); + let mut pair = Pair::default(); + let (client_ch, server_ch) = pair.connect(); + + // Force the client to generate a large ACK frame by dropping several packets + for _ in 0..10 { + pair.server_conn_mut(server_ch).ping(); + pair.drive_server(); + pair.client.inbound.pop_back(); + pair.server_conn_mut(server_ch).ping(); + pair.drive_server(); + } + + let max_size = pair.client_datagrams(client_ch).max_size().unwrap(); + let msg = Bytes::from(vec![0; max_size]); + pair.client_datagrams(client_ch) + .send(msg.clone(), true) + .unwrap(); + let initial_datagrams = pair.client_conn_mut(client_ch).stats().udp_tx.datagrams; + pair.drive(); + let final_datagrams = pair.client_conn_mut(client_ch).stats().udp_tx.datagrams; + assert_eq!(pair.server_datagrams(server_ch).recv().unwrap(), msg); + assert_eq!(final_datagrams - initial_datagrams, 2); +}