Skip to content

Advertise the daemon on the local network with Bonjour #2032

Description

@codymullins

Summary

A client cannot find a daemon on the network. The user must know the
endpoint URL and type it. This is not easy.

I propose we add Bonjour to the daemon. With Bonjour, the daemon
sends its name and address on the local network. A client app can then
find the daemon and show its endpoint to the user.

I am building an iOS app (via Uno Platform) for Netclaw. It is a separate product in a
separate repo. That app is the first client for this feature, and it
is the test for the design.

Current state

  • The daemon does not send announcements on the network.
  • The daemon binds to 127.0.0.1:5199 by default
    (Netclaw.Daemon/Program.cs).
  • DaemonConfig.ExposureMode has these values: local,
    reverse-proxy, tailscale-serve, tailscale-funnel, and
    cloudflare-tunnel.
  • The pairing flow controls trust. Discovery only helps a client find
    the endpoint. Discovery must not change the pairing flow.

Design

  • The daemon uses Bonjour to send the service _netclaw._tcp.local.
  • The daemon sends the service only when it is available from other
    machines. The daemon must not send the service in the local
    exposure mode.
  • The instance name is the service name of the daemon. If there is no
    service name, use the host name.
  • The TXT record has only these keys:
    • version — the protocol version
    • tls — 0 or 1
    • path — the base path prefix, if set
      Do not add other keys. Do not add device names. Do not add token
      data. The version key lets us change the record format for future
      clients.
  • Configuration: add the boolean AdvertiseOnLan to DaemonConfig.
    The default value is off. Update netclaw-config.v1.schema.json in
    the same PR (schema sync rule).
  • Doctor: show if the advertisement is active. Show a warning when
    AdvertiseOnLan is true but the exposure mode stops the
    advertisement.

Security requirements

  • The advertisement is off by default. The advertisement must not be
    active in the local exposure mode.
  • A client that finds a daemon is not trusted. The client must
    complete the one-time pairing code exchange first.
  • The TXT record has only the three keys given above.

Acceptance criteria

  • The daemon sends _netclaw._tcp when AdvertiseOnLan is true
    and the bind address is not loopback. The command
    dns-sd -B _netclaw._tcp on a different machine on the same
    network shows the service.
  • The TXT record has only version, tls, and path.
  • The daemon does not send the service in local mode. The daemon
    does not send the service when AdvertiseOnLan is false. Unit
    tests make sure of this.
  • The advertisement stops correctly when the daemon stops.
  • The schema is updated. netclaw doctor shows the advertisement
    state.
  • The service type and the TXT record format are in the
    documentation as the discovery contract. External clients, such
    as my iOS app, can then code against the contract.

Follow-up work (separate issues)

  • Discovery on more platforms after the iOS app shows that the flow
    is good.
  • Discovery through Tailscale. Multicast does not go across the
    tailnet.

Out of scope

  • All client-side work. The iOS app is a separate product and repo,
    and its browsing feature is tracked there.
  • A custom UDP beacon protocol.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions