cottsay / openelp

Open Source EchoLink Proxy
BSD 3-Clause "New" or "Revised" License
22 stars 8 forks source link

question about number of slots #26

Open iddq opened 1 week ago

iddq commented 1 week ago

Can I use -F option on live system? How many slots we have? I don't find the definitions regarding to slot numbers. THX

iddq commented 1 week ago

My current assumption is that the number of slots is not limited but depends on the number of running processes or threads. Furthermore, I assume that in the case of -F, only one thread is working, which is why an error message appeared in the log stating that no available slots were free. That's why the above questions arose.

iddq commented 1 week ago

I got the following error message Dropping client because there are no available slots. It is possible that this issue is completely unrelated to the "-F" option.

cottsay commented 1 week ago

Hi there, thanks for your interest.

The -F option only controls the behavior of the process, and doesn't affect the behavior of the proxy at all. It simply controls whether the process is forked to the background or remains active in the foreground. The same number of threads and slots are created in either case. Foreground mode is mainly used for troubleshooting, testing, and temporarily running the proxy, but if you intend the proxy to run long-term, you should use your platform's native daemon management system (i.e. systemd, Windows services, system V, etc).

Slots should be allocated for each interface on the system that has a distinct route to a public IP address. This proxy does not act like a Echo Link relay - only a proxy. You still need a free public IP address with properly forwarded ports for each slot. Unless specifically configured to do so with the AdditionalExternalBindAddresses option, there will be only a single slot on the proxy.

Configuring more than one slot on a Linux system is not trivial. It involves creating new routing tables for each publicly routeable IP address and listing the local IP for each of those interfaces in AdditionalExternalBindAddresses. You shouldn't need to mess with the routing tables to do the same thing on Windows, but I haven't tried for many years.

iddq commented 1 week ago

but what could be the reason that I get the following message just after connecting to port 8100, e.g. telnet 127.0.0.1 8100?

Oct 12 21:22:33 : Starting a processing run... Oct 12 21:22:33 : Waiting for a client... Oct 12 21:24:16 : Incoming connection from [::ffff:127.0.0.1]:11905. Oct 12 21:24:16 : Dropping client because there are no available slots. Oct 12 21:24:16 : Starting a processing run... Oct 12 21:24:16 : Waiting for a client...

cottsay commented 1 week ago

This is the message I'd expect to see if the proxy was already in use, and there is a separate connection to 8100 active. This should be the same behavior as the official Java client if you tried to connect to a proxy that's already in use though I don't think it prints any messages to the log like OpenELP does.

If you're seeing this immediately after startup without having connected to the proxy at all, then I'd like to hear more about your system and configuration before making a recommendation.

iddq commented 1 week ago

So should I take this to mean that the proxy can't handle multiple connections at once?

cottsay commented 1 week ago

Unless your system has multiple public IP addresses and you configure the proxy to use them, it's not possible to create an EchoLink proxy that can handle more than one connection.

There is a concept known as a "relay" that takes multiple clients on a single public IP, but the trade off is that those clients can't accept connections from other users - it only supports outgoing connections from proxy clients.

iddq commented 1 week ago

Thank you for the explanation, I think I'm starting to understand. So if I understand correctly, the Echolink protocol does not send any Session ID within the message, and the port is always the same, so there is no way to separate the sessions, and thus, in the case of an incoming connection, it is not possible to know which client would be the recipient. Do I understand correctly?

cottsay commented 1 week ago

That's a pretty good summary, yes.

iddq commented 1 week ago

What do you think, would it be possible to allow the Authorization phase instead of immediately rejecting the new connection from the client, and if a client with the same callsign as the currently connected one wants to connect, allow it, and the new connection would take the place of the old one? This way, if the client reconnects, even due to a restart, it wouldn’t be rejected until the proxy-side timeout expires.

cottsay commented 1 week ago

Interesting idea.

Here are couple of things to consider:

  1. I'm not sure that the EchoLink client would act appropriately if the authentication phase were started and then dropped. It might tell the user that they're not authorized, or it might consider it to be a dropped connection and just attempt to reconnect. We'd have to give it a try.
  2. At a high level, the initial authentication phase for the proxy needs two things from the client: a. The user's callsign b. A password

    There is room for innovation here, because all of the EchoLink proxy implementations I'm aware of (including OpenELP) check these two values independently, so there can be a restriction on what callsigns can connect and a restriction on what password is accepted, but not callsign/password pairs. Also worth noting is that the proxy doesn't authorize the callsign against the EchoLink servers, so it's not very useful for determining with any level of certainty who an incoming connection is from. For example, though the client won't let you do this, it would theoretically be possible to connect to the proxy with one callsign and register with the EchoLink servers with a different one.

There is probably room for a configuration flag to indicate that a proxy effectively intended for a single user, so we should always attempt to authorize incoming connections and any successful authorization would immediately grab a slot, but my initial thoughts would be that this behavior would probably have too many adverse side effects to implement as a default behavior, especially for a public proxy.

cottsay commented 1 week ago

...so [the callsign] not very useful for determining with any level of certainty who an incoming connection is from...

An additional note on this. OpenELP does in fact use the callsign on an incoming connection to check if there was another recent connection from that same callsign on a free slot, and assigns the same slot to that user again. The public IP of the slot gets registered with the EchoLink servers with that callsign and if a proxy client reconnects, it would be better if the address that was already registered and distributed to other EchoLink users was still correct. For this reason, slots are allocated based on how long they've been idle so that there is more time for a user to reconnect and claim the same slot, or there is more time for other EchoLink users to refresh their catalog and drop the record for the callsign that has disconnected before someone new takes the slot (so you could say that the free slots are in a First In First Out queue).

iddq commented 1 week ago

Currently, I am experiencing the issue, at least on Linux, that anyone can simply open a TCP connection to port 8100, and even if they don't send any data, this alone prevents others from connecting to the proxy. This is because after the connection, they are immediately rejected with a message indicating that there are no free slots.

iddq commented 5 days ago

A bigger problem is that the Android client can also cause this situation. For some reason, it initiates multiple connections, and if the first one isn’t closed before the second one reaches its destination, it can’t connect to the proxy. I must note that the entire network handling of the Android client is terrible.