Skip to content

Commit

Permalink
Only genenerate the random fallback MAC address once
Browse files Browse the repository at this point in the history
This avoids changing our hostname every time we restart advertising, in
scenarios where a real physical MAC is unavailable (e.g. on iOS).
  • Loading branch information
ksperling-apple committed Mar 24, 2024
1 parent f47d8d4 commit 41ba3d5
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 10 deletions.
32 changes: 22 additions & 10 deletions src/app/server/Dnssd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@
#include <setup_payload/SetupPayload.h>
#include <system/TimeSource.h>

#include <algorithm>

using namespace chip;
using namespace chip::DeviceLayer;

namespace chip {
namespace app {
namespace {
Expand Down Expand Up @@ -165,6 +170,21 @@ void DnssdServer::AddICDKeyToAdvertisement(AdvertisingParams & advParams)
}
#endif

void DnssdServer::GetPrimaryOrFallbackMACAddress(chip::MutableByteSpan mac)
{
if (ConfigurationMgr().GetPrimaryMACAddress(mac) != CHIP_NO_ERROR)
{
// Only generate a fallback "MAC" once, so we don't keep constantly changing our host name.
if (std::all_of(std::begin(mFallbackMAC), std::end(mFallbackMAC), [](uint8_t v) { return v == 0; }))
{
ChipLogError(Discovery, "Failed to get primary mac address of device. Generating a random one.");
Crypto::DRBG_get_bytes(mFallbackMAC, sizeof(mFallbackMAC));
}
VerifyOrDie(mac.size() == sizeof(mFallbackMAC)); // kPrimaryMACAddressLength
memcpy(mac.data(), mFallbackMAC, sizeof(mFallbackMAC));
}
}

/// Set MDNS operational advertisement
CHIP_ERROR DnssdServer::AdvertiseOperational()
{
Expand All @@ -179,11 +199,7 @@ CHIP_ERROR DnssdServer::AdvertiseOperational()

uint8_t macBuffer[DeviceLayer::ConfigurationManager::kPrimaryMACAddressLength];
MutableByteSpan mac(macBuffer);
if (chip::DeviceLayer::ConfigurationMgr().GetPrimaryMACAddress(mac) != CHIP_NO_ERROR)
{
ChipLogError(Discovery, "Failed to get primary mac address of device. Generating a random one.");
Crypto::DRBG_get_bytes(macBuffer, sizeof(macBuffer));
}
GetPrimaryOrFallbackMACAddress(mac);

auto advertiseParameters = chip::Dnssd::OperationalAdvertisingParameters()
.SetPeerId(fabricInfo.GetPeerId())
Expand Down Expand Up @@ -224,11 +240,7 @@ CHIP_ERROR DnssdServer::Advertise(bool commissionableNode, chip::Dnssd::Commissi

uint8_t macBuffer[DeviceLayer::ConfigurationManager::kPrimaryMACAddressLength];
MutableByteSpan mac(macBuffer);
if (chip::DeviceLayer::ConfigurationMgr().GetPrimaryMACAddress(mac) != CHIP_NO_ERROR)
{
ChipLogError(Discovery, "Failed to get primary mac address of device. Generating a random one.");
Crypto::DRBG_get_bytes(macBuffer, sizeof(macBuffer));
}
GetPrimaryOrFallbackMACAddress(mac);
advertiseParameters.SetMac(mac);

uint16_t value;
Expand Down
5 changes: 5 additions & 0 deletions src/app/server/Dnssd.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,11 @@ class DLL_EXPORT DnssdServer : public ICDStateObserver
/// Set MDNS commissionable node advertisement
CHIP_ERROR AdvertiseCommissionableNode(chip::Dnssd::CommissioningMode mode);

// Our randomly-generated fallback "MAC address", in case we don't have a real one.
uint8_t mFallbackMAC[chip::DeviceLayer::ConfigurationManager::kPrimaryMACAddressLength] = { 0 };

void GetPrimaryOrFallbackMACAddress(chip::MutableByteSpan mac);

//
// Check if we have any valid operational credentials present in the fabric table and return true
// if we do.
Expand Down

0 comments on commit 41ba3d5

Please sign in to comment.