Closed genesisproject2020 closed 3 years ago
There is some information missing in this scenario. How are the internal servers addressed from the Internet? (Meaning how are you managing the router, NAT, and firewall functions?) How are the addresses and port mapping determined? This is a scenario where using domain names for each server can help. For the described scenario to be stable, you would have to manually manage your (internal) IP addresses. For long-term convenience, it is best to (find a solution) using DNS and DHCP.
One basic example and use case:
Internet - Firewall with NAT - an internal server "real ip" - port mapping - internal server with a few Jamulus servers running on different ports 193.x.x.x - port 23000 - 10.0.0.10:23000 (jamulus central server) 193.x.x.x - port 23001 - 10.0.0.10:23001 (jamulus server registered --centalserver 10.0.0.10:23000) 193.x.x.x - port 23002 - 10.0.0.10:23002 (jamulus server registered --centalserver 10.0.0.10:23000) 193.x.x.x - port 23003 - 10.0.0.10:23003 (jamulus server registered --centalserver 10.0.0.10:23000)
The server in the example above the central server will present it self with ip 193.x.x.x and the rest will be presented with 10.0.0.10. There is no need for a dns name (but it makes it easier for the users). Everything is manually handled but I do not see that as a problem for most people.
1- what is your public IP address? 2- How do you want clients on the public network to address these internal addresses? You need to create a mapping between your public IP:port to internal IP:port for every portl in your internal network. 3- for clients on the local network, do you want your users to use those internal (numerical) addresses? You can use host names if you enter the host name/IP address mapping in each computer's host table.
DNS was invented (long ago) to eliminate the need of managing all those host tables.
1) A public IPv4 address reachable from the world. And yes, DNS can be used to make it easier to remember. 2) As described above, with port mapping, as most private servers are configured. I do not see any problem to configure a few port mappings. 3) The internal network is irrelevant in this scenario. But, all servers can be addressed directly and an internal DNS/DHCP can make it easier.
I have a hard time to see the relevance in the questions above connected to the addresses the central server presents to the clients.
My request is to be able to configure the IP address the server presents to the clients.
You have more than one server in your internal network. They connect to the public network through a router/gateway using NAT. If you want an external client to contact an internal server, the messages have to be addressed to the gateway IP:port that is mapped to the internal server internal-IP:port. This is easy to do with one internal server and hard (impossible?) to do with multiple internal servers. you don't have a problem if all the users are on your internal network.
There is no problem to address more servers on an internal network through just one public IP with port mapping. A server can use whatever port available and present it to the client through a central server. If you want more servers just use different ports to all servers and you will be able to address them all. As I wrote, internal addressing is irrelevant. Only external access where the clients connect from Internet is in focus. (If it was an only internal environment the current configuration options will work perfectly.)
I suggest you build your port mapping table. If I understand your scenario, the table will be very difficult to specify. I'd love to see a table that solves your needs.
Port mapping is not the problem so please focus on the question to be able to choose the IP that's presented to the client from the central server list.
@genesisproject2020: I quickly put something together, is this what you want?
https://github.com/hoffie/jamulus/commit/8e8ed739c02e8d6d9ffad42c2632a2dcc62bf59b
The behavior I have seen is the central server reports the gateway public IP address as the server address. If you have three servers on your private LAN, I expect the central server will report the same IP address for all three servers. The reported port numbers for each server will be different.
A quick scan through the code looks to me as follows:
The slave server calls SlaveServerRegis
... which calls CProtocol::CreateCLRegisterServerExMes.
This sends a PROTMESSID_CLM_REGISTER_SERVER_EX
message and contains an IP address, which is autodetected by preparing a request to Cloudflare's 1.1.1.1
and using the outgoing IP address of this socket.
The central server gets the registration request via CProtocol::EvaluateCLRegisterServerExMes
... sends a CLRegisterServerExReceived
signal
... which is connected to OnCLRegisterServerExReceived
... which calls CServerListManager::CentralServerRegisterServer which places both the UDP/IP source address and the address from the packet content in the internal server list.
When a client asks a central server for a server list, there is special logic to choose which IP address to return. When the requesting client's IP is identical to the the server entry's originating IP, it is assumed that both requests come within the same NAT'ed environment. As such, the central server returns the internal IP of the Jamulus server.
So, the current behavior is:
Possible solutions:
All in all, this sounds like a legitimate issue/request (although maybe a bit niche until now).
@genesisproject2020 In case you want to try, I have updated my branch with the necessary change to the server list logic (i.e. both your central server and your slaves would need to run with this code base; clients are unchanged).
Note: This is completely untested, I only know that it compiles.
@hoffie Compilation worked but the server module do not recognize the option (--serverexternalip).
@hoffie Compilation worked but the server module do not recognize the option (--serverexternalip).
Hrm, that's strange as that works for me. Can you share how you start your test server (full command line)? Can you also share the output of Jamulus --version
? I suspect that the built may have been done without the new code somehow? The Github UI may be a bit misleading. I linked to my branch, but when you select Code > Clone
, you will be given the URL for the whole repo. This means, after cloning you will still have to switch branches (git checkout override-external-ip
) and run the build afterwards.
@hoffie Thanks! I did a misstake with the config.
The version I use now is: Version 3.6.2dev-5b7a8daa-dirty Command server 1 (ip 10.1.1.10): Jamulus -s -n -p 10000 -e localhost Command server 2 (ip 10.1.1.11): Jamulus --serverexternalip xx.xx.xx.xx -s -n -p 10001 -e 10.1.1.10:10000
Server 1 message: jamulus[2015417]: Requested to register entry for 10.1.1.11:10001 (xx.xx.xx.xx:10001): Server 2
But.. the central server still presents the internal ip. I use https://explorer.jamulus.io to check what's presented to the world. If I use a client and connect to the central server I only see the central server and no other server. I think the reason is the presentation of a server with internal ip is not reachable from Internet.
There is no difference if I add --serverexternalip to the central server. The presentation is correct from the beginning so it should not be of any use.
Have I missed anything?
Have I missed anything?
Hrm, maybe I have missed adding an important detail: The central server modification currently depends on a Qt function which is only available in rather recent versions (5.11 or newer). Which version of Qt are you using (check with rpm -qa | grep
, dpkg -l
or something)?
If this is the problem, I can try modifying the code to work without that function.
The Ubuntu 20.04 LTS that I use for testing has Qt 5.12.8 installed. Maybe I can downgrade to 5.11.
The Ubuntu 20.04 LTS that I use for testing has Qt 5.12.8 installed. Maybe I can downgrade to 5.11.
This should not be necessary, anything newer than 5.11 should be fine. I'll look into the issue again with your Jamulus Explorer example. Maybe I still have a logic mistake somewhere.
@genesisproject2020 I just tried again:
$ Jamulus -s -n -p 44124 -e localhost
$ Jamulus -s -n -p 10001 -e 127.0.0.1:44124 --serverexternalip 1.2.3.4
Pointing Jamulus Explorer's central server address to myhost:44124 shows the slave server as 1.2.3.4.
My only idea would be to confirm once again that also your central server runs the new build (Jamulus Explorer should say: 3.6.2dev-5b7a8daa
) and that it was built on a system with Qt 5.11 or newer.
I wrote you on Telegram, maybe we can figure it out there and add the results here.
After some back and forth with debugging code, I think I found the issue. I assumed QHostAddr::isGlobal()
would return false
for private networks such as 10.1.2.0/24
. It doesn't. It worked in my test because I tested with both the central server and the slave server on the same machine. Therefore I used 127.0.0.1
which did behave as expected in isGlobal()
.
I've now replaced the isGlobal()
usage by a custom helper function which explicitly lists the RFC-defined private networks. This should be a better fit for this use case and also helps with Qt compatability.
@genesisproject2020 Can you try with the latest code again? Version should be 3.6.2dev-e2b43e55
after make clean && qmake ... && make
It seams to work perfectly. I have to do some more testing and connect clients to be sure.
Works great!!
Thank you, I was extremely happy to find that this has already been solved. It landed as --serverpublicip
in 3.7.
I'm trying to run my own central server together with a few local servers reporting to my central server to make it easy for a group to have "break out sessions". All servers exist locally with local ip addresses.
Problem... With the current configuration alternatives the central server presents its public IP correct the outside but the servers registered will be presented with its internal ip to the outside. In a standard senario a server will register it self to a central server elsewhere and the public will be correctly presented. When building everything in a local environment and then publish it to the world the current options will not work.
Request... Be able to send the IP (or url) that the server should present to be able to build local environments. Each server will require a unique port when the servers use the same external IP.