libtailscale, android: fix allow LAN access

-Update local routes in VPNServiceBuilder
-Maybe update TUN on new state update where state >= starting
-Clean up updateTUN

Updates tailscale/corp#18984
Updates tailscale/corp#18202

Signed-off-by: kari-ts <kari@tailscale.com>
kari-ts 2 weeks ago
parent 5ad25262ad
commit 022cd0ad27

@ -147,7 +147,7 @@ $(LIBTAILSCALE): Makefile android/libs $(LIBTAILSCALE_SOURCES) $(GOBIN)/gomobile
-ldflags "$(FULL_LDFLAGS)" \
-o $@ ./libtailscale
libtailscale: $(LIBTAILSCALE)
libtailscale: $(LIBTAILSCALE) ## Build libtailscale
ANDROID_SOURCES=$(shell find android -type f -not -path "android/build/*" -not -path '*/.*')
DEBUG_INTERMEDIARY = android/build/outputs/apk/debug/android-debug.apk

@ -15,7 +15,7 @@ class VPNServiceBuilder(private val builder: VpnService.Builder) : libtailscale.
builder.addDnsServer(p0)
}
override fun addRoute(p0: String, p1: Int) {
override fun addRoute(p0: String, p1: Int) {
builder.addRoute(p0, p1)
}

@ -17,6 +17,7 @@ import kotlinx.coroutines.launch
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.decodeFromStream
import libtailscale.Libtailscale
// Notifier is a wrapper around the IPN Bus notifier. It provides a way to watch
// for changes in various parts of the Tailscale engine. You will typically only use
@ -83,9 +84,8 @@ object Notifier {
state.collect { currstate ->
readyToPrepareVPN.set(currstate > Ipn.State.Stopped)
tileReady.set(currstate >= Ipn.State.Stopped)
}
}
}
}
fun stop() {
Log.d(TAG, "Stopping")

@ -7,13 +7,13 @@ require (
gioui.org v0.0.0-20230206180804-32c6a9b10d0b
gioui.org/cmd v0.0.0-20210925100615-41f3a7e74ee6
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
github.com/tailscale/wireguard-go v0.0.0-20231121184858-cc193a0b3272
github.com/tailscale/wireguard-go v0.0.0-20240413175505-64040e66467d
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a
golang.org/x/exp/shiny v0.0.0-20230817173708-d852ddb80c63
golang.org/x/mobile v0.0.0-20240319015410-c58ccf4b0c87
golang.org/x/sys v0.18.0
inet.af/netaddr v0.0.0-20220617031823-097006376321
tailscale.com v1.63.0-pre.0.20240405184358-1fbaf26106ef
tailscale.com v1.65.0-pre.0.20240415205755-449f46c2070f
)
require (

@ -422,6 +422,8 @@ github.com/tailscale/web-client-prebuilt v0.0.0-20240226180453-5db17b287bf1 h1:t
github.com/tailscale/web-client-prebuilt v0.0.0-20240226180453-5db17b287bf1/go.mod h1:agQPE6y6ldqCOui2gkIh7ZMztTkIQKH049tv8siLuNQ=
github.com/tailscale/wireguard-go v0.0.0-20231121184858-cc193a0b3272 h1:zwsem4CaamMdC3tFoTpzrsUSMDPV0K6rhnQdF7kXekQ=
github.com/tailscale/wireguard-go v0.0.0-20231121184858-cc193a0b3272/go.mod h1:BOm5fXUBFM+m9woLNBoxI9TaBXXhGNP50LX/TGIvGb4=
github.com/tailscale/wireguard-go v0.0.0-20240413175505-64040e66467d h1:IREg0cn4nDyMjnqTgPacjgl66qDYmoOnt1k/vb96ius=
github.com/tailscale/wireguard-go v0.0.0-20240413175505-64040e66467d/go.mod h1:BOm5fXUBFM+m9woLNBoxI9TaBXXhGNP50LX/TGIvGb4=
github.com/tailscale/xnet v0.0.0-20240117122442-62b9a7c569f9 h1:81P7rjnikHKTJ75EkjppvbwUfKHDHYk6LJpO5PZy8pA=
github.com/tailscale/xnet v0.0.0-20240117122442-62b9a7c569f9/go.mod h1:orPd6JZXXRyuDusYilywte7k094d7dycXXU5YnWsrwg=
github.com/tc-hib/winres v0.2.1 h1:YDE0FiP0VmtRaDn7+aaChp1KiF4owBiJa5l964l5ujA=
@ -674,3 +676,5 @@ tailscale.com v1.63.0-pre.0.20240404175649-853e3e29a0a6 h1:olrk8pALH8inlmr4+eusz
tailscale.com v1.63.0-pre.0.20240404175649-853e3e29a0a6/go.mod h1:6kGByHNxnFfK1i4gVpdtvpdS1HicHohWXnsfwmXy64I=
tailscale.com v1.63.0-pre.0.20240405184358-1fbaf26106ef h1:P6VOuMZ838hOfjEWe+6Om+4LzhXW+OIKYlW1p/+uuO8=
tailscale.com v1.63.0-pre.0.20240405184358-1fbaf26106ef/go.mod h1:6kGByHNxnFfK1i4gVpdtvpdS1HicHohWXnsfwmXy64I=
tailscale.com v1.65.0-pre.0.20240415205755-449f46c2070f h1:X1RJaob/P+66yN6PHyMeNqY27FjwJv2wS6DVRCq+udM=
tailscale.com v1.65.0-pre.0.20240415205755-449f46c2070f/go.mod h1:p7jW7hf6RapU3m3/7HfztM1Z6soNO2/+rR+dEUmta6o=

@ -5,6 +5,7 @@ package libtailscale
import (
"context"
"errors"
"fmt"
"log"
"net/http"
@ -165,6 +166,27 @@ func (a *App) runBackend(ctx context.Context) error {
select {
case s := <-stateCh:
state = s
if cfg.rcfg != nil && state >= ipn.Starting {
// On state change, check if there are router or config changes requiring an update to VPNBuilder
if err := b.updateTUN(service, cfg.rcfg, cfg.dcfg); err != nil {
if errors.Is(err, errMultipleUsers) {
// TODO: surface error to user
}
log.Printf("VPN update failed: %v", err)
mp := new(ipn.MaskedPrefs)
mp.WantRunning = false
mp.WantRunningSet = true
_, err := a.EditPrefs(*mp)
if err != nil {
log.Printf("localapi edit prefs error %v", err)
}
b.lastCfg = nil
b.CloseTUNs()
}
}
case n := <-netmapCh:
networkMap = n
case c := <-configs:
@ -213,6 +235,8 @@ func (a *App) runBackend(ctx context.Context) error {
if err := b.updateTUN(service, cfg.rcfg, cfg.dcfg); err != nil {
log.Printf("VPN update failed: %v", err)
service.Close()
b.lastCfg = nil
b.CloseTUNs()
}
}
case s := <-onDisconnect:

@ -8,11 +8,6 @@ import (
)
var (
// onVPNPrepared is notified when VpnService.prepare succeeds.
onVPNPrepared = make(chan struct{}, 1)
// onVPNRevoked is notified whenever the VPN service is revoked.
onVPNRevoked = make(chan struct{}, 1)
// onVPNRequested receives global IPNService references when
// a VPN connection is requested.
onVPNRequested = make(chan IPNService)
@ -34,20 +29,6 @@ func OnDnsConfigChanged() {
}
}
func notifyVPNPrepared() {
select {
case onVPNPrepared <- struct{}{}:
default:
}
}
func notifyVPNRevoked() {
select {
case onVPNRevoked <- struct{}{}:
default:
}
}
var android struct {
// mu protects all fields of this structure. However, once a
// non-nil jvm is returned from javaVM, all the other fields may

@ -18,9 +18,14 @@ import (
"strings"
"sync"
"time"
"tailscale.com/ipn"
)
// CallLocalAPI calls the given endpoint on the local API using the given HTTP method
const timeoutMillis = 30000
// CallLocalAPI is the method for making localapi calls from Kotlin. It calls
// the given endpoint on the local API using the given HTTP method and
// optionally sending the given body. It returns a Response representing the
// result of the call and an error if the call could not be completed or the
// local API returned a status code in the 400 series or greater.
@ -103,6 +108,12 @@ func (app *App) CallLocalAPIMultipart(timeoutMillis int, method, endpoint string
}
}
func (app *App) EditPrefs(prefs ipn.MaskedPrefs) (LocalAPIResponse, error) {
r, w := io.Pipe()
defer w.Close()
return app.callLocalAPI(timeoutMillis, "PATCH", "prefs", nil, r)
}
func (app *App) callLocalAPI(timeoutMillis int, method, endpoint string, header http.Header, body io.ReadCloser) (LocalAPIResponse, error) {
defer func() {
if p := recover(); p != nil {

@ -170,6 +170,12 @@ func (b *backend) updateTUN(service IPNService, rcfg *router.Config, dcfg *dns.O
return err
}
}
for _, route := range rcfg.LocalRoutes {
route = route.Masked()
if err := builder.AddRoute(route.Addr().String(), int32(route.Bits())); err != nil {
return err
}
}
b.logger.Logf("updateTUN: added %d routes", len(rcfg.Routes))
for _, addr := range rcfg.LocalAddrs {
@ -210,12 +216,6 @@ func (b *backend) updateTUN(service IPNService, rcfg *router.Config, dcfg *dns.O
b.devices.add(tunDev)
b.logger.Logf("updateTUN: added TUN device")
// TODO(oxtoacart): figure out what to do with this
// if err != nil {
// b.lastCfg = nil
// b.CloseTUNs()
// return err
// }
b.lastCfg = rcfg
b.lastDNSCfg = dcfg
return nil

Loading…
Cancel
Save