Peer: prefer v4 endpoints to v6
This works around DNS64 XLAT changeovers. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
parent
49a9475c4a
commit
c23d58bc27
71
app/src/main/java/com/wireguard/config/InetEndpoint.java
Normal file
71
app/src/main/java/com/wireguard/config/InetEndpoint.java
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.wireguard.config;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
|
||||||
|
import com.wireguard.android.Application;
|
||||||
|
import com.wireguard.android.R;
|
||||||
|
|
||||||
|
import java.net.Inet4Address;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
public class InetEndpoint {
|
||||||
|
private final String host;
|
||||||
|
private final int port;
|
||||||
|
@Nullable private InetAddress resolvedHost;
|
||||||
|
|
||||||
|
public InetEndpoint(@Nullable final String endpoint) {
|
||||||
|
if (endpoint.indexOf('/') != -1 || endpoint.indexOf('?') != -1 || endpoint.indexOf('#') != -1)
|
||||||
|
throw new IllegalArgumentException(Application.get().getString(R.string.tunnel_error_forbidden_endpoint_chars));
|
||||||
|
final URI uri;
|
||||||
|
try {
|
||||||
|
uri = new URI("wg://" + endpoint);
|
||||||
|
} catch (final URISyntaxException e) {
|
||||||
|
throw new IllegalArgumentException(e);
|
||||||
|
}
|
||||||
|
host = uri.getHost();
|
||||||
|
port = uri.getPort();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHost() {
|
||||||
|
return host;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPort() {
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("DefaultLocale")
|
||||||
|
public String getResolvedEndpoint() throws UnknownHostException {
|
||||||
|
if (resolvedHost == null) {
|
||||||
|
final InetAddress[] candidates = InetAddress.getAllByName(host);
|
||||||
|
if (candidates.length == 0)
|
||||||
|
throw new UnknownHostException(host);
|
||||||
|
for (final InetAddress addr : candidates) {
|
||||||
|
if (addr instanceof Inet4Address) {
|
||||||
|
resolvedHost = addr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (resolvedHost == null)
|
||||||
|
resolvedHost = candidates[0];
|
||||||
|
}
|
||||||
|
return String.format(resolvedHost instanceof Inet4Address ?
|
||||||
|
"[%s]:%d" : "%s:%d", resolvedHost.getHostAddress(), port);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("DefaultLocale")
|
||||||
|
public String getEndpoint() {
|
||||||
|
return String.format(host.contains(":") && !host.contains("[") ?
|
||||||
|
"[%s]:%d" : "%s:%d", host, port);
|
||||||
|
}
|
||||||
|
}
|
@ -37,7 +37,7 @@ import java9.lang.Iterables;
|
|||||||
|
|
||||||
public class Peer {
|
public class Peer {
|
||||||
private final List<InetNetwork> allowedIPsList;
|
private final List<InetNetwork> allowedIPsList;
|
||||||
@Nullable private InetSocketAddress endpoint;
|
@Nullable private InetEndpoint endpoint;
|
||||||
private int persistentKeepalive;
|
private int persistentKeepalive;
|
||||||
@Nullable private String preSharedKey;
|
@Nullable private String preSharedKey;
|
||||||
@Nullable private String publicKey;
|
@Nullable private String publicKey;
|
||||||
@ -67,19 +67,15 @@ public class Peer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public InetSocketAddress getEndpoint() {
|
public InetEndpoint getEndpoint() {
|
||||||
return endpoint;
|
return endpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("DefaultLocale")
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private String getEndpointString() {
|
private String getEndpointString() {
|
||||||
if (endpoint == null)
|
if (endpoint == null)
|
||||||
return null;
|
return null;
|
||||||
if (endpoint.getHostString().contains(":") && !endpoint.getHostString().contains("["))
|
return endpoint.getEndpoint();
|
||||||
return String.format("[%s]:%d", endpoint.getHostString(), endpoint.getPort());
|
|
||||||
else
|
|
||||||
return String.format("%s:%d", endpoint.getHostString(), endpoint.getPort());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getPersistentKeepalive() {
|
public int getPersistentKeepalive() {
|
||||||
@ -103,21 +99,10 @@ public class Peer {
|
|||||||
return publicKey;
|
return publicKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("DefaultLocale")
|
|
||||||
public String getResolvedEndpointString() throws UnknownHostException {
|
public String getResolvedEndpointString() throws UnknownHostException {
|
||||||
if (endpoint == null)
|
if (endpoint == null)
|
||||||
throw new UnknownHostException("{empty}");
|
throw new UnknownHostException("{empty}");
|
||||||
if (endpoint.isUnresolved())
|
return endpoint.getResolvedEndpoint();
|
||||||
endpoint = new InetSocketAddress(endpoint.getHostString(), endpoint.getPort());
|
|
||||||
if (endpoint.isUnresolved())
|
|
||||||
throw new UnknownHostException(endpoint.getHostString());
|
|
||||||
if (endpoint.getAddress() instanceof Inet6Address)
|
|
||||||
return String.format("[%s]:%d",
|
|
||||||
endpoint.getAddress().getHostAddress(),
|
|
||||||
endpoint.getPort());
|
|
||||||
return String.format("%s:%d",
|
|
||||||
endpoint.getAddress().getHostAddress(),
|
|
||||||
endpoint.getPort());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void parse(final String line) {
|
public void parse(final String line) {
|
||||||
@ -150,24 +135,14 @@ public class Peer {
|
|||||||
addAllowedIPs(Attribute.stringToList(allowedIPsString));
|
addAllowedIPs(Attribute.stringToList(allowedIPsString));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setEndpoint(@Nullable final InetSocketAddress endpoint) {
|
private void setEndpoint(@Nullable final InetEndpoint endpoint) {
|
||||||
this.endpoint = endpoint;
|
this.endpoint = endpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setEndpointString(@Nullable final String endpoint) {
|
private void setEndpointString(@Nullable final String endpoint) {
|
||||||
if (endpoint != null && !endpoint.isEmpty()) {
|
if (endpoint != null && !endpoint.isEmpty())
|
||||||
final InetSocketAddress constructedEndpoint;
|
setEndpoint(new InetEndpoint(endpoint));
|
||||||
if (endpoint.indexOf('/') != -1 || endpoint.indexOf('?') != -1 || endpoint.indexOf('#') != -1)
|
else
|
||||||
throw new IllegalArgumentException(context.getString(R.string.tunnel_error_forbidden_endpoint_chars));
|
|
||||||
final URI uri;
|
|
||||||
try {
|
|
||||||
uri = new URI("wg://" + endpoint);
|
|
||||||
} catch (final URISyntaxException e) {
|
|
||||||
throw new IllegalArgumentException(e);
|
|
||||||
}
|
|
||||||
constructedEndpoint = InetSocketAddress.createUnresolved(uri.getHost(), uri.getPort());
|
|
||||||
setEndpoint(constructedEndpoint);
|
|
||||||
} else
|
|
||||||
setEndpoint(null);
|
setEndpoint(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user