# tsnet_flutter Embed [Tailscale's tsnet](https://pkg.go.dev/tailscale.com/tsnet) in Flutter apps. Provides a userspace WireGuard tunnel with a localhost TCP proxy — **no VPN entitlement needed** on iOS. ## How it works ``` Flutter App (Dart) └── tsnet_flutter plugin ├── iOS/macOS: Swift MethodChannel → C bridge → Go static library (.a) └── Android/Linux: Dart FFI → Go shared library (.so) ↓ Go tsnet (WireGuard + userspace netstack) ↓ localhost TCP proxy (127.0.0.1:PORT) ↓ WireGuard tunnel → remote device (100.x.x.x) ``` Your app connects to `localhost:PORT`. Traffic is forwarded through a WireGuard tunnel to the target device's Tailscale IP. Your app doesn't know about Tailscale — it just sees a localhost port. ## Usage ```dart import 'package:tsnet_flutter/tsnet_flutter.dart'; final tsnet = TsnetFlutter(); // Join the Tailnet await tsnet.start(authKey: 'tskey-auth-...'); // Create a local proxy to the remote device final localPort = await tsnet.startProxy('100.64.0.5', port: 5050); // Connect your client to the proxy yourClient.connect('127.0.0.1', port: localPort); // Clean up await tsnet.stopProxy(); await tsnet.stop(); ``` ## API | Method | Description | |--------|-------------| | `start(authKey, hostname)` | Join a Tailnet with an auth key. Idempotent — safe to call multiple times. | | `startProxy(ip, port)` | Create a localhost TCP proxy to a remote Tailscale IP. Returns the local port. | | `stopProxy()` | Stop the localhost proxy. | | `stop()` | Disconnect from the Tailnet. | | `status()` | Get the current Tailscale connection status (state, peers, IPs). | | `tailscaleIP()` | Get this device's Tailscale IPv4 address (100.x.x.x). | ## Platform support | Platform | Tailscale tunnel | Binary type | Architectures | |----------|-----------------|-------------|---------------| | iOS | Supported | c-archive (.a in xcframework) | arm64 device + arm64 simulator | | macOS | Supported | c-archive (.a in xcframework) | arm64 + x86_64 universal | | Linux | Supported | c-shared (.so) | amd64 | | Android | Local only (WIP) | c-shared (.so in jniLibs) | arm64-v8a + x86_64 | **Android note:** Local TCP connections work. Tailscale tunnel is blocked by Go's `net.Interfaces()` requiring `CAP_NET_ADMIN` on Android. Full tunnel support will require `libtailscale` integration from [tailscale-android](https://github.com/tailscale/tailscale-android). ## Platform setup ### iOS No special entitlements or permissions needed. No VPN entitlement required. ### macOS macOS apps run sandboxed. Add these entitlements to both `DebugProfile.entitlements` and `Release.entitlements`: ```xml com.apple.security.network.client com.apple.security.network.server ``` `network.client` allows the app to connect to the localhost proxy and external networks. `network.server` allows the Go layer to open a localhost listener for the proxy. ### Android Add the `INTERNET` permission to your `AndroidManifest.xml`: ```xml ``` ### Linux No special setup needed. The shared library is bundled automatically. ## Requirements - Tailscale auth key — generate at [login.tailscale.com/admin/settings/keys](https://login.tailscale.com/admin/settings/keys) - Auth keys can be reusable and tag-scoped for ACL isolation ## Building from source The pre-built binaries are included in the package. To rebuild from Go source: ```bash # Prerequisites: Go 1.23+, Xcode (for Apple platforms), Android NDK (for Android) ./build_go.sh # build all platforms ./build_go.sh ios # iOS only ./build_go.sh macos # macOS only ./build_go.sh android # Android only (requires NDK) ./build_go.sh linux # Linux only (uses Docker on macOS) ./build_go.sh apple # iOS + macOS ``` ## Binary sizes | Platform | Size | Notes | |----------|------|-------| | iOS (device) | ~23 MB | After App Store compression: ~14 MB | | iOS (simulator) | ~23 MB | Development only | | macOS (universal) | ~49 MB | arm64 + x86_64 | | Android (arm64) | ~20 MB | | | Android (x86_64) | ~22 MB | Emulator only | | Linux (amd64) | ~24 MB | | Size is dominated by WireGuard + gVisor netstack + Go runtime. Feature tags strip ~35 unused Tailscale subsystems (SSH, Drive, Serve, etc.). ## License BSD-3-Clause — compatible with Tailscale's license. See [LICENSE](LICENSE).