diff options
7 files changed, 118 insertions, 90 deletions
diff --git a/app/src/main/java/com/wireguard/android/backend/GoBackend.java b/app/src/main/java/com/wireguard/android/backend/GoBackend.java index 10d8d911..fbe9d8ea 100644 --- a/app/src/main/java/com/wireguard/android/backend/GoBackend.java +++ b/app/src/main/java/com/wireguard/android/backend/GoBackend.java @@ -21,7 +21,7 @@ import com.wireguard.android.model.Tunnel.Statistics; import com.wireguard.android.util.ExceptionLoggers; import com.wireguard.android.util.SharedLibraryLoader; import com.wireguard.config.Config; -import com.wireguard.config.IPCidr; +import com.wireguard.config.InetNetwork; import com.wireguard.config.Interface; import com.wireguard.config.Peer; import com.wireguard.crypto.KeyEncoding; @@ -156,7 +156,7 @@ public final class GoBackend implements Backend { fmt.format("endpoint=%s\n", peer.getResolvedEndpointString()); if (peer.getPersistentKeepalive() != 0) fmt.format("persistent_keepalive_interval=%d\n", peer.getPersistentKeepalive()); - for (final IPCidr addr : peer.getAllowedIPs()) { + for (final InetNetwork addr : peer.getAllowedIPs()) { fmt.format("allowed_ip=%s\n", addr.toString()); } } @@ -171,15 +171,15 @@ public final class GoBackend implements Backend { configureIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); builder.setConfigureIntent(PendingIntent.getActivity(context, 0, configureIntent, 0)); - for (final IPCidr addr : config.getInterface().getAddresses()) - builder.addAddress(addr.getAddress(), addr.getCidr()); + for (final InetNetwork addr : config.getInterface().getAddresses()) + builder.addAddress(addr.getAddress(), addr.getMask()); for (final InetAddress addr : config.getInterface().getDnses()) builder.addDnsServer(addr.getHostAddress()); for (final Peer peer : config.getPeers()) { - for (final IPCidr addr : peer.getAllowedIPs()) - builder.addRoute(addr.getAddress(), addr.getCidr()); + for (final InetNetwork addr : peer.getAllowedIPs()) + builder.addRoute(addr.getAddress(), addr.getMask()); } int mtu = config.getInterface().getMtu(); diff --git a/app/src/main/java/com/wireguard/config/Attribute.java b/app/src/main/java/com/wireguard/config/Attribute.java index 98e9fcbc..7fbffa7f 100644 --- a/app/src/main/java/com/wireguard/config/Attribute.java +++ b/app/src/main/java/com/wireguard/config/Attribute.java @@ -8,9 +8,6 @@ package com.wireguard.config; import android.text.TextUtils; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.net.InetAddress; import java.util.HashMap; import java.util.Locale; import java.util.Map; @@ -36,7 +33,6 @@ enum Attribute { private static final String[] EMPTY_LIST = new String[0]; private static final Map<String, Attribute> KEY_MAP; private static final Pattern LIST_SEPARATOR_PATTERN = Pattern.compile("\\s*,\\s*"); - private static final Method NUMERIC_ADDRESS_PARSER; private static final Pattern SEPARATOR_PATTERN = Pattern.compile("\\s|="); static { @@ -46,14 +42,6 @@ enum Attribute { } } - static { - try { - NUMERIC_ADDRESS_PARSER = InetAddress.class.getMethod("parseNumericAddress", String.class); - } catch (final Exception e) { - throw new RuntimeException(e); - } - } - private final Pattern pattern; private final String token; @@ -70,21 +58,6 @@ enum Attribute { return KEY_MAP.get(SEPARATOR_PATTERN.split(line)[0].toLowerCase()); } - public static InetAddress parseIPString(final String address) { - if (address == null || address.isEmpty()) - throw new IllegalArgumentException("Empty address"); - try { - return (InetAddress) NUMERIC_ADDRESS_PARSER.invoke(null, address); - } catch (final IllegalAccessException e) { - throw new RuntimeException(e); - } catch (final InvocationTargetException e) { - if (e.getCause() instanceof IllegalArgumentException) - throw (IllegalArgumentException) e.getCause(); - else - throw new IllegalArgumentException(e.getCause()); - } - } - public static String[] stringToList(final String string) { if (string == null) return EMPTY_LIST; diff --git a/app/src/main/java/com/wireguard/config/IPCidr.java b/app/src/main/java/com/wireguard/config/IPCidr.java deleted file mode 100644 index bfa92e07..00000000 --- a/app/src/main/java/com/wireguard/config/IPCidr.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright © 2018 Samuel Holland <samuel@sholland.org> - * Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. - * SPDX-License-Identifier: GPL-2.0-or-later - */ - -package com.wireguard.config; - -import java.net.Inet4Address; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.util.Locale; - -public class IPCidr { - private final InetAddress address; - private int cidr; - - @SuppressWarnings("MagicNumber") - public IPCidr(String in) { - cidr = -1; - final int slash = in.lastIndexOf('/'); - if (slash != -1 && slash < in.length() - 1) { - try { - cidr = Integer.parseInt(in.substring(slash + 1), 10); - in = in.substring(0, slash); - } catch (final Exception ignored) { - } - } - address = Attribute.parseIPString(in); - if ((address instanceof Inet6Address) && (cidr > 128 || cidr < 0)) - cidr = 128; - else if ((address instanceof Inet4Address) && (cidr > 32 || cidr < 0)) - cidr = 32; - } - - public InetAddress getAddress() { - return address; - } - - public int getCidr() { - return cidr; - } - - @Override - public String toString() { - return String.format(Locale.getDefault(), "%s/%d", address.getHostAddress(), cidr); - } -} diff --git a/app/src/main/java/com/wireguard/config/InetAddresses.java b/app/src/main/java/com/wireguard/config/InetAddresses.java new file mode 100644 index 00000000..d351d53c --- /dev/null +++ b/app/src/main/java/com/wireguard/config/InetAddresses.java @@ -0,0 +1,42 @@ +/* + * Copyright © 2018 Samuel Holland <samuel@sholland.org> + * Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +package com.wireguard.config; + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.InetAddress; + +public final class InetAddresses { + private static final Method PARSER_METHOD; + + static { + try { + // This method is only present on Android. + PARSER_METHOD = InetAddress.class.getMethod("parseNumericAddress", String.class); + } catch (final NoSuchMethodException e) { + throw new RuntimeException(e); + } + } + + private InetAddresses() { + // Prevent instantiation. + } + + @NonNull + public static InetAddress parse(@Nullable final String address) { + if (address == null || address.isEmpty()) + throw new IllegalArgumentException("Empty address"); + try { + return (InetAddress) PARSER_METHOD.invoke(null, address); + } catch (final IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException(e); + } + } +} diff --git a/app/src/main/java/com/wireguard/config/InetNetwork.java b/app/src/main/java/com/wireguard/config/InetNetwork.java new file mode 100644 index 00000000..27825e6a --- /dev/null +++ b/app/src/main/java/com/wireguard/config/InetNetwork.java @@ -0,0 +1,61 @@ +/* + * Copyright © 2018 Samuel Holland <samuel@sholland.org> + * Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +package com.wireguard.config; + +import android.support.annotation.NonNull; + +import java.net.Inet4Address; +import java.net.InetAddress; +import java.util.Objects; + +public class InetNetwork { + private final InetAddress address; + private final int mask; + + public InetNetwork(@NonNull final String input) { + final int slash = input.lastIndexOf('/'); + final int rawMask; + final String rawAddress; + if (slash >= 0) { + rawMask = Integer.parseInt(input.substring(slash + 1), 10); + rawAddress = input.substring(0, slash); + } else { + rawMask = -1; + rawAddress = input; + } + address = InetAddresses.parse(rawAddress); + final int maxMask = (address instanceof Inet4Address) ? 32 : 128; + mask = rawMask >= 0 && rawMask <= maxMask ? rawMask : maxMask; + } + + @Override + public boolean equals(final Object obj) { + if (!(obj instanceof InetNetwork)) + return false; + final InetNetwork other = (InetNetwork) obj; + return Objects.equals(address, other.address) && mask == other.mask; + } + + @NonNull + public InetAddress getAddress() { + return address; + } + + public int getMask() { + return mask; + } + + @Override + public int hashCode() { + return address.hashCode() ^ mask; + } + + @Override + public String toString() { + return address.getHostAddress() + '/' + mask; + } +} diff --git a/app/src/main/java/com/wireguard/config/Interface.java b/app/src/main/java/com/wireguard/config/Interface.java index e9423518..824bb122 100644 --- a/app/src/main/java/com/wireguard/config/Interface.java +++ b/app/src/main/java/com/wireguard/config/Interface.java @@ -23,7 +23,7 @@ import java.util.List; */ public class Interface { - private final List<IPCidr> addressList; + private final List<InetNetwork> addressList; private final List<InetAddress> dnsList; private Keypair keypair; private int listenPort; @@ -39,7 +39,7 @@ public class Interface { for (final String addr : addresses) { if (addr.isEmpty()) throw new IllegalArgumentException("Address is empty"); - addressList.add(new IPCidr(addr)); + addressList.add(new InetNetwork(addr)); } } } @@ -47,7 +47,7 @@ public class Interface { private void addDnses(final String[] dnses) { if (dnses != null && dnses.length > 0) { for (final String dns : dnses) { - dnsList.add(Attribute.parseIPString(dns)); + dnsList.add(InetAddresses.parse(dns)); } } } @@ -58,8 +58,8 @@ public class Interface { return Attribute.iterableToString(addressList); } - public IPCidr[] getAddresses() { - return addressList.toArray(new IPCidr[addressList.size()]); + public InetNetwork[] getAddresses() { + return addressList.toArray(new InetNetwork[addressList.size()]); } private String getDnsString() { diff --git a/app/src/main/java/com/wireguard/config/Peer.java b/app/src/main/java/com/wireguard/config/Peer.java index 17ad7b29..1d69beb2 100644 --- a/app/src/main/java/com/wireguard/config/Peer.java +++ b/app/src/main/java/com/wireguard/config/Peer.java @@ -28,7 +28,7 @@ import java.util.Locale; */ public class Peer { - private final List<IPCidr> allowedIPsList; + private final List<InetNetwork> allowedIPsList; private InetSocketAddress endpoint; private int persistentKeepalive; private String preSharedKey; @@ -41,13 +41,13 @@ public class Peer { private void addAllowedIPs(final String[] allowedIPs) { if (allowedIPs != null && allowedIPs.length > 0) { for (final String allowedIP : allowedIPs) { - allowedIPsList.add(new IPCidr(allowedIP)); + allowedIPsList.add(new InetNetwork(allowedIP)); } } } - public IPCidr[] getAllowedIPs() { - return allowedIPsList.toArray(new IPCidr[allowedIPsList.size()]); + public InetNetwork[] getAllowedIPs() { + return allowedIPsList.toArray(new InetNetwork[allowedIPsList.size()]); } private String getAllowedIPsString() { |