engeloded/mdns-relay

By engeloded

•Updated about 1 year ago

A fast, cross-platform mDNS relay written in Rust with multi-arch Docker support

Image
Networking
0

2.5K

engeloded/mdns-relay repository overview

⁠mdns-relay

A lightweight, high-performance mDNS (multicast DNS) relay written in Rust.

It forwards mDNS packets between network interfaces for both IPv4 and IPv6, enabling service discovery across isolated subnets — ideal for Matter, HomeKit, and other protocols that rely on link-local multicast.

šŸ‘‰ Full source and documentation: https://github.com/engel0/mdns-relay⁠


⁠✨ Features

  • šŸ“” Supports IPv4 (224.0.0.251) and IPv6 (ff02::fb)
  • šŸ” Interface-to-interface forwarding with unidirectional or bidirectional configuration
  • 🧠 Loop prevention with TTL-based deduplication cache
  • šŸ”§ Clean, TOML-based configuration (config-driven architecture)
  • ⚔ Single-threaded tokio async runtime
  • šŸ–„ļø Native systemd support for Linux
  • 🐳 Docker-ready with multi-arch support (x86_64, ARM64, ARMv7)
  • šŸ“Š Runtime statistics logging for packet processing

ā šŸš€ Quick Start

⁠Requirements
  • Linux (with multicast + NET_RAW support)
  • Docker (for container usage; host networking required)
  • systemd (for native service management)
⁠Install & Run
# Build or download binary
make build

# Copy config and binary
sudo cp target/x86_64-unknown-linux-musl/release/mdns-relay /usr/local/bin/
sudo cp etc/mdns-relay.toml /etc/

# Run manually (uses /etc/mdns-relay.toml)
mdns-relay

# Show version or help
mdns-relay --version
mdns-relay --help

ā šŸ”§ Configuration (/etc/mdns-relay.toml)

The service is fully config-driven using a TOML file.

By default, it loads /etc/mdns-relay.toml, but this path can be overridden via --config.

āž”ļø See the full documented config file at mdns-relay.toml⁠ for all supported options and examples.

# Interface bridging
[[interface]]
src = "eth0"
dst = "wlan0"
stack = "dual"

[[interface]]
src = "wlan0"
dst = "eth0"
stack = "dual"

# TTL-based cache to prevent loops
ttl = 10
cache_size = 1000

# Logging
log_level = "info"
log_format = "pretty"

# Performance tuning
buffer_size = 2048
max_events = 64
loop_detection_ms = 200
stats_interval_seconds = 300
cleanup_interval_seconds = 30
max_packet_size = 9000

šŸ” See example configurations⁠ for VLANs, Docker, and Proxmox setups.


ā šŸ–„ļø Run as systemd Service (Linux)

# Install binary + service
make install

# Start service
sudo systemctl enable --now mdns-relay
sudo systemctl status mdns-relay

# Logs
sudo journalctl -u mdns-relay -f

⁠🐳 Run with Docker

docker build -t mdns-relay .

docker run --rm --net=host --cap-add=NET_RAW \
  -v /etc/mdns-relay.toml:/etc/mdns-relay.toml:ro \
  mdns-relay:latest
⁠Docker Compose
version: '3.8'

services:
  mdns-relay:
    build: .
    image: engeloded/mdns-relay:latest
    network_mode: host
    cap_add: [NET_RAW]
    volumes:
      - /etc/mdns-relay.toml:/etc/mdns-relay.toml:ro
    restart: unless-stopped

šŸ’” The :latest tag is a multi-arch manifest (x86_64, arm64, armv7). You can also pull a specific image like:

docker pull engeloded/mdns-relay:1.0.0-aarch64-unknown-linux-musl

ā šŸ—ļø Build from Source

# Build for your native system
make build

# Build for ARM64 (RPi 4+)
make build TARGET=aarch64-unknown-linux-musl

# Build for ARMv7 (RPi 3)
make build TARGET=armv7-unknown-linux-musleabihf

# Build for all supported platforms
make build-all

ā šŸ” Command Line Options

mdns-relay --help
Usage: mdns-relay [OPTIONS]

Options:
  -c, --config <FILE>  Configuration file path [default: /etc/mdns-relay.toml]
  -v, --version        Print version information
  -h, --help           Print help

⁠🧰 Example Configurations

⁠HomeKit or Matter Across Wi-Fi & Ethernet
[[interface]]
src = "eth0"
dst = "wlan0"
stack = "dual"

[[interface]]
src = "wlan0"
dst = "eth0"
stack = "dual"
⁠Bridging VLANs
[[interface]]
src = "eth0"
dst = "eth0.100"
stack = "ipv4"
⁠Docker Host + LAN
[[interface]]
src = "docker0"
dst = "eth0"
stack = "ipv4"
⁠Proxmox or Hypervisor Networks
[[interface]]
src = "vmbr0"
dst = "eth0"
stack = "dual"

⁠🄮 Troubleshooting

⁠Debug Mode
log_level = "debug"

[[interface]]
src = "eth0"
dst = "eth1"
stack = "dual"
mdns-relay --config debug.toml
⁠mDNS Discovery
# View services
avahi-browse -a
dns-sd -B _services._dns-sd._udp
⁠Log Monitoring
# systemd logs
sudo journalctl -u mdns-relay -f

# Docker logs
docker logs -f mdns-relay

⁠🧠 Best Practices

  • Use stack = "dual" for maximum compatibility
  • Use bidirectional interface definitions (src → dst and dst → src)
  • Always verify interface names via ip link show
  • Ensure Docker runs with --net=host --cap-add=NET_RAW
  • Test with log_level = "debug" to confirm packet flow

ā šŸ“¦ Docker Images

Published with make release, tags include:

  • engeloded/mdns-relay:latest – multi-arch (auto-selects arch)
  • engeloded/mdns-relay:<version>-<target> – arch-specific

Supported targets:

  • x86_64-unknown-linux-musl
  • aarch64-unknown-linux-musl
  • armv7-unknown-linux-musleabihf
  • i686-unknown-linux-musl

ā šŸ“œ License

MIT License — see LICENSE⁠


ā āœļø Author

Created by Engel Oded Contributions and feedback welcome!


Tag summary

Content type

Image

Digest

sha256:0441074fc…

Size

5.1 MB

Last updated

about 1 year ago

docker pull engeloded/mdns-relay