summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMarkus Pettersson <markus.pettersson@mullvad.net>2025-07-14 13:52:43 +0200
committerDavid Lönnhager <david.l@mullvad.net>2025-07-23 09:41:54 +0200
commit5bf76da983c89530743ee7b6e21ea5a6d93d8697 (patch)
tree78e04d0ad4dbec45cdf713817c0ef19407940ef3
parentc30fd84b3aaf7945e5fde9cbe48cf73e7c6463ca (diff)
downloadmullvadvpn-5bf76da983c89530743ee7b6e21ea5a6d93d8697.tar.xz
mullvadvpn-5bf76da983c89530743ee7b6e21ea5a6d93d8697.zip
Filter relay list by QUIC
-rw-r--r--desktop/packages/mullvad-vpn/src/main/grpc-type-convertions.ts17
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/select-location/RelayListContext.tsx18
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/lib/filter-locations.ts10
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/redux/settings/reducers.ts2
-rw-r--r--desktop/packages/mullvad-vpn/src/shared/daemon-rpc-types.ts16
5 files changed, 59 insertions, 4 deletions
diff --git a/desktop/packages/mullvad-vpn/src/main/grpc-type-convertions.ts b/desktop/packages/mullvad-vpn/src/main/grpc-type-convertions.ts
index 6d8ebcb17b..1a49dae202 100644
--- a/desktop/packages/mullvad-vpn/src/main/grpc-type-convertions.ts
+++ b/desktop/packages/mullvad-vpn/src/main/grpc-type-convertions.ts
@@ -25,6 +25,7 @@ import {
ErrorStateCause,
ErrorStateDetails,
FeatureIndicator,
+ FeaturesType,
FirewallPolicyError,
FirewallPolicyErrorType,
IAppVersionInfo,
@@ -129,6 +130,7 @@ function convertFromRelayListRelay(relay: grpcTypes.Relay): IRelayListHostname {
return {
...relayObject,
endpointType: convertFromRelayType(relayObject.endpointType),
+ features: relayObject.features ? featuresFromRelayType(relayObject.features) : undefined,
daita,
};
}
@@ -142,6 +144,21 @@ function convertFromRelayType(relayType: grpcTypes.Relay.RelayType): RelayEndpoi
return protocolMap[relayType];
}
+function featuresFromRelayType(features: grpcTypes.Relay.Features.AsObject): FeaturesType {
+ const daita = features.daita;
+ const quic = features.quic
+ ? {
+ domain: features.quic.domain,
+ token: features.quic.token,
+ addr_in: features.quic.addrInList,
+ }
+ : undefined;
+ return {
+ daita,
+ quic,
+ };
+}
+
function convertFromWireguardKey(publicKey: Uint8Array | string): string {
if (typeof publicKey === 'string') {
return publicKey;
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/select-location/RelayListContext.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/select-location/RelayListContext.tsx
index 07b2aa9c62..bc5fbecdca 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/select-location/RelayListContext.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/select-location/RelayListContext.tsx
@@ -1,6 +1,10 @@
import React, { useCallback, useContext, useEffect, useMemo, useState } from 'react';
-import { compareRelayLocation, RelayLocation } from '../../../shared/daemon-rpc-types';
+import {
+ compareRelayLocation,
+ ObfuscationType,
+ RelayLocation,
+} from '../../../shared/daemon-rpc-types';
import {
EndpointType,
filterLocations,
@@ -68,6 +72,9 @@ export function RelayListContextProvider(props: RelayListContextProviderProps) {
const { locationType, searchTerm } = useSelectLocationContext();
const daita = useSelector((state) => state.settings.wireguard.daita?.enabled ?? false);
const directOnly = useSelector((state) => state.settings.wireguard.daita?.directOnly ?? false);
+ const quic = useSelector(
+ (state) => state.settings.obfuscationSettings.selectedObfuscation === ObfuscationType.quic,
+ );
const fullRelayList = useSelector((state) => state.settings.relayLocations);
const relaySettings = useNormalRelaySettings();
@@ -99,11 +106,16 @@ export function RelayListContextProvider(props: RelayListContextProviderProps) {
relaySettings?.wireguard.useMultihop,
]);
+ // Only show relays that have QUIC endpoints when QUIC obfuscation is enabled.
+ const relayListForQuic = useMemo(() => {
+ return filterLocationsByQuic(relayListForDaita, quic, tunnelProtocol);
+ }, [quic, relayListForDaita, tunnelProtocol]);
+
// Filters the relays to only keep the relays matching the currently selected filters, e.g.
// ownership and providers
const relayListForFilters = useMemo(() => {
- return filterLocations(relayListForDaita, relaySettings?.ownership, relaySettings?.providers);
- }, [relaySettings?.ownership, relaySettings?.providers, relayListForDaita]);
+ return filterLocations(relayListForQuic, relaySettings?.ownership, relaySettings?.providers);
+ }, [relaySettings?.ownership, relaySettings?.providers, relayListForQuic]);
// Filters the relays based on the provided search term
const relayListForSearch = useMemo(() => {
diff --git a/desktop/packages/mullvad-vpn/src/renderer/lib/filter-locations.ts b/desktop/packages/mullvad-vpn/src/renderer/lib/filter-locations.ts
index f73bd14a9e..fcfd3a38da 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/lib/filter-locations.ts
+++ b/desktop/packages/mullvad-vpn/src/renderer/lib/filter-locations.ts
@@ -32,6 +32,16 @@ export function filterLocationsByEndPointType(
return filterLocationsImpl(locations, getTunnelProtocolFilter(endpointType, tunnelProtocol));
}
+export function filterLocationsByQuic(
+ locations: IRelayLocationCountryRedux[],
+ quic: boolean,
+ tunnelProtocol: TunnelProtocol,
+): IRelayLocationCountryRedux[] {
+ const quicFilterActive = quic && tunnelProtocol !== 'openvpn';
+ const quickOnRelay = (relay: IRelayLocationRelayRedux) => relay.features?.quic !== undefined;
+ return quicFilterActive ? filterLocationsImpl(locations, quickOnRelay) : locations;
+}
+
export function filterLocationsByDaita(
locations: IRelayLocationCountryRedux[],
daita: boolean,
diff --git a/desktop/packages/mullvad-vpn/src/renderer/redux/settings/reducers.ts b/desktop/packages/mullvad-vpn/src/renderer/redux/settings/reducers.ts
index 909004faf6..9fc8a6d30e 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/redux/settings/reducers.ts
+++ b/desktop/packages/mullvad-vpn/src/renderer/redux/settings/reducers.ts
@@ -7,6 +7,7 @@ import {
BridgeType,
CustomLists,
CustomProxy,
+ FeaturesType,
IDaitaSettings,
IDnsOptions,
IpVersion,
@@ -77,6 +78,7 @@ export interface IRelayLocationRelayRedux {
weight: number;
endpointType: RelayEndpointType;
daita: boolean;
+ features?: FeaturesType;
}
export interface IRelayLocationCityRedux {
diff --git a/desktop/packages/mullvad-vpn/src/shared/daemon-rpc-types.ts b/desktop/packages/mullvad-vpn/src/shared/daemon-rpc-types.ts
index 63ec8d0b9b..f12c3123f8 100644
--- a/desktop/packages/mullvad-vpn/src/shared/daemon-rpc-types.ts
+++ b/desktop/packages/mullvad-vpn/src/shared/daemon-rpc-types.ts
@@ -340,6 +340,7 @@ export type ConnectionConfig =
addresses: string[];
endpoint: string;
};
+
ipv4Gateway: string;
ipv6Gateway?: string;
};
@@ -395,9 +396,22 @@ export interface IRelayListHostname {
weight: number;
owned: boolean;
endpointType: RelayEndpointType;
- daita: boolean;
+ daita: boolean; // TODO: Deprecate in favor of Features 👇
+ features?: FeaturesType;
}
+// The absence of a value signals that the relay does not have it enabled.
+export type FeaturesType = {
+ daita: boolean;
+ quic?: Quic;
+};
+
+export type Quic = {
+ domain: string;
+ token: string;
+ addrIn: string[];
+};
+
export type RelayEndpointType = 'wireguard' | 'openvpn' | 'bridge';
export interface ITunnelOptions {