android: support allow LAN access for API < 33

Don't add routes from LocalRoutes for devices running API < 33
kari/allowlan
kari-ts 6 months ago
parent 28f1931531
commit 96c29dbd54

@ -289,6 +289,8 @@ class App : UninitializedApp(), libtailscale.AppContext, ViewModelStoreOwner {
override fun getOSVersion(): String = Build.VERSION.RELEASE override fun getOSVersion(): String = Build.VERSION.RELEASE
override fun getAPILevel(): Int = Build.VERSION.SDK_INT
override fun isChromeOS(): Boolean { override fun isChromeOS(): Boolean {
return packageManager.hasSystemFeature("android.hardware.type.pc") return packageManager.hasSystemFeature("android.hardware.type.pc")
} }

@ -100,9 +100,7 @@ fun ExitNodePicker(
} }
} }
// https://developer.android.com/reference/android/net/VpnService.Builder#excludeRoute(android.net.IpPrefix) - excludeRoute is only supported in API 33+, so don't show the option if allow LAN access is not enabled. if (!allowLanAccessMDMDisposition.value.hiddenFromUser) {
if (!allowLanAccessMDMDisposition.value.hiddenFromUser &&
Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
item(key = "allowLANAccess") { item(key = "allowLANAccess") {
Lists.SectionDivider() Lists.SectionDivider()

@ -32,6 +32,9 @@ type AppContext interface {
// GetOSVersion gets the Android version. // GetOSVersion gets the Android version.
GetOSVersion() (string, error) GetOSVersion() (string, error)
// GetAPILevel gets the SDK version.
GetAPILevel() (int32, error)
// GetModelName gets the Android device's model name. // GetModelName gets the Android device's model name.
GetModelName() (string, error) GetModelName() (string, error)

@ -165,9 +165,20 @@ func (b *backend) updateTUN(rcfg *router.Config, dcfg *dns.OSConfig) error {
b.logger.Logf("updateTUN: set nameservers") b.logger.Logf("updateTUN: set nameservers")
} }
apiLevel, err := b.appCtx.GetAPILevel()
supportsExcludeRoutes := false
if err == nil && apiLevel >= 33 {
supportsExcludeRoutes = true
}
for _, route := range rcfg.Routes { for _, route := range rcfg.Routes {
// Normalize route address; Builder.addRoute does not accept non-zero masked bits. // Normalize route address; Builder.addRoute does not accept non-zero masked bits.
route = route.Masked() route = route.Masked()
if !supportsExcludeRoutes && isLocalRoute(rcfg, route) {
continue
}
if err := builder.AddRoute(route.Addr().String(), int32(route.Bits())); err != nil { if err := builder.AddRoute(route.Addr().String(), int32(route.Bits())); err != nil {
return err return err
} }
@ -237,6 +248,15 @@ func (b *backend) updateTUN(rcfg *router.Config, dcfg *dns.OSConfig) error {
return nil return nil
} }
func isLocalRoute(rcfg *router.Config, r netip.Prefix) bool {
for _, lr := range rcfg.LocalRoutes {
if lr.Masked() == r {
return true
}
}
return false
}
func closeFileDescriptor() error { func closeFileDescriptor() error {
if vpnService.fd != -1 && vpnService.fdDetached { if vpnService.fd != -1 && vpnService.fdDetached {
err := syscall.Close(int(vpnService.fd)) err := syscall.Close(int(vpnService.fd))

@ -77,6 +77,15 @@ func (a *App) osVersion() string {
return version return version
} }
// apiLevel returns android.os.Build.VERSION.SDK_INT.
func (a *App) apiLevel() int32 {
level, err := a.appCtx.GetAPILevel()
if err != nil {
panic(err)
}
return level
}
// modelName return the MANUFACTURER + MODEL from // modelName return the MANUFACTURER + MODEL from
// android.os.Build. // android.os.Build.
func (a *App) modelName() string { func (a *App) modelName() string {

Loading…
Cancel
Save