Skip to content

Implement TR-10-9 Section 15 DNS-SD browse strategy#484

Merged
lo-simon merged 4 commits intosony:masterfrom
simonbaren:feature/tr-10-9-dns-sd-browse-strategy
Apr 30, 2026
Merged

Implement TR-10-9 Section 15 DNS-SD browse strategy#484
lo-simon merged 4 commits intosony:masterfrom
simonbaren:feature/tr-10-9-dns-sd-browse-strategy

Conversation

@simonbaren
Copy link
Copy Markdown
Contributor

@simonbaren simonbaren commented Mar 17, 2026

Summary

Implements the DNS-SD browse strategy required by TR-10-9 Section 15 for IPMX device service discovery.

Changes

  • New dns_sd_browse_mode setting ("both" / "unicast" / "mdns") to control DNS-SD browse method
    • "both" (default): try unicast DNS first with half the timeout budget; fall back to mDNS if no services found
    • "unicast": unicast DNS only
    • "mdns": mDNS only
  • Domain class filtering in browse results to prevent mDNS results leaking into unicast DNS queries and vice versa
  • Refactored resolve_service to delegate to resolve_service_ with the dual-discovery logic

Motivation

TR-10-9 Section 15 requires IPMX devices to support both mDNS and unicast DNS for DNS-SD browse operations, defaulting to using both methods. When using both, unicast DNS must be attempted first, with mDNS as a fallback only if unicast is unsuccessful.

Files changed

  • Development/nmos/settings.h — new dns_sd_browse_mode field
  • Development/nmos/mdns.cpp — dual-browse logic and domain class filtering

https://static.vsf.tv/download/technical_recommendations/VSF_TR-10-9_v2_2025-05-13.pdf

@simonbaren simonbaren force-pushed the feature/tr-10-9-dns-sd-browse-strategy branch from fb842e3 to 8a965c6 Compare March 17, 2026 09:22
TR-10-9 Section 15 requires IPMX devices to:
- Support both mDNS and unicast DNS for DNS-SD browse operations
- Default to using both methods
- Provide user mechanisms to limit browsing to unicast or mDNS only
- When using both: try unicast DNS first, fall back to mDNS only
  if unicast is unsuccessful (no service discovered)
- When multiple results are returned: select by best priority,
  failing over to next-best if unresponsive
- Once a service is selected and responsive: perform no further
  browse operations for that service type
- If the selected service becomes unresponsive: perform a new
  DNS-SD browse and restart selection

Add dns_sd_browse_mode setting ("both"/"unicast"/"mdns") to implement
the required dual-discovery strategy. In "both" mode (default), unicast
DNS is tried first with half the timeout budget; if no records are
found, mDNS fallback gets the remaining half. "unicast" and "mdns"
modes restrict to a single method.

Also filters browse results by domain class to prevent mDNS results
leaking into unicast DNS queries and vice versa.

Signed-off-by: Semyon Barenboym <simonbaren@gmail.com>
@simonbaren simonbaren force-pushed the feature/tr-10-9-dns-sd-browse-strategy branch from 8a965c6 to cc1dab4 Compare March 17, 2026 09:23
@lo-simon
Copy link
Copy Markdown
Collaborator

Thank you, @simonbaren, for your PR, we will look into it shortly.

@simonbaren
Copy link
Copy Markdown
Contributor Author

simonbaren commented Apr 15, 2026

Hi @lo-simon, kindly reminder.

@lo-simon
Copy link
Copy Markdown
Collaborator

lo-simon commented Apr 28, 2026

Hi @simonbaren

So sorry for the late reply.

I am happy with your PR. There are a few points I would like to address and offer suggestions on.

  1. For dns_sd_browse_mode, it would be better to use an enum rather than a string, following the style of href_mode.
  2. Add dns_sd_browse_mode to the example nmos-cpp-node/config.json.
  3. Mark the unused resolve_service function (line 711 in mdns.cpp) as deprecated in both the cpp and header files by adding a comment.
  4. Update the resolve_service and resolve_service_ comments in the header and in the cpp.
  5. I think it would be better to keep the same discovery timeout for both primary and fallback resolves, rather than halving it. What do you think, @jonathan-r-thorpe and @garethsb?
  6. Shall we add the following table to settings.h and config.json as a reminder?
dns_sd_browse_mode domain expected-resolve-behaviour
both example.com unicast->mdns
both local. mdns
unicast example.com unicast
unicast local. mdns
mdns example.com mdns
mdns local. mdns

- Use string_enum for dns_sd_browse_mode (nmos::dns_sd_browse_modes::{both,unicast,mdns})
- Add dns_sd_browse_mode example + behaviour table to nmos-cpp-node config.json
- Add expected-behaviour table to settings.h
- Mark unused URI-returning resolve_service overload as deprecated (comment)
- Refresh resolve_service / resolve_service_ doc comments in mdns.h/.cpp

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@simonbaren
Copy link
Copy Markdown
Contributor Author

Hi @lo-simon, thanks for the review. Pushed a commit addressing items 1–4 and 6:

  1. dns_sd_browse_mode as enum — used the string_enum pattern (DEFINE_STRING_ENUM) rather than the integer href_mode style. Rationale: The string-based pattern is consistent with most other JSON-string enums in nmos-cpp (interlace_mode, activation_mode, event_type, etc.) and keeps the config human-readable. Happy to switch to int-enum if you'd prefer.
  2. config.json — added a commented-out dns_sd_browse_mode entry next to domain, with the behaviour table inline.
  3. Deprecated marker — added // DEPRECATED: … comments above the unused web::uri-returning resolve_service overload (and its inline template wrapper) in both mdns.h and mdns.cpp.
  4. Refreshed commentsresolve_service and resolve_service_ doc comments in both mdns.h and mdns.cpp now distinguish the web::uri vs resolved_service return shapes and reference the TR-10-9 mode selection.
  5. Timeout halving — left as-is for now, awaiting input from @jonathan-r-thorpe / @garethsb.
  6. Behaviour table — added next to the dns_sd_browse_mode field declaration in settings.h and next to the entry in config.json.

Let me know if anything needs adjusting.

@jonathan-r-thorpe
Copy link
Copy Markdown
Contributor

@lo-simon @simonbaren on 5. I agree with @lo-simon that I would expect the primary service timeout to remain unchanged, even when there is a fallback service. My expectation would therefore be that the timeout applied per service (i.e. don't halve it).

Per maintainer review (jonathan-r-thorpe, lo-simon): the primary service
timeout should remain unchanged when a fallback is in play, with the same
timeout applied per service rather than halved across them.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@simonbaren
Copy link
Copy Markdown
Contributor Author

Thanks @jonathan-r-thorpe. Done in the latest commit - primary and fallback now both use the full discovery_backoff_max timeout (no more halving).

Copy link
Copy Markdown
Collaborator

@lo-simon lo-simon left a comment

Choose a reason for hiding this comment

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

Use an enum rather than a string for the dns_sd_browse_mode to reduce the risk of typos.

Comment thread Development/nmos-cpp-node/config.json Outdated
Comment on lines +89 to +91
// "both" (default) = unicast DNS first, mDNS fallback if unsuccessful
// "unicast" = unicast DNS only
// "mdns" = mDNS only
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
// "both" (default) = unicast DNS first, mDNS fallback if unsuccessful
// "unicast" = unicast DNS only
// "mdns" = mDNS only
// both(0) (default) = unicast DNS first, mDNS fallback if unsuccessful
// unicast(1) = unicast DNS only
// mdns(2) = mDNS only

Comment thread Development/nmos-cpp-node/config.json Outdated
// unicast | local. | mdns
// mdns | example.com | mdns
// mdns | local. | mdns
//"dns_sd_browse_mode": "both",
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
//"dns_sd_browse_mode": "both",
//"dns_sd_browse_mode": 0,

Comment thread Development/nmos/dns_sd_browse_mode.h Outdated
#ifndef NMOS_DNS_SD_BROWSE_MODE_H
#define NMOS_DNS_SD_BROWSE_MODE_H

#include "nmos/string_enum.h"
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
#include "nmos/string_enum.h"

Comment thread Development/nmos/dns_sd_browse_mode.h Outdated
Comment on lines +10 to +16
DEFINE_STRING_ENUM(dns_sd_browse_mode)
namespace dns_sd_browse_modes
{
const dns_sd_browse_mode both{ U("both") }; // unicast DNS first, mDNS fallback if unsuccessful
const dns_sd_browse_mode unicast{ U("unicast") }; // unicast DNS only
const dns_sd_browse_mode mdns{ U("mdns") }; // mDNS only
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
DEFINE_STRING_ENUM(dns_sd_browse_mode)
namespace dns_sd_browse_modes
{
const dns_sd_browse_mode both{ U("both") }; // unicast DNS first, mDNS fallback if unsuccessful
const dns_sd_browse_mode unicast{ U("unicast") }; // unicast DNS only
const dns_sd_browse_mode mdns{ U("mdns") }; // mDNS only
}
enum dns_sd_browse_mode
{
both = 0, // unicast DNS first, mDNS fallback if unsuccessful
unicast = 1, // unicast DNS only
mdns = 2 // mDNS only
};

Comment thread Development/nmos/mdns.cpp Outdated
Comment on lines +747 to +749
// - "both" (default): unicast DNS first, mDNS fallback if unsuccessful
// - "unicast" : unicast DNS only
// - "mdns" : mDNS only
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
// - "both" (default): unicast DNS first, mDNS fallback if unsuccessful
// - "unicast" : unicast DNS only
// - "mdns" : mDNS only
// - both (default): unicast DNS first, mDNS fallback if unsuccessful
// - unicast : unicast DNS only
// - mdns : mDNS only

Comment thread Development/nmos/mdns.h Outdated
Comment on lines +201 to +203
// - "both" (default): unicast DNS first, mDNS fallback if unsuccessful
// - "unicast" : unicast DNS only
// - "mdns" : mDNS only
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
// - "both" (default): unicast DNS first, mDNS fallback if unsuccessful
// - "unicast" : unicast DNS only
// - "mdns" : mDNS only
// - both (default): unicast DNS first, mDNS fallback if unsuccessful
// - unicast : unicast DNS only
// - mdns : mDNS only

Comment thread Development/nmos/settings.h Outdated
Comment on lines +87 to +89
// "both" (default) = unicast DNS first, mDNS fallback if unsuccessful
// "unicast" = unicast DNS only
// "mdns" = mDNS only
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
// "both" (default) = unicast DNS first, mDNS fallback if unsuccessful
// "unicast" = unicast DNS only
// "mdns" = mDNS only
// both(0) (default) = unicast DNS first, mDNS fallback if unsuccessful
// unicast(1) = unicast DNS only
// mdns(2) = mDNS only

Comment thread Development/nmos/settings.h Outdated
// unicast | local. | mdns
// mdns | example.com | mdns
// mdns | local. | mdns
const web::json::field_as_string_or dns_sd_browse_mode{ U("dns_sd_browse_mode"), U("both") };
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
const web::json::field_as_string_or dns_sd_browse_mode{ U("dns_sd_browse_mode"), U("both") };
const web::json::field_as_integer_or dns_sd_browse_mode{ U("dns_sd_browse_mode"), 0 };

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Use an enum rather than a string for the dns_sd_browse_mode to reduce the risk of typos.

Per lo-simon's review: use a typed enum (compile-checked) rather than a
string to reduce typo risk in user configurations.

- enum dns_sd_browse_mode { dns_sd_browse_mode_both = 0, _unicast = 1,
  _mdns = 2 } defined file-local in mdns.cpp under nmos::experimental,
  mirroring how href_mode lives in settings.cpp
- field becomes field_as_integer_or with default 0
- example config.json now shows //"dns_sd_browse_mode": 0,
- doc comments updated; dns_sd_browse_mode.h header removed

Used dns_sd_browse_mode_* prefix on the enumerators (rather than the bare
both/unicast/mdns suggested in the review) to avoid polluting nmos:: with
generic identifiers, matching the href_mode_* convention.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@simonbaren simonbaren force-pushed the feature/tr-10-9-dns-sd-browse-strategy branch from 28d14db to 09df043 Compare April 30, 2026 08:38
@simonbaren
Copy link
Copy Markdown
Contributor Author

Hi @lo-simon, thanks for the detailed review. Switched to a typed integer enum.
Two small deviations from your literal suggestions, both for consistency with the existing href_mode pattern you originally cited — happy to revert either if you'd prefer:

  1. Enumerator naming — used dns_sd_browse_mode_both / _unicast / _mdns (prefixed) rather than bare both / unicast / mdns. Bare names would land directly in the nmos:: namespace, where nmos::both etc. are quite generic. The prefixed form matches href_mode's href_mode_default / href_mode_name / etc.

  2. Header location — moved the enum into mdns.cpp (file-local, under namespace nmos) and deleted Development/nmos/dns_sd_browse_mode.h that was added in previous commit. This mirrors how href_mode lives entirely in settings.cpp rather than in a public header. The setting field stays in settings.h; the integer value descriptions are inlined in the comment there (per your suggestion).

All other inline suggestions applied verbatim:

  • field_as_integer_or dns_sd_browse_mode{ U("dns_sd_browse_mode"), 0 }
  • //"dns_sd_browse_mode": 0, in the example config
  • both(0) / unicast(1) / mdns(2) in the settings.h and config.json comment tables
  • doc comments in mdns.h/mdns.cpp use bare both/unicast/mdns

@lo-simon lo-simon merged commit db23439 into sony:master Apr 30, 2026
10 checks passed
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