summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2025-04-10 16:00:00 +0200
committerDavid Lönnhager <david.l@mullvad.net>2025-04-10 16:45:21 +0200
commitafdb6280d30c4bb05c51695075f00530684a37dc (patch)
tree50e21c575da46099c477092baa706dec2e57e47e
parent6fabb9c2548f14d68926ddd3d097d6e1feb1a570 (diff)
downloadmullvadvpn-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.rs46
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.