Syncthing running on my Android phone is getting a (kcp) connection from a unknown device, which match my laptop (and vice-versa). As the smartphone and laptop doesn’t contain each other as remote device, this shouldn’t happen.
Log line (on my Android phone):
Connection from at <ip of my server, where syncthing is running> (kcp-client) rejected: unknown device
Network overview:
Smartphone: Local 192.168.xx.xx ip
Laptop: Local 192.168.xx.xx ip
Server: Local 192.168.xx.xx ip and external xx.xx.xx.xx ip
I’m not sure why this is happening from time to time, but I think local discovery and the fact that my server is available through both a internal and external ip has something to say.
Usually this is caused by two devices A and B behind the same NAT device. A announces itself globally and so does B, both assuming that they have a working port forward. Only one of them does, lets say A. Another device C wants to connect to B, and connects to the port forward. It gets connected to A instead. Both A and C get the “unknown device” notification since neither of them knows or wants to talk to the other.
With KCP I’m sure this can happen without explicit port forwards.
I only have a port-forward for my server, but my laptop/smartphone is maybe using/trying to use UPNP.
Per the log on my laptop, it looks like my smartphone tried connecting directly to my laptop through the internal network, if it did connect through a port-forward the traffic should be coming from the external ip (?).
Best way to understand would be to look at same addresses announced by both devices, there is a utility that you’d have to compile yourself to test that.
Looking at https://discovery-v4-4.syncthing.net/v2/?device=<id> for my laptop and smartphone, both announce <external-ip>:22000 and <external-ip>:22020, where <external-ip>:22000 points to my server. I’m not sure about what port 22020, should I forward that port to my server?.
Both also announce <external-ip>:13xx (UPNP?), so that could explain the behaviour. Ex: My laptop announce a old port-forward which my smartphone now use.
Addresses expire in 30mins or 60mins I think. If 13xx is TCP then it’s most likely UPnP, if it’s KCP then it’s most likely a UDP port mapping on router expiring and being given to the other device, which then explains why you see this. The RFC for STUN talks that if we send a packet ever 24s (which we do by stun keepalive), the mapping should not expire. Perhaps your router does not adhere to that, as well as picks sequential ports.
I’m not sure what you mean the difference would be. It’s connecting because it’s looking for a device that’s added to the config, and one of the lookup mechanisms returned this address.
Potentially the connecting side could say “I’m expecting device XYZ” and if the receiving side is not XYZ it can just disconnect and ignore. That’s an information leak from the connecting side, though.
The connecting side would say (when linking first time): “i’m initiating first connect, please approve me…” it that case the receiving device will respond.
But if receiving side would get a connection from unknown device without “please approve me” than it’ll ignore it.
(and once “approved”, the connecting device will store in the config: “i’ve been approved by this device already, don’t ask “please approve” from it again”)