UPnP observation

Since many people have problems with UPnP (me included), I tried to look at it a little. But the code in this project is too fancy for me.

I did notice this, however:

Three instances of 0.11.5, one on windows, one on a QNAP (212, with a fairly slow ARM) and one on a zenfone (atom, fast for a phone, but slow in this context).

There is no problem with UPnP on my ddwrt, it opens ports left and right for other services and applications. Syncthing has problems with UPnP, though.

ddwrt opens a port for syncthing on windows. A permanent one.

For the zenfone, there is none opened. For the QNAP, something else happens: When I restart, I can sometimes see that there is for a short while a port opened, then closed. It might be everytime, but it is so short that I probably miss it.

Now all three instances run the same code…the differences are that they have different folder to sync and other differences in the config file, and that they have different speed of execution of syncthing processes (and other parallel processes).

Very mysterious.

Completely wiped the QNAP and reinstalled, but the UPnP behavior is the same.


func (s *IGDService) AddPortMapping(localIPAddress string, protocol Protocol, externalPort, internalPort int, description string, timeout int) error { tpl := <u:AddPortMapping xmlns:u="%s"> <NewRemoteHost></NewRemoteHost> <NewExternalPort>%d</NewExternalPort> <NewProtocol>%s</NewProtocol> <NewInternalPort>%d</NewInternalPort> <NewInternalClient>%s</NewInternalClient> <NewEnabled>1</NewEnabled> <NewPortMappingDescription>%s</NewPortMappingDescription> <NewLeaseDuration>%d</NewLeaseDuration> </u:AddPortMapping> body := fmt.Sprintf(tpl, s.serviceURN, externalPort, protocol, internalPort, localIPAddress, description, timeout)

timeout is not used for lease time in the other functions above. It is used for something else. Maybe this is not the problem, but pretty it isn’t. :sweat_smile:

What do you mean? It’s used for duration? UPnP had bugs which I am not yet sure if a version that has it fixed is releases.

I suggest you get upnp logs from all devices thst have problems for investigation.

I had the impression it is used for timeout (i.e. the time you spend until you give up) when trying to talk to UPnP devices in the code higher up in that file, which would make sense.

But NewLeaseDuration is the time you want the connection to be active. I think it might as well be set to 0 = indefinite in the case of syncthing.

You can adjust that in config.xml

Thanks for the information!

I just changed that to 0 on the phone (the android version has a convenient way of accessing config.xml) and it started working immediately.

I changed it on the QNAP as well (much harder), and UPnP started working there as well. When UPnP works, globa discovery works with no problems as well.

I didn’t change it on the QNAP, because I couldn’t find the config.xml. But I ser now when I am iut and about that it is connected to the phone and has a UPnP lease after failing to get one for a week.

Hm. No, it only works once on QNAP without changing requested lease time to 0. I have changed it to 0 now and it always works now.

The next step in finding this bug should be to see the output of the “AddPortMApping” function that generates that UPnP request and see what it generates on different platforms (i.e. linux etc) for different values of “timeout” (which is an unfortunate parameter name).

It might be something completely different coming out on different platforms, as the function uses an undefined format (yes, int is undefined in golang, it shouldn’t be used!) so there is a chance that the problem is outside the UPnP library and rather a compiler messup.

But I have never set up a build environment for any of these platforms, so it will take time.

Just set STTRACE=upnp environment variable and you will see requests and responses.

Really? That is a very cool function. Will try tomorrow.

Make sure to use v0.11.6 when you do, as there are two minor UPnP bugs fixed there.