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:
@@ -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
|
## Open Questions
|
||||||
|
|
||||||
- What is the graph's representation format — in-memory object graph, serialized config, or both?
|
- 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.
|
- 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?
|
- 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?
|
- 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?
|
- Should per-output byte budgets be hard limits or soft limits with hysteresis?
|
||||||
|
|||||||
Reference in New Issue
Block a user