Easily switch listening address of Syncthing in Web UI and App

I would like to see the ability to easily switch between listening address in Syncthing Web UI and android app. I explain below the background to this feature request, but to give an idea of what I mean, I would like something like

  • auto discovery of available addresses to listen to (if the device is connected to a router and a tethering network, it displays two available listening addresses like “192.168.1.4”, with default port 22000)
  • a dropdown list in the Web UI directly on the home page where I can choose the listening address.
  • the same kind of feature on the Android app.

I would like to know your opinion on this feature, whether you find it as important as I do, and try to understand how this could be implemented.

I love syncthing and hope we can make it even better! <3

Background

I noticed several topics 1 (which I created) 2 3 4 concerning the same issue: how to sync two devices (smartphone and PC) in tethering over Wifi or USB.

The ideal scenario would be to be able to sync without the need of an internet connection, but from what I understand, syncthing with tethering requires one device at least to be connected to a router.

That said, using the smartphone data network as internet connection is fine in most case, that is as long as I am in a location within connectivity range.

So to solve this issue, people recommend to do this.

  1. Connect smartphone to data network.
  2. Connect smartphone with PC via USB tethering or Wifi tethering
  3. Get for the PC’s assigned local IP on the tethering network using “ip a” command for example.
  4. Get the smartphone’s local IP on tethering via an app like “IP tools: wifi analyzer”
  5. Fill these information in the syncthing web ui on PC and the app on the smartphone, into the listening address field.
  6. Restart syncthing on PC

This is a tedious process, but the ability to sync over a simple USB cable or direct Wifi tethering between PC and smartphone is I think an awesome feat.

So I would like to be able to do this directly in Syncthing UI in a convenient way.

If these addresses are on the same tethering “LAN”, doesn’t local discovery work over that and just let them connect without any faffing? If not, why not? (I got the impression local discovery had been fixed somehow on Android, in one direction or the other?)

I’m assuming that you’re using Android and Windows/Linux (USB tethering in macOS and iOS is a completely different setup).

Technically speaking, a router isn’t required, although having one makes connecting more convenient. An external router definitely isn’t required.

Not all phones support Wi-Fi hotspot mode and/or USB tethering either due to hardware limitations, or in the case of mobile carrier locked phones, it’s been disabled.

But if both the computer and phone support USB tethering, the phone’s USB port behaves like a virtual network link that’s connected to a virtual router provided by the phone. Syncthing running on the computer and Syncthing for Android will discover and connect to one another just as they would on a physical LAN.

On a related note, sometime in the possibly near future a big change is coming to USB tethering in Linux (and by extension Android): Linux Preparing To Disable Drivers For Microsoft’s RNDIS Protocol

Wi-Fi hotspot mode is a bit more complicated, but if properly set up, Syncthing on the computer and phone will also auto-discover each other.

1 Like

I think auto discovery is limited to the network the listening address in the configuration is attached to.

If my phone is tethering via USB to my PC, this creates a new network interface which I can see when I run “ip a” command in Linux, and syncthing never discovers the smartphone, unless I go to settings and set the listening address to tcp://192.168.xx.xx:22000 that is the local ip of the device on this new network.

Edit: … Or does the “default” value for listening address sets the auto discovery to listen to all network interfaces? Maybe it is my mistake.

So the issue with tethering might come from the PC not actually supporting it?

My smartphone is a Google Pixel 6a and it obviously provide a USB tethering functionality.

My PC is a ASUS Zenbook 14 with NixOS.

I just tried again to sync with tethered network. The logs of Syncthing on PC says “Discovered 1 NAT service”, which is a good sign, but the devices remain disconnected in the UI. That is unless I change the configuration of the listening address on both devices, which is a tedious thing to do every time.

Edit: Here is the log appearing on my PC:

[OHGH6] 2024/03/10 08:02:12 INFO: Detected 1 NAT service
[OHGH6] 2024/03/10 08:03:12 INFO: Relay listener (dynamic+https://relays.syncthing.net/endpoint) starting
[OHGH6] 2024/03/10 08:03:22 INFO: Relay listener (dynamic+https://relays.syncthing.net/endpoint) shutting down
[OHGH6] 2024/03/10 08:03:22 INFO: listenerSupervisor@dynamic+https://relays.syncthing.net/endpoint: service dynamic+https://relays.syncthing.net/endpoint failed: Get "https://relays.syncthing.net/endpoint": dial tcp 143.244.196.6:443: connect: network is unreachable
[OHGH6] 2024/03/10 08:03:22 INFO: Relay listener (dynamic+https://relays.syncthing.net/endpoint) starting
[OHGH6] 2024/03/10 08:03:52 INFO: Relay listener (dynamic+https://relays.syncthing.net/endpoint) shutting down
[OHGH6] 2024/03/10 08:03:52 INFO: listenerSupervisor@dynamic+https://relays.syncthing.net/endpoint: service dynamic+https://relays.syncthing.net/endpoint failed: Get "https://relays.syncthing.net/endpoint": dial tcp 143.244.196.6:443: i/o timeout (non-context)
[OHGH6] 2024/03/10 08:03:52 INFO: Relay listener (dynamic+https://relays.syncthing.net/endpoint) starting
[OHGH6] 2024/03/10 08:04:22 INFO: Relay listener (dynamic+https://relays.syncthing.net/endpoint) shutting down
[OHGH6] 2024/03/10 08:04:22 INFO: listenerSupervisor@dynamic+https://relays.syncthing.net/endpoint: service dynamic+https://relays.syncthing.net/endpoint failed: Get "https://relays.syncthing.net/endpoint": dial tcp 143.244.196.6:443: i/o timeout
[OHGH6] 2024/03/10 08:04:22 INFO: Relay listener (dynamic+https://relays.syncthing.net/endpoint) starting

It tries to connect and fails in a loop.

Yes, it’s a possibility…

For example, the macOS kernel doesn’t support RNDIS, so a 3rd-party solution is required.

As far as I’m aware of, all of the popular Linux distributions still bundle the rndis_host kernel module.

Windows XP thru 10 bundle a RNDIS driver, while some versions of 11 might require a separate download.

I’ve seen mentions that Google Pixel 6 and up no longer use RNDIS, but can’t confirm it (I only have access to a Pixel 2).

If you’re running the latest release of NixOS, the Linux 6.1 kernel still includes the RNDIS driver, but it’s not guaranteed that NixOS included it in the build. If it’s available, it’s more than likely a module instead of being compiled in. See if the following command returns an error:

modinfo rndis_host.ko

If not, set up the USB tether between your laptop and phone. Then immediately after turning on USB tethering, check the kernel messages (the -T is optional, but it starts each message with a helpful timestamp):

dmesg -T

If RNDIS is supported on both the laptop and phone, there will be kernel messages similar to the following:

usbcore: registered new interface driver rndis_host
usb 1-2.1: USB disconnect, device number 14
usb 1-2.1: new high-speed USB device number 15 using xhci_hcd
usb 1-2.1: New USB device found, idVendor=22b8, idProduct=2e24, bcdDevice= 4.04
usb 1-2.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 1-2.1: Product: moto x4
usb 1-2.1: Manufacturer: motorola
usb 1-2.1: SerialNumber: xxxxxxxxxx
rndis_host 1-2.1:1.0 usb0: register 'rndis_host' at usb-0000:00:14.0-2.1, RNDIS device, xx:xx:xx:xx:xx:xx
rndis_host 1-2.1:1.0 enp0s20u2u1: renamed from usb0

On my (Fedora Linux) laptop, when I check the network device shown in the last line of the kernel messages above, I get the following details:

$ ip address show dev enp0s20u2u1
6: enp0s20u2u1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 1000
    link/ether 7a:fc:a3:c8:bb:67 brd ff:ff:ff:ff:ff:ff
    inet 192.168.42.197/24 brd 192.168.42.255 scope global dynamic noprefixroute enp0s20u2u1
       valid_lft 2138sec preferred_lft 2138sec
    inet6 fe80::590f:172e:4381:183c/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever

Routing table entries:

$ ip route show dev enp0s20u2u1
default via 192.168.42.129 proto dhcp src 192.168.42.197 metric 20101 
192.168.42.0/24 proto kernel scope link src 192.168.42.197 metric 101 

And the phone as it appears in Syncthing’s GUI on the laptop:

Moto_X4

So the network topology when Syncthing connects over the USB tether is:

  • laptop: 192.168.42.197
  • phone: 192.168.42.129
  • gateway: 192.168.42.129

(Note how the phone is both a host and the network gateway – it’s similar to two PCs connected via an Ethernet cable and a pair of gigabit NICs.)

Syncthing on both endpoints is using the stock default value for “Sync Protocol Listen Addresses” which causes Syncthing to bind to all available network interfaces. On the laptop:

$ ss -lnp | grep :22000
udp   UNCONN 0      0                                                                      *:22000                  *:*    users:(("syncthing",pid=2264,fd=14))                                   
tcp   LISTEN 0      4096                                                                   *:22000                  *:*    users:(("syncthing",pid=2264,fd=13))     

(Note that my phone no longer has a mobile data plan and it was in airplane mode when I captured the screenshot and network info above.)

There’s no NAT between a PC and a phone with USB tethering, so you’ve got a separate networking issue.

2 Likes

Syncthing by default listens to all addresses on all interfaces, and performs discovery on the same.

1 Like

modinfo rndis_host.ko outputs

modinfo: ERROR: Module rndis_host.ko not found.

And dmesg -T shows

[lun. 11 mars 22:29:37 2024] usb 3-1: Product: Pixel 6a
[lun. 11 mars 22:29:37 2024] usb 3-1: Manufacturer: Google
[lun. 11 mars 22:29:37 2024] usb 3-1: SerialNumber: xxxxxxxxxx
[lun. 11 mars 22:29:37 2024] cdc_ncm 3-1:1.0: MAC-Address: xxxxxxxxxx
[lun. 11 mars 22:29:37 2024] cdc_ncm 3-1:1.0 usb0: register 'cdc_ncm' at usb-0000:04:00.4-1, CDC NCM (NO ZLP), xxxxxxxxxxxxxx
[lun. 11 mars 22:29:37 2024] usbcore: registered new interface driver cdc_ncm
[lun. 11 mars 22:29:37 2024] usbcore: registered new interface driver cdc_wdm
[lun. 11 mars 22:29:37 2024] usbcore: registered new interface driver cdc_mbim
[lun. 11 mars 22:29:37 2024] cdc_ncm 3-1:1.0 enp4s0f4u1: renamed from usb0
[lun. 11 mars 22:29:37 2024] IPv6: ADDRCONF(NETDEV_CHANGE): enp4s0f4u1: link becomes ready

No sign of rndis, but cdc_ncm shows up.

Also I checked the following behavior is the same whether on USB or Wifi tethering: The PC discovers the smartphone only if the smartphone is connected either with data network or Wifi, otherwise logs on PC shows it keeps trying to reconnect but fails in loop.

So my understanding is it is likely to be the Pixel 6a being locked intentionally or it having hardware limitations.

PS: sorry for this was more of an support issue than a feature request in the end!

My bad… I had a typo. Should have been without the “.ko” part (“rndis_host.ko” is the actual filename while “rndis_host” is the module name):

modinfo rndis_host

Not actually a bad thing because cdc_ncm is the driver for “Ethernet over USB”. So it means that the Pixel 6 and up have dropped RNDIS support in favor of the newer USB communications device class.

According to the kernel messages above, a network device named enp4s0f4u1 was created when you enabled USB tethering.

What’s the output from the following two commands?

ip a s enp4s0f4u1
ip r s dev enp4s0f4u1

As far as Syncthing is concerned, it makes no difference if it’s RNDIS or Ethernet-over-USB because both ultimately look like standard network interfaces.

Sounds like run conditions are enabled in Syncthing on the phone.

Not necessarily, at least according to the kernel messages you posted.

:grinning: