Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,26 @@
# Version 0.18.0 (2026-02-15)

A few new features, documentation enhancements and breaking changes.

## Breaking changes
- Removed one default feature: `reuseport`. It is handled transparently now. (see commit `58bc8c5`)
- New feature: support `.` and `\` in instance names (see commit `3481b94`)
- New internal fix: proper cleanup on daemon shutdown (see commit `8d24304`)
- New internal fix: exclude point-to-point interfaces by default (e.g. tunnel interface) (see commit `85b6cd9`)

## All changes
* `b694333 2026-02-12` Added documentation about service name length (FelixSelter)
* `85b6cd9 2026-02-10` fix for macOS: exclude IFF_POINTTOPOINT interfaces and exclude Apple P2P interfaces by default (#425) (keepsimple1)
* `58bc8c5 2026-02-09` fix: invert reuseport feature (#430) (keepsimple1)
* `8d24304 2026-02-07` feat: add proper cleanup on daemon shutdown (#421) (Thibaut M.)
* `69418d6 2026-02-05` chore: update some comments (#429) (keepsimple1)
* `3481b94 2026-02-06` feat: implement RFC 6763 Section 4.3 escaping for instance names (#420) (Thibaut M.)
* `58c15b4 2026-01-27` fix: only add a scope in Display to unicast link local v6 addresses (#424) (hrzlgnm)
* `3f34136 2026-01-24` Return errors from send_dns_outgoing (#419) (keepsimple1)
* `0e323f6 2026-01-21` ci: update github action checkout (#422) (Thibaut M.)

Thanks and welcome new contributors: @thibaut-pascal, @FelixSelter

# Version 0.17.2 (2026-01-16)

## New features (non-breaking)
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mdns-sd"
version = "0.17.2"
version = "0.18.0"
authors = ["keepsimple <keepsimple@gmail.com>"]
edition = "2018"
rust-version = "1.71.0"
Expand Down
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
//! // Create a daemon
//! let mdns = ServiceDaemon::new().expect("Failed to create daemon");
//!
//! // Recommended: Setup a monitor connection to receive events, especially errors from the daemon thread.
//! // Optional: setup a monitor channel to receive events, especially errors from the daemon.
//! let receiver = mdns.monitor().expect("Failed to monitor daemon");
//! std::thread::spawn(move || {
//! while let Ok(event) = receiver.recv() {
Expand All @@ -88,7 +88,7 @@
//! });
//!
//! // Create a service info.
//! // Make sure that the service name: "mdns-sd-my-test" is not longer than the max length limit. (15 characters by default)
//! // Make sure that the service name: "mdns-sd-my-test" is not longer than the max length limit (15 by default).
//! let service_type = "_mdns-sd-my-test._udp.local.";
//! let instance_name = "my_instance";
//! let ip = "192.168.1.12";
Expand Down
10 changes: 3 additions & 7 deletions src/service_daemon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5258,17 +5258,16 @@ mod tests {

#[test]
fn test_cache_only_unsolicited() {
// construct service info
let service_type = "_cache_only._udp.local.";
let service_type = "_c_unsolicit._udp.local.";
let instance = "test_instance";
let host_name = "cache_only_host.local.";
let host_name = "c_unsolicit_host.local.";
let service_ip_addr = my_ip_interfaces(false)
.iter()
.find(|iface| iface.ip().is_ipv4())
.map(|iface| iface.ip())
.unwrap();

let mut my_service = ServiceInfo::new(
let my_service = ServiceInfo::new(
service_type,
instance,
host_name,
Expand All @@ -5278,9 +5277,6 @@ mod tests {
)
.unwrap();

let new_ttl = 3; // for testing only.
my_service._set_other_ttl(new_ttl);

// register my service
let mdns_server = ServiceDaemon::new().expect("Failed to create mdns server");
let result = mdns_server.register(my_service);
Expand Down
15 changes: 6 additions & 9 deletions src/service_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,10 @@ fn escape_instance_name(name: &str) -> String {
/// as well as A (IPv4 Address) and AAAA (IPv6 Address) records.
#[derive(Debug, Clone)]
pub struct ServiceInfo {
// With default settings service name length must be <= 15 bytes
// so "_abcdefghijklmno._udp.local." would be valid but "_abcdefghijklmnop._udp.local." is not
ty_domain: String, // <service>.<domain>
/// Service type and domain: {service-type-name}.{domain}
/// By default the service-type-name length must be <= 15.
/// so "_abcdefghijklmno._udp.local." would be valid but "_abcdefghijklmnop._udp.local." is not
ty_domain: String,

/// See RFC6763 section 7.1 about "Subtypes":
/// <https://datatracker.ietf.org/doc/html/rfc6763#section-7.1>
Expand Down Expand Up @@ -128,12 +129,8 @@ pub(crate) enum ServiceStatus {
impl ServiceInfo {
/// Creates a new service info.
///
/// `ty_domain` is the service type and the domain label, for example
/// "_my-service._udp.local.".
/// With default settings service name length must be <= 15 bytes
/// so "_abcdefghijklmno._udp.local." would be valid but "_abcdefghijklmnop._udp.local." is not
/// ❗ **This will fail with an error log which may not be noticed unless you properly setup logging**.
/// It is recommended to setup a monitor connection via `ServiceDaemon::monitor()`
/// `ty_domain` is the service type and the domain label, for example "_my-service._udp.local.".
/// By default the service type length must be <= 15 bytes
///
/// `my_name` is the instance name, without the service type suffix.
/// It allows dots (`.`) and backslashes (`\`).
Expand Down