Skip to content

Commit 938ba13

Browse files
committed
Merge remote-tracking branch 'origin/main' into atavism/linux-arm
2 parents bcab4b3 + fe09a5d commit 938ba13

28 files changed

Lines changed: 450 additions & 326 deletions

android/app/src/main/kotlin/org/getlantern/lantern/service/LanternVpnService.kt

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import org.getlantern.lantern.BuildConfig
2020
import org.getlantern.lantern.MainActivity
2121
import org.getlantern.lantern.constant.VPNStatus
2222
import org.getlantern.lantern.notification.NotificationHelper
23+
import org.getlantern.lantern.service.LanternVpnService.Companion.ACTION_STOP_VPN
2324
import org.getlantern.lantern.utils.AppLogger
2425
import org.getlantern.lantern.utils.DeviceUtil
2526
import org.getlantern.lantern.utils.FlutterEventListener
@@ -146,8 +147,20 @@ class LanternVpnService :
146147
closeTunInterface()
147148
// Clean up synchronously — cannot use serviceScope here because
148149
// it is cancelled in the finally block below.
149-
runCatching { Mobile.stopVPN() }
150-
.onFailure { e -> AppLogger.e(TAG, "Mobile.stopVPN() failed during destroy", e) }
150+
// Only call stopVPN if Radiance IPC is actually running; calling it before
151+
// setup completes results in a misleading "IPC not running" error.
152+
if (Mobile.isRadianceConnected()) {
153+
runCatching { Mobile.stopVPN() }
154+
.onFailure { e ->
155+
AppLogger.e(
156+
TAG,
157+
"Mobile.stopVPN() failed during destroy",
158+
e
159+
)
160+
}
161+
} else {
162+
AppLogger.d(TAG, "Skipping stopVPN — Radiance IPC not running")
163+
}
151164
runCatching {
152165
runBlocking(Dispatchers.IO) { DefaultNetworkMonitor.stop() }
153166
}.onFailure { e ->
@@ -263,6 +276,14 @@ class LanternVpnService :
263276
// VPN service starts, replaced by connected notification on success.
264277
notificationHelper.showStartingVPNConnectedNotification(this@LanternVpnService)
265278
runCatching {
279+
// Radiance is pre-warmed via ACTION_START_RADIANCE, but as a background
280+
// service it may have been killed by the OS before setup completed.
281+
// Re-run setup here under the foreground notification so it is guaranteed
282+
// to finish before we attempt to start the VPN tunnel.
283+
if (!Mobile.isRadianceConnected()) {
284+
AppLogger.d(TAG, "Radiance not ready, setting up before VPN start")
285+
Mobile.setupRadiance(opts(), flutterEventListener)
286+
}
266287
DefaultNetworkMonitor.start()
267288
connect()
268289
VpnStatusManager.postVPNStatus(VPNStatus.Connected)
@@ -296,7 +317,13 @@ class LanternVpnService :
296317
private suspend fun stopVPNTunnel() {
297318
try {
298319
closeTunInterface()
299-
runCatching { Mobile.stopVPN() }
320+
runCatching {
321+
if (!Mobile.isVPNConnected()) {
322+
AppLogger.d(TAG, "VPN is not connected, skipping stopVPN")
323+
return@runCatching
324+
}
325+
Mobile.stopVPN()
326+
}
300327
.onFailure { e -> AppLogger.e(TAG, "Mobile.stopVPN() failed", e) }
301328

302329
runCatching { DefaultNetworkMonitor.stop() }

android/app/src/main/kotlin/org/getlantern/lantern/utils/LanternLogger.kt

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,16 @@ object AppLogger {
5151
writeAsync("INFO", tag, message)
5252
}
5353

54-
fun w(tag: String, message: String, tr: Throwable? = null) {
55-
Log.w(tag, message, tr)
56-
writeAsync("WARN", tag, message)
54+
fun w(tag: String, message: String, throwable: Throwable? = null) {
55+
Log.w(tag, message, throwable)
56+
val errorMessage = buildString {
57+
append(message)
58+
if (throwable != null) {
59+
append("\n")
60+
append(throwable.stackTraceToString())
61+
}
62+
}
63+
writeAsync("WARN", tag, errorMessage)
5764
}
5865

5966
fun e(tag: String, message: String, throwable: Throwable? = null) {

go.mod

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ require (
2525
github.com/alecthomas/assert/v2 v2.3.0
2626
github.com/getlantern/common v1.2.1-0.20260224184656-5aefb9c21c85
2727
github.com/getlantern/lantern-server-provisioner v0.0.0-20251031121934-8ea031fccfa9
28-
github.com/getlantern/radiance v0.0.0-20260318170544-725ad379e90b
28+
github.com/getlantern/radiance v0.0.0-20260320012916-fcb0501214cd
2929
github.com/sagernet/sing-box v1.12.22
3030
golang.org/x/mobile v0.0.0-20250711185624-d5bb5ecc55c0
3131
golang.org/x/sys v0.40.0
@@ -174,11 +174,11 @@ require (
174174
github.com/getlantern/amp v0.0.0-20260305201851-782bc8045e58 // indirect
175175
github.com/getlantern/appdir v0.0.0-20250324200952-507a0625eb01 // indirect
176176
github.com/getlantern/dnstt v0.0.0-20260112160750-05100563bd0d // indirect
177-
github.com/getlantern/fronted v0.0.0-20260316001628-14e5f21104b5 // indirect
177+
github.com/getlantern/fronted v0.0.0-20260319225233-cf2160f85053 // indirect
178178
github.com/getlantern/golog v0.0.0-20230503153817-8e72de7e0a65 // indirect
179179
github.com/getlantern/iptool v0.0.0-20230112135223-c00e863b2696 // indirect
180180
github.com/getlantern/keepcurrent v0.0.0-20260304213122-017d542145ae // indirect
181-
github.com/getlantern/kindling v0.0.0-20260305202005-ca73a10f13ac // indirect
181+
github.com/getlantern/kindling v0.0.0-20260319225424-4736208dd171 // indirect
182182
github.com/getlantern/lantern-box v0.0.42 // indirect
183183
github.com/getlantern/lantern-water v0.0.0-20260313142412-dfc64287c8c8 // indirect
184184
github.com/getlantern/mtime v0.0.0-20200417132445-23682092d1f7 // indirect

go.sum

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,10 +238,13 @@ github.com/getlantern/dnstt v0.0.0-20260112160750-05100563bd0d/go.mod h1:LA7cwZQ
238238
github.com/getlantern/errors v1.0.1/go.mod h1:l+xpFBrCtDLpK9qNjxs+cHU6+BAdlBaxHqikB6Lku3A=
239239
github.com/getlantern/errors v1.0.4 h1:i2iR1M9GKj4WuingpNqJ+XQEw6i6dnAgKAmLj6ZB3X0=
240240
github.com/getlantern/errors v1.0.4/go.mod h1:/Foq8jtSDGP8GOXzAjeslsC4Ar/3kB+UiQH+WyV4pzY=
241+
github.com/getlantern/fdcount v0.0.0-20190912142506-f89afd7367c4 h1:JdD4XSaT6/j6InM7MT1E4WRvzR8gurxfq53A3ML3B/Q=
241242
github.com/getlantern/fdcount v0.0.0-20210503151800-5decd65b3731 h1:v+vJ3LgV4nW4xRPZo+xkADDflXLpRbG+Lv69XKWFjTQ=
242243
github.com/getlantern/fdcount v0.0.0-20210503151800-5decd65b3731/go.mod h1:XZwE+iIlAgr64OFbXKFNCllBwV4wEipPx8Hlo2gZdbM=
243244
github.com/getlantern/fronted v0.0.0-20260316001628-14e5f21104b5 h1:TEVUZpGVQ3+jAf+Oq/Ahx/TltaWHRT2Crj7upb7GZJo=
244245
github.com/getlantern/fronted v0.0.0-20260316001628-14e5f21104b5/go.mod h1:1a+iv1xzGxZWj/vCHzr8Z3dF9H1sNTuMSPHUqRsgbl0=
246+
github.com/getlantern/fronted v0.0.0-20260319225233-cf2160f85053 h1:bq5D3qSjLg2PVBPOqhLE5nQCJpfYHYu8MYavHfPJC78=
247+
github.com/getlantern/fronted v0.0.0-20260319225233-cf2160f85053/go.mod h1:2miS+mgq6csnGAUvW3w+VUODRAeo08rohkpkR99YGyM=
245248
github.com/getlantern/golog v0.0.0-20210606115803-bce9f9fe5a5f/go.mod h1:ZyIjgH/1wTCl+B+7yH1DqrWp6MPJqESmwmEQ89ZfhvA=
246249
github.com/getlantern/golog v0.0.0-20230503153817-8e72de7e0a65 h1:NlQedYmPI3pRAXJb+hLVVDGqfvvXGRPV8vp7XOjKAZ0=
247250
github.com/getlantern/golog v0.0.0-20230503153817-8e72de7e0a65/go.mod h1:+ZU1h+iOVqWReBpky6d5Y2WL0sF2Llxu+QcxJFs2+OU=
@@ -257,6 +260,8 @@ github.com/getlantern/keepcurrent v0.0.0-20260304213122-017d542145ae h1:NMq3K7h3
257260
github.com/getlantern/keepcurrent v0.0.0-20260304213122-017d542145ae/go.mod h1:ag5g9aWUw2FJcX5RVRpJ9EBQBy5yJuy2WXDouIn/m4w=
258261
github.com/getlantern/kindling v0.0.0-20260305202005-ca73a10f13ac h1:ev9Y7AsmNVtUdH1bhSGFLU2CUbAMs83KhtbkHa8geAo=
259262
github.com/getlantern/kindling v0.0.0-20260305202005-ca73a10f13ac/go.mod h1:gKsfk+rBgfIEEF71fn/PHNHp5RaDD1avj2MODUpc2WA=
263+
github.com/getlantern/kindling v0.0.0-20260319225424-4736208dd171 h1:UEjX+Gg+T6oGVUbzHJ4JfLhlsIh8Wl8PmTXZYWGS43A=
264+
github.com/getlantern/kindling v0.0.0-20260319225424-4736208dd171/go.mod h1:c5cFjpNrqX8wQ0PUE2blHrO7knAlRCVx3j1/G6zaVlY=
260265
github.com/getlantern/lantern-box v0.0.42 h1:Cn8f41dNWC21RQBtljV1D2uNd3hm29OjELG2Stq1/7o=
261266
github.com/getlantern/lantern-box v0.0.42/go.mod h1:HhBd4LrHj0vIo8XFwvJVONoAySo8kz7jaqDQOzaZVRo=
262267
github.com/getlantern/lantern-server-provisioner v0.0.0-20251031121934-8ea031fccfa9 h1:6seyD2f9tz2am0YQd/Qn+q7LFiiQgnmxgwWFnVceGZw=
@@ -277,8 +282,10 @@ github.com/getlantern/osversion v0.0.0-20240418205916-2e84a4a4e175 h1:JWH5BB2o0e
277282
github.com/getlantern/osversion v0.0.0-20240418205916-2e84a4a4e175/go.mod h1:h3S9LBmmzN/xM+lwYZHE4abzTtCTtidKtG+nxZcCZX0=
278283
github.com/getlantern/pluriconfig v0.0.0-20251126214241-8cc8bc561535 h1:rtDmW8YLAuT8r51ApR5z0d8/qjhHu3TW+divQ2C98Ac=
279284
github.com/getlantern/pluriconfig v0.0.0-20251126214241-8cc8bc561535/go.mod h1:WKJEdjMOD4IuTRYwjQHjT4bmqDl5J82RShMLxPAvi0Q=
280-
github.com/getlantern/radiance v0.0.0-20260318170544-725ad379e90b h1:TYLWfqi5L3ijG0TdonpA4M0kgzWRKgndy7OIUqn8WMs=
281-
github.com/getlantern/radiance v0.0.0-20260318170544-725ad379e90b/go.mod h1:QG9fHG/GresYdPa3Tr5gYeg8yDkE+crdyvg6KXChQdQ=
285+
github.com/getlantern/radiance v0.0.0-20260318200641-bf610b5661c5 h1:2Ygz2U1eqTVPDSD/9coWmGwcr1bb2/Eor3Q9M2d/iDI=
286+
github.com/getlantern/radiance v0.0.0-20260318200641-bf610b5661c5/go.mod h1:QG9fHG/GresYdPa3Tr5gYeg8yDkE+crdyvg6KXChQdQ=
287+
github.com/getlantern/radiance v0.0.0-20260320012916-fcb0501214cd h1:C1C97PpN8zHX3xjrNJA2GqNIGyZJJccz0tGG/x5M9Sc=
288+
github.com/getlantern/radiance v0.0.0-20260320012916-fcb0501214cd/go.mod h1:54gfT+9fEFJAXLxSynr31iaeksM/M+uGhSvtJPoGEnE=
282289
github.com/getlantern/samizdat v0.0.3-0.20260310125445-325cf1bd1b60 h1:m9eXjDK9vllbVH467+QXbrxUFFM9Yp7YJ90wZLw4dwU=
283290
github.com/getlantern/samizdat v0.0.3-0.20260310125445-325cf1bd1b60/go.mod h1:uEeykQSW2/6rTjfPlj3MTTo59poSHXfAHTGgzYDkbr0=
284291
github.com/getlantern/sing v0.7.18-lantern h1:QKGgIUA3LwmKYP/7JlQTRkxj9jnP4cX2Q/B+nd8XEjo=

ios/Podfile.lock

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,6 @@ PODS:
2626
- OrderedSet (6.0.3)
2727
- package_info_plus (0.4.5):
2828
- Flutter
29-
- Sentry/HybridSDK (8.56.2)
30-
- sentry_flutter (9.14.0):
31-
- Flutter
32-
- FlutterMacOS
33-
- Sentry/HybridSDK (= 8.56.2)
3429
- share_plus (0.0.1):
3530
- Flutter
3631
- shared_preferences_foundation (0.0.1):
@@ -112,7 +107,6 @@ DEPENDENCIES:
112107
- integration_test (from `.symlinks/plugins/integration_test/ios`)
113108
- mobile_scanner (from `.symlinks/plugins/mobile_scanner/darwin`)
114109
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
115-
- sentry_flutter (from `.symlinks/plugins/sentry_flutter/ios`)
116110
- share_plus (from `.symlinks/plugins/share_plus/ios`)
117111
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
118112
- store_checker (from `.symlinks/plugins/store_checker/ios`)
@@ -122,7 +116,6 @@ DEPENDENCIES:
122116
SPEC REPOS:
123117
https://github.com/CocoaPods/Specs.git:
124118
- OrderedSet
125-
- Sentry
126119
- Stripe
127120
- StripeApplePay
128121
- StripeCore
@@ -154,8 +147,6 @@ EXTERNAL SOURCES:
154147
:path: ".symlinks/plugins/mobile_scanner/darwin"
155148
package_info_plus:
156149
:path: ".symlinks/plugins/package_info_plus/ios"
157-
sentry_flutter:
158-
:path: ".symlinks/plugins/sentry_flutter/ios"
159150
share_plus:
160151
:path: ".symlinks/plugins/share_plus/ios"
161152
shared_preferences_foundation:
@@ -179,8 +170,6 @@ SPEC CHECKSUMS:
179170
mobile_scanner: 77265f3dc8d580810e91849d4a0811a90467ed5e
180171
OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94
181172
package_info_plus: c0502532a26c7662a62a356cebe2692ec5fe4ec4
182-
Sentry: b53951377b78e21a734f5dc8318e333dbfc682d7
183-
sentry_flutter: a9f60d84bfddcae9a0ebf834547702f8854766a1
184173
share_plus: 8b6f8b3447e494cca5317c8c3073de39b3600d1f
185174
shared_preferences_foundation: 5086985c1d43c5ba4d5e69a4e8083a389e2909e6
186175
store_checker: a7be624ac44a4ba88e7917e71afe8433f197161e

lantern-core/core.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ type App interface {
6060
IsVPNRunning() (bool, error)
6161
GetAvailableServers() []byte
6262
MyDeviceId() string
63-
GetServerByTag(tag string) (servers.Server, bool)
63+
GetServerByTagJSON(tag string) ([]byte, bool, error)
6464
ReferralAttachment(referralCode string) (bool, error)
6565
UpdateLocale(locale string) error
6666
StartBackgroundListeners()
@@ -230,7 +230,7 @@ func (lc *LanternCore) initialize(opts *utils.Opts, eventEmitter utils.FlutterEv
230230
func (lc *LanternCore) listeningServerLocationChanges() {
231231
events.Subscribe(func(evt vpn.AutoSelectionsEvent) {
232232
tag := evt.Selections.Lantern
233-
servers, ok := lc.GetServerByTag(tag)
233+
servers, ok := lc.serverManager.GetServerByTag(tag)
234234
if !ok {
235235
slog.Error("no server found with tag", "tag", tag)
236236
return
@@ -347,9 +347,11 @@ func (lc *LanternCore) StopBackgroundListeners() {
347347
slog.Info("Background listeners stopped")
348348
}
349349

350-
func (lc *LanternCore) GetServerByTag(tag string) (servers.Server, bool) {
351-
return lc.serverManager.GetServerByTag(tag)
352-
350+
// GetServerByTagJSON returns the server for a given tag as pre-marshalled JSON.
351+
// This is safe to call from CGo callback stacks because the pointer-rich Server
352+
// types are marshalled here rather than being returned to the caller.
353+
func (lc *LanternCore) GetServerByTagJSON(tag string) ([]byte, bool, error) {
354+
return lc.serverManager.GetServerByTagJSON(tag)
353355
}
354356

355357
func (lc *LanternCore) VPNStatus() (vpn.Status, error) {
@@ -394,13 +396,13 @@ func (lc *LanternCore) AvailableFeatures() []byte {
394396
}
395397

396398
func (lc *LanternCore) GetAvailableServers() []byte {
397-
serversList := lc.rad.ServerManager().Servers()
398-
jsonBytes, err := json.Marshal(serversList)
399+
// Use ServersJSON which marshals under the lock, avoiding GC write barrier
400+
// panics when pointer-rich sing-box types are copied on a CGo callback stack.
401+
jsonBytes, err := lc.rad.ServerManager().ServersJSON()
399402
if err != nil {
400403
slog.Error("Error marshalling servers", "error", err)
401404
return nil
402405
}
403-
slog.Debug("Available servers JSON", "json", string(jsonBytes))
404406
return jsonBytes
405407
}
406408

lantern-core/ffi/ffi.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -265,14 +265,15 @@ func getAutoLocation() *C.char {
265265
return SendError(err)
266266
}
267267

268-
servers, ok := c.GetServerByTag(location.Lantern)
269-
if !ok {
270-
return SendError(fmt.Errorf("error finding server with tag: %s", location.Lantern))
271-
}
272-
jsonBytes, err := json.Marshal(servers)
268+
// Use GetServerByTagJSON which marshals internally, avoiding GC write
269+
// barrier panics when pointer-rich Server types are copied on the CGo stack.
270+
jsonBytes, ok, err := c.GetServerByTagJSON(location.Lantern)
273271
if err != nil {
274272
return SendError(fmt.Errorf("error marshalling server: %v", err))
275273
}
274+
if !ok {
275+
return SendError(fmt.Errorf("error finding server with tag: %s", location.Lantern))
276+
}
276277
return C.CString(string(jsonBytes))
277278
}
278279

lantern-core/mobile/mobile.go

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -217,8 +217,7 @@ func StopAutoLocationListener() error {
217217
})
218218
}
219219

220-
// // GetAvailableServers returns the available servers in JSON format.
221-
// // This function retrieves the servers from lantern
220+
// GetAvailableServers returns the available servers in JSON format.
222221
func GetAvailableServers() ([]byte, error) {
223222
return withCoreR(func(c lanterncore.Core) ([]byte, error) { return c.GetAvailableServers(), nil })
224223
}
@@ -237,14 +236,13 @@ func GetAutoLocation() (string, error) {
237236
return "", err
238237
}
239238
return withCoreR(func(c lanterncore.Core) (string, error) {
240-
servers, ok := c.GetServerByTag(location.Lantern)
241-
if !ok {
242-
return "", fmt.Errorf("no server found with tag: %s", location.Lantern)
243-
}
244-
jsonBytes, err := json.Marshal(servers)
239+
jsonBytes, ok, err := c.GetServerByTagJSON(location.Lantern)
245240
if err != nil {
246241
return "", fmt.Errorf("error marshalling server: %v", err)
247242
}
243+
if !ok {
244+
return "", fmt.Errorf("no server found with tag: %s", location.Lantern)
245+
}
248246
slog.Debug("Auto location server:", "server", string(jsonBytes))
249247
return string(jsonBytes), nil
250248
})

lib/core/common/app_secrets.dart

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import 'dart:io';
2-
31
import 'package:flutter_dotenv/flutter_dotenv.dart';
42

53
class AppSecrets {
@@ -18,13 +16,4 @@ class AppSecrets {
1816

1917
static String get lanternPackageName => "org.getlantern.lantern";
2018

21-
static String dnsConfig() {
22-
if (Platform.isAndroid) {
23-
return "https://4753d78f885f4b79a497435907ce4210@o75725.ingest.sentry.io/5850353";
24-
}
25-
if (Platform.isIOS) {
26-
return "https://c14296fdf5a6be272e1ecbdb7cb23f76@o75725.ingest.sentry.io/4506081382694912";
27-
}
28-
return "https://7397d9db6836eb599f41f2c496dee648@o75725.ingest.us.sentry.io/4507734480912384";
29-
}
3019
}

lib/core/models/feature_flags.dart

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
enum FeatureFlag {
2-
sentry('sentry'),
32
privateGcp('private.gcp'),
4-
autoUpdateEnabled('autoUpdateEnabled'),
53
metrics('otel.metrics'),
6-
traces('otel.traces');
4+
traces('otel.traces'),
5+
autoUpdateEnabled('autoUpdateEnabled');
76

87
final String key;
98

0 commit comments

Comments
 (0)