GMDNS is a high-performance mDNS (Multicast DNS) protocol library built with Rust, specifically designed for P2P network discovery and NAT traversal scenarios. It supports the standard RFC 6762 protocol while extending endpoint discovery capabilities through custom resource records, enabling publication and verification of both direct and relay addresses. Additionally, it integrates HTTP/3 support for secure DNS over HTTP/3 (DoH3) interactions with remote DNS servers.
- Standards Compliant: Supports standard DNS packet format and mDNS multicast discovery.
- P2P Enhanced: Custom
Erecord type supporting IPv4/IPv6 direct and relay addresses. - Security Verification: Built-in signature schemes (Ed25519, etc.) ensuring endpoint data authenticity and integrity.
- High Performance Parsing: Zero-copy parsing framework based on
nomfor blazing-fast packet processing. - Async-Driven: Fully compatible with
tokioasync runtime for high-concurrency network environments. - HTTP/3 Integration: Supports DNS over HTTP/3 (DoH3) for secure remote DNS queries and publishing.
Add to your Cargo.toml:
[dependencies]
gmdns = { path = "../gmdns" }For HTTP/3 features, enable the h3x-resolver feature:
[dependencies]
gmdns = { path = "../gmdns", features = ["h3x-resolver"] }use gmdns::mdns::Mdns;
use futures::StreamExt;
#[tokio::main]
async fn main() -> Result<(), std::io::Error> {
// Create mDNS instance
let mdns = Mdns::new("_genmeta.local", "127.0.0.1".parse().unwrap(), "lo0")?;
// Listen to discovery stream
let mut stream = mdns.discover();
while let Some((addr, packet)) = stream.next().await {
println!("Discovered packet from {}: {:?}", addr, packet);
}
Ok(())
}use gmdns::{resolver::h3_resolver::H3Resolver, parser::record::endpoint::EndpointAddr};
use std::path::Path;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resolver = H3Resolver::new(
"https://localhost:4433/",
Path::new("examples/keychain/localhost/ca.cert"),
"client",
Path::new("examples/keychain/localhost/client.cert"),
Path::new("examples/keychain/localhost/client.key"),
)?;
// Publish a DNS record
let endpoint = EndpointAddr::direct_v4("127.0.0.1:5555".parse()?);
resolver.publish("client.genmeta.net", &[endpoint]).await?;
Ok(())
}GMDNS includes support for DNS over HTTP/3 (DoH3), allowing secure publication and querying of DNS records via HTTP/3 protocol. This is useful for remote networks where multicast mDNS is not feasible.
Publish DNS service records to an HTTP/3 DNS server:
cargo run --example publish --features="h3x-resolver" \
--server-ca /path/to/root.crt \
--client-name demo.example.genmeta.net \
--client-cert /path/to/demo.example.genmeta.net.pem \
--client-key /path/to/demo.example.genmeta.net.key \
--host demo.example.genmeta.net \
--addr 192.168.1.100:8080Query DNS service records from an HTTP/3 DNS server:
cargo run --example query --features="h3x-resolver" \
--server-ca /path/to/root.crt \
--host stun.genmeta.netStart an HTTP/3 DNS server:
cargo run --example server --features="h3x-resolver" \
--listen 127.0.0.1:4433 \
--cert examples/keychain/localhost/server.cert \
--key examples/keychain/localhost/server.keyFor detailed parameters and HTTP packet structures, see examples/README.md.
DNS packets consist of a fixed header and four variable-length sections:
+---------------------+-----------------------+-----------------------+-----------------------+-----------------------+
| Header (12 bytes) | Question Section | Answer Section | Nameserver Section | Additional Section |
+---------------------+-----------------------+-----------------------+-----------------------+-----------------------+
| Transaction ID | Query list | Answer RR list | Authority RR list | Additional RR list |
| and Flags | | | | |
+---------------------+-----------------------+-----------------------+-----------------------+-----------------------+
Fixed length of 12 bytes. Contains ID, Flags, and counters for subsequent sections (QDCOUNT, ANCOUNT, NSCOUNT, ARCOUNT).
Answer, Nameserver, and Additional sections all use this format:
- NAME: Variable-length domain name, supports RFC 1035 compression.
- TYPE (u16): Record type (e.g., A=1, SRV=33, E=266).
- CLASS (u16): Protocol class. In mDNS, the highest bit (bit 15) is used for cache-flush flag.
- TTL (u32): Cache time-to-live (seconds).
- RDLEN (u16): Length of resource data (RDATA).
- RDATA: Specific resource content, format determined by TYPE.
| Type | Value | Description | RDATA Format |
|---|---|---|---|
| A | 1 | IPv4 address | 4-byte IP |
| AAAA | 28 | IPv6 address | 16-byte IP |
| SRV | 33 | Service location | Priority + Weight + Port + Target |
| E | 266 | Endpoint address | Flags + Seq + Addr(s) + [Sig] |
+--------+-----------------+--------------------+----------------------------+
| flags | sequence(varint)| addr(s) | signature (optional) |
+--------+-----------------+--------------------+----------------------------+
| u8 | QUIC varint | v4: 2+4 / v6: 2+16 | scheme(u16)+len(varint)+N |
+--------+-----------------+--------------------+----------------------------+
- bit 7 (0x80): FAMILY - Address family (0=IPv4, 1=IPv6)
- bit 6 (0x40): MAIN - Primary address flag
- bit 5 (0x20): SEQUENCED - Sequence number present
- bit 4 (0x10): FORWARD - Connection type (0=direct, 1=relay)
- bit 3 (0x08): SIGNED - Signature present
- bits 2-0: Reserved
- Direct:
port(u16)+IP(u32/u128) - Relay:
outer_port(u16)+outer_IP(u32/u128)+agent_port(u16)+agent_IP(u32/u128) - sequence: DNS record sequence number. Records with the same sequence are considered from the same machine and can use multipath connections.
- signature: When
SIGNEDflag is set, signature field is appended.
0b1000_0000: FAMILY (Address family: 0=IPv4, 1=IPv6)0b0100_0000: MAIN (Primary address flag)0b0010_0000: SEQUENCED (Sequence number present)0b0001_0000: FORWARD (Connection type: 0=direct, 1=relay)0b0000_1000: SIGNED (Signature present)
- Direct:
Port(u16)+IP(u32/u128) - Relay:
OuterPort(u16)+OuterIP(u32/u128)+AgentPort(u16)+AgentIP(u32/u128)
When signature is present: Scheme (u16) + Length (VarInt) + Data (N bytes).
src/parser/: Core protocol parsing implementation (Nom parsers).src/protocol.rs: UDP multicast and packet routing logic.src/mdns.rs: High-level mDNS discovery and response API.src/resolver/: HTTP/3 resolver implementation for DoH3 support.examples/: Sample code including mDNS discovery/query, and HTTP/3 publishing/querying/server examples.