summaryrefslogtreecommitdiffhomepage
path: root/mullvad-masque-proxy/tests/proxy.rs
blob: 6825f7d75d454d308b25b4be5185384dcdeb9dc9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
use std::net::SocketAddr;
use std::sync::Arc;

use anyhow::Context;
use bytes::BytesMut;
use tokio::fs;

use mullvad_masque_proxy::client;
use mullvad_masque_proxy::server;
use tokio::net::UdpSocket;

/// Set up a MASQUE proxy and test that it can be used to communicate with some UDP destination
#[tokio::test]
async fn test_server_and_client_forwarding() -> anyhow::Result<()> {
    const MAXIMUM_PACKET_SIZE: u16 = 1700;
    const HOST: &str = "test.test";

    let any_localhost_addr: SocketAddr = "127.0.0.1:0".parse().unwrap();

    // Set up destination UDP server
    let target_udp_server = UdpSocket::bind(any_localhost_addr).await?;
    let target_udp_addr = target_udp_server
        .local_addr()
        .context("Retrieve dest UDP server addr")?;

    // Set up MASQUE server
    let server_tls_config = load_server_test_cert().await?;
    let server = server::Server::bind(
        any_localhost_addr,
        Default::default(),
        Arc::new(server_tls_config),
        MAXIMUM_PACKET_SIZE,
    )
    .context("Failed to start MASQUE server")?;

    let masque_server_addr = server.local_addr()?;

    tokio::spawn(server.run());

    // Set up MASQUE client
    let local_socket = UdpSocket::bind(any_localhost_addr)
        .await
        .context("Failed to bind address")?;
    let masque_client_addr = local_socket.local_addr().unwrap();

    let client = client::Client::connect_with_tls_config(
        local_socket,
        masque_server_addr,
        // Local QUIC address
        any_localhost_addr,
        target_udp_addr,
        HOST,
        client::default_tls_config(),
        MAXIMUM_PACKET_SIZE,
    )
    .await
    .context("Failed to start MASQUE client")?;

    tokio::spawn(client.run());

    // Connect to local UDP socket
    let proxy_client = UdpSocket::bind(any_localhost_addr).await?;
    proxy_client
        .connect(masque_client_addr)
        .await
        .context("Failed to connect to local UDP server")?;

    // Proxy client -> destination
    let mut rx_buf = BytesMut::with_capacity(128);
    proxy_client.send(b"abc").await?;
    let (_, proxy_addr) = target_udp_server
        .recv_buf_from(&mut rx_buf)
        .await
        .context("Expected to receive message")?;
    assert_eq!(&*rx_buf, b"abc", "Expected to receive message from client");

    // Destination -> proxy client
    let mut rx_buf = BytesMut::with_capacity(128);
    target_udp_server.send_to(b"def", proxy_addr).await?;
    proxy_client
        .recv_buf(&mut rx_buf)
        .await
        .context("Expected to receive message")?;
    assert_eq!(&*rx_buf, b"def", "Expected to receive message from server");

    Ok(())
}

async fn load_server_test_cert() -> anyhow::Result<rustls::ServerConfig> {
    let key = fs::read("tests/test.key").await.context("Read test key")?;
    let key = rustls_pemfile::private_key(&mut &*key)?.context("Invalid test key")?;

    let cert_chain = fs::read("tests/test.crt")
        .await
        .context("Read test certificate")?;
    let cert_chain = rustls_pemfile::certs(&mut &*cert_chain)
        .collect::<Result<_, _>>()
        .context("Invalid test certificate")?;

    let mut tls_config = rustls::ServerConfig::builder_with_provider(Arc::new(
        rustls::crypto::ring::default_provider(),
    ))
    .with_protocol_versions(&[&rustls::version::TLS13])?
    .with_no_client_auth()
    .with_single_cert(cert_chain, key)?;

    tls_config.max_early_data_size = u32::MAX;
    tls_config.alpn_protocols = vec![b"h3".into()];

    Ok(tls_config)
}