Skip to content

mdns discovery - #79

Merged
gh0st42 merged 3 commits into
dtn7:masterfrom
Marlinski:feature/mdns
May 27, 2026
Merged

gh0st42 merged 3 commits into
dtn7:masterfrom
Marlinski:feature/mdns

Conversation

@Marlinski

@Marlinski Marlinski commented Nov 28, 2025 •

Copy link
Copy Markdown
Contributor

Current neighbor discovery uses binding to a local udp port with multicast. Thus two dtn node on the same host can't discover themselves and also cannot bind on the same port.

This PR Implements neighbour discovery over mDNS, this doesn't require any binding to local port, the service messages encapsulate all eid and services in a similar fashion to the beacon with udp multicast discovery.

I also Added new options for dtnd to select which neighbouring discovery protocol to use.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds an mDNS/DNS-SD based neighbor discovery mechanism to dtn7-rs (as an alternative to legacy UDP multicast IPND) and introduces configuration/CLI options to select the discovery transport, enabling same-host multi-daemon discovery without UDP port binding conflicts.

Changes:

  • Added mDNS discovery implementation (_dtn._udp.local.) and transport selection (udp-multicast / mdns / both).
  • Refactored legacy UDP multicast discovery into its own module and wired it through a unified spawn_neighbour_discovery() dispatcher.
  • Added documentation and configuration examples, plus a new dependency (mdns-sd).

Reviewed changes

Copilot reviewed 9 out of 10 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
examples/dtn7.toml.example Documents new discovery.transport option.
doc/mdns-discovery.md New mDNS discovery documentation and usage examples.
core/dtn7/src/ipnd/udp_discovery.rs Extracted UDP multicast discovery implementation into a dedicated module.
core/dtn7/src/ipnd/neighbour_discovery.rs Dispatches discovery startup based on configured transport.
core/dtn7/src/ipnd/mod.rs Exposes new mdns_discovery and udp_discovery modules.
core/dtn7/src/ipnd/mdns_discovery.rs New mDNS/DNS-SD discovery implementation.
core/dtn7/src/dtnconfig.rs Adds DiscoveryTransport enum and config-file parsing for transport selection.
core/dtn7/src/bin/dtnd.rs Adds --discovery-transport CLI flag and parsing into config.
core/dtn7/Cargo.toml Adds mdns-sd dependency.
Cargo.lock Locks transitive dependencies introduced by mdns-sd.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +16 to +33
let config = CONFIG.lock();
let nodeid = config.nodeid.clone();
let eid = config.host_eid.clone();
let interval_duration = config.announcement_interval;
drop(config);

info!("Starting mDNS discovery for service type: {}", MDNS_SERVICE_TYPE);

// Create mDNS daemon
let mdns = ServiceDaemon::new().expect("Failed to create mDNS daemon");

// Build and register our service
let service_info = build_mdns_service_info(&nodeid, &eid);
mdns.register(service_info)
.expect("Failed to register mDNS service");

info!("Registered mDNS service type: {} (Node: {})", MDNS_SERVICE_TYPE, nodeid);

Comment on lines +96 to +118
// Add available CLAs with their ports
let clas = CLAS.lock();
let cla_props: Vec<(String, String)> = clas.iter()
.enumerate()
.map(|(idx, cla)| {
(format!("cla{}", idx), format!("{}:{}", cla.name(), cla.port()))
})
.collect();
drop(clas);

for (key, val) in cla_props {
properties.push((Box::leak(key.into_boxed_str()), val));
}

// Add custom services
let services = DTNCORE.lock().service_list.clone();
let svc_props: Vec<(String, String)> = services.iter()
.map(|(tag, payload)| (format!("svc{}", tag), payload.clone()))
.collect();

for (key, val) in svc_props {
properties.push((Box::leak(key.into_boxed_str()), val));
}
Comment on lines +24 to +37
// Create mDNS daemon
let mdns = ServiceDaemon::new().expect("Failed to create mDNS daemon");

// Build and register our service
let service_info = build_mdns_service_info(&nodeid, &eid);
mdns.register(service_info)
.expect("Failed to register mDNS service");

info!("Registered mDNS service type: {} (Node: {})", MDNS_SERVICE_TYPE, nodeid);

// Browse for other DTN nodes
let receiver = mdns.browse(MDNS_SERVICE_TYPE)
.expect("Failed to browse for mDNS services");

Comment on lines +109 to +110
(*CONFIG.lock()).update_beacon_sequence_number(&destination.to_string());
pkt.set_beacon_sequence_number(bsn);
Comment on lines +189 to +196
if v6 {
let addr: SocketAddr = format!("[::1]:{}", port).parse()?;
let addr = addr.into();
let socket = Socket::new(Domain::IPV6, Type::DGRAM, None)?;
socket.set_reuse_address(true)?;
socket.set_only_v6(true)?;
socket.bind(&addr)?;

Comment thread core/dtn7/src/ipnd/udp_discovery.rs Outdated
Comment thread doc/mdns-discovery.md
Comment on lines +69 to +76
| Feature | UDP Multicast | mDNS |
|---------|--------------|------|
| Port conflicts | Yes (only one daemon/host) | No (system manages mDNS) |
| Same-host discovery | No | Yes |
| Standard tooling | Limited | Full (dns-sd, avahi-browse) |
| Name resolution | No | Yes (`.local` hostnames) |
| Legacy compatibility | IPND | New |

Comment thread core/dtn7/src/bin/dtnd.rs
Comment on lines +366 to +369
if let Some(transport) = matches.get_one::<String>("discoverytransport") {
cfg.discovery_transport = transport.parse()
.expect("Invalid discovery transport! Use: udp-multicast, mdns, or both");
}
Comment on lines +191 to +196
dtncfg.discovery_transport = if let Ok(transport) = s.get_string("discovery.transport") {
DiscoveryTransport::from_str(&transport).unwrap_or_default()
} else {
dtncfg.discovery_transport
};
debug!("discovery-transport: {:?}", dtncfg.discovery_transport);
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@gh0st42

gh0st42 commented May 26, 2026

Copy link
Copy Markdown
Member

Wow, thx for this PR. mDNS was on my todo list for a very long time! appreciate that it works on multiple platforms!

@gh0st42

gh0st42 commented May 26, 2026

Copy link
Copy Markdown
Member

@copilot resolve the merge conflicts in this pull request

@gh0st42
gh0st42 merged commit c30181b into dtn7:master May 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants