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 getAPILevel(): Int = Build.VERSION.SDK_INT
override fun isChromeOS(): Boolean {
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 &&
Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
if (!allowLanAccessMDMDisposition.value.hiddenFromUser) {
item(key = "allowLANAccess") {
Lists.SectionDivider()

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

@ -165,9 +165,20 @@ func (b *backend) updateTUN(rcfg *router.Config, dcfg *dns.OSConfig) error {
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 {
// Normalize route address; Builder.addRoute does not accept non-zero masked bits.
route = route.Masked()
if !supportsExcludeRoutes && isLocalRoute(rcfg, route) {
continue
}
if err := builder.AddRoute(route.Addr().String(), int32(route.Bits())); err != nil {
return err
}
@ -237,6 +248,15 @@ func (b *backend) updateTUN(rcfg *router.Config, dcfg *dns.OSConfig) error {
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 {
if vpnService.fd != -1 && vpnService.fdDetached {
err := syscall.Close(int(vpnService.fd))

@ -77,6 +77,15 @@ func (a *App) osVersion() string {
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
// android.os.Build.
func (a *App) modelName() string {

Loading…
Cancel
Save