summaryrefslogtreecommitdiffhomepage
path: root/mullvad-masque-proxy/src
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2025-04-07 15:54:28 +0200
committerDavid Lönnhager <david.l@mullvad.net>2025-04-07 15:54:28 +0200
commit666455314b4339d7ee5200e750bf0c67631373a0 (patch)
tree0a7e8686ba71ebc3a0b0ed7ab309be146c553119 /mullvad-masque-proxy/src
parent775bfa0a419f1b44f03a906855dab85a85c71137 (diff)
parentba8d1374b6eb59fbb3bd2fa243ae66c361651db9 (diff)
downloadmullvadvpn-666455314b4339d7ee5200e750bf0c67631373a0.tar.xz
mullvadvpn-666455314b4339d7ee5200e750bf0c67631373a0.zip
Merge branch 'add-masque-test'
Diffstat (limited to 'mullvad-masque-proxy/src')
-rw-r--r--mullvad-masque-proxy/src/client/mod.rs68
-rw-r--r--mullvad-masque-proxy/src/fragment.rs8
-rw-r--r--mullvad-masque-proxy/src/server/mod.rs20
3 files changed, 53 insertions, 43 deletions
diff --git a/mullvad-masque-proxy/src/client/mod.rs b/mullvad-masque-proxy/src/client/mod.rs
index 4fd7ee5729..182ec580ba 100644
--- a/mullvad-masque-proxy/src/client/mod.rs
+++ b/mullvad-masque-proxy/src/client/mod.rs
@@ -38,39 +38,42 @@ pub struct Client {
pub type Result<T> = std::result::Result<T, Error>;
-#[derive(Debug)]
+#[derive(Debug, thiserror::Error)]
pub enum Error {
- Bind(io::Error),
- Connect(quinn::ConnectError),
- Connection(quinn::ConnectionError),
- /// Connection closed while sending request to initiate proxying
+ #[error("Failed to bind local socket")]
+ Bind(#[source] io::Error),
+ #[error("Failed to begin connecting to QUIC endpoint")]
+ Connect(#[from] quinn::ConnectError),
+ #[error("Failed to connect to QUIC endpoint")]
+ Connection(#[from] quinn::ConnectionError),
+ #[error("Connection closed while sending request to initiate proxying")]
ConnectionClosedPrematurely,
- /// QUIC connection failed while sending request to initiate proxying
- ConnectionFailed(h3::Error),
- /// Request failed to illicit a response.
- RequestError(h3::Error),
- /// Received response was not a 200.
+ #[error("QUIC connection failed while sending request to initiate proxying")]
+ ConnectionFailed(#[source] h3::Error),
+ #[error("Request failed to illicit a response.")]
+ RequestError(#[source] h3::Error),
+ #[error("Received response was not a 200: {}", .0)]
UnexpectedStatus(http::StatusCode),
- /// Failed to receive data from client socket
- ClientRead(io::Error),
- /// Failed to send data to client socket
- ClientWrite(io::Error),
- /// Failed to receive data from server socket
- ServerRead(h3::Error),
- /// Failed to create a client
- CreateClient(h3::Error),
- /// Failed to receive good response from proxy
- ProxyResponse(h3::Error),
- /// Failed to construct a URI
- Uri(http::Error),
- /// Failed to send datagram to proxy
- SendDatagram(h3::Error),
- /// Failed to read certificates
- ReadCerts(io::Error),
- /// Failed to parse certificates
+ #[error("Failed to receive data from client socket")]
+ ClientRead(#[source] io::Error),
+ #[error("Failed to send data to client socket")]
+ ClientWrite(#[source] io::Error),
+ #[error("Failed to receive data from server socket")]
+ ServerRead(#[source] h3::Error),
+ #[error("Failed to create a client")]
+ CreateClient(#[source] h3::Error),
+ #[error("Failed to receive good response from proxy")]
+ ProxyResponse(#[source] h3::Error),
+ #[error("Failed to construct a URI")]
+ Uri(#[source] http::Error),
+ #[error("Failed to send datagram to proxy")]
+ SendDatagram(#[source] h3::Error),
+ #[error("Failed to read certificates")]
+ ReadCerts(#[source] io::Error),
+ #[error("Failed to parse certificates")]
ParseCerts,
- /// Failed to fragment a packet - it is too large
- PacketTooLarge(fragment::PacketTooLarge),
+ #[error("Failed to fragment a packet - it is too large")]
+ PacketTooLarge(#[from] fragment::PacketTooLarge),
}
impl Client {
@@ -137,11 +140,9 @@ impl Client {
// TODO: Set EndpointConfig::max_udp_payload_size instead of using X-Mullvad-Uplink-Mtu
let endpoint = Endpoint::client(local_addr).map_err(Error::Bind)?;
- let connecting = endpoint
- .connect_with(client_config, server_addr, server_host)
- .map_err(Error::Connect)?;
+ let connecting = endpoint.connect_with(client_config, server_addr, server_host)?;
- let connection = connecting.await.map_err(Error::Connection)?;
+ let connection = connecting.await?;
let (connection, send_stream, request_stream) =
Self::setup_h3_connection(connection, target_addr, server_host, maximum_packet_size)
@@ -229,7 +230,6 @@ impl Client {
self.maximum_packet_size,
&mut send_buf,
fragment_id)
- .map_err(Error::PacketTooLarge)
? {
self.connection.send_datagram(stream_id, fragment).map_err(Error::SendDatagram)?;
}
diff --git a/mullvad-masque-proxy/src/fragment.rs b/mullvad-masque-proxy/src/fragment.rs
index 6dbee00a34..f60c3b927d 100644
--- a/mullvad-masque-proxy/src/fragment.rs
+++ b/mullvad-masque-proxy/src/fragment.rs
@@ -12,15 +12,19 @@ pub struct Fragments {
}
// When a packet that arrives is too small to be decoded.
-#[derive(Debug)]
+#[derive(Debug, thiserror::Error)]
pub enum DefragError {
+ #[error("Bad context id: {:?}", .0)]
#[allow(dead_code)] // TODO: use this error or remove it.
BadContextId(Result<VarInt, h3::proto::coding::UnexpectedEnd>),
+
+ #[error("Payload is too small")]
PayloadTooSmall,
}
// When a packet is larger than u16::MAX, it can't be fragmented.
-#[derive(Debug)]
+#[derive(Debug, thiserror::Error)]
+#[error("Packet is too large to fragment")]
pub struct PacketTooLarge(pub usize);
impl Fragments {
diff --git a/mullvad-masque-proxy/src/server/mod.rs b/mullvad-masque-proxy/src/server/mod.rs
index 4abc810a4d..710edaa537 100644
--- a/mullvad-masque-proxy/src/server/mod.rs
+++ b/mullvad-masque-proxy/src/server/mod.rs
@@ -19,11 +19,14 @@ use tokio::{net::UdpSocket, time::interval};
use crate::fragment::{self, Fragments};
-#[derive(Debug)]
+#[derive(Debug, thiserror::Error)]
pub enum Error {
- BadTlsConfig(quinn::crypto::rustls::NoInitialCipherSuite),
- BindSocket(io::Error),
- SendNegotiationResponse(h3::Error),
+ #[error("Bad TLS config")]
+ BadTlsConfig(#[source] quinn::crypto::rustls::NoInitialCipherSuite),
+ #[error("Failed to bind server socket")]
+ BindSocket(#[source] io::Error),
+ #[error("Failed to send negotiation response")]
+ SendNegotiationResponse(#[source] h3::Error),
}
pub type Result<T> = std::result::Result<T, Error>;
@@ -69,6 +72,10 @@ impl Server {
})
}
+ pub fn local_addr(&self) -> io::Result<SocketAddr> {
+ self.endpoint.local_addr()
+ }
+
pub async fn run(self) -> Result<()> {
while let Some(new_connection) = self.endpoint.accept().await {
tokio::spawn(Self::handle_incoming_connection(
@@ -164,7 +171,7 @@ impl Server {
client_send = connection.read_datagram() => {
match client_send {
Ok(Some(received_packet)) => {
- handle_client_packet(received_packet, stream_id, &mut fragments, &udp_socket, target_addr).await;
+ handle_client_packet(received_packet, stream_id, &mut fragments, &udp_socket).await;
},
Ok(None) => {
return;
@@ -224,7 +231,6 @@ async fn handle_client_packet(
stream_id: StreamId,
fragments: &mut Fragments,
proxy_socket: &UdpSocket,
- target_addr: SocketAddr,
) {
if received_packet.stream_id() != stream_id {
// log::trace!("Received unexpected stream ID from server");
@@ -232,7 +238,7 @@ async fn handle_client_packet(
}
if let Ok(Some(payload)) = fragments.handle_incoming_packet(received_packet.into_payload()) {
- let _ = proxy_socket.send_to(&payload, target_addr).await;
+ let _ = proxy_socket.send(&payload).await;
}
}