diff options
| author | David Lönnhager <david.l@mullvad.net> | 2025-04-10 16:00:00 +0200 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2025-04-10 16:45:21 +0200 |
| commit | afdb6280d30c4bb05c51695075f00530684a37dc (patch) | |
| tree | 50e21c575da46099c477092baa706dec2e57e47e | |
| parent | 6fabb9c2548f14d68926ddd3d097d6e1feb1a570 (diff) | |
| download | mullvadvpn-afdb6280d30c4bb05c51695075f00530684a37dc.tar.xz mullvadvpn-afdb6280d30c4bb05c51695075f00530684a37dc.zip | |
Test different MTU and packet sizes
Co-authored-by: Joakim Hulthe <joakim.hulthe@mullvad.net>
| -rw-r--r-- | mullvad-masque-proxy/tests/proxy.rs | 46 |
1 files changed, 36 insertions, 10 deletions
diff --git a/mullvad-masque-proxy/tests/proxy.rs b/mullvad-masque-proxy/tests/proxy.rs index 378d3f85f9..61a15e5136 100644 --- a/mullvad-masque-proxy/tests/proxy.rs +++ b/mullvad-masque-proxy/tests/proxy.rs @@ -1,9 +1,12 @@ +use std::iter; use std::net::SocketAddr; use std::sync::Arc; use std::time::Duration; +use anyhow::anyhow; use anyhow::Context; use bytes::BytesMut; +use mullvad_masque_proxy::MIN_IPV4_MTU; use rand::RngCore; use tokio::fs; @@ -47,20 +50,33 @@ async fn test_server_and_client_forwarding() -> anyhow::Result<()> { /// reach their destinations when fragmentation *should* be present. #[tokio::test] async fn test_server_and_client_fragmentation() -> anyhow::Result<()> { - timeout(Duration::from_secs(1), async { - const MTU: u16 = 1500; - const SEND_PACKET_SIZE: usize = 2500; + #[allow(unused_mut)] + let mut valid_send_packet_sizes = vec![0u16, 1, 10, 100, 1280, 5000]; - let (client, server) = setup_masque(MTU).await?; + // Maximum packet size sans UDP and QUIC headers, sans 1 byte context ID. + // + // NOTE: On macOS, the maximum UDP packet size is equal to the value set by + // `sysctl net.inet.udp.maxdgram` + #[cfg(not(target_os = "macos"))] + valid_send_packet_sizes.push(u16::MAX - 8 - 41 - 1); + + let valid_mtus = [MIN_IPV4_MTU, 1280, 1500, 1700, 5000, 20000, u16::MAX]; + + let params = valid_mtus + .into_iter() + .flat_map(|mtu| iter::repeat(mtu).zip(&valid_send_packet_sizes)); + + async fn run_test(mtu: u16, send_packet_size: usize) -> anyhow::Result<()> { + let (client, server) = setup_masque(mtu).await?; // Proxy client -> destination // Send a random packet, large enough to be fragmented - let mut fragment_me = vec![0u8; SEND_PACKET_SIZE]; + let mut fragment_me = vec![0u8; send_packet_size]; rand::thread_rng().fill_bytes(&mut fragment_me); client.send(&fragment_me).await?; - let mut rx_buf = BytesMut::with_capacity(SEND_PACKET_SIZE + 100); + let mut rx_buf = BytesMut::with_capacity(send_packet_size + 100); let (_, proxy_addr) = server .recv_buf_from(&mut rx_buf) .await @@ -73,12 +89,12 @@ async fn test_server_and_client_fragmentation() -> anyhow::Result<()> { // Destination -> proxy client // Send a random packet, large enough to be fragmented - let mut fragment_me = vec![0u8; SEND_PACKET_SIZE]; + let mut fragment_me = vec![0u8; send_packet_size]; rand::thread_rng().fill_bytes(&mut fragment_me); server.send_to(&fragment_me, proxy_addr).await?; - let mut rx_buf = BytesMut::with_capacity(SEND_PACKET_SIZE + 100); + let mut rx_buf = BytesMut::with_capacity(send_packet_size + 100); let blen = client .recv_buf(&mut rx_buf) .await @@ -97,8 +113,18 @@ async fn test_server_and_client_fragmentation() -> anyhow::Result<()> { ); Ok(()) - }) - .await? + } + + for (mtu, &send_packet_size) in params { + timeout( + Duration::from_secs(1), + run_test(mtu, send_packet_size.into()), + ) + .await? + .context(anyhow!("mtu={mtu}, send_packet_size={send_packet_size}"))?; + } + + Ok(()) } /// Set up a client and server connected by a MASQUE proxy. |
