fix(discovery): announce all participant locators on multi-homed hosts - #34
Closed
SandraK82 wants to merge 6 commits into
Closed
fix(discovery): announce all participant locators on multi-homed hosts#34SandraK82 wants to merge 6 commits into
SandraK82 wants to merge 6 commits into
Conversation
…overy Multi-homed hosts can announce an unreachable discovery locator when the OS default-route probe diverges from the peer's segment (#27). Add deterministic enumeration of eligible unicast IPv4 interfaces (UP, multicast-capable, non-loopback; addresses excluding loopback, link-local, unspecified, broadcast, multicast), de-duplicated and stably ordered by ip/name/index, for the DCPS announce path to fan out over. Interface flags via pnet_datalink (already resolved in the workspace lock); std-gated behind the crate's std feature.
ParticipantBuiltinTopicData's four locator fields change from Option<Locator> to Vec<Locator> — every field that is semantically a locator list (DDSI-RTPS 2.5 §9.6.1: a *_LOCATOR PID may repeat). No parallel compatibility fields. - Empty list = no locator announced. - Encode emits one PID per locator, wire order preserved, exact duplicates removed. - Decode retains ALL valid locators for zero/one/repeated PIDs, in LE and BE (new Locator::from_bytes_be closes the prior BE-decode gap). - No routing/usability filtering during decode — that moves to DCPS/transport. pick_routable_locator is removed from the decode path; locator_looks_routable stays as a pub predicate for DCPS to order the retained list. - Small primary_* helpers and metatraffic_or_default_unicast_locators() for call sites; ZERODDS_INTERFACE behaviour is untouched here. DCPS/discovery send sites are adapted to the new type but keep their current single-locator behaviour; the announce-all + fan-out change follows in a separate commit. Tests: multi-locator round-trip (retain-all, order, LE+BE), dedup on encode, zero-locator empty lists, locator_looks_routable predicate.
) Automatic discovery now announces the FULL set of eligible unicast interface addresses, not just the single default-route probe result. A peer on any shared segment therefore always learns a reachable locator — closing the #27 half-completed discovery (participant discovered, endpoints never matched) on multi-homed hosts. - announce_locators() enumerates eligible interfaces (Commit 1) at the socket's bound port; automatic mode announces all, an explicit ZERODDS_INTERFACE keeps its deterministic single-interface behaviour, non-UDPv4 and empty-enumeration fall back to the single probe. Never announces an empty list. - Participant SPDP default/metatraffic unicast locators and every SEDP endpoint's unicast_locators carry the full set (user_announce_locators). - Send fan-out: UDP cannot detect a dead destination, so metatraffic is sent to EVERY deduplicated usable peer locator (WLP pulse; SEDP/user data already fan out via the reader-proxy locator list + send_to_all). Tests: reliable_writer fans out to every unicast locator of a proxy (first advertised unreachable, second reachable → the second is targeted); announce_locators pins to a single interface and is non-empty + probe-inclusive in automatic mode.
…erral The #27 interop reader now reports discovered_participants_count separately from matched/samples, so a half-completed discovery (peer participant discovered, endpoints never matched) is visible in the RESULT line — the exact #27 symptom, and the signal the Windows multi-NIC A/B keys on. Docs: OPEN-ITEMS records the deferred multi-interface multicast join/TX hardening (not required for #27 — the capture proved multicast TX/RX was never the failing operation); the follow-up spells out the gate to implement it (an independent reproduction where the OS mis-selects the multicast interface, not just the unicast source probe).
…ink (#27) pnet_datalink pulls pnet_sys, which links Npcap's Packet.lib — absent on a stock Windows toolchain, so reader.exe (and the GitHub windows-smoke CI) fails to link with LNK1181 "cannot open input file Packet.lib". if-addrs enumerates interfaces via getifaddrs / GetAdaptersAddresses with no pcap dependency, so it links everywhere. The filter/order/dedup logic and its tests are unchanged; only the flag source differs. get_if_addrs returns only operational (UP) interfaces and does not expose the multicast flag, which is assumed here — the announced set drives unicast locators, and the multicast-flag-dependent per-interface join/TX is deferred hardening.
…a locator-list change Workspace + zerodds-rtps CHANGELOG: the multi-homed discovery fix (#27) and the breaking Option<Locator> -> Vec<Locator> field change with migration notes (construction, primary_* accessors, decode filtering moved to DCPS, no wire-format break).
|
@SandraK82 Why this has been closed? 🥲 |
Contributor
Author
|
i'm trying codex the first time.. its complicated :) pr is open now as pr #35 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes participant discovery on multi-homed systems where multicast traffic and the OS-selected unicast route use different network interfaces.
Addresses #27. Related to #28.
Root cause
ZeroDDS announced only one participant unicast locator, selected through an OS route probe.
On the reproduced Windows 11 multi-adapter setup:
This explains the observed state where CycloneDDS Insight sees the Cyclone writer but not the ZeroDDS reader.
The problem is independent of XCDR, extensibility, and DataRepresentation.
Changes
ZERODDS_INTERFACEas a deterministic single-interface override.Option<Locator>toVec<Locator>.Multi-interface multicast transmission is intentionally not part of this change. Packet captures showed that multicast used the correct interface in the reproduced failure; the incorrect announced unicast locator was the failing operation.
Breaking API change
The locator fields in
ParticipantBuiltinTopicDatanow useVec<Locator>instead ofOption<Locator>because the RTPS fields are locator lists and repeated locator PIDs are valid on the wire.Migration guidance is included in the changelog.
Validation
discovered=1 matched=0 samples=0discovered=1 matched=1 samples=25/26