android: correctly grab DNS settings

Closes #ENG-3005

Signed-off-by: Percy Wegmann <percy@tailscale.com>
pull/241/head
Percy Wegmann 3 months ago committed by Percy Wegmann
parent a15fdd44bf
commit 6a875e8854

@ -23,12 +23,12 @@ import android.content.res.Configuration
import android.net.ConnectivityManager import android.net.ConnectivityManager
import android.net.LinkProperties import android.net.LinkProperties
import android.net.Network import android.net.Network
import android.net.NetworkCapabilities
import android.net.NetworkRequest
import android.net.Uri import android.net.Uri
import android.net.VpnService import android.net.VpnService
import android.os.Build import android.os.Build
import android.os.Environment import android.os.Environment
import android.os.Handler
import android.os.Looper
import android.provider.MediaStore import android.provider.MediaStore
import android.provider.Settings import android.provider.Settings
import android.util.Log import android.util.Log
@ -64,7 +64,6 @@ import java.util.Objects
class App : Application(), libtailscale.AppContext { class App : Application(), libtailscale.AppContext {
private val applicationScope = CoroutineScope(SupervisorJob() + Dispatchers.Default) private val applicationScope = CoroutineScope(SupervisorJob() + Dispatchers.Default)
var dnsConfigObj = DnsConfig()
companion object { companion object {
const val STATUS_CHANNEL_ID = "tailscale-status" const val STATUS_CHANNEL_ID = "tailscale-status"
@ -75,11 +74,13 @@ class App : Application(), libtailscale.AppContext {
private const val FILE_CHANNEL_ID = "tailscale-files" private const val FILE_CHANNEL_ID = "tailscale-files"
private const val FILE_NOTIFICATION_ID = 3 private const val FILE_NOTIFICATION_ID = 3
private const val TAG = "App" private const val TAG = "App"
private val mainHandler = Handler(Looper.getMainLooper()) private val networkConnectivityRequest =
NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
.build()
lateinit var appInstance: App lateinit var appInstance: App
private fun isEmpty(str: String?) = str.isNullOrEmpty()
@JvmStatic @JvmStatic
fun startActivityForResult(act: Activity, intent: Intent?, request: Int) { fun startActivityForResult(act: Activity, intent: Intent?, request: Int) {
val f: Fragment = act.getFragmentManager().findFragmentByTag(PEER_TAG) val f: Fragment = act.getFragmentManager().findFragmentByTag(PEER_TAG)
@ -143,34 +144,37 @@ class App : Application(), libtailscale.AppContext {
} }
// requestNetwork attempts to find the best network that matches the passed NetworkRequest. It is // requestNetwork attempts to find the best network that matches the passed NetworkRequest. It is
// possible that // possible that this might return an unusuable network, eg a captive portal.
// this might return an unusuable network, eg a captive portal.
private fun setAndRegisterNetworkCallbacks() { private fun setAndRegisterNetworkCallbacks() {
connectivityManager.requestNetwork( connectivityManager.requestNetwork(
dnsConfigObj.dnsConfigNetworkRequest, networkConnectivityRequest,
object : ConnectivityManager.NetworkCallback() { object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) { override fun onAvailable(network: Network) {
super.onAvailable(network) super.onAvailable(network)
val sb = StringBuilder() val sb = StringBuilder()
val linkProperties: LinkProperties? = connectivityManager.getLinkProperties(network) val linkProperties: LinkProperties? = connectivityManager.getLinkProperties(network)
val dnsList: MutableList<InetAddress> = val dnsList: MutableList<InetAddress> = linkProperties?.dnsServers ?: mutableListOf()
linkProperties?.getDnsServers() ?: mutableListOf()
for (ip in dnsList) { for (ip in dnsList) {
sb.append(ip.getHostAddress()).append(" ") sb.append(ip.hostAddress).append(" ")
} }
val searchDomains: String? = linkProperties?.getDomains() val searchDomains: String? = linkProperties?.domains
if (searchDomains != null) { if (searchDomains != null) {
sb.append("\n") sb.append("\n")
sb.append(searchDomains) sb.append(searchDomains)
} }
dnsConfigObj.updateDNSFromNetwork(sb.toString())
if (dns.updateDNSFromNetwork(sb.toString())) {
Libtailscale.onDnsConfigChanged() Libtailscale.onDnsConfigChanged()
} }
}
override fun onLost(network: Network) { override fun onLost(network: Network) {
super.onLost(network) super.onLost(network)
if (dns.updateDNSFromNetwork("")) {
Libtailscale.onDnsConfigChanged() Libtailscale.onDnsConfigChanged()
} }
}
}) })
} }

@ -3,9 +3,6 @@
package com.tailscale.ipn; package com.tailscale.ipn;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
// Tailscale DNS Config retrieval // Tailscale DNS Config retrieval
// //
// Tailscale's DNS support can either override the local DNS servers with a set of servers // Tailscale's DNS support can either override the local DNS servers with a set of servers
@ -44,14 +41,14 @@ public class DnsConfig {
} }
} }
void updateDNSFromNetwork(String dnsConfigs) { boolean updateDNSFromNetwork(String dnsConfigs) {
synchronized (this) { synchronized (this) {
if (!dnsConfigs.equals(this.dnsConfigs)) {
this.dnsConfigs = dnsConfigs; this.dnsConfigs = dnsConfigs;
return true;
} else {
return false;
} }
} }
NetworkRequest getDNSConfigNetworkRequest() {
// Request networks that are able to reach the Internet.
return new NetworkRequest.Builder().addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET).build();
} }
} }

Loading…
Cancel
Save