Skip to content

Add dynamic peer discovery (mDNS/DNS-SD) #5

@kitplummer

Description

@kitplummer

Summary

Peer connections are currently configured statically via the --peer CLI flag or PEAT_SIDECAR_PEERS environment variable. This requires knowing Iroh endpoint IDs at deployment time, which is impractical for dynamic environments where sidecars scale up/down or join the mesh at runtime.

Current State

Peers are configured at startup only (src/main.rs:55-57, 109-117):

#[arg(long, env = "PEAT_SIDECAR_PEERS", value_delimiter = ',')]
peer: Vec<String>,
for peer_id in &args.peer {
    if let Err(e) = node.connect_peer(peer_id).await {
        warn!(peer = peer_id, "failed to connect to peer: {e}");
    }
}

Peer connection is also available via ConnectPeer gRPC RPC (proto/sidecar.proto:25), but this requires an external orchestrator to know endpoint IDs and call the API.

There is no mechanism for automatic peer discovery within a LAN, cluster, or formation.

Proposed Approach

Option A: mDNS/DNS-SD (LAN discovery)

Best for edge scenarios where sidecars are on the same L2 network (e.g., tactical mesh, BLE bridge range).

  1. Announce service via mDNS: _peat-sidecar._udp.local with TXT records for app_id and endpoint_id
  2. Discover peers matching the same app_id
  3. Auto-connect on discovery, skip if already connected
  4. Crate: mdns-sd or libmdns

Option B: Kubernetes headless service discovery

Best for in-cluster scenarios where sidecars run as Kubernetes pods.

  1. Create a headless Service that resolves to all sidecar pod IPs
  2. Periodically resolve DNS (e.g., peat-sidecar-headless.peat-system.svc.cluster.local)
  3. Exchange endpoint IDs via a lightweight handshake on a known port
  4. Auto-connect discovered peers

Option C: Gossip-based discovery

Best for multi-cluster or WAN scenarios.

  1. Each peer maintains a peer table of known endpoint IDs
  2. On connection, exchange known peer lists
  3. Attempt connections to newly discovered peers (with backoff)
  4. Peers propagate via transitive closure

Configuration

New CLI flags:

--discovery-mode <none|mdns|dns|gossip>  / PEAT_SIDECAR_DISCOVERY_MODE (default: none)
--discovery-service <dns-name>           / PEAT_SIDECAR_DISCOVERY_SERVICE
--discovery-interval <seconds>           / PEAT_SIDECAR_DISCOVERY_INTERVAL (default: 30)

Impact

Dynamic discovery is essential for:

  • Autoscaling deployments where pod count changes
  • Tactical edge networks where nodes appear/disappear
  • Reducing deployment complexity (no pre-sharing of endpoint IDs)
  • The mobile mesh/tablet bridge scenario described in docs/DESIGN.md

Files

  • src/main.rs:55-57 — current static --peer flag
  • src/node.rs:232-248connect_peer() method
  • chart/peat-sidecar/templates/service.yaml — K8s service (would need headless variant)
  • Cargo.toml — new dependency for mDNS crate

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