summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOskar Nyberg <oskar@mullvad.net>2021-09-13 13:35:20 +0200
committerOskar Nyberg <oskar@mullvad.net>2021-09-13 13:35:20 +0200
commitb8930db15b76d1866ab18cd58cdf9936dbe0ffa2 (patch)
tree6e6e0f647050d3bfc08758283ed6137b62cbe67f
parent343fd4ff64150920f14de07c66385f5bb3fff9ed (diff)
parent268644e1193789539b6226eb04704a7a6f29d938 (diff)
downloadmullvadvpn-b8930db15b76d1866ab18cd58cdf9936dbe0ffa2.tar.xz
mullvadvpn-b8930db15b76d1866ab18cd58cdf9936dbe0ffa2.zip
Merge branch 'add-ip-version-setting'
-rw-r--r--CHANGELOG.md1
-rw-r--r--gui/locales/messages.pot15
-rw-r--r--gui/src/main/daemon-rpc.ts33
-rw-r--r--gui/src/main/index.ts1
-rw-r--r--gui/src/renderer/app.tsx5
-rw-r--r--gui/src/renderer/components/WireguardSettings.tsx55
-rw-r--r--gui/src/renderer/containers/WireguardSettingsPage.tsx17
-rw-r--r--gui/src/renderer/redux/settings/reducers.ts4
-rw-r--r--gui/src/shared/daemon-rpc-types.ts3
-rw-r--r--gui/src/shared/relay-settings-builder.ts12
10 files changed, 133 insertions, 13 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2ddd96508a..ae614d1461 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -29,6 +29,7 @@ Line wrap the file at 100 chars. Th
- Add WireGuard over TCP CLI option for all relays.
- Add GUI environment variable `MULLVAD_DISABLE_UPDATE_NOTIFICATION`. If set to `1`, GUI
notification will be disabled when an update is available.
+- Add setting for changing between IPv4 and IPv6 for the connection to WireGuard servers on desktop.
#### Android
- Added toggle for Split tunneling view to be able to show system apps
diff --git a/gui/locales/messages.pot b/gui/locales/messages.pot
index a5eaab8525..84f8b8d24e 100644
--- a/gui/locales/messages.pot
+++ b/gui/locales/messages.pot
@@ -120,6 +120,12 @@ msgstr ""
msgid "Invalid account number"
msgstr ""
+msgid "IPv4"
+msgstr ""
+
+msgid "IPv6"
+msgstr ""
+
msgid "less than a day"
msgstr ""
@@ -1243,6 +1249,10 @@ msgid "WireGuard settings"
msgstr ""
msgctxt "wireguard-settings-view"
+msgid "IP version"
+msgstr ""
+
+msgctxt "wireguard-settings-view"
msgid "MTU"
msgstr ""
@@ -1263,6 +1273,11 @@ msgctxt "wireguard-settings-view"
msgid "The automatic setting will randomly choose from a wide range of ports."
msgstr ""
+#. The hint displayed below the WireGuard IP version selector.
+msgctxt "wireguard-settings-view"
+msgid "This allows access to WireGuard for devices that only support IPv6."
+msgstr ""
+
msgctxt "wireguard-settings-view"
msgid "WireGuard key"
msgstr ""
diff --git a/gui/src/main/daemon-rpc.ts b/gui/src/main/daemon-rpc.ts
index c52c2370da..7464e0b5c9 100644
--- a/gui/src/main/daemon-rpc.ts
+++ b/gui/src/main/daemon-rpc.ts
@@ -1157,12 +1157,24 @@ function convertFromOpenVpnConstraints(
function convertFromWireguardConstraints(
constraints: grpcTypes.WireguardConstraints,
): IWireguardConstraints {
- const transportPort = convertFromConstraint(constraints.getPort());
- if (transportPort !== 'any' && 'only' in transportPort) {
- const port = convertFromConstraint(transportPort.only.getPort());
- return { port };
+ const result: IWireguardConstraints = { port: 'any', ipVersion: 'any' };
+
+ const port = constraints.getPort()?.getPort();
+ if (port) {
+ result.port = { only: port };
+ }
+
+ const ipVersion = constraints.getIpVersion()?.getProtocol();
+ switch (ipVersion) {
+ case grpcTypes.IpVersion.V4:
+ result.ipVersion = { only: 'ipv4' };
+ break;
+ case grpcTypes.IpVersion.V6:
+ result.ipVersion = { only: 'ipv6' };
+ break;
}
- return { port: 'any' };
+
+ return result;
}
function convertFromTunnelTypeConstraint(
@@ -1265,6 +1277,7 @@ function convertToWireguardConstraints(
): grpcTypes.WireguardConstraints | undefined {
if (constraint) {
const wireguardConstraints = new grpcTypes.WireguardConstraints();
+
const port = liftConstraint(constraint.port);
if (port) {
const portConstraints = new grpcTypes.TransportPort();
@@ -1272,6 +1285,16 @@ function convertToWireguardConstraints(
portConstraints.setProtocol(grpcTypes.TransportProtocol.UDP);
wireguardConstraints.setPort(portConstraints);
}
+
+ const ipVersion = liftConstraint(constraint.ipVersion);
+ if (ipVersion) {
+ const ipVersionProtocol =
+ ipVersion === 'ipv4' ? grpcTypes.IpVersion.V4 : grpcTypes.IpVersion.V6;
+ const ipVersionConstraints = new grpcTypes.IpVersionConstraint();
+ ipVersionConstraints.setProtocol(ipVersionProtocol);
+ wireguardConstraints.setIpVersion(ipVersionConstraints);
+ }
+
return wireguardConstraints;
}
return undefined;
diff --git a/gui/src/main/index.ts b/gui/src/main/index.ts
index ff7e9e64a7..34aa60ce6d 100644
--- a/gui/src/main/index.ts
+++ b/gui/src/main/index.ts
@@ -152,6 +152,7 @@ class ApplicationMain {
},
wireguardConstraints: {
port: 'any',
+ ipVersion: 'any',
},
},
},
diff --git a/gui/src/renderer/app.tsx b/gui/src/renderer/app.tsx
index cf7a354694..c888480033 100644
--- a/gui/src/renderer/app.tsx
+++ b/gui/src/renderer/app.tsx
@@ -644,7 +644,10 @@ export default class AppRenderer {
port: liftConstraint(openvpnConstraints.port),
protocol: liftConstraint(openvpnConstraints.protocol),
},
- wireguard: { port: liftConstraint(wireguardConstraints.port) },
+ wireguard: {
+ port: liftConstraint(wireguardConstraints.port),
+ ipVersion: liftConstraint(wireguardConstraints.ipVersion),
+ },
tunnelProtocol: liftConstraint(tunnelProtocol),
},
});
diff --git a/gui/src/renderer/components/WireguardSettings.tsx b/gui/src/renderer/components/WireguardSettings.tsx
index f60ac9fb53..8bd379d7d4 100644
--- a/gui/src/renderer/components/WireguardSettings.tsx
+++ b/gui/src/renderer/components/WireguardSettings.tsx
@@ -1,6 +1,7 @@
import * as React from 'react';
import { sprintf } from 'sprintf-js';
import styled from 'styled-components';
+import { IpVersion } from '../../shared/daemon-rpc-types';
import { messages } from '../../shared/gettext';
import { AriaDescription, AriaInput, AriaInputGroup, AriaLabel } from './AriaGroup';
import * as Cell from './cell';
@@ -21,6 +22,7 @@ const MAX_WIREGUARD_MTU_VALUE = 1420;
const WIREUGARD_UDP_PORTS = [51820, 53];
type OptionalPort = number | undefined;
+type OptionalIpVersion = IpVersion | undefined;
function mapPortToSelectorItem(value: number): ISelectorItem<number> {
return { label: value.toString(), value };
@@ -43,16 +45,17 @@ export const StyledInputFrame = styled(Cell.InputFrame)({
});
interface IProps {
- wireguard: { port?: number };
+ wireguard: { port?: number; ipVersion?: IpVersion };
wireguardMtu?: number;
setWireguardMtu: (value: number | undefined) => void;
- setWireguardRelayPort: (port?: number) => void;
+ setWireguardRelayPortAndIpVersion: (port?: number, ipVersion?: IpVersion) => void;
onViewWireguardKeys: () => void;
onClose: () => void;
}
export default class WireguardSettings extends React.Component<IProps> {
private wireguardPortItems: Array<ISelectorItem<OptionalPort>>;
+ private wireguardIpVersionItems: Array<ISelectorItem<OptionalIpVersion>>;
constructor(props: IProps) {
super(props);
@@ -65,6 +68,21 @@ export default class WireguardSettings extends React.Component<IProps> {
this.wireguardPortItems = [automaticPort].concat(
WIREUGARD_UDP_PORTS.map(mapPortToSelectorItem),
);
+
+ this.wireguardIpVersionItems = [
+ {
+ label: messages.gettext('Automatic'),
+ value: undefined,
+ },
+ {
+ label: messages.gettext('IPv4'),
+ value: 'ipv4',
+ },
+ {
+ label: messages.gettext('IPv6'),
+ value: 'ipv6',
+ },
+ ];
}
public render() {
@@ -99,7 +117,7 @@ export default class WireguardSettings extends React.Component<IProps> {
<AriaInputGroup>
<StyledSelectorContainer>
<StyledSelectorForFooter
- // TRANSLATORS: The title for the shadowsocks bridge selector section.
+ // TRANSLATORS: The title for the WireGuard port selector.
title={messages.pgettext('wireguard-settings-view', 'Port')}
values={this.wireguardPortItems}
value={this.props.wireguard.port}
@@ -121,6 +139,31 @@ export default class WireguardSettings extends React.Component<IProps> {
</Cell.Footer>
</AriaInputGroup>
+ <AriaInputGroup>
+ <StyledSelectorContainer>
+ <StyledSelectorForFooter
+ // TRANSLATORS: The title for the WireGuard IP version selector.
+ title={messages.pgettext('wireguard-settings-view', 'IP version')}
+ values={this.wireguardIpVersionItems}
+ value={this.props.wireguard.ipVersion}
+ onSelect={this.onSelectWireguardIpVersion}
+ />
+ </StyledSelectorContainer>
+ <Cell.Footer>
+ <AriaDescription>
+ <Cell.FooterText>
+ {
+ // TRANSLATORS: The hint displayed below the WireGuard IP version selector.
+ messages.pgettext(
+ 'wireguard-settings-view',
+ 'This allows access to WireGuard for devices that only support IPv6.',
+ )
+ }
+ </Cell.FooterText>
+ </AriaDescription>
+ </Cell.Footer>
+ </AriaInputGroup>
+
<Cell.CellButtonGroup>
<Cell.CellButton onClick={this.props.onViewWireguardKeys}>
<Cell.Label>
@@ -181,7 +224,11 @@ export default class WireguardSettings extends React.Component<IProps> {
}
private onSelectWireguardPort = (port?: number) => {
- this.props.setWireguardRelayPort(port);
+ this.props.setWireguardRelayPortAndIpVersion(port, this.props.wireguard.ipVersion);
+ };
+
+ private onSelectWireguardIpVersion = (ipVersion?: IpVersion) => {
+ this.props.setWireguardRelayPortAndIpVersion(this.props.wireguard.port, ipVersion);
};
private static removeNonNumericCharacters(value: string) {
diff --git a/gui/src/renderer/containers/WireguardSettingsPage.tsx b/gui/src/renderer/containers/WireguardSettingsPage.tsx
index e89bcff62a..cf7833d116 100644
--- a/gui/src/renderer/containers/WireguardSettingsPage.tsx
+++ b/gui/src/renderer/containers/WireguardSettingsPage.tsx
@@ -1,4 +1,5 @@
import { connect } from 'react-redux';
+import { IpVersion } from '../../shared/daemon-rpc-types';
import log from '../../shared/logging';
import RelaySettingsBuilder from '../../shared/relay-settings-builder';
import WireguardSettings from '../components/WireguardSettings';
@@ -21,7 +22,13 @@ const mapStateToProps = (state: IReduxState) => {
const mapRelaySettingsToProtocolAndPort = (relaySettings: RelaySettingsRedux) => {
if ('normal' in relaySettings) {
const port = relaySettings.normal.wireguard.port;
- return { wireguard: { port: port === 'any' ? undefined : port } };
+ const ipVersion = relaySettings.normal.wireguard.ipVersion;
+ return {
+ wireguard: {
+ port: port === 'any' ? undefined : port,
+ ipVersion: ipVersion === 'any' ? undefined : ipVersion,
+ },
+ };
// since the GUI doesn't display custom settings, just display the default ones.
// If the user sets any settings, then those will be applied.
} else if ('customTunnelEndpoint' in relaySettings) {
@@ -39,7 +46,7 @@ const mapDispatchToProps = (_dispatch: ReduxDispatch, props: IHistoryProps & IAp
props.history.pop();
},
- setWireguardRelayPort: async (port?: number) => {
+ setWireguardRelayPortAndIpVersion: async (port?: number, ipVersion?: IpVersion) => {
const relayUpdate = RelaySettingsBuilder.normal()
.tunnel.wireguard((wireguard) => {
if (port) {
@@ -47,6 +54,12 @@ const mapDispatchToProps = (_dispatch: ReduxDispatch, props: IHistoryProps & IAp
} else {
wireguard.port.any();
}
+
+ if (ipVersion) {
+ wireguard.ipVersion.exact(ipVersion);
+ } else {
+ wireguard.ipVersion.any();
+ }
})
.build();
try {
diff --git a/gui/src/renderer/redux/settings/reducers.ts b/gui/src/renderer/redux/settings/reducers.ts
index bbab124d36..3e1e5cb19d 100644
--- a/gui/src/renderer/redux/settings/reducers.ts
+++ b/gui/src/renderer/redux/settings/reducers.ts
@@ -8,6 +8,7 @@ import {
RelayProtocol,
TunnelProtocol,
IDnsOptions,
+ IpVersion,
} from '../../../shared/daemon-rpc-types';
import { IGuiSettingsState } from '../../../shared/gui-settings-state';
import log from '../../../shared/logging';
@@ -25,6 +26,7 @@ export type RelaySettingsRedux =
};
wireguard: {
port: LiftedConstraint<number>;
+ ipVersion: LiftedConstraint<IpVersion>;
};
};
}
@@ -159,7 +161,7 @@ const initialState: ISettingsReduxState = {
location: 'any',
tunnelProtocol: 'any',
providers: [],
- wireguard: { port: 'any' },
+ wireguard: { port: 'any', ipVersion: 'any' },
openvpn: {
port: 'any',
protocol: 'any',
diff --git a/gui/src/shared/daemon-rpc-types.ts b/gui/src/shared/daemon-rpc-types.ts
index 0ce24bf8a2..8e42147f43 100644
--- a/gui/src/shared/daemon-rpc-types.ts
+++ b/gui/src/shared/daemon-rpc-types.ts
@@ -130,10 +130,13 @@ export interface IOpenVpnConstraints {
export interface IWireguardConstraints {
port: Constraint<number>;
+ ipVersion: Constraint<IpVersion>;
}
export type TunnelProtocol = 'wireguard' | 'openvpn';
+export type IpVersion = 'ipv4' | 'ipv6';
+
interface IRelaySettingsNormal<OpenVpn, Wireguard> {
location: Constraint<RelayLocation>;
tunnelProtocol: Constraint<TunnelProtocol>;
diff --git a/gui/src/shared/relay-settings-builder.ts b/gui/src/shared/relay-settings-builder.ts
index 182e44063f..418de10888 100644
--- a/gui/src/shared/relay-settings-builder.ts
+++ b/gui/src/shared/relay-settings-builder.ts
@@ -1,6 +1,7 @@
import {
Constraint,
IOpenVpnConstraints,
+ IpVersion,
IWireguardConstraints,
RelayProtocol,
RelaySettingsNormalUpdate,
@@ -21,6 +22,7 @@ interface IOpenVPNConfigurator {
interface IWireguardConfigurator {
port: IExactOrAny<number, IWireguardConfigurator>;
+ ipVersion: IExactOrAny<IpVersion, IWireguardConfigurator>;
}
interface ITunnelProtocolConfigurator {
@@ -125,6 +127,16 @@ class NormalRelaySettingsBuilder {
any: () => apply('any'),
};
},
+ get ipVersion() {
+ const apply = (ipVersion: Constraint<IpVersion>) => {
+ updateWireguard({ ipVersion });
+ return this;
+ };
+ return {
+ exact: (value: IpVersion) => apply({ only: value }),
+ any: () => apply('any'),
+ };
+ },
};
configurator(wireguardBuilder);
return this;