You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
-c can't reach all servers listed on a built-in directory #1122
As @rdicamentions here, the -c command line option can't reach every server listed on a built-in directory. In fact, most servers might not be reachable using -c, because most clients rely on a "hole punch" procedure to reach a server without the server explicitly opening the port.
I think the answer hinges on the suggested approach in #3801, which explicitly calls for it to be "Incremental, in parallel with existing functionality" — migrating one area at a time while keeping the current implementation working throughout. That implies leaving the existing connection paths in place while we build API alternatives, but it also means the parity gaps between those paths become the thing worth documenting as we go.
Here's the gap I hit. There are three ways to reach a server, and they don't behave the same:
GUI — when you connect to a directory-listed server, the client asks the directory to open the server's port for you (the directory tells the server to send a hole-punch packet toward you). This is why double-clicking a listing "just works" even for servers behind NAT.
Command line (-c) — dials the server address directly. It does not go through the directory, so if the server's port isn't already open, the connection just fails. There's no flag to route the connect through a directory the way the GUI does.
JSON-RPC (draft in #3806) — as written, jamulusclient/connect also dials directly and does not perform the directory hole-punch. (I checked; the new connect path doesn't touch the directory/hole-punch code.)
So today: GUI opens ports; command line and JSON-RPC do not.
The directory-assisted hole-punch is very much doable outside the GUI — I've implemented exactly this technique in my own gojam-based tooling (a --directory option that asks a named directory to open the target's port before connecting), so it's not GUI-specific magic; it's just protocol work that the CLI/RPC paths haven't picked up yet.
Which raises the real design question for #3801: is JSON-RPC meant to mimic the GUI or the command line? I'd argue it should follow the GUI — full parity means an RPC client should be able to reach directory-listed servers behind NAT, same as a user double-clicking a listing. Following the deficient command-line behavior instead would bake the gap in. Ideally all three connection paths should be able to navigate directory-listed servers; a natural incremental step would be adding a --directory companion to -c on the CLI and a directory parameter to the RPC connect method.
Regardless of how that lands: this is a documentation gap worth noting now. The docs for -c should say the server's port must already be open, and that some directory-listed servers rely on the directory to open their port — a service the GUI uses but the command line currently doesn't. Decades of writing docs have made me comfortable with parallel featuresets that lack parity, but the gaps are exactly what needs to be spelled out.
Command line (-c) — dials the server address directly. It does not go through the directory, so if the server's port isn't already open, the connection just fails. There's no flag to route the connect through a directory the way the GUI does.
One solution would be to require the Client to specify the Directory where the Server was registered saying "ping me please".
I'd not be happy with "pick some random Directory or Server and ask it to trigger the ping".
The situation is rather philosophical for me. Should we ever skip the disclosure and just improve the feature? Almost never — because the disclosure should be lightweight and quick to ship (perhaps not so here, but it should be). My whole career has been disclosing dirty secrets of running software, and I have always tussled with engineers who would rather improve the software behavior. Which is why the disclosure PR is already up: #1156.
I'd not be happy with "pick some random Directory or Server and ask it to trigger the ping".
It also wouldn't necessarily work: in the same way the Client hole punch works, if the Server hadn't registered with the Directory (and kept refreshing), an unsolicited request from a random Directory (honest) to ping some Client would be dropped.
Activity
pljones commentedon Jul 19, 2026
Did you say you had a fix for this as part of the Connect refactoring? Is it worth closing this and just doing that?
mcfnord commentedon Jul 19, 2026
I think the answer hinges on the suggested approach in #3801, which explicitly calls for it to be "Incremental, in parallel with existing functionality" — migrating one area at a time while keeping the current implementation working throughout. That implies leaving the existing connection paths in place while we build API alternatives, but it also means the parity gaps between those paths become the thing worth documenting as we go.
Here's the gap I hit. There are three ways to reach a server, and they don't behave the same:
-c) — dials the server address directly. It does not go through the directory, so if the server's port isn't already open, the connection just fails. There's no flag to route the connect through a directory the way the GUI does.jamulusclient/connectalso dials directly and does not perform the directory hole-punch. (I checked; the new connect path doesn't touch the directory/hole-punch code.)So today: GUI opens ports; command line and JSON-RPC do not.
The directory-assisted hole-punch is very much doable outside the GUI — I've implemented exactly this technique in my own gojam-based tooling (a
--directoryoption that asks a named directory to open the target's port before connecting), so it's not GUI-specific magic; it's just protocol work that the CLI/RPC paths haven't picked up yet.Which raises the real design question for #3801: is JSON-RPC meant to mimic the GUI or the command line? I'd argue it should follow the GUI — full parity means an RPC client should be able to reach directory-listed servers behind NAT, same as a user double-clicking a listing. Following the deficient command-line behavior instead would bake the gap in. Ideally all three connection paths should be able to navigate directory-listed servers; a natural incremental step would be adding a
--directorycompanion to-con the CLI and adirectoryparameter to the RPCconnectmethod.Regardless of how that lands: this is a documentation gap worth noting now. The docs for
-cshould say the server's port must already be open, and that some directory-listed servers rely on the directory to open their port — a service the GUI uses but the command line currently doesn't. Decades of writing docs have made me comfortable with parallel featuresets that lack parity, but the gaps are exactly what needs to be spelled out.pljones commentedon Jul 19, 2026
OK, so I think
One solution would be to require the Client to specify the Directory where the Server was registered saying "ping me please".
I'd not be happy with "pick some random Directory or Server and ask it to trigger the ping".
So an extra CLI parameter and JSONRPC parameter.
("ping" = hole punch empty message)
Document -c port-reachability limitation
mcfnord commentedon Jul 21, 2026
The situation is rather philosophical for me. Should we ever skip the disclosure and just improve the feature? Almost never — because the disclosure should be lightweight and quick to ship (perhaps not so here, but it should be). My whole career has been disclosing dirty secrets of running software, and I have always tussled with engineers who would rather improve the software behavior. Which is why the disclosure PR is already up: #1156.
JSON-RPC: add optional directory hole punch to jamulusclient/connect
Add directory-assisted hole punch to -c via --connectdirectory
JSON-RPC: add optional directory hole punch to jamulusclient/connect
pljones commentedon Jul 21, 2026
It also wouldn't necessarily work: in the same way the Client hole punch works, if the Server hadn't registered with the Directory (and kept refreshing), an unsolicited request from a random Directory (honest) to ping some Client would be dropped.
Add directory-assisted hole punch to -c via --connectdirectory
JSON-RPC: add optional directory hole punch to jamulusclient/connect
mcfnord commentedon Sep 30, 2026
#1156 merged