Fix #255: do not treat an all zero MAC as a host identity - #319
Open
quadseven wants to merge 1 commit into
Open
Conversation
A host is not required to report a MAC. Sunshine answers serverinfo with 00:00:00:00:00:00 when it cannot determine its own, and every guard in the codebase tested that with !mac.empty(), which an all zero MAC passes. So the placeholder was accepted as a real identity in five separate places. Wake-on-LAN (XITRIX#255): normalize_mac_address() turns 00:00:00:00:00:00 into twelve valid hex digits, so can_wake_up_host() returns true, the user is offered the wake action, and a well formed magic packet is broadcast to a MAC that belongs to nothing. It fails silently, with no error and nothing to see. Host identity: hosts_match() early returns if (!lhs.mac.empty() && !rhs.mac.empty()) return lhs.mac == rhs.mac; so two different hosts that both report the placeholder compare equal and never reach the address comparison below. Add a second Sunshine host and it merges into the first instead of being added. host_key() has the same problem and keys the m_active_addresses cache on "mac:00:00:00:00:00:00", so the resolved address of one host is served for another. Forwarders: forwarder_maker.cpp emitted --host=00:00:00:00:00:00 rather than falling back to --ip=<address>, producing a forwarder that cannot find its host. Add is_usable_mac(), which accepts a MAC only if it parses as hex and has at least one nonzero digit, and use it at every site that was testing !mac.empty() for identity: hosts_match(), merge_host(), add_host(), host_key(), merge_discovered_host(), DiscoverManager's merge, and the forwarder argument builder. normalize_mac_address() rejects the all zero case too, so can_wake_up_host() stops advertising an action that cannot work and wake_up_host()'s existing "Missing or invalid host MAC address" becomes accurate. The empty() checks in main_args.cpp are left alone. Those ask whether the user supplied an argument at all, which is a different question. Verified with a unit test over the predicate covering the empty string, the all zero MAC in colon, dash and bare forms, an ordinary MAC, a MAC with a leading zero octet, and non hex input. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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 #255.
The bug
A host is not required to report a MAC. Sunshine answers
serverinfowith00:00:00:00:00:00when it cannot work out its own. Every guard in thecodebase tested for a MAC with
!mac.empty(), and an all zero MAC passesthat, so the placeholder was accepted as a real identity in five separate
places.
Here is the relevant part of a real
settings.jsonfrom a Switch paired to aSunshine host:
{ "address": "10.0.0.x", "hostname": "...", "mac": "00:00:00:00:00:00", ... }Wake-on-LAN, which is #255.
normalize_mac_address()turns00:00:00:00:00:00into twelve valid hex digits, socan_wake_up_host()returns true. The user is offered the wake action, a well formed magic packet
is built and broadcast, and it is addressed to a MAC that belongs to nothing.
Nothing wakes, no error is shown, and there is nothing for the user to see.
Host identity.
hosts_match()early returns:Two different hosts that both report the placeholder compare equal here and
never reach the address comparison below. Add a second Sunshine host and it
merges into the first instead of being added as its own entry.
host_key()has the same problem, and keysm_active_addresseson"mac:00:00:00:00:00:00", so the resolved address of one host can be servedfor a different one.
Forwarders.
forwarder_maker.cppemitted--host=00:00:00:00:00:00instead of falling back to
--ip=<address>, producing a forwarder that cannotfind the host it was made for.
The change
Add
is_usable_mac()next tohosts_match()inSettings.hpp. It accepts aMAC only if it parses as hex and contains at least one nonzero digit, and it
tolerates the usual separators.
Use it at every site that was testing
!mac.empty()to mean "this identifiesa host":
hosts_match()merge_host()andSettings::add_host()host_key()andmerge_discovered_host()inGameStreamClient.cppDiscoverManager.cppforwarder_maker.cppnormalize_mac_address()inWakeOnLanManager.cpprejects the all zero caseas well, so
can_wake_up_host()stops advertising an action that cannot work,and the existing "Missing or invalid host MAC address" in
wake_up_host()becomes accurate rather than unreachable.
With no usable MAC, all of these fall through to the address based paths that
were already there, which is the behaviour hosts without a MAC field already
got.
The
mac.empty()checks inmain_args.cppare deliberately left alone. Thoseask whether the user supplied an argument at all, which is a different
question.
Testing
Settings.o,GameStreamClient.o,WakeOnLanManager.o,DiscoverManager.oandforwarder_maker.oall rebuilt and the NROproduced.
dash and bare forms, an ordinary MAC, a MAC with a leading zero octet, a
value whose only nonzero digit is last, the broadcast address, and non hex
input. All ten cases behave as intended.
On-console confirmation that the wake action now correctly disappears for a
Sunshine host reporting a null MAC is in progress, and I will report back.