Skip to content

Commit

Permalink
Add support to browse and resolve on both local and SRP domain (proje…
Browse files Browse the repository at this point in the history
…ct-chip#32779)

* Add domain names matching the DnssdServices stored in Browse Context

This is needed to pass the domain returned from a call to Browse to the Resolve.

* Restyled by clang-format

* Add the domain names to the services vector

* Restyled by clang-format

* Add support to browse and resolve on both local and SRP domain

* Restyled by clang-format

* Fix the code that gets the domain name returned from browse and pass it into the resolve

* Restyled by clang-format

* Apply suggestions from code review

Co-authored-by: Boris Zbarsky <[email protected]>

* Address review comments

* Updated the comment about shouldStartSRPTimerForResolve

* Restyled by clang-format

* Apply suggestions from code review

Co-authored-by: Boris Zbarsky <[email protected]>

* Addressed more review comments

* Restyled by clang-format

* Add a null check for domain when erasing the contents of services

* Fix the check for domain name when erasing services and pass the correct ResolveContextWithType for the case where domain is not null during resolve

* Restyled by clang-format

---------

Co-authored-by: Restyled.io <[email protected]>
Co-authored-by: Boris Zbarsky <[email protected]>
  • Loading branch information
3 people authored Mar 30, 2024
1 parent e39cef5 commit 401fbf0
Show file tree
Hide file tree
Showing 3 changed files with 257 additions and 52 deletions.
83 changes: 58 additions & 25 deletions src/platform/Darwin/DnssdContexts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,6 @@ namespace {

constexpr uint8_t kDnssdKeyMaxSize = 32;
constexpr uint8_t kDnssdTxtRecordMaxEntries = 20;
constexpr char kLocalDot[] = "local.";

bool IsLocalDomain(const char * domain)
{
return strcmp(kLocalDot, domain) == 0;
}

std::string GetHostNameWithoutDomain(const char * hostnameWithDomain)
{
Expand Down Expand Up @@ -341,7 +335,8 @@ void RegisterContext::DispatchSuccess()
mHostNameRegistrar.Register();
}

BrowseContext * BrowseContext::sContextDispatchingSuccess = nullptr;
BrowseContext * BrowseContext::sContextDispatchingSuccess = nullptr;
std::vector<DnssdService> * BrowseContext::sDispatchedServices = nullptr;

BrowseContext::BrowseContext(void * cbContext, DnssdBrowseCallback cb, DnssdServiceProtocol cbContextProtocol)
{
Expand Down Expand Up @@ -373,7 +368,10 @@ void BrowseContext::DispatchPartialSuccess()
{
dnsServices.push_back(std::move(iter.first));
}

sDispatchedServices = &dnsServices;
callback(context, dnsServices.data(), dnsServices.size(), false, CHIP_NO_ERROR);
sDispatchedServices = nullptr;
sContextDispatchingSuccess = nullptr;
services.clear();
}
Expand All @@ -393,7 +391,6 @@ void BrowseContext::OnBrowseAdd(const char * name, const char * type, const char
ChipLogProgress(Discovery, "Mdns: %s name: %s, type: %s, domain: %s, interface: %" PRIu32, __func__, StringOrNullMarker(name),
StringOrNullMarker(type), StringOrNullMarker(domain), interfaceId);

VerifyOrReturn(IsLocalDomain(domain));
auto service = GetService(name, type, protocol, interfaceId);
services.push_back(std::make_pair(std::move(service), std::string(domain)));
}
Expand All @@ -404,13 +401,13 @@ void BrowseContext::OnBrowseRemove(const char * name, const char * type, const c
StringOrNullMarker(type), StringOrNullMarker(domain), interfaceId);

VerifyOrReturn(name != nullptr);
VerifyOrReturn(IsLocalDomain(domain));
std::string domain_str(domain);

services.erase(std::remove_if(services.begin(), services.end(),
[name, type, interfaceId, domain](const auto & service) {
[name, type, interfaceId, &domain_str](const auto & service) {
return strcmp(name, service.first.mName) == 0 && type == GetFullType(&service.first) &&
service.first.mInterface == chip::Inet::InterfaceId(interfaceId) &&
strcmp(domain, service.second.c_str()) == 0;
service.second == domain_str;
}),
services.end());
}
Expand Down Expand Up @@ -449,8 +446,6 @@ void BrowseWithDelegateContext::OnBrowseAdd(const char * name, const char * type
ChipLogProgress(Discovery, "Mdns: %s name: %s, type: %s, domain: %s, interface: %" PRIu32, __func__, StringOrNullMarker(name),
StringOrNullMarker(type), StringOrNullMarker(domain), interfaceId);

VerifyOrReturn(IsLocalDomain(domain));

auto delegate = static_cast<DnssdBrowseDelegate *>(context);
auto service = GetService(name, type, protocol, interfaceId);
delegate->OnBrowseAdd(service);
Expand All @@ -462,7 +457,6 @@ void BrowseWithDelegateContext::OnBrowseRemove(const char * name, const char * t
StringOrNullMarker(type), StringOrNullMarker(domain), interfaceId);

VerifyOrReturn(name != nullptr);
VerifyOrReturn(IsLocalDomain(domain));

auto delegate = static_cast<DnssdBrowseDelegate *>(context);
auto service = GetService(name, type, protocol, interfaceId);
Expand Down Expand Up @@ -494,7 +488,13 @@ ResolveContext::ResolveContext(CommissioningResolveDelegate * delegate, chip::In
consumerCounter = std::move(consumerCounterToUse);
}

ResolveContext::~ResolveContext() {}
ResolveContext::~ResolveContext()
{
if (isSRPTimerRunning)
{
CancelSRPTimer();
}
}

void ResolveContext::DispatchFailure(const char * errorStr, CHIP_ERROR err)
{
Expand Down Expand Up @@ -554,7 +554,8 @@ void ResolveContext::DispatchSuccess()

for (auto & interface : interfaces)
{
if (TryReportingResultsForInterfaceIndex(interface.first))
if (TryReportingResultsForInterfaceIndex(interface.first.interfaceId, interface.first.hostname,
interface.first.isSRPResult))
{
break;
}
Expand All @@ -566,16 +567,17 @@ void ResolveContext::DispatchSuccess()
}
}

bool ResolveContext::TryReportingResultsForInterfaceIndex(uint32_t interfaceIndex)
bool ResolveContext::TryReportingResultsForInterfaceIndex(uint32_t interfaceIndex, const std::string & hostname, bool isSRPResult)
{
if (interfaceIndex == 0)
{
// Not actually an interface we have.
return false;
}

auto & interface = interfaces[interfaceIndex];
auto & ips = interface.addresses;
InterfaceKey interfaceKey = { interfaceIndex, hostname, isSRPResult };
auto & interface = interfaces[interfaceKey];
auto & ips = interface.addresses;

// Some interface may not have any ips, just ignore them.
if (ips.size() == 0)
Expand All @@ -602,15 +604,45 @@ bool ResolveContext::TryReportingResultsForInterfaceIndex(uint32_t interfaceInde
return true;
}

CHIP_ERROR ResolveContext::OnNewAddress(uint32_t interfaceId, const struct sockaddr * address)
bool ResolveContext::TryReportingResultsForInterfaceIndex(uint32_t interfaceIndex)
{
for (auto & interface : interfaces)
{
if (interface.first.interfaceId == interfaceIndex)
{
if (TryReportingResultsForInterfaceIndex(interface.first.interfaceId, interface.first.hostname,
interface.first.isSRPResult))
{
return true;
}
}
}
return false;
}

void ResolveContext::SRPTimerExpiredCallback(chip::System::Layer * systemLayer, void * callbackContext)
{
auto sdCtx = static_cast<ResolveContext *>(callbackContext);
VerifyOrDie(sdCtx != nullptr);
sdCtx->Finalize();
}

void ResolveContext::CancelSRPTimer()
{
DeviceLayer::SystemLayer().CancelTimer(SRPTimerExpiredCallback, static_cast<void *>(this));
}

CHIP_ERROR ResolveContext::OnNewAddress(const InterfaceKey & interfaceKey, const struct sockaddr * address)
{
// If we don't have any information about this interfaceId, just ignore the
// address, since it won't be usable anyway without things like the port.
// This can happen if "local" is set up as a search domain in the DNS setup
// on the system, because the hostnames we are looking up all end in
// ".local". In other words, we can get regular DNS results in here, not
// just DNS-SD ones.
if (interfaces.find(interfaceId) == interfaces.end())
auto interfaceId = interfaceKey.interfaceId;

if (interfaces.find(interfaceKey) == interfaces.end())
{
return CHIP_NO_ERROR;
}
Expand All @@ -633,7 +665,7 @@ CHIP_ERROR ResolveContext::OnNewAddress(uint32_t interfaceId, const struct socka
return CHIP_NO_ERROR;
}

interfaces[interfaceId].addresses.push_back(ip);
interfaces[interfaceKey].addresses.push_back(ip);

return CHIP_NO_ERROR;
}
Expand All @@ -652,7 +684,7 @@ bool ResolveContext::HasAddress()
}

void ResolveContext::OnNewInterface(uint32_t interfaceId, const char * fullname, const char * hostnameWithDomain, uint16_t port,
uint16_t txtLen, const unsigned char * txtRecord)
uint16_t txtLen, const unsigned char * txtRecord, bool isFromSRPResolve)
{
#if CHIP_PROGRESS_LOGGING
std::string txtString;
Expand Down Expand Up @@ -715,7 +747,8 @@ void ResolveContext::OnNewInterface(uint32_t interfaceId, const char * fullname,
// resolving.
interface.fullyQualifiedDomainName = hostnameWithDomain;

interfaces.insert(std::make_pair(interfaceId, std::move(interface)));
InterfaceKey interfaceKey = { interfaceId, hostnameWithDomain, isFromSRPResolve };
interfaces.insert(std::make_pair(std::move(interfaceKey), std::move(interface)));
}

bool ResolveContext::HasInterface()
Expand All @@ -731,7 +764,7 @@ InterfaceInfo::InterfaceInfo()

InterfaceInfo::InterfaceInfo(InterfaceInfo && other) :
service(std::move(other.service)), addresses(std::move(other.addresses)),
fullyQualifiedDomainName(std::move(other.fullyQualifiedDomainName))
fullyQualifiedDomainName(std::move(other.fullyQualifiedDomainName)), isDNSLookUpRequested(other.isDNSLookUpRequested)
{
// Make sure we're not trying to free any state from the other DnssdService,
// since we took over ownership of its allocated bits.
Expand Down
Loading

0 comments on commit 401fbf0

Please sign in to comment.