From 1b42117791266251b41959fc18e6c6215a85f739 Mon Sep 17 00:00:00 2001
From: kari-ts <135075563+kari-ts@users.noreply.github.com>
Date: Wed, 17 Jan 2024 11:10:41 -0800
Subject: [PATCH] use network callback to update DNS config when network
changes (#147)
* use network callback to update DNS config when network changes
-Use requestNetwork, which gets the best network matching the passed in network request, to listen for changes to network and cache DNS config
-Call netmon.InjectEvent on network change to indicate a change
Follow-up will fix issue in netmon where IsMajorChangeFrom doesn't identify major changes when a network is added
Fixes #10107
* use network callback to update DNS config when network changes
-Use requestNetwork, which gets the best network matching the passed in network request, to listen for changes to network and cache DNS config
-Call netmon.InjectEvent on network change to indicate a change
Follow-up will fix issue in netmon where IsMajorChangeFrom doesn't identify major changes when a network is added
Updates tailscale/tailscale/#10107
hi
* hi
* .
* use network callback to update DNS config when network changes
-Use requestNetwork, which gets the best network matching the passed in network request, to listen for changes to network and cache DNS config
-Call netmon.InjectEvent on network change to indicate a change
Follow-up will fix issue in netmon where IsMajorChangeFrom doesn't identify major changes when a network is added
Updates tailscale/tailscale/#10107
* fixed missing connectivity manager
---
.vscode/settings.json | 0
android/src/main/AndroidManifest.xml | 1 +
.../src/main/java/com/tailscale/ipn/App.java | 44 +--
.../java/com/tailscale/ipn/DnsConfig.java | 321 +-----------------
.../java/com/tailscale/ipn/DnsConfigTest.java | 21 --
cmd/tailscale/backend.go | 2 +-
cmd/tailscale/callbacks.go | 27 +-
cmd/tailscale/main.go | 10 +-
eclipse-formatter.xml | 315 +++++++++++++++++
9 files changed, 373 insertions(+), 368 deletions(-)
create mode 100644 .vscode/settings.json
delete mode 100644 android/src/test/java/com/tailscale/ipn/DnsConfigTest.java
create mode 100644 eclipse-formatter.xml
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..e69de29
diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml
index 327951b..8523e9d 100644
--- a/android/src/main/AndroidManifest.xml
+++ b/android/src/main/AndroidManifest.xml
@@ -5,6 +5,7 @@
+
diff --git a/android/src/main/java/com/tailscale/ipn/App.java b/android/src/main/java/com/tailscale/ipn/App.java
index 299d354..a1da150 100644
--- a/android/src/main/java/com/tailscale/ipn/App.java
+++ b/android/src/main/java/com/tailscale/ipn/App.java
@@ -71,7 +71,7 @@ import androidx.browser.customtabs.CustomTabsIntent;
import org.gioui.Gio;
public class App extends Application {
- private final static String PEER_TAG = "peer";
+ private static final String PEER_TAG = "peer";
static final String STATUS_CHANNEL_ID = "tailscale-status";
static final int STATUS_NOTIFICATION_ID = 1;
@@ -82,16 +82,19 @@ public class App extends Application {
private static final String FILE_CHANNEL_ID = "tailscale-files";
private static final int FILE_NOTIFICATION_ID = 3;
- private final static Handler mainHandler = new Handler(Looper.getMainLooper());
+ private static final Handler mainHandler = new Handler(Looper.getMainLooper());
- public DnsConfig dns = new DnsConfig(this);
+ private ConnectivityManager connectivityManager;
+ public DnsConfig dns = new DnsConfig();
public DnsConfig getDnsConfigObj() { return this.dns; }
@Override public void onCreate() {
super.onCreate();
// Load and initialize the Go library.
Gio.init(this);
- registerNetworkCallback();
+
+ this.connectivityManager = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
+ setAndRegisterNetworkCallbacks();
createNotificationChannel(NOTIFY_CHANNEL_ID, "Notifications", NotificationManagerCompat.IMPORTANCE_DEFAULT);
createNotificationChannel(STATUS_CHANNEL_ID, "VPN Status", NotificationManagerCompat.IMPORTANCE_LOW);
@@ -99,26 +102,27 @@ public class App extends Application {
}
- private void registerNetworkCallback() {
- ConnectivityManager cMgr = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
- cMgr.registerNetworkCallback(new NetworkRequest.Builder().build(), new ConnectivityManager.NetworkCallback() {
- private void reportConnectivityChange() {
- NetworkInfo active = cMgr.getActiveNetworkInfo();
- // https://developer.android.com/training/monitoring-device-state/connectivity-status-type
- boolean isConnected = active != null && active.isConnectedOrConnecting();
- onConnectivityChanged(isConnected);
+ // requestNetwork attempts to find the best network that matches the passed NetworkRequest. It is possible that
+ // this might return an unusuable network, eg a captive portal.
+ private void setAndRegisterNetworkCallbacks() {
+ connectivityManager.requestNetwork(dns.getDNSConfigNetworkRequest(), new ConnectivityManager.NetworkCallback(){
+ @Override
+ public void onAvailable(Network network){
+ super.onAvailable(network);
+ StringBuilder sb = new StringBuilder("");
+ LinkProperties linkProperties = connectivityManager.getLinkProperties(network);
+ List dnsList = linkProperties.getDnsServers();
+ for (InetAddress ip : dnsList) {
+ sb.append(ip.getHostAddress()).append(" ");
+ }
+ dns.updateDNSFromNetwork(sb.toString());
+ onDnsConfigChanged();
}
@Override
public void onLost(Network network) {
super.onLost(network);
- this.reportConnectivityChange();
- }
-
- @Override
- public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {
- super.onLinkPropertiesChanged(network, linkProperties);
- this.reportConnectivityChange();
+ onDnsConfigChanged();
}
});
}
@@ -347,7 +351,7 @@ public class App extends Application {
}
static native void onVPNPrepared();
- private static native void onConnectivityChanged(boolean connected);
+ private static native void onDnsConfigChanged();
static native void onShareIntent(int nfiles, int[] types, String[] mimes, String[] items, String[] names, long[] sizes);
static native void onWriteStorageGranted();
diff --git a/android/src/main/java/com/tailscale/ipn/DnsConfig.java b/android/src/main/java/com/tailscale/ipn/DnsConfig.java
index 5c2cdbc..1168e1a 100644
--- a/android/src/main/java/com/tailscale/ipn/DnsConfig.java
+++ b/android/src/main/java/com/tailscale/ipn/DnsConfig.java
@@ -4,14 +4,8 @@
package com.tailscale.ipn;
-import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.DhcpInfo;
-import android.net.LinkProperties;
-import android.net.Network;
import android.net.NetworkCapabilities;
-import android.net.NetworkInfo;
-import android.net.wifi.WifiManager;
+import android.net.NetworkRequest;
import java.lang.reflect.Method;
@@ -20,6 +14,8 @@ import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
// Tailscale DNS Config retrieval
//
@@ -32,65 +28,9 @@ import java.util.Locale;
// Importantly, after the Tailscale VPN comes up it will set a DNS server of 100.100.100.100
// but we still want to retrieve the underlying DNS servers received from DHCP. If we roam
// from Wi-Fi to LTE, we want the DNS servers received from LTE.
-//
-// --------------------- Android 7 and later -----------------------------------------
-//
-// ## getDnsConfigFromLinkProperties
-// Android provides a getAllNetworks interface in the ConnectivityManager. We walk through
-// each interface to pick the most appropriate one.
-// - If there is an Ethernet interface active we use that.
-// - If Wi-Fi is active we use that.
-// - If LTE is active we use that.
-// - We never use a VPN's DNS servers. That VPN is likely us. Even if not us, Android
-// only allows one VPN at a time so a different VPN's DNS servers won't be available
-// once Tailscale comes up.
-//
-// getAllNetworks() is used as the sole mechanism for retrieving the DNS config with
-// Android 7 and later.
-//
-// --------------------- Releases older than Android 7 -------------------------------
-//
-// We support Tailscale back to Android 5. Android versions 5 and 6 supply a getAllNetworks()
-// implementation but it always returns an empty list.
-//
-// ## getDnsConfigFromLinkProperties with getActiveNetwork
-// ConnectivityManager also supports a getActiveNetwork() routine, which Android 5 and 6 do
-// return a value for. If Tailscale isn't up yet and we can get the Wi-Fi/LTE/etc DNS
-// config using getActiveNetwork(), we use that.
-//
-// Once Tailscale is up, getActiveNetwork() returns tailscale0 with DNS server 100.100.100.100
-// and that isn't useful. So we try two other mechanisms:
-//
-// ## getDnsServersFromSystemProperties
-// Android versions prior to 8 let us retrieve the actual system DNS servers from properties.
-// Later Android versions removed the properties and only return an empty string.
-//
-// We check the net.dns1 - net.dns4 DNS servers. If Tailscale is up the DNS server will be
-// 100.100.100.100, which isn't useful, but if we get something different we'll use that.
-//
-// getDnsServersFromSystemProperties can only retrieve the IPv4 or IPv6 addresses of the
-// configured DNS servers. We also want to know the DNS Search Domains configured, but
-// we have no way to retrieve this using these interfaces. We return an empty list of
-// search domains. Sorry.
-//
-// ## getDnsServersFromNetworkInfo
-// ConnectivityManager supports an older API called getActiveNetworkInfo to return the
-// active network interface. It doesn't handle VPNs, so the interface will always be Wi-Fi
-// or Cellular even if Tailscale is up.
-//
-// For Wi-Fi interfaces we retrieve the DHCP response from the WifiManager. For Cellular
-// interfaces we check for properties populated by most of the radio drivers.
-//
-// getDnsServersFromNetworkInfo does not have a way to retrieve the DNS Search Domains,
-// so we return an empty list. Additionally, these interfaces are so old that they only
-// support IPv4. We can't retrieve IPv6 DNS server addresses this way.
public class DnsConfig {
- private Context ctx;
-
- public DnsConfig(Context ctx) {
- this.ctx = ctx;
- }
+ private String dnsConfigs;
// getDnsConfigAsString returns the current DNS configuration as a multiline string:
// line[0] DNS server addresses separated by spaces
@@ -102,260 +42,27 @@ public class DnsConfig {
//
// an empty string means the current DNS configuration could not be retrieved.
String getDnsConfigAsString() {
- String s = getDnsConfigFromLinkProperties();
+ String s = getDnsConfigs();
if (!s.trim().isEmpty()) {
return s;
}
- if (android.os.Build.VERSION.SDK_INT >= 23) {
- // If ConnectivityManager.getAllNetworks() works, it is the
- // authoritative mechanism and we rely on it. The other methods
- // which follow involve more compromises.
- return "";
- }
-
- s = getDnsServersFromSystemProperties();
- if (!s.trim().isEmpty()) {
- return s;
- }
- return getDnsServersFromNetworkInfo();
- }
-
- // getDnsConfigFromLinkProperties finds the DNS servers for each Network interface
- // returned by ConnectivityManager getAllNetworks().LinkProperties, and return the
- // one that (heuristically) would be the primary DNS servers.
- //
- // on a Nexus 4 with Android 5.1 on wifi: 2602:248:7b4a:ff60::1 10.1.10.1
- // on a Nexus 7 with Android 6.0 on wifi: 2602:248:7b4a:ff60::1 10.1.10.1
- // on a Pixel 3a with Android 12.0 on wifi: 2602:248:7b4a:ff60::1 10.1.10.1\nlocaldomain
- // on a Pixel 3a with Android 12.0 on LTE: fd00:976a::9 fd00:976a::10
- //
- // One odd behavior noted on Pixel3a with Android 12:
- // With Wi-Fi already connected, starting Tailscale returned DNS servers 2602:248:7b4a:ff60::1 10.1.10.1
- // Turning off Wi-Fi and connecting LTE returned DNS servers fd00:976a::9 fd00:976a::10.
- // Turning Wi-Fi back on return DNS servers: 10.1.10.1. The IPv6 DNS server is gone.
- // This appears to be the ConnectivityManager behavior, not something we are doing.
- //
- // This implementation can work through Android 12 (SDK 30). In SDK 31 the
- // getAllNetworks() method is deprecated and we'll need to implement a
- // android.net.ConnectivityManager.NetworkCallback instead to monitor
- // link changes and track which DNS server to use.
- String getDnsConfigFromLinkProperties() {
- ConnectivityManager cMgr = (ConnectivityManager) ctx.getSystemService(Context.CONNECTIVITY_SERVICE);
- if (cMgr == null) {
- return "";
- }
-
- Network[] networks = cMgr.getAllNetworks();
- if (networks == null) {
- // Android 6 and before often returns an empty list, but we
- // can try again with just the active network.
- //
- // Once Tailscale is connected, the active network will be Tailscale
- // which will have 100.100.100.100 for its DNS server. We reject
- // TYPE_VPN in getPreferabilityForNetwork, so it won't be returned.
- Network active = cMgr.getActiveNetwork();
- if (active == null) {
- return "";
- }
- networks = new Network[]{active};
- }
-
- // getPreferabilityForNetwork returns an index into dnsConfigs from 0-3.
- String[] dnsConfigs = new String[]{"", "", "", ""};
- for (Network network : networks) {
- int idx = getPreferabilityForNetwork(cMgr, network);
- if ((idx < 0) || (idx > 3)) {
- continue;
- }
-
- LinkProperties linkProp = cMgr.getLinkProperties(network);
- NetworkCapabilities nc = cMgr.getNetworkCapabilities(network);
- List dnsList = linkProp.getDnsServers();
- StringBuilder sb = new StringBuilder("");
- for (InetAddress ip : dnsList) {
- sb.append(ip.getHostAddress() + " ");
- }
-
- String d = linkProp.getDomains();
- if (d != null) {
- sb.append("\n");
- sb.append(d);
- }
-
- dnsConfigs[idx] = sb.toString();
- }
-
- // return the lowest index DNS config which exists. If an Ethernet config
- // was found, return it. Otherwise if Wi-fi was found, return it. Etc.
- for (String s : dnsConfigs) {
- if (!s.trim().isEmpty()) {
- return s;
- }
- }
-
return "";
}
- // getDnsServersFromSystemProperties returns DNS servers found in system properties.
- // On Android versions prior to Android 8, we can directly query the DNS
- // servers the system is using. More recent Android releases return empty strings.
- //
- // Once Tailscale is connected these properties will return 100.100.100.100, which we
- // suppress.
- //
- // on a Nexus 4 with Android 5.1 on wifi: 2602:248:7b4a:ff60::1 10.1.10.1
- // on a Nexus 7 with Android 6.0 on wifi: 2602:248:7b4a:ff60::1 10.1.10.1
- // on a Pixel 3a with Android 12.0 on wifi:
- // on a Pixel 3a with Android 12.0 on LTE:
- //
- // The list of DNS search domains does not appear to be available in system properties.
- String getDnsServersFromSystemProperties() {
- try {
- Class SystemProperties = Class.forName("android.os.SystemProperties");
- Method method = SystemProperties.getMethod("get", String.class);
- List servers = new ArrayList();
- for (String name : new String[]{"net.dns1", "net.dns2", "net.dns3", "net.dns4"}) {
- String value = (String) method.invoke(null, name);
- if (value != null && !value.isEmpty() &&
- !value.equals("100.100.100.100") &&
- !servers.contains(value)) {
- servers.add(value);
- }
- }
- return String.join(" ", servers);
- } catch (Exception e) {
- return "";
+ private String getDnsConfigs(){
+ synchronized(this) {
+ return this.dnsConfigs;
}
}
-
- public String intToInetString(int hostAddress) {
- return String.format(java.util.Locale.ROOT, "%d.%d.%d.%d",
- (0xff & hostAddress),
- (0xff & (hostAddress >> 8)),
- (0xff & (hostAddress >> 16)),
- (0xff & (hostAddress >> 24)));
- }
-
- // getDnsServersFromNetworkInfo retrieves DNS servers using ConnectivityManager
- // getActiveNetworkInfo() plus interface-specific mechanisms to retrieve the DNS servers.
- // Only IPv4 DNS servers are supported by this mechanism, neither the WifiManager nor the
- // interface-specific dns properties appear to populate IPv6 DNS server addresses.
- //
- // on a Nexus 4 with Android 5.1 on wifi: 10.1.10.1
- // on a Nexus 7 with Android 6.0 on wifi: 10.1.10.1
- // on a Pixel-3a with Android 12.0 on wifi: 10.1.10.1
- // on a Pixel-3a with Android 12.0 on LTE:
- //
- // The list of DNS search domains is not available in this way.
- String getDnsServersFromNetworkInfo() {
- ConnectivityManager cMgr = (ConnectivityManager) ctx.getSystemService(Context.CONNECTIVITY_SERVICE);
- if (cMgr == null) {
- return "";
- }
-
- NetworkInfo info = cMgr.getActiveNetworkInfo();
- if (info == null) {
- return "";
+ void updateDNSFromNetwork(String dnsConfigs){
+ synchronized(this) {
+ this.dnsConfigs = dnsConfigs;
}
-
- Class SystemProperties;
- Method method;
-
- try {
- SystemProperties = Class.forName("android.os.SystemProperties");
- method = SystemProperties.getMethod("get", String.class);
- } catch (Exception e) {
- return "";
- }
-
- List servers = new ArrayList();
-
- switch(info.getType()) {
- case ConnectivityManager.TYPE_WIFI:
- case ConnectivityManager.TYPE_WIMAX:
- for (String name : new String[]{
- "net.wifi0.dns1", "net.wifi0.dns2", "net.wifi0.dns3", "net.wifi0.dns4",
- "net.wlan0.dns1", "net.wlan0.dns2", "net.wlan0.dns3", "net.wlan0.dns4",
- "net.eth0.dns1", "net.eth0.dns2", "net.eth0.dns3", "net.eth0.dns4",
- "dhcp.wlan0.dns1", "dhcp.wlan0.dns2", "dhcp.wlan0.dns3", "dhcp.wlan0.dns4",
- "dhcp.tiwlan0.dns1", "dhcp.tiwlan0.dns2", "dhcp.tiwlan0.dns3", "dhcp.tiwlan0.dns4"}) {
- try {
- String value = (String) method.invoke(null, name);
- if (value != null && !value.isEmpty() && !servers.contains(value)) {
- servers.add(value);
- }
- } catch (Exception e) {
- continue;
- }
- }
-
- WifiManager wMgr = (WifiManager) ctx.getSystemService(Context.WIFI_SERVICE);
- if (wMgr != null) {
- DhcpInfo dhcp = wMgr.getDhcpInfo();
- if (dhcp.dns1 != 0) {
- String value = intToInetString(dhcp.dns1);
- if (value != null && !value.isEmpty() && !servers.contains(value)) {
- servers.add(value);
- }
- }
- if (dhcp.dns2 != 0) {
- String value = intToInetString(dhcp.dns2);
- if (value != null && !value.isEmpty() && !servers.contains(value)) {
- servers.add(value);
- }
- }
- }
- return String.join(" ", servers);
- case ConnectivityManager.TYPE_MOBILE:
- case ConnectivityManager.TYPE_MOBILE_HIPRI:
- for (String name : new String[]{
- "net.rmnet0.dns1", "net.rmnet0.dns2", "net.rmnet0.dns3", "net.rmnet0.dns4",
- "net.rmnet1.dns1", "net.rmnet1.dns2", "net.rmnet1.dns3", "net.rmnet1.dns4",
- "net.rmnet2.dns1", "net.rmnet2.dns2", "net.rmnet2.dns3", "net.rmnet2.dns4",
- "net.rmnet3.dns1", "net.rmnet3.dns2", "net.rmnet3.dns3", "net.rmnet3.dns4",
- "net.rmnet4.dns1", "net.rmnet4.dns2", "net.rmnet4.dns3", "net.rmnet4.dns4",
- "net.rmnet5.dns1", "net.rmnet5.dns2", "net.rmnet5.dns3", "net.rmnet5.dns4",
- "net.rmnet6.dns1", "net.rmnet6.dns2", "net.rmnet6.dns3", "net.rmnet6.dns4",
- "net.rmnet7.dns1", "net.rmnet7.dns2", "net.rmnet7.dns3", "net.rmnet7.dns4",
- "net.pdp0.dns1", "net.pdp0.dns2", "net.pdp0.dns3", "net.pdp0.dns4",
- "net.pdpbr0.dns1", "net.pdpbr0.dns2", "net.pdpbr0.dns3", "net.pdpbr0.dns4"}) {
- try {
- String value = (String) method.invoke(null, name);
- if (value != null && !value.isEmpty() && !servers.contains(value)) {
- servers.add(value);
- }
- } catch (Exception e) {
- continue;
- }
-
- }
- }
-
- return "";
}
- // getPreferabilityForNetwork is a utility routine which implements a priority for
- // different types of network transport, used in a heuristic to pick DNS servers to use.
- int getPreferabilityForNetwork(ConnectivityManager cMgr, Network network) {
- NetworkCapabilities nc = cMgr.getNetworkCapabilities(network);
-
- if (nc == null) {
- return -1;
- }
- if (nc.hasTransport(NetworkCapabilities.TRANSPORT_VPN)) {
- // tun0 has both VPN and WIFI set, have to check VPN first and return.
- return -1;
- }
-
- if (nc.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)) {
- return 0;
- } else if (nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
- return 1;
- } else if (nc.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
- return 2;
- } else {
- return 3;
- }
+ NetworkRequest getDNSConfigNetworkRequest(){
+ // Request networks that are able to reach the Internet.
+ return new NetworkRequest.Builder().addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET).build();
}
}
diff --git a/android/src/test/java/com/tailscale/ipn/DnsConfigTest.java b/android/src/test/java/com/tailscale/ipn/DnsConfigTest.java
deleted file mode 100644
index b93e168..0000000
--- a/android/src/test/java/com/tailscale/ipn/DnsConfigTest.java
+++ /dev/null
@@ -1,21 +0,0 @@
-import org.junit.Before;
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-import com.tailscale.ipn.DnsConfig;
-
-public class DnsConfigTest {
- DnsConfig dns;
-
- @Before
- public void setup() {
- dns = new DnsConfig(null);
- }
-
- @Test
- public void dnsConfig_intToInetStringTest() {
- assertEquals(dns.intToInetString(0x0101a8c0), "192.168.1.1");
- assertEquals(dns.intToInetString(0x04030201), "1.2.3.4");
- assertEquals(dns.intToInetString(0), "0.0.0.0");
- }
-}
diff --git a/cmd/tailscale/backend.go b/cmd/tailscale/backend.go
index 8e1a446..e8c79e8 100644
--- a/cmd/tailscale/backend.go
+++ b/cmd/tailscale/backend.go
@@ -184,7 +184,7 @@ func (b *backend) Start(notify func(n ipn.Notify)) error {
return b.backend.Start(ipn.Options{})
}
-func (b *backend) LinkChange() {
+func (b *backend) NetworkChanged() {
if b.sys != nil {
if nm, ok := b.sys.NetMon.GetOK(); ok {
nm.InjectEvent()
diff --git a/cmd/tailscale/callbacks.go b/cmd/tailscale/callbacks.go
index 534e439..b922367 100644
--- a/cmd/tailscale/callbacks.go
+++ b/cmd/tailscale/callbacks.go
@@ -30,9 +30,6 @@ var (
// onDisconnect receives global IPNService references when
// disconnecting.
onDisconnect = make(chan jni.Object)
- // onConnectivityChange is notified every time the network
- // conditions change.
- onConnectivityChange = make(chan bool, 1)
// onGoogleToken receives google ID tokens.
onGoogleToken = make(chan string)
@@ -42,6 +39,9 @@ var (
// onWriteStorageGranted is notified when we are granted WRITE_STORAGE_PERMISSION.
onWriteStorageGranted = make(chan struct{}, 1)
+
+ // onDNSConfigChanged is notified when the network changes and the DNS config needs to be updated.
+ onDNSConfigChanged = make(chan struct{}, 1)
)
const (
@@ -109,21 +109,12 @@ func Java_com_tailscale_ipn_IPNService_disconnect(env *C.JNIEnv, this C.jobject)
//export Java_com_tailscale_ipn_StartVPNWorker_connect
func Java_com_tailscale_ipn_StartVPNWorker_connect(env *C.JNIEnv, this C.jobject) {
- requestBackend(ConnectEvent{Enable: true})
+ requestBackend(ConnectEvent{Enable: true})
}
//export Java_com_tailscale_ipn_StopVPNWorker_disconnect
func Java_com_tailscale_ipn_StopVPNWorker_disconnect(env *C.JNIEnv, this C.jobject) {
- requestBackend(ConnectEvent{Enable: false})
-}
-
-//export Java_com_tailscale_ipn_App_onConnectivityChanged
-func Java_com_tailscale_ipn_App_onConnectivityChanged(env *C.JNIEnv, cls C.jclass, connected C.jboolean) {
- select {
- case <-onConnectivityChange:
- default:
- }
- onConnectivityChange <- connected == C.JNI_TRUE
+ requestBackend(ConnectEvent{Enable: false})
}
//export Java_com_tailscale_ipn_QuickToggleService_onTileClick
@@ -200,3 +191,11 @@ func Java_com_tailscale_ipn_App_onShareIntent(env *C.JNIEnv, cls C.jclass, nfile
}
onFileShare <- files
}
+
+//export Java_com_tailscale_ipn_App_onDnsConfigChanged
+func Java_com_tailscale_ipn_App_onDnsConfigChanged(env *C.JNIEnv, cls C.jclass) {
+ select {
+ case onDNSConfigChanged <- struct{}{}:
+ default:
+ }
+}
diff --git a/cmd/tailscale/main.go b/cmd/tailscale/main.go
index e1285a9..dde90d9 100644
--- a/cmd/tailscale/main.go
+++ b/cmd/tailscale/main.go
@@ -526,11 +526,6 @@ func (a *App) runBackend() error {
notifyVPNClosed()
}
}
- case <-onConnectivityChange:
- if b != nil {
- go b.LinkChange()
- }
- a.notify(state)
case s := <-onDisconnect:
b.CloseTUNs()
jni.Do(a.jvm, func(env *jni.Env) error {
@@ -545,6 +540,11 @@ func (a *App) runBackend() error {
if state.State >= ipn.Starting {
notifyVPNClosed()
}
+ case <-onDNSConfigChanged:
+ if b != nil {
+ go b.NetworkChanged()
+ }
+ a.notify(state)
}
}
}
diff --git a/eclipse-formatter.xml b/eclipse-formatter.xml
new file mode 100644
index 0000000..7f8c57d
--- /dev/null
+++ b/eclipse-formatter.xml
@@ -0,0 +1,315 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+