Local discovery not working on android 11

Hi, I have two android phones with a recent version of android (11 and 12). The phones do not discover each other while in the same network, neither on a dedicated router nor on a hotspot. The logs indicate nothing suspicious. Is this a known issue?

These are the logs: --------- beginning of main --------- beginning of system

Very well known. The only workaround that I know is to run Syncthing as root. You usually can also hard-code the IP addresses or hostnames to get around the limitation.

Ok thank you! That’s good to know but sad. What do you mean by “run as root”? What causes this issue and what would it take to fix it?

There’s an option in the app settings to “run as root”. Obviously, your devices need to be rooted beforehand (see https://wikipedia.org/wiki/Rooting_(Android)).

1 Like

Actually just not disabling global discovery should also work to get a local connection, at least between an android and a non-broken platform (anything non-android). Between android it won’t work indeed. Rooting a phone just for local discovery in syncthing seems a bit heavy handed (though I can recommend tinkering with your android for various other reasons, like security updates and de-googling :slight_smile: ).

My setup was a little different (Android 11 and Android 10 Tablet, non rooted, local WiFi only) it worked for me entering tcp://:22000 in the “Sync Protocol Listen Addresses” manually (incl. enable local discovery).

However, later I changed it to have a client - server sync with all devices. So maybe this also can be a work around for you.

That’s already covered by the default value of default which translates to tcp://0.0.0.0:22000, dynamic+https://relays.syncthing.net/endpoint, quic://0.0.0.0:22000. In other words, replacing default with tcp://:22000 shall only end up disabling QUIC and relays which isn’t normally desired.

3 Likes

I’m not too well informed about the internals of Syncthing, but from what I understand would the following maybe be a solution?

Somehow android prevents the Syncthing binary from doing the local discovery. However, there’s an api in android for just this:

Why don’t we create a discovery service on the android side of the Syncthing app that finds the ip addresses of other android Syncthing devices on the local network, send this info to the Golang binary, and receive this info in a new discovery method in go? I know it’s ugly to get platform specific, but this issue is really annoying…

1 Like

We don’t even need NSD. A simple REST endpoint to feed interface IPs to Syncthing would be enough to solve this.

1 Like

You mean we just create an http endpoint on each android Syncthing instance and try to ping it on every possible IP address in the local network? This means we would not need a platform special API?

Syncthing already has a REST API. We would only need to add a new endpoint. The app would collect the interface IPs at startup and after address changes using Android APIs and pass them to the Syncthing process via REST.

The endpoint could also have further utility if someone wanted to feed additional addresses into their Syncthing instance.

We apparently even had it at one point, though not anymore!

https://docs.syncthing.net/rest/system-discovery-post.html

But yes, the local discovery protocol is quite simple, an “external” implementation would be doable.

I’ve experimented with Wifi direct and java based doscovery some year ago. There is still a branch on the forks repo about that. Never finished but that could be partly used to discover other running Syncthing Android app instances and feed the IP to a new REST endpoint.

1 Like

We don’t even need to re-implement Syncthing’s discovery protocol if we just want to fix LAN transfer, which is what most people want.

This already works with global discovery if at least one device is able to determine its own LAN IPs. So if we can extend the interface IP discovery and tell it to the discovery server, the LAN transfer should work again.

If we want fully local discovery we would need to re-implement the protocol as @calmh pointed out. As this only uses broadcast/multicast we could bind the port with SO_REUSEPORT in Syncthing and allow the wrapper to use the same.

1 Like

What’s the actual problem? Does android now have multiple network adapters and we advertise the wrong one or something?

Android started restricting syscalls the go standard library uses to discover the interface. Apparently there are potential fixes: x/mobile: Calling net.InterfaceAddrs() fails on Android SDK 30 · Issue #40569 · golang/go · GitHub

I have a pair of A12 devices (one is now A13, but that’s irrelevant for this). One of them is a legacy device and the other is newer.

The legacy device can be locally discovered by my PC. But not the newer one. For that I need to manually enter its LAN IP address.

The only relevant difference between the two I can think of is MAC randomisation. The legacy device doesn’t have the hardware, so the feature is unavailable there. The newer one has it.

Otherwise, just being on A12 doesn’t explain why my legacy A12 device and PC can discover each other.

Can someone please provide a YouTube Tutorial so everyone whose need help can solve their problem, it would be more appropriate method to help someone.…Thanks in advance…

My version is 1.23.0. Does scanning the qr code also help when the devices are already paired?