(This could conceivably be seen as a feature, but considering you provide a setting to change the local bind address for listen, it is possible that this is just incomplete support.)
Problem
The issue is as follows. On hosts where you have multiple outgoing routes, setting the bind address in the settings is not sufficient to guarantee the route (first hop) that syncthing will use. When a local bind address is not given to a socket at creation time, the local OS will use standard destination based routing. This means the ffirst (highest priority) network device that is capable of routing the packet will be chosen, and the interface’s IP is chosen as the “local address”.
In low level posix calls, to avoid this you call bind() on the socket to choose the local address, and then you call connect(). In go terms, you call DialTCP() with the optional local port filled out (or create a dialer with LocalAddr set.)
Reproduction
- Setup a network where you have two routes to a server possible (each has a different interface IP.)
- Set the Sync Protocol Listen Address to the second interface’s IP.
- Restart Syncthing
- Use netstat or some similar tool, you will see local addresses on the connections that are for the first interface’s IP.
Notes
I had managed to make a local patch for 11.x, a friend had offered to submit it etc to you folks, but by that time so much effort had switched to 12.x that there was little interest. I am not supper proficient in go, and so much changed, I’ve been unable to make a sufficient patch in 12.x. I’d be happy to provide the details around 11.x if they would be helpful.