summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gui/src/main/daemon-rpc.ts13
-rw-r--r--mullvad-cli/src/cmds/relay.rs49
-rw-r--r--mullvad-daemon/src/relays.rs66
-rw-r--r--mullvad-management-interface/proto/management_interface.proto12
-rw-r--r--mullvad-management-interface/src/types.rs43
-rw-r--r--mullvad-types/src/relay_constraints.rs33
6 files changed, 136 insertions, 80 deletions
diff --git a/gui/src/main/daemon-rpc.ts b/gui/src/main/daemon-rpc.ts
index 1c3e9a67ba..24594c5e4d 100644
--- a/gui/src/main/daemon-rpc.ts
+++ b/gui/src/main/daemon-rpc.ts
@@ -1154,8 +1154,12 @@ function convertFromOpenVpnConstraints(
function convertFromWireguardConstraints(
constraints: grpcTypes.WireguardConstraints,
): IWireguardConstraints {
- const port = convertFromConstraint(constraints.getPort());
- return { port };
+ const transportPort = convertFromConstraint(constraints.getPort());
+ if (transportPort !== 'any' && 'only' in transportPort) {
+ const port = convertFromConstraint(transportPort.only.getPort());
+ return { port };
+ }
+ return { port: 'any' };
}
function convertFromTunnelTypeConstraint(
@@ -1260,7 +1264,10 @@ function convertToWireguardConstraints(
const wireguardConstraints = new grpcTypes.WireguardConstraints();
const port = liftConstraint(constraint.port);
if (port) {
- wireguardConstraints.setPort(port);
+ const portConstraints = new grpcTypes.TransportPort();
+ portConstraints.setPort(port);
+ portConstraints.setProtocol(grpcTypes.TransportProtocol.UDP);
+ wireguardConstraints.setPort(portConstraints);
}
return wireguardConstraints;
}
diff --git a/mullvad-cli/src/cmds/relay.rs b/mullvad-cli/src/cmds/relay.rs
index e4fdfff478..64cb4c3e4b 100644
--- a/mullvad-cli/src/cmds/relay.rs
+++ b/mullvad-cli/src/cmds/relay.rs
@@ -12,7 +12,7 @@ use mullvad_management_interface::types::{
connection_config::{self, OpenvpnConfig, WireguardConfig},
relay_settings, relay_settings_update, ConnectionConfig, CustomRelaySettings, IpVersion,
IpVersionConstraint, NormalRelaySettingsUpdate, OpenvpnConstraints, ProviderUpdate,
- RelayListCountry, RelayLocation, RelaySettingsUpdate, TransportProtocol,
+ RelayListCountry, RelayLocation, RelaySettingsUpdate, TransportPort, TransportProtocol,
TransportProtocolConstraint, TunnelType, TunnelTypeConstraint, TunnelTypeUpdate,
WireguardConstraints,
};
@@ -164,15 +164,18 @@ impl Command for Relay {
.arg(
clap::Arg::with_name("port")
.help("Port to use. Either 'any' or a specific port")
- .required(true)
+ .long("port")
+ .takes_value(true)
+ .requires("transport protocol"),
)
.arg(
clap::Arg::with_name("transport protocol")
.help("Transport protocol. If TCP is selected, traffic is \
sent over TCP using a udp-over-tcp proxy")
.long("protocol")
- .default_value("any")
- .possible_values(&["any", "udp", "tcp"]),
+ .takes_value(true)
+ .possible_values(&["udp", "tcp"])
+ .requires("port"),
)
.arg(
clap::Arg::with_name("ip version")
@@ -535,8 +538,19 @@ impl Relay {
}
async fn set_wireguard_constraints(&self, matches: &clap::ArgMatches<'_>) -> Result<()> {
- let port = parse_port_constraint(matches.value_of("port").unwrap())?;
- let protocol = parse_protocol_constraint(matches.value_of("transport protocol").unwrap());
+ let protocol = matches.value_of("transport protocol").map(parse_protocol);
+ let port = match matches.value_of("port").map(parse_port_constraint) {
+ None => None,
+ Some(Err(error)) => return Err(error),
+ Some(Ok(Constraint::Any)) => Some(TransportPort {
+ protocol: protocol.unwrap() as i32,
+ port: 0,
+ }),
+ Some(Ok(Constraint::Only(port))) => Some(TransportPort {
+ protocol: protocol.unwrap() as i32,
+ port: u32::from(port),
+ }),
+ };
let ip_version = parse_ip_version_constraint(matches.value_of("ip version").unwrap());
let entry_location =
parse_entry_location_constraint(matches.values_of("entry location").unwrap());
@@ -545,12 +559,7 @@ impl Relay {
r#type: Some(relay_settings_update::Type::Normal(
NormalRelaySettingsUpdate {
wireguard_constraints: Some(WireguardConstraints {
- port: port.unwrap_or(0) as u32,
- protocol: protocol
- .option()
- .map(|protocol| TransportProtocolConstraint {
- protocol: protocol as i32,
- }),
+ port,
ip_version: ip_version.option().map(|protocol| IpVersionConstraint {
protocol: protocol as i32,
}),
@@ -750,12 +759,12 @@ impl Relay {
if let Some(constraints) = constraints {
let mut out = format!(
"{} over {} over {}",
- Self::format_port(constraints.port),
+ Self::format_port(constraints.port.as_ref().map(|port| port.port).unwrap_or(0)),
Self::format_transport_protocol(
constraints
- .protocol
+ .port
.clone()
- .map(|protocol| TransportProtocol::from_i32(protocol.protocol).unwrap())
+ .map(|port| TransportProtocol::from_i32(port.protocol).unwrap())
),
Self::format_ip_version(
constraints
@@ -832,8 +841,14 @@ fn parse_port_constraint(raw_port: &str) -> Result<Constraint<u16>> {
fn parse_protocol_constraint(raw_protocol: &str) -> Constraint<TransportProtocol> {
match raw_protocol {
"any" => Constraint::Any,
- "udp" => Constraint::Only(TransportProtocol::Udp),
- "tcp" => Constraint::Only(TransportProtocol::Tcp),
+ protocol => Constraint::Only(parse_protocol(protocol)),
+ }
+}
+
+fn parse_protocol(raw_protocol: &str) -> TransportProtocol {
+ match raw_protocol {
+ "udp" => TransportProtocol::Udp,
+ "tcp" => TransportProtocol::Tcp,
_ => unreachable!(),
}
}
diff --git a/mullvad-daemon/src/relays.rs b/mullvad-daemon/src/relays.rs
index 019c6ac2c1..186e4ed76b 100644
--- a/mullvad-daemon/src/relays.rs
+++ b/mullvad-daemon/src/relays.rs
@@ -15,7 +15,7 @@ use mullvad_types::{
location::Location,
relay_constraints::{
BridgeState, Constraint, InternalBridgeConstraints, LocationConstraint, Match,
- OpenVpnConstraints, Providers, RelayConstraints, Set, WireguardConstraints,
+ OpenVpnConstraints, Providers, RelayConstraints, Set, TransportPort, WireguardConstraints,
},
relay_list::{OpenVpnEndpointData, Relay, RelayList, RelayTunnels, WireguardEndpointData},
};
@@ -53,8 +53,10 @@ const EXPONENTIAL_BACKOFF_FACTOR: u32 = 8;
const DEFAULT_WIREGUARD_PORT: u16 = 51820;
const WIREGUARD_EXIT_CONSTRAINTS: WireguardConstraints = WireguardConstraints {
- port: Constraint::Only(DEFAULT_WIREGUARD_PORT),
- protocol: Constraint::Only(TransportProtocol::Udp),
+ port: Constraint::Only(TransportPort {
+ protocol: TransportProtocol::Udp,
+ port: Constraint::Only(DEFAULT_WIREGUARD_PORT),
+ }),
ip_version: Constraint::Only(IpVersion::V4),
entry_location: None,
};
@@ -388,7 +390,11 @@ impl RelaySelector {
}
if relay_constraints.wireguard_constraints.port.is_any() {
- relay_constraints.wireguard_constraints.port = preferred_port;
+ relay_constraints.wireguard_constraints.port =
+ Constraint::Only(TransportPort {
+ protocol: preferred_protocol,
+ port: preferred_port,
+ });
}
relay_constraints.tunnel_protocol = Constraint::Only(preferred_tunnel);
@@ -408,19 +414,17 @@ impl RelaySelector {
}
}
Constraint::Only(TunnelType::Wireguard) => {
- if relay_constraints.wireguard_constraints.protocol
- != Constraint::Only(TransportProtocol::Tcp)
- {
- relay_constraints.wireguard_constraints =
- original_constraints.wireguard_constraints.clone();
- // This ensures that if after the first 2 failed attempts the daemon does not
- // connect, then afterwards 2 of each 4 successive attempts will try to connect
- // on port 53.
- if retry_attempt % 4 > 1
- && relay_constraints.wireguard_constraints.port.is_any()
- {
- relay_constraints.wireguard_constraints.port = Constraint::Only(53);
- }
+ relay_constraints.wireguard_constraints =
+ original_constraints.wireguard_constraints.clone();
+ // This ensures that if after the first 2 failed attempts the daemon does not
+ // connect, then afterwards 2 of each 4 successive attempts will try to connect
+ // on port 53.
+ if retry_attempt % 4 > 1 && relay_constraints.wireguard_constraints.port.is_any() {
+ relay_constraints.wireguard_constraints.port =
+ Constraint::Only(TransportPort {
+ protocol: TransportProtocol::Udp,
+ port: Constraint::Only(53),
+ });
}
}
}
@@ -757,9 +761,9 @@ impl RelaySelector {
tunnels: &RelayTunnels,
constraints: &WireguardConstraints,
) -> Vec<WireguardEndpointData> {
- if constraints.protocol == Constraint::Only(TransportProtocol::Tcp) {
- match constraints.port {
- Constraint::Only(port) => {
+ match constraints.port {
+ Constraint::Only(port) if port.protocol == TransportProtocol::Tcp => {
+ if let Constraint::Only(port) = port.port {
if !WIREGUARD_TCP_PORTS
.iter()
.any(|range| port >= range.0 && port <= range.1)
@@ -767,9 +771,9 @@ impl RelaySelector {
return vec![];
}
}
- _ => (),
+ return tunnels.wireguard.clone();
}
- return tunnels.wireguard.clone();
+ _ => (),
}
tunnels
.wireguard
@@ -881,7 +885,10 @@ impl RelaySelector {
public_key: data.public_key,
endpoint: SocketAddr::new(host, port),
allowed_ips: all_of_the_internet(),
- protocol: constraints.protocol.unwrap_or(TransportProtocol::Udp),
+ protocol: constraints
+ .port
+ .map(|port| port.protocol)
+ .unwrap_or(TransportProtocol::Udp),
};
Some(MullvadEndpoint::Wireguard {
peer: peer_config,
@@ -907,12 +914,19 @@ impl RelaySelector {
data: &WireguardEndpointData,
constraints: &WireguardConstraints,
) -> Option<u16> {
- let port_ranges = match constraints.protocol {
- Constraint::Only(TransportProtocol::Tcp) => &WIREGUARD_TCP_PORTS[..],
+ let port_ranges = match constraints.port {
+ Constraint::Only(port) if port.protocol == TransportProtocol::Tcp => {
+ &WIREGUARD_TCP_PORTS[..]
+ }
_ => &data.port_ranges,
};
- match constraints.port {
+ match constraints
+ .port
+ .as_ref()
+ .map(|port| port.port)
+ .unwrap_or(Constraint::Any)
+ {
Constraint::Any => {
let get_port_amount =
|range: &(u16, u16)| -> u64 { (1 + range.1 - range.0) as u64 };
diff --git a/mullvad-management-interface/proto/management_interface.proto b/mullvad-management-interface/proto/management_interface.proto
index 1d3b40258b..489b8982d3 100644
--- a/mullvad-management-interface/proto/management_interface.proto
+++ b/mullvad-management-interface/proto/management_interface.proto
@@ -317,6 +317,11 @@ message TransportProtocolConstraint {
TransportProtocol protocol = 1;
}
+message TransportPort {
+ TransportProtocol protocol = 1;
+ uint32 port = 2;
+}
+
message OpenvpnConstraints {
uint32 port = 1;
TransportProtocolConstraint protocol = 2;
@@ -332,10 +337,9 @@ message IpVersionConstraint {
}
message WireguardConstraints {
- uint32 port = 1;
- TransportProtocolConstraint protocol = 2;
- IpVersionConstraint ip_version = 3;
- RelayLocation entry_location = 4;
+ TransportPort port = 1;
+ IpVersionConstraint ip_version = 2;
+ RelayLocation entry_location = 3;
}
message CustomRelaySettings {
diff --git a/mullvad-management-interface/src/types.rs b/mullvad-management-interface/src/types.rs
index 79a450e2c3..cf3a624d3d 100644
--- a/mullvad-management-interface/src/types.rs
+++ b/mullvad-management-interface/src/types.rs
@@ -319,6 +319,15 @@ impl From<IpVersion> for IpVersionConstraint {
}
}
+impl From<mullvad_types::relay_constraints::TransportPort> for TransportPort {
+ fn from(port: mullvad_types::relay_constraints::TransportPort) -> Self {
+ TransportPort {
+ protocol: TransportProtocol::from(port.protocol) as i32,
+ port: port.port.map(u32::from).unwrap_or(0),
+ }
+ }
+}
+
impl
From<
mullvad_types::relay_constraints::Constraint<
@@ -491,14 +500,11 @@ impl From<mullvad_types::relay_constraints::RelaySettings> for RelaySettings {
}),
wireguard_constraints: Some(WireguardConstraints {
- port: u32::from(constraints.wireguard_constraints.port.unwrap_or(0)),
- protocol: constraints
+ port: constraints
.wireguard_constraints
- .protocol
- .as_ref()
+ .port
.option()
- .map(|protocol| TransportProtocol::from(*protocol))
- .map(TransportProtocolConstraint::from),
+ .map(TransportPort::from),
ip_version: constraints
.wireguard_constraints
.ip_version
@@ -892,16 +898,22 @@ impl TryFrom<RelaySettingsUpdate> for mullvad_types::relay_constraints::RelaySet
} else {
None
};
- let wireguard_transport_protocol =
+ let wireguard_transport_port =
if let Some(ref constraints) = settings.wireguard_constraints {
- match &constraints.protocol {
- Some(constraint) => Some(
- TransportProtocol::from_i32(constraint.protocol)
+ match &constraints.port {
+ Some(port) => {
+ let protocol = TransportProtocol::from_i32(port.protocol)
.ok_or(FromProtobufTypeError::InvalidArgument(
"invalid transport protocol",
))?
- .into(),
- ),
+ .into();
+ let port = if port.port != 0 {
+ Constraint::Only(port.port as u16)
+ } else {
+ Constraint::Any
+ };
+ Some(mullvad_constraints::TransportPort { protocol, port })
+ }
None => None,
}
} else {
@@ -950,12 +962,7 @@ impl TryFrom<RelaySettingsUpdate> for mullvad_types::relay_constraints::RelaySet
tunnel_protocol,
wireguard_constraints: settings.wireguard_constraints.map(|constraints| {
mullvad_constraints::WireguardConstraints {
- port: if constraints.port != 0 {
- Constraint::Only(constraints.port as u16)
- } else {
- Constraint::Any
- },
- protocol: Constraint::from(wireguard_transport_protocol),
+ port: Constraint::from(wireguard_transport_port),
ip_version: Constraint::from(ip_version),
entry_location: constraints.entry_location.map(
Constraint::<
diff --git a/mullvad-types/src/relay_constraints.rs b/mullvad-types/src/relay_constraints.rs
index 100daa2088..5e300716b9 100644
--- a/mullvad-types/src/relay_constraints.rs
+++ b/mullvad-types/src/relay_constraints.rs
@@ -445,6 +445,12 @@ impl Match<WireguardEndpointData> for TunnelConstraints {
}
}
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Deserialize, Serialize)]
+pub struct TransportPort {
+ pub protocol: TransportProtocol,
+ pub port: Constraint<u16>,
+}
+
/// [`Constraint`]s applicable to OpenVPN relay servers.
#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Deserialize, Serialize)]
pub struct OpenVpnConstraints {
@@ -476,8 +482,7 @@ impl Match<OpenVpnEndpointData> for OpenVpnConstraints {
#[derive(Debug, Default, Clone, Eq, PartialEq, Deserialize, Serialize)]
#[serde(default)]
pub struct WireguardConstraints {
- pub port: Constraint<u16>,
- pub protocol: Constraint<TransportProtocol>,
+ pub port: Constraint<TransportPort>,
pub ip_version: Constraint<IpVersion>,
pub entry_location: Option<Constraint<LocationConstraint>>,
}
@@ -486,12 +491,13 @@ impl fmt::Display for WireguardConstraints {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
match self.port {
Constraint::Any => write!(f, "any port")?,
- Constraint::Only(port) => write!(f, "port {}", port)?,
- }
- write!(f, " over ")?;
- match self.protocol {
- Constraint::Any => write!(f, "any protocol")?,
- Constraint::Only(protocol) => write!(f, "{}", protocol)?,
+ Constraint::Only(port) => {
+ match port.port {
+ Constraint::Any => write!(f, "any port")?,
+ Constraint::Only(port) => write!(f, "port {}", port)?,
+ }
+ write!(f, " over {}", port.protocol)?;
+ }
}
write!(f, " over ")?;
match self.ip_version {
@@ -510,10 +516,13 @@ impl Match<WireguardEndpointData> for WireguardConstraints {
fn matches(&self, endpoint: &WireguardEndpointData) -> bool {
match self.port {
Constraint::Any => true,
- Constraint::Only(port) => endpoint
- .port_ranges
- .iter()
- .any(|range| (port >= range.0 && port <= range.1)),
+ Constraint::Only(port) => match port.port {
+ Constraint::Any => true,
+ Constraint::Only(port) => endpoint
+ .port_ranges
+ .iter()
+ .any(|range| (port >= range.0 && port <= range.1)),
+ },
}
}
}