From 10de11420810449c2d2073c2c6c2c605f92aa427 Mon Sep 17 00:00:00 2001
From: Mikael Magnusson <mikma@users.sourceforge.net>
Date: Fri, 3 Mar 2023 00:39:07 +0100
Subject: WIP: add dhcp addresses to tunnel details

---
 .../java/com/wireguard/android/backend/Dhcp.java   | 31 ++++++++++++++++++++++
 .../com/wireguard/android/backend/GoBackend.java   | 31 +++++++++++++++-------
 .../java/com/wireguard/android/backend/Tunnel.java |  7 +++++
 .../java/com/wireguard/config/InetNetwork.java     |  2 +-
 4 files changed, 60 insertions(+), 11 deletions(-)
 create mode 100644 tunnel/src/main/java/com/wireguard/android/backend/Dhcp.java

(limited to 'tunnel')

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 f4648813..d7cae373 100644
--- a/tunnel/src/main/java/com/wireguard/android/backend/GoBackend.java
+++ b/tunnel/src/main/java/com/wireguard/android/backend/GoBackend.java
@@ -78,6 +78,7 @@ import java.net.UnknownHostException;
 import java.net.URL;
 import java.nio.ByteOrder;
 import java.util.Collections;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Optional;
 import java.util.Set;
@@ -398,8 +399,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);
 
@@ -416,6 +432,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) {
@@ -500,7 +517,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");
@@ -516,14 +533,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 766df443..6c0f54e3 100644
--- a/tunnel/src/main/java/com/wireguard/android/backend/Tunnel.java
+++ b/tunnel/src/main/java/com/wireguard/android/backend/Tunnel.java
@@ -54,4 +54,11 @@ public interface Tunnel {
             return running ? UP : DOWN;
         }
     }
+
+    /**
+     * 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);
 }
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;
     }
-- 
cgit v1.2.3