Document custom mDNS-inspired discovery in architecture

Reuse UDP multicast transport (224.0.0.251:5353) with our own binary
wire format — no Avahi, no Bonjour, no daemon dependency.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-25 22:28:56 +00:00
parent 94ac152d55
commit 5dc28890f0

View File

@@ -298,6 +298,48 @@ The preprocessor is the same tool planned for generating error location codes (s
---
## Node Discovery
Standard mDNS (RFC 6762) uses UDP multicast over `224.0.0.251:5353` with DNS-SD service records. The wire protocol is well-defined and the multicast group is already in active use on most LANs. The standard service discovery stack (Avahi, Bonjour, `nss-mdns`) provides that transport but brings significant overhead: persistent daemons, D-Bus dependencies, complex configuration surface, and substantial resident memory. None of that is needed here.
The approach: **reuse the multicast transport, define our own wire format**.
Rather than DNS wire format, node announcements are encoded as binary frames using the same serialization layer (`serial`) and frame header used for video transport. A node joins the multicast group, broadcasts periodic announcements, and listens for announcements from peers.
### Announcement Frame
| Field | Size | Purpose |
|---|---|---|
| `message_type` | 2 bytes | Discovery message type (e.g. `0x0010` for node announcement) |
| `channel_id` | 2 bytes | Reserved / zero |
| `payload_length` | 4 bytes | Byte length of payload |
| Payload | variable | Encoded node identity and capabilities |
Payload fields:
| Field | Type | Purpose |
|---|---|---|
| `protocol_version` | u8 | Wire format version |
| `tcp_port` | u16 | Port where this node accepts transport connections |
| `name_len` | u8 | Length of name string |
| `name` | bytes | Node name (`namespace:instance`, e.g. `v4l2:microscope`) |
| `function_len` | u8 | Length of function string |
| `function` | bytes | Node function identifier (`source`, `relay`, `sink`, ...) |
### Behaviour
- Nodes send announcements periodically (e.g. every 5 s) and immediately on startup
- No daemon — the node process itself sends and listens; no background service required
- On receiving an announcement, the control plane records the peer (address, port, name, function) and can initiate a transport connection if needed
- A node going silent for a configured number of announcement intervals is considered offline
- Announcements are informational only — the hub validates identity at connection time
### No Avahi/Bonjour Dependency
The system does not link against, depend on, or interact with Avahi or Bonjour. It opens a raw UDP multicast socket directly, which requires only standard POSIX socket APIs. This keeps the runtime dependency footprint minimal and the behaviour predictable.
---
## Open Questions
- What is the graph's representation format — in-memory object graph, serialized config, or both?
@@ -305,5 +347,4 @@ The preprocessor is the same tool planned for generating error location codes (s
- Drop policy for completeness queues: drop oldest (recency) or drop newest (continuity)? Should be per-output configurable.
- When a relay has multiple inputs on an encapsulated transport, how are streams tagged on the outbound side — same stream_id passthrough, or remapped?
- What transport is used for relay edges — TCP, UDP, shared memory for local hops?
- How are nodes discovered — static config, mDNS, manual registration?
- Should per-output byte budgets be hard limits or soft limits with hysteresis?