Files
syncthing/lib/netutil/netutil.go
Catfriend1 06dd8ee6d7 fix(pmp, netutil): workaround native code denied to discover gateway ipv4 addr on Android 14+ (#10204)
### Purpose

As discussed on the forum:
https://forum.syncthing.net/t/reviving-nat-pmp-in-v2-x-on-android-14/24554

TL;DR
Android 14+ only lets java code get the gateway IPv4 address which is
used in SyncthingNative’s NAT-PMP feature.

So I’ve added the java code to the wrapper, got the router IP address
and feeded it to SyncthingNative by setting the env var
“FALLBACK_NET_GATEWAY_IPV4”.

This revives the NAT feature:

> [Z36WU] INFO: Detected 1 NAT service

### Testing

Local build and test via Android emulator (AVD 15).
2025-07-02 20:40:38 +02:00

45 lines
1.1 KiB
Go

// Copyright (C) 2023 The Syncthing Authors.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.
package netutil
import (
"fmt"
"net"
"net/url"
"os"
"github.com/jackpal/gateway"
)
// Address constructs a URL from the given network and hostname.
func AddressURL(network, host string) string {
u := url.URL{
Scheme: network,
Host: host,
}
return u.String()
}
// Gateway returns the IP address of the default network gateway.
func Gateway() (ip net.IP, err error) {
ip, err = gateway.DiscoverGateway()
if err != nil {
// Fails on Android 14+ due to permission denied error when reading
// /proc/net/route. The wrapper may give a hint then because it is
// able to discover the gateway from java code.
if v := os.Getenv("FALLBACK_NET_GATEWAY_IPV4"); v != "" {
ip = net.ParseIP(v)
if ip == nil {
return nil, fmt.Errorf("%q: invalid IP", v)
}
return ip, nil
}
return ip, err
}
return ip, nil
}