summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMarkus Pettersson <markus.pettersson@mullvad.net>2025-07-14 14:43:30 +0200
committerDavid Lönnhager <david.l@mullvad.net>2025-07-23 09:41:54 +0200
commitc30fd84b3aaf7945e5fde9cbe48cf73e7c6463ca (patch)
tree8d4ad610b860993237184aa9ebb96d7c9e24eb54
parentdc2db9cc8a63e8bcbd3cbf70c28c7446d7f83733 (diff)
downloadmullvadvpn-c30fd84b3aaf7945e5fde9cbe48cf73e7c6463ca.tar.xz
mullvadvpn-c30fd84b3aaf7945e5fde9cbe48cf73e7c6463ca.zip
Add `Relay::Features` message to protobuf
-rw-r--r--mullvad-management-interface/proto/management_interface.proto12
-rw-r--r--mullvad-management-interface/src/types/conversions/relay_list.rs81
-rw-r--r--mullvad-types/src/relay_list.rs4
3 files changed, 94 insertions, 3 deletions
diff --git a/mullvad-management-interface/proto/management_interface.proto b/mullvad-management-interface/proto/management_interface.proto
index 199f4f2000..fc453afe9b 100644
--- a/mullvad-management-interface/proto/management_interface.proto
+++ b/mullvad-management-interface/proto/management_interface.proto
@@ -722,6 +722,16 @@ message Relay {
BRIDGE = 1;
WIREGUARD = 2;
}
+ message Features {
+ message Quic {
+ string domain = 1;
+ string token = 2;
+ repeated string addr_in = 3;
+ }
+
+ bool daita = 1;
+ Quic quic = 2;
+ }
string hostname = 1;
string ipv4_addr_in = 2;
@@ -732,8 +742,10 @@ message Relay {
string provider = 7;
fixed64 weight = 8;
RelayType endpoint_type = 9;
+ // XXX: wtf, why is this untyped
google.protobuf.Any endpoint_data = 10;
Location location = 11;
+ Features features = 12;
}
message WireguardRelayEndpointData {
diff --git a/mullvad-management-interface/src/types/conversions/relay_list.rs b/mullvad-management-interface/src/types/conversions/relay_list.rs
index b002634177..780900413c 100644
--- a/mullvad-management-interface/src/types/conversions/relay_list.rs
+++ b/mullvad-management-interface/src/types/conversions/relay_list.rs
@@ -4,6 +4,8 @@ use std::{
str::FromStr,
};
+use mullvad_types::relay_list::Features;
+
use crate::types::{
FromProtobufTypeError,
conversions::{bytes_to_pubkey, to_proto_any, try_from_proto_any},
@@ -135,6 +137,7 @@ impl From<mullvad_types::relay_list::Relay> for proto::Relay {
"mullvad_daemon.management_interface/WireguardRelayEndpointData",
proto::WireguardRelayEndpointData {
public_key: data.public_key.as_bytes().to_vec(),
+ // TODO: Deprecate in favor of new `features` key
daita: data.daita,
shadowsocks_extra_addr_in: data
.shadowsocks_extra_addr_in
@@ -153,10 +156,80 @@ impl From<mullvad_types::relay_list::Relay> for proto::Relay {
latitude: relay.location.latitude,
longitude: relay.location.longitude,
}),
+ features: Some(proto::relay::Features::from(relay.features)),
+ }
+ }
+}
+
+impl From<mullvad_types::relay_list::Features> for proto::relay::Features {
+ fn from(features: mullvad_types::relay_list::Features) -> Self {
+ Self {
+ daita: features.daita(),
+ quic: features
+ .quic()
+ .cloned()
+ .map(proto::relay::features::Quic::from),
+ }
+ }
+}
+
+impl TryFrom<proto::relay::Features> for mullvad_types::relay_list::Features {
+ type Error = FromProtobufTypeError;
+
+ fn try_from(value: proto::relay::Features) -> Result<Self, Self::Error> {
+ let features = Features::empty();
+ let features = if value.daita {
+ features.configure_daita()
+ } else {
+ features
+ };
+ let features = {
+ let quic = value
+ .quic
+ .map(mullvad_types::relay_list::Quic::try_from)
+ .transpose()?;
+ if let Some(options) = quic {
+ features.configure_quic(options)
+ } else {
+ features
+ }
+ };
+ Ok(features)
+ }
+}
+
+impl From<mullvad_types::relay_list::Quic> for proto::relay::features::Quic {
+ fn from(value: mullvad_types::relay_list::Quic) -> Self {
+ let domain = value.hostname().to_owned();
+ let token = value.auth_token().to_owned();
+ let addr_in = value.in_addr().iter().map(|ip| ip.to_string()).collect();
+ Self {
+ domain,
+ token,
+ addr_in,
}
}
}
+impl TryFrom<proto::relay::features::Quic> for mullvad_types::relay_list::Quic {
+ type Error = FromProtobufTypeError;
+
+ fn try_from(value: proto::relay::features::Quic) -> Result<Self, Self::Error> {
+ let domain = value.domain;
+ let token = value.token;
+ let addr_in = value
+ .addr_in
+ .iter()
+ .map(|addr| {
+ addr.parse().map_err(|_err| {
+ FromProtobufTypeError::InvalidArgument("Invalid IP address: {addr}")
+ })
+ })
+ .collect::<Result<_, FromProtobufTypeError>>()?;
+ Ok(Self::new(addr_in, token, domain))
+ }
+}
+
impl TryFrom<proto::RelayList> for mullvad_types::relay_list::RelayList {
type Error = FromProtobufTypeError;
@@ -286,9 +359,11 @@ impl TryFrom<proto::Relay> for mullvad_types::relay_list::Relay {
})
.transpose()?;
- // TODO: Eventually, we will need to decide how to represent extra relay features in the
- // protobuf message.
- let features = mullvad_types::relay_list::Features::default();
+ let features = relay
+ .features
+ .map(mullvad_types::relay_list::Features::try_from)
+ .transpose()?
+ .unwrap_or_default();
let relay = MullvadRelay {
hostname: relay.hostname,
diff --git a/mullvad-types/src/relay_list.rs b/mullvad-types/src/relay_list.rs
index 99aaf60059..aceff060b0 100644
--- a/mullvad-types/src/relay_list.rs
+++ b/mullvad-types/src/relay_list.rs
@@ -201,6 +201,10 @@ impl Quic {
pub fn auth_token(&self) -> &str {
&self.token
}
+
+ pub fn in_addr(&self) -> &[IpAddr] {
+ &self.addr_in
+ }
}
impl Relay {