Client: add --connectdirectory for directory-assisted hole punch on --connect - #3815
Client: add --connectdirectory for directory-assisted hole punch on --connect#3815mcfnord wants to merge 4 commits into
Conversation
This is an extract from jamulussoftware#2550 Co-authored-by: ann0see <20726856+ann0see@users.noreply.github.com>
Introduce EConnectionState (disconnected / connecting / connected) owned by CClient as the single source of truth. A connection is 'requested' when the audio stream starts (CS_CONNECTING) and 'established' once the server assigns our channel ID (CS_CONNECTED). Every transition emits ConnectionStateChanged. Rename the Connected(name) signal emitted from Start() to Connecting(name), since at that point the connection is only requested, not established. CClient::Connect() now terminates any current connection first, so connecting while connected behaves as a reconnect. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- SIGTERM/SIGINT: route through Disconnect() instead of a raw Stop(), and guard Disconnect() on the connection state rather than IsRunning() (which tracks the audio device). IsRunning() is false while connecting and in headless mode, so the old guard could skip notifying the server on shutdown; the raw Stop() worked around that but also fired a spurious disconnect when idle. Now the server is notified iff a connection is pending or established, via the single Disconnect() path. - Move EConnectionState from util.h to client.h (it is client specific). - Add a doc-comment to SetConnectionState; reword two member comments. Addresses review feedback on jamulussoftware#3805. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
-c / --connect connects straight to the given address and, unlike selecting a server from the GUI directory list, never asks a directory to open the target's firewall. Servers behind a cloud firewall/NAT that the GUI reaches fine are therefore silently unreachable via -c. Give CClient::Connect an optional directory argument: when set it sends a CLM_REQ_SERVER_LIST to that directory (which makes the directory poke its registered servers towards our socket -- the same UDP hole punch the GUI relies on), waits HOLE_PUNCH_CONNECT_DELAY_MS, then connects. The server address is used verbatim and need not be listed by the directory. Expose it on the command line as --connectdirectory <host:port>, wired through both the GUI and headless connect-on-startup paths in main.cpp. Relates to jamulussoftware/jamuluswebsite#1122 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1339edc to
1e9a6b3
Compare
|
Best case |
The client would need to know which directory to use, and that will have to be specified by the CLI parameters. It would be too sloppy and nuts to guess all 7, and even if we do, it might be some other directory entirely. |
We should definitely not make this a default. The current |
|
We don't actually need this because server admins can always create the server as a private directory which takes care of hole-punching without leaking the IP. |
It's not the lack of hole-punching in So the option in this PR would not actually open the client to that correlation behaviour. But having said that, I don't feel there is much usefulness in adding the feature in this PR. |
Yes, if creating a private server that is not intended to register with a directory, it is actually a very useful idea to make it its own directory with |
I still think we should let the user decide if he wants his IP leaked by |
dingodoppelt
left a comment
There was a problem hiding this comment.
I'd rather not pull this in at all because of the security implications.
| // tells each registered server to send us an "empty message", which opens | ||
| // the server's firewall for our socket (UDP hole punching). | ||
| CreateCLReqServerListMes ( haDirectoryAddress ); | ||
|
|
There was a problem hiding this comment.
This breaks --connect's current behaviour by leaking the user's IP.
Short description of changes
Adds an optional
--connectdirectory <host:port>client option and givesCClient::Connectan optional directory argument. When a directory is supplied, the client first asks that directory for its server list — which makes the directory tell its registered servers to send an "empty message" toward the client's socket (the same directory-assisted UDP hole punch the GUI directory list relies on) — waitsHOLE_PUNCH_CONNECT_DELAY_MS, then connects.Today
-c/--connectconnects straight to the address and never contacts a directory, so a server behind a cloud firewall/NAT that the GUI reaches fine is silently unreachable via-c. The server address is connected to verbatim and need not appear in the directory's server list, so this also lets you reach a server that isn't in any built-in directory by naming the (possibly custom/private) directory it is registered with.CHANGELOG: Client: Added
--connectdirectoryto hole-punch through a directory when connecting on startup with--connectContext: Fixes an issue?
Relates to jamulussoftware/jamuluswebsite#1122, which documents this
-creachability limitation. This is the code side of that gap.Stacked on #3805 — it uses the
CClient::Connectrefactor introduced there, so the diff currently includes #3805's commit; the single top commit is the change in this PR. Please review/merge #3805 first.Does this change need documentation? What needs to be documented and how?
Yes — a short website entry for
--connectdirectorynext to the-ctext (a companion to the-cnote added in jamuluswebsite#1156). A draft on the website repo will follow.Status of this Pull Request
Working implementation. Verified with a UDP capture: with
--connectdirectorythe client sendsCLM_REQ_SERVER_LISTto the directory and connects ~400 ms later; without it there is no directory traffic and behaviour is unchanged. Clean SIGTERM shutdown, including when interrupted during the hole-punch delay.What is missing until this pull request can be merged?
Depends on #3805 merging first. Otherwise ready for review.
Checklist