Skip to content

Commit 4556714

Browse files
committed
android, libtailscale: pass BuildConfig to Go code; use for DNS config
This commit wires up a method to allow the Tailscale Go backend to obtain the build configuration, and then adds a new build configuration to the build to control whether we fall back to the Google public DNS servers if we can't determine the platform's DNS configuration. This replaces the previous "IsPlayVersion" / "MaybeGoogle" check for whether to use the DNS servers as fallbacks, to allow users to decide this independently of what version of the Android app this is. Updates tailscale/tailscale#13431 Signed-off-by: Andrew Dunham <[email protected]>
1 parent 283e1eb commit 4556714

File tree

6 files changed

+52
-11
lines changed

6 files changed

+52
-11
lines changed

android/build.gradle

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,14 @@ android {
3939
targetSdkVersion 34
4040
versionCode 241
4141
versionName "1.73.114-t0970615b1-gab7ab737364"
42+
43+
// This setting, which defaults to 'true', will cause Tailscale to fall
44+
// back to the Google DNS servers if it cannot determine what the
45+
// operating system's DNS configuration is.
46+
//
47+
// Set it to false either here or in your local.properties file to
48+
// disable this behaviour.
49+
buildConfigField "boolean", "USE_GOOGLE_DNS_FALLBACK", getLocalProperty("tailscale.useGoogleDnsFallback", "true")
4250
}
4351

4452
compileOptions {
@@ -54,6 +62,7 @@ android {
5462
jvmTarget = "17"
5563
}
5664
buildFeatures {
65+
buildConfig true
5766
compose true
5867
}
5968
composeOptions {
@@ -66,9 +75,9 @@ android {
6675
applicationTest {
6776
initWith debug
6877
manifestPlaceholders.leanbackRequired = false
69-
buildConfigField "String", "GITHUB_USERNAME", "\"" + getLocalProperty("githubUsername")+"\""
70-
buildConfigField "String", "GITHUB_PASSWORD", "\"" + getLocalProperty("githubPassword")+"\""
71-
buildConfigField "String", "GITHUB_2FA_SECRET", "\"" + getLocalProperty("github2FASecret")+"\""
78+
buildConfigField "String", "GITHUB_USERNAME", "\"" + getLocalProperty("githubUsername", "")+"\""
79+
buildConfigField "String", "GITHUB_PASSWORD", "\"" + getLocalProperty("githubPassword", "")+"\""
80+
buildConfigField "String", "GITHUB_2FA_SECRET", "\"" + getLocalProperty("github2FASecret", "")+"\""
7281
}
7382
debug {
7483
manifestPlaceholders.leanbackRequired = false
@@ -156,12 +165,12 @@ dependencies {
156165
implementation("androidx.compose.ui:ui-tooling-preview")
157166
}
158167

159-
def getLocalProperty(key) {
168+
def getLocalProperty(key, defaultValue) {
160169
try {
161170
Properties properties = new Properties()
162171
properties.load(project.file('local.properties').newDataInputStream())
163-
return properties.getProperty(key)
172+
return properties.getProperty(key) ?: defaultValue
164173
} catch(Throwable ignored) {
165-
return ""
174+
return defaultValue
166175
}
167176
}

android/src/main/java/com/tailscale/ipn/App.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import kotlinx.coroutines.cancel
3838
import kotlinx.coroutines.launch
3939
import kotlinx.serialization.encodeToString
4040
import kotlinx.serialization.json.Json
41+
import libtailscale.BuildConfig as GoBuildConfig
4142
import libtailscale.Libtailscale
4243
import java.io.File
4344
import java.io.IOException
@@ -311,6 +312,13 @@ class App : UninitializedApp(), libtailscale.AppContext, ViewModelStoreOwner {
311312
}
312313
}
313314

315+
// getBuildConfig implements the libtailscale.AppContext interface.
316+
override fun getBuildConfig(): GoBuildConfig {
317+
var buildConfig = GoBuildConfig()
318+
buildConfig.useGoogleDNSFallback = BuildConfig.USE_GOOGLE_DNS_FALLBACK
319+
return buildConfig
320+
}
321+
314322
fun notifyPolicyChanged() {
315323
app.notifyPolicyChanged()
316324
}

libtailscale/backend.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ type App struct {
4444
// appCtx is a global reference to the com.tailscale.ipn.App instance.
4545
appCtx AppContext
4646

47+
// buildConfig is the build configuration for the app.
48+
buildConfig *BuildConfig
49+
4750
store *stateStore
4851
policyStore *syspolicyHandler
4952
logIDPublicAtomic atomic.Pointer[logid.PublicID]
@@ -97,7 +100,8 @@ type backend struct {
97100
// when no nameservers are provided by Tailscale.
98101
avoidEmptyDNS bool
99102

100-
appCtx AppContext
103+
appCtx AppContext
104+
buildConfig *BuildConfig
101105
}
102106

103107
type settingsFunc func(*router.Config, *dns.OSConfig) error
@@ -262,9 +266,10 @@ func (a *App) newBackend(dataDir, directFileRoot string, appCtx AppContext, stor
262266

263267
logf := logger.RusagePrefixLog(log.Printf)
264268
b := &backend{
265-
devices: newTUNDevices(),
266-
settings: settings,
267-
appCtx: appCtx,
269+
devices: newTUNDevices(),
270+
settings: settings,
271+
appCtx: appCtx,
272+
buildConfig: a.buildConfig,
268273
}
269274
var logID logid.PrivateID
270275
logID.UnmarshalText([]byte("dead0000dead0000dead0000dead0000dead0000dead0000dead0000dead0000"))

libtailscale/interfaces.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,12 @@ type AppContext interface {
5757
// GetSyspolicyStringArrayValue returns the current string array value for the given system policy,
5858
// expressed as a JSON string.
5959
GetSyspolicyStringArrayJSONValue(key string) (string, error)
60+
61+
// GetBuildConfig gets the build configuration of the Android app.
62+
//
63+
// The returned BuildConfig should not change during the lifetime of
64+
// the app.
65+
GetBuildConfig() *BuildConfig
6066
}
6167

6268
// IPNService corresponds to our IPNService in Java.
@@ -166,3 +172,11 @@ func RequestVPN(service IPNService) {
166172
func ServiceDisconnect(service IPNService) {
167173
onDisconnect <- service
168174
}
175+
176+
// BuildConfig is a struct that represents the build configuration of the
177+
// Android application, as set in BuildConfig.java.
178+
type BuildConfig struct {
179+
// UseGoogleDNSFallback is whether to fall back to the Google public
180+
// DNS servers if the platform's DNS servers cannot be determined.
181+
UseGoogleDNSFallback bool
182+
}

libtailscale/net.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ func (b *backend) getDNSBaseConfig() (ret dns.OSConfig, _ error) {
287287
// DNS config are lacking, and almost all Android phones use Google
288288
// services anyway, so it's a reasonable default: it's an ecosystem the
289289
// user has selected by having an Android device.
290-
if len(ret.Nameservers) == 0 && b.appCtx.IsPlayVersion() {
290+
if len(ret.Nameservers) == 0 && b.buildConfig.UseGoogleDNSFallback {
291291
log.Printf("getDNSBaseConfig: none found; falling back to Google public DNS")
292292
ret.Nameservers = append(ret.Nameservers, googleDNSServers...)
293293
}

libtailscale/tailscale.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ func newApp(dataDir, directFileRoot string, appCtx AppContext) Application {
3838
}
3939
a.ready.Add(2)
4040

41+
// Get the build configuration, if any.
42+
if bc := appCtx.GetBuildConfig(); bc != nil {
43+
a.buildConfig = bc
44+
}
45+
4146
a.store = newStateStore(a.appCtx)
4247
a.policyStore = &syspolicyHandler{a: a}
4348
netmon.RegisterInterfaceGetter(a.getInterfaces)

0 commit comments

Comments
 (0)