diff options
7 files changed, 107 insertions, 15 deletions
diff --git a/tunnel/src/main/java/com/wireguard/android/backend/Dhcp.java b/tunnel/src/main/java/com/wireguard/android/backend/Dhcp.java new file mode 100644 index 00000000..59a3e69c --- /dev/null +++ b/tunnel/src/main/java/com/wireguard/android/backend/Dhcp.java @@ -0,0 +1,31 @@ +/* + * Copyright © 2017-2023 WireGuard LLC. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +package com.wireguard.android.backend; + +import com.wireguard.config.InetNetwork; +import com.wireguard.util.NonNullForAll; + +import java.util.Set; + +/** + * Class representing DHCP info for a {@link Tunnel} instance. + */ +@NonNullForAll +public class Dhcp { + private Set<InetNetwork> addresses; + + Dhcp(Set<InetNetwork> addresses) { + this.addresses = addresses; + } + + public Set<InetNetwork> getAddresses() { + return addresses; + } + + public String toString() { + return "DHCP"; + } +} diff --git a/tunnel/src/main/java/com/wireguard/android/backend/GoBackend.java b/tunnel/src/main/java/com/wireguard/android/backend/GoBackend.java index cf88aa2a..438bf9e8 100644 --- a/tunnel/src/main/java/com/wireguard/android/backend/GoBackend.java +++ b/tunnel/src/main/java/com/wireguard/android/backend/GoBackend.java @@ -74,6 +74,7 @@ import java.net.URL; import java.time.Instant; import java.nio.ByteOrder; import java.util.Collections; +import java.util.LinkedHashSet; import java.util.List; import java.util.Optional; import java.util.Set; @@ -390,8 +391,23 @@ public final class GoBackend implements Backend { DhcpResponse resp = stub.dhcp(request); Log.i(TAG, "Dhcp: " + resp.getError().getMessage()); + Set<InetNetwork> addresses = new LinkedHashSet<>(); + if (resp.getLeasesList() != null) { + for (final Lease lease: resp.getLeasesList()) { + try { + InetAddress addr = InetAddress.getByAddress(lease.getAddress().getAddress().toByteArray()); + Log.i(TAG, "Lease: " + addr); + addresses.add(new InetNetwork(addr, 128)); + } catch (UnknownHostException ex) { + // Ignore + } + } + } + + Dhcp dhcp = new Dhcp(addresses); + // Replace the vpn tunnel - final VpnService.Builder builder = getBuilder(currentTunnel.getName(), currentConfig, service, resp.getLeasesList()); + final VpnService.Builder builder = getBuilder(currentTunnel.getName(), currentConfig, service, dhcp.getAddresses()); Log.i(TAG, "Builder: " + builder); @@ -408,6 +424,7 @@ public final class GoBackend implements Backend { service.protect(wgGetSocketV4(currentTunnelHandle)); service.protect(wgGetSocketV6(currentTunnelHandle)); Log.i(TAG, "Dhcp done"); + currentTunnel.onDhcpChange(dhcp); } private int getConnectionOwnerUid(int protocol, InetSocketAddress local, InetSocketAddress remote) { @@ -492,7 +509,7 @@ public final class GoBackend implements Backend { Log.i(TAG, "Exit streamReverse"); } - private VpnService.Builder getBuilder(final String name, @Nullable final Config config, final VpnService service, @Nullable final List<Lease> leases) throws PackageManager.NameNotFoundException { + private VpnService.Builder getBuilder(final String name, @Nullable final Config config, final VpnService service, @Nullable final Set<InetNetwork> leases) throws PackageManager.NameNotFoundException { Log.i(TAG, "Builder 1"); final VpnService.Builder builder = service.getBuilder(); Log.i(TAG, "Builder 2"); @@ -508,14 +525,8 @@ public final class GoBackend implements Backend { Log.i(TAG, "Builder 5"); if (leases != null) { - for (final Lease lease: leases) { - try { - InetAddress addr = InetAddress.getByAddress(lease.getAddress().getAddress().toByteArray()); - Log.i(TAG, "Lease: " + addr); - builder.addAddress(addr, 128); - } catch (UnknownHostException ex) { - // Ignore - } + for (final InetNetwork lease: leases) { + builder.addAddress(lease.getAddress(), lease.getMask()); } } diff --git a/tunnel/src/main/java/com/wireguard/android/backend/Tunnel.java b/tunnel/src/main/java/com/wireguard/android/backend/Tunnel.java index 1a67a530..fc94375b 100644 --- a/tunnel/src/main/java/com/wireguard/android/backend/Tunnel.java +++ b/tunnel/src/main/java/com/wireguard/android/backend/Tunnel.java @@ -61,6 +61,13 @@ public interface Tunnel { } } + /** + * React to a change of DHCP of the tunnel. Should only be directly called by Backend. + * + * @param newDhcp The new DHCP info of the tunnel. + */ + void onDhcpChange(Dhcp newDhcp); + void onEndpointChange(Key publicKey, @Nullable InetEndpoint newEndpoint); void onAllowedIpsChange(Key publicKey, @Nullable List<InetNetwork> addNetworks, @Nullable List<InetNetwork> removeNetworks); diff --git a/tunnel/src/main/java/com/wireguard/config/InetNetwork.java b/tunnel/src/main/java/com/wireguard/config/InetNetwork.java index 4a918044..02ccd946 100644 --- a/tunnel/src/main/java/com/wireguard/config/InetNetwork.java +++ b/tunnel/src/main/java/com/wireguard/config/InetNetwork.java @@ -20,7 +20,7 @@ public final class InetNetwork { private final InetAddress address; private final int mask; - private InetNetwork(final InetAddress address, final int mask) { + public InetNetwork(final InetAddress address, final int mask) { this.address = address; this.mask = mask; } diff --git a/ui/src/main/java/com/wireguard/android/model/ObservableTunnel.kt b/ui/src/main/java/com/wireguard/android/model/ObservableTunnel.kt index 03280b2f..55c84df5 100644 --- a/ui/src/main/java/com/wireguard/android/model/ObservableTunnel.kt +++ b/ui/src/main/java/com/wireguard/android/model/ObservableTunnel.kt @@ -9,6 +9,7 @@ import androidx.databinding.BaseObservable import androidx.databinding.Bindable import com.wireguard.android.Application import com.wireguard.android.BR +import com.wireguard.android.backend.Dhcp import com.wireguard.android.backend.Statistics import com.wireguard.android.backend.Tunnel import com.wireguard.android.databinding.Keyed @@ -64,6 +65,7 @@ class ObservableTunnel internal constructor( fun onStateChanged(state: Tunnel.State): Tunnel.State { if (state != Tunnel.State.UP) { onStatisticsChanged(null) + onDhcpChanged(null) Application.getCoroutineScope().launch { onPeersReset() } @@ -159,6 +161,19 @@ class ObservableTunnel internal constructor( return statistics } + @get:Bindable + var dhcp: Dhcp? = null + private set + + override fun onDhcpChange(newDhcp: Dhcp) { + onDhcpChanged(newDhcp) + } + + fun onDhcpChanged(dhcp: Dhcp?): Dhcp? { + this.dhcp = dhcp + notifyPropertyChanged(BR.dhcp) + return dhcp + } // Remove dynamic peers, and reset static peers fun onPeersReset() { diff --git a/ui/src/main/res/layout/tunnel_detail_fragment.xml b/ui/src/main/res/layout/tunnel_detail_fragment.xml index 6e2aaf16..425b364d 100644 --- a/ui/src/main/res/layout/tunnel_detail_fragment.xml +++ b/ui/src/main/res/layout/tunnel_detail_fragment.xml @@ -141,8 +141,8 @@ android:layout_height="wrap_content" android:contentDescription="@string/addresses" android:nextFocusUp="@id/public_key_text" - android:nextFocusDown="@id/dns_servers_text" - android:nextFocusForward="@id/dns_servers_text" + android:nextFocusDown="@id/dynamic_addresses_text" + android:nextFocusForward="@id/dynamic_addresses_text" android:onClick="@{ClipboardUtils::copyTextView}" android:text="@{config.config.interface.addresses}" android:textAppearance="?attr/textAppearanceBodyLarge" @@ -152,6 +152,33 @@ tools:text="fc00:bbbb:bbbb:bb11::3:368b/128" /> <TextView + android:id="@+id/dynamic_addresses_label" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="8dp" + android:labelFor="@+id/dynamic_addresses_text" + android:text="@string/dynamic_addresses" + android:visibility="@{tunnel.dhcp == null ? android.view.View.GONE : android.view.View.VISIBLE}" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/addresses_text" /> + + <TextView + android:id="@+id/dynamic_addresses_text" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:contentDescription="@string/dynamic_addresses" + android:nextFocusUp="@id/addresses_text" + android:nextFocusDown="@id/dns_servers_text" + android:nextFocusForward="@id/dns_servers_text" + android:onClick="@{ClipboardUtils::copyTextView}" + android:text="@{tunnel.dhcp.addresses}" + android:textAppearance="?attr/textAppearanceBodyLarge" + android:visibility="@{tunnel.dhcp == null ? android.view.View.GONE : android.view.View.VISIBLE}" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/dynamic_addresses_label" + tools:text="fc00:bbbb:bbbb:bb11::3:368b/128" /> + + <TextView android:id="@+id/dns_servers_label" android:layout_width="wrap_content" android:layout_height="wrap_content" @@ -160,14 +187,14 @@ android:text="@string/dns_servers" android:visibility="@{config.config.interface.dnsServers.isEmpty() ? android.view.View.GONE : android.view.View.VISIBLE}" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@id/addresses_text" /> + app:layout_constraintTop_toBottomOf="@id/dynamic_addresses_text" /> <TextView android:id="@+id/dns_servers_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:contentDescription="@string/dns_servers" - android:nextFocusUp="@id/addresses_text" + android:nextFocusUp="@id/dynamic_addresses_text" android:nextFocusDown="@id/dns_search_domains_text" android:nextFocusForward="@id/dns_search_domains_text" android:onClick="@{ClipboardUtils::copyTextView}" diff --git a/ui/src/main/res/values/strings.xml b/ui/src/main/res/values/strings.xml index 87e75768..3f16aed2 100644 --- a/ui/src/main/res/values/strings.xml +++ b/ui/src/main/res/values/strings.xml @@ -105,6 +105,7 @@ <string name="dark_theme_summary_on">Currently using dark (night) theme</string> <string name="dark_theme_title">Use dark theme</string> <string name="delete">Delete</string> + <string name="dynamic_addresses">Dynamic addresses</string> <string name="tv_delete">Select tunnel to delete</string> <string name="tv_select_a_storage_drive">Select a storage drive</string> <string name="tv_no_file_picker">Please install a file management utility to browse files</string> |