Repository navigation
Conversation
…d) (sonn-audio#356) deriveHardwareAddress added zoneId to the last byte of the per-zone sourceMac, but those sourceMacs are not unique across zones — so the sum collided: sourceMac ..68 +zoneId 5 and ..67 +zoneId 6 both produced ..6D. Wohnzimmer and Elternbad therefore advertised the same RAOP/AirPlay identifier (and Küche/Außenbereich another), so an AirPlay client selecting by identifier streamed into the wrong room. zoneId is unique per zone, so set the last byte from it directly instead of adding it to a non-unique base. Verified: all 11 zones now advertise distinct identifiers (…1001…100C) and an AirPlay stream targeted at Wohnzimmer's id reaches zoneId=5. Fixes sonn-audio#356. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Collaborator
|
Went with a slightly different fix: the address is now derived from a SHA-256 hash of serial+zoneId, with the locally-administered bit set. Setting the last byte to zoneId alone fixes a single server, but two audioservers with near-adjacent serials (identical first five bytes) would still collide on equal player ids — hashing the full pair covers that case too, and the locally-administered bit keeps the synthetic address out of the real MAC space. Unit tests cover both collision classes, including your ..68+5 == ..67+6 case. |
rudyberends
added a commit
that referenced
this pull request
Aug 29, 2026
deriveHardwareAddress added zoneId to the last byte of the zone's sourceMac, but sourceMac is the serial of whichever device carries the zone's outputs — shared by zones on one extension, with sibling serials differing only in the last bytes. The sums collided (..68+5 == ..67+6), so two rooms advertised the same AirPlay identifier and senders that select by id landed in the wrong room. Derive the address from a hash of serial+zoneId instead: unique for every (device, zone) pair — also across audioservers with adjacent serials, which setting the last byte to zoneId alone would still let collide — and marked locally administered so it can never coincide with a real device's MAC. Fixes #356. Closes #357.
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.
Fixes #356 — root cause found and fix verified live (patched into the running container's dist).
Root cause
deriveHardwareAddress(sourceMac, zoneId)inairplayInstance.tsbuilds each zone's RAOP identifier byadding
zoneIdto the last byte of the zone'ssourceMac:But the per-zone
sourceMacvalues are not unique — several zones share one (in this install:…1067,…1068,…1069,…106Aeach appear on two zones). AddingzoneIdon top then collides wheneversourceMacLastByte + zoneIdcoincides:So Wohnzimmer/Elternbad and Küche/Außenbereich each advertised the same
_raop._tcpidentifier (only theport differed). An AirPlay client that selects by identifier lands on whichever resolves first — verified:
streaming to
88AEDD68106Dplayed into Elternbad, not the intended Wohnzimmer.Fix
zoneIdis unique per zone, so derive the last byte from it directly rather than adding it to a non-uniquebase:
Verification (dist-patched into the running container)
All 11 zones now advertise distinct identifiers, and every zone shows up in discovery (previously the
colliding ones shadowed each other):
Streaming an AirPlay tone to Wohnzimmer's id (
…1005) now lands in the right room —[Input|AirPlay][Wohnzimmer] airplay pcm chunk … zoneId=5.(Deeper cleanup out of scope here: the per-zone
sourceMacvalues probably shouldn't be assigned withduplicates in the first place. Making the identifier derive from the unique
zoneIdfixes the user-visiblecollision regardless.)