Skip to content

-c can't reach all servers listed on a built-in directory #1122

Closed

Description

@mcfnord

As @rdica mentions 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.

This probably merits mentioning in the command-line documentation for this feature.

Activity

  1. added this to the Release 4.0.0 milestone on Apr 26, 2026
  2. pljones commented on Jul 19, 2026

    @pljones
    Contributor

    Did you say you had a fix for this as part of the Connect refactoring? Is it worth closing this and just doing that?

  3. mcfnord commented on Jul 19, 2026

    @mcfnord
    ContributorAuthor

    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.

  4. pljones commented on Jul 19, 2026

    @pljones
    Contributor

    OK, so I think

    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".

    So an extra CLI parameter and JSONRPC parameter.

    ("ping" = hole punch empty message)

  5. mcfnord commented on Jul 21, 2026

    @mcfnord
    ContributorAuthor

    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.

  6. pljones commented on Jul 21, 2026

    @pljones
    Contributor

    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.

  7. mcfnord commented on Sep 30, 2026

    @mcfnord
    ContributorAuthor

    #1156 merged

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    • Status
      Done

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions