Jamulus: Use a different approach to get external IP address

Created on 28 Sep 2020  路  17Comments  路  Source: corrados/jamulus

From discussion in #572...

NetworkUtil::GetLocalAddress is used by CServerListManager's constructor to provide an idea of the server's own address for the first entry in the server list. Currently it works by opening a TCP connection to Google's public DNS server and using Qt's wrapper for getsockname to get the local end's address, which isn't ideal for privacy reasons.

We could rework this to use a connect()-ed UDP socket, which would achieve the same effect without actually sending any packets (on Linux/FreeBSD at least; I don't know if this works on Windows/MacOS). Or we might be able to get the address from one of the Jamulus server's existing sockets when replying to a server list request.

improvement

All 17 comments

Given the version lookup is done to the Default Central Server list server, that might as well be the address used, if the TCP connection is going to work.

(Note that many other methods were investigated and not found to be available cross-platform. This is the most reliable, as far as I could tell.)

Well, jamulus.fischvolk.de doesn't have port 80 open.

The requirements here are:

  • we need a host that has a fixed IP address (to avoid slow DNS look ups)
  • we need a host that is always available (to avoid slow connection set up and failure)
  • we need a host that exposes a well known TCP service (to avoid firewall issues)
  • we need a host that is happy to have random connections to an exposed port (we're not high volume is a redeeming feature here)

Given the fact that this ticket originally came from the POV of privacy, I see CloudFlare "_doesn't just promise that it won't use your browsing data to serve ads; it commits that it will never write the querying IP address (yours) to disk. Any logs that do exist will be deleted within 24 hours_."

So maybe 1.1.1.1 is a good enough alternative?

As a quick fix 1.1.1.1 might work.

@pljones Do you want to apply the change (since you have written that code)?

Done: #662

Running on jamulus.drealm.info and I can connect locally okay (i.e. it uses my LAN address) using the server list entry.

Note to self: update privacy statement when this gets released.

I think it has been merged

Ok, should we close this one then?

Not sure. We still rely on a third party.

The _default_ here needs to be to use the Well Known service. Perhaps, in some circumstances, someone is running a server list with registered servers that do not expose their public IP addresses - but that case is going to be incredibly rare if it ever happens. Should it happen, perhaps an IP/port rewriting rule could be inserted in a firewall, or similar, to have the lookup handled some other way, without being routed outwards.

We still rely on a third party.

From what I understand, not relying on a third party isn't going to be possible if the central server(s) don't have well known TCP ports open. Which they don't.

I haven't had a chance to try implementing this yet, but I've had a look through the Qt documentation today and found a few more potential ways of doing it if my first suggestion above doesn't work on all platforms. So we could:

  • Open a QUdpSocket, connect() it to an arbitrary Internet address (which for UDP doesn't send/receive any packets, it's just setting up the local address), read the local address.
  • Defer filling in the server list entry until we get our first packet from another host, and look at the destination address of that packet (using recvmsg with the IP_PKTINFO socket option set, or changing the socket code to use QUdpSocket and using QNetworkDatagram::destinationAddress() which is Qt's wrapper for the same thing).
  • Use QNetworkInterface to get a list of the local network interfaces' addresses and filter out those that are obviously not public addresses - this is a bit more work so it's less preferable than the above two options.

So it looks like there are plenty of options that don't need a remote server or any network communication at all.

Well. Rocking good news!

I tried the first option and it didn't appear to work - hence using TCP. I may well have done something wrong...

A central server _could_ be started with a "known" set of hosts, so there wasn't an option to wait without significantly rewriting the start up code, which wasn't a priority.

And the third option is not only messy, it's unreliable in many situations (e.g. within cloud data centres, it can give completely the wrong answer).

So either a working version for option 1, which is simplest, or a substantial - hence risky - rewrite of a core part of the Jamulus server list processing.

Has anyone managed to get option 1 working on Windows, Mac and Linux yet?

There is another closed Issue https://github.com/corrados/jamulus/issues/690 in which it was recommended to make the IP lookup time out higher (from 500 ms to 5 s). But when there is another method of getting the local IP is going to be supported, that Issue would no longer be relevant.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

keepers305 picture keepers305  路  7Comments

fleutot picture fleutot  路  9Comments

gilgongo picture gilgongo  路  15Comments

chrisrimple picture chrisrimple  路  8Comments

trebmuh picture trebmuh  路  12Comments