diff options
| author | David Lönnhager <david.l@mullvad.net> | 2025-04-04 23:33:04 +0200 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2025-04-07 15:52:19 +0200 |
| commit | ecfe6fc8dfd2c82799981e482a3e3c743a28c472 (patch) | |
| tree | eb39dde5b970bfe969fc5fac85b6e7e7639b9d80 | |
| parent | 775bfa0a419f1b44f03a906855dab85a85c71137 (diff) | |
| download | mullvadvpn-ecfe6fc8dfd2c82799981e482a3e3c743a28c472.tar.xz mullvadvpn-ecfe6fc8dfd2c82799981e482a3e3c743a28c472.zip | |
Implement Error in mullvad-masque-proxy
| -rw-r--r-- | Cargo.lock | 1 | ||||
| -rw-r--r-- | mullvad-masque-proxy/Cargo.toml | 5 | ||||
| -rw-r--r-- | mullvad-masque-proxy/src/client/mod.rs | 68 | ||||
| -rw-r--r-- | mullvad-masque-proxy/src/fragment.rs | 8 | ||||
| -rw-r--r-- | mullvad-masque-proxy/src/server/mod.rs | 11 |
5 files changed, 51 insertions, 42 deletions
diff --git a/Cargo.lock b/Cargo.lock index 4fbf93a399..b29f46eebc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2881,6 +2881,7 @@ dependencies = [ "rand 0.8.5", "rustls 0.23.18", "rustls-pemfile 2.1.3", + "thiserror 2.0.9", "tokio", ] diff --git a/mullvad-masque-proxy/Cargo.toml b/mullvad-masque-proxy/Cargo.toml index 644d52755c..e6307eb3f4 100644 --- a/mullvad-masque-proxy/Cargo.toml +++ b/mullvad-masque-proxy/Cargo.toml @@ -10,10 +10,11 @@ description = "A limited functionality UDP over HTTP3 proxy" [dependencies] quinn = { version = "0.11", default-features = false, features = ["log", "runtime-tokio", "rustls-ring"] } -tokio = { workspace = true, features = [ "macros", "io-util" ] } +thiserror = { workspace = true } +tokio = { workspace = true, features = ["fs", "macros", "io-util"] } h3 = "0.0.7" h3-datagram = "0.0.1" -h3-quinn = { version = "0.0.9", features = [ "datagram" ]} +h3-quinn = { version = "0.0.9", features = ["datagram"] } http = "1" rustls = { version = "0.23", default-features = false } rustls-pemfile = "2.1.3" 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..fef323cdf6 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>; |
