summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock1
-rw-r--r--mullvad-masque-proxy/Cargo.toml5
-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.rs11
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>;