diff options
| author | Oskar Nyberg <oskar@mullvad.net> | 2021-09-13 13:35:20 +0200 |
|---|---|---|
| committer | Oskar Nyberg <oskar@mullvad.net> | 2021-09-13 13:35:20 +0200 |
| commit | b8930db15b76d1866ab18cd58cdf9936dbe0ffa2 (patch) | |
| tree | 6e6e0f647050d3bfc08758283ed6137b62cbe67f | |
| parent | 343fd4ff64150920f14de07c66385f5bb3fff9ed (diff) | |
| parent | 268644e1193789539b6226eb04704a7a6f29d938 (diff) | |
| download | mullvadvpn-b8930db15b76d1866ab18cd58cdf9936dbe0ffa2.tar.xz mullvadvpn-b8930db15b76d1866ab18cd58cdf9936dbe0ffa2.zip | |
Merge branch 'add-ip-version-setting'
| -rw-r--r-- | CHANGELOG.md | 1 | ||||
| -rw-r--r-- | gui/locales/messages.pot | 15 | ||||
| -rw-r--r-- | gui/src/main/daemon-rpc.ts | 33 | ||||
| -rw-r--r-- | gui/src/main/index.ts | 1 | ||||
| -rw-r--r-- | gui/src/renderer/app.tsx | 5 | ||||
| -rw-r--r-- | gui/src/renderer/components/WireguardSettings.tsx | 55 | ||||
| -rw-r--r-- | gui/src/renderer/containers/WireguardSettingsPage.tsx | 17 | ||||
| -rw-r--r-- | gui/src/renderer/redux/settings/reducers.ts | 4 | ||||
| -rw-r--r-- | gui/src/shared/daemon-rpc-types.ts | 3 | ||||
| -rw-r--r-- | gui/src/shared/relay-settings-builder.ts | 12 |
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; |
