Matter.framework should explicitly look for things in the SRP domain. (#33319)
The operational browse and connectivity monitoring in Matter.framework should
happen on both the SRP domain and the default domain, so we are sure we'll
notice Thread devices properly.
diff --git a/src/darwin/Framework/CHIP/MTRDeviceConnectivityMonitor.mm b/src/darwin/Framework/CHIP/MTRDeviceConnectivityMonitor.mm
index 38c73b6..0d65304 100644
--- a/src/darwin/Framework/CHIP/MTRDeviceConnectivityMonitor.mm
+++ b/src/darwin/Framework/CHIP/MTRDeviceConnectivityMonitor.mm
@@ -23,10 +23,12 @@
#import <os/lock.h>
#include <lib/dnssd/ServiceNaming.h>
+#include <lib/support/CodeUtils.h>
+#include <vector>
@implementation MTRDeviceConnectivityMonitor {
NSString * _instanceName;
- DNSServiceRef _resolver;
+ std::vector<DNSServiceRef> _resolvers;
NSMutableDictionary<NSString *, nw_connection_t> * _connections;
MTRDeviceConnectivityMonitorHandler _monitorHandler;
@@ -34,7 +36,10 @@
}
namespace {
-constexpr char kLocalDot[] = "local.";
+constexpr const char * kResolveDomains[] = {
+ "default.service.arpa.", // SRP
+ "local.",
+};
constexpr char kOperationalType[] = "_matter._tcp";
constexpr int64_t kSharedConnectionLingerIntervalSeconds = (10);
}
@@ -68,8 +73,8 @@
- (void)dealloc
{
- if (_resolver) {
- DNSServiceRefDeallocate(_resolver);
+ for (auto & resolver : _resolvers) {
+ DNSServiceRefDeallocate(resolver);
}
}
@@ -188,32 +193,39 @@
_handlerQueue = queue;
// If there's already a resolver running, just return
- if (_resolver) {
+ if (_resolvers.size() != 0) {
MTR_LOG_INFO("%@ connectivity monitor already running", self);
return;
}
MTR_LOG_INFO("%@ start connectivity monitoring for %@ (%lu monitoring objects)", self, _instanceName, static_cast<unsigned long>(sConnectivityMonitorCount));
- _resolver = [MTRDeviceConnectivityMonitor _sharedResolverConnection];
- if (!_resolver) {
+ auto sharedConnection = [MTRDeviceConnectivityMonitor _sharedResolverConnection];
+ if (!sharedConnection) {
MTR_LOG_ERROR("%@ failed to get shared resolver connection", self);
return;
}
- DNSServiceErrorType dnsError = DNSServiceResolve(&_resolver,
- kDNSServiceFlagsShareConnection,
- kDNSServiceInterfaceIndexAny,
- _instanceName.UTF8String,
- kOperationalType,
- kLocalDot,
- ResolveCallback,
- (__bridge void *) self);
- if (dnsError != kDNSServiceErr_NoError) {
- MTR_LOG_ERROR("%@ failed to create resolver", self);
- return;
+
+ for (auto domain : kResolveDomains) {
+ DNSServiceRef resolver = sharedConnection;
+ DNSServiceErrorType dnsError = DNSServiceResolve(&resolver,
+ kDNSServiceFlagsShareConnection,
+ kDNSServiceInterfaceIndexAny,
+ _instanceName.UTF8String,
+ kOperationalType,
+ domain,
+ ResolveCallback,
+ (__bridge void *) self);
+ if (dnsError == kDNSServiceErr_NoError) {
+ _resolvers.emplace_back(std::move(resolver));
+ } else {
+ MTR_LOG_ERROR("%@ failed to create resolver for \"%s\" domain: %" PRId32, self, StringOrNullMarker(domain), dnsError);
+ }
}
- sConnectivityMonitorCount++;
+ if (_resolvers.size() != 0) {
+ sConnectivityMonitorCount++;
+ }
}
- (void)_stopMonitoring
@@ -227,9 +239,11 @@
_monitorHandler = nil;
_handlerQueue = nil;
- if (_resolver) {
- DNSServiceRefDeallocate(_resolver);
- _resolver = NULL;
+ if (_resolvers.size() != 0) {
+ for (auto & resolver : _resolvers) {
+ DNSServiceRefDeallocate(resolver);
+ }
+ _resolvers.clear();
// If no monitor objects exist, schedule to deallocate shared connection and queue
sConnectivityMonitorCount--;
diff --git a/src/darwin/Framework/CHIP/MTROperationalBrowser.mm b/src/darwin/Framework/CHIP/MTROperationalBrowser.mm
index 689bab9..1ddc786 100644
--- a/src/darwin/Framework/CHIP/MTROperationalBrowser.mm
+++ b/src/darwin/Framework/CHIP/MTROperationalBrowser.mm
@@ -21,13 +21,16 @@
#include <cinttypes>
#include <lib/dnssd/ServiceNaming.h>
+#include <lib/support/CodeUtils.h>
#include <lib/support/logging/CHIPLogging.h>
#include <platform/LockTracker.h>
namespace {
-constexpr char kLocalDot[] = "local.";
+constexpr const char * kBrowseDomains[] = {
+ "default.service.arpa.", // SRP
+ "local.",
+};
constexpr char kOperationalType[] = "_matter._tcp";
-constexpr DNSServiceFlags kBrowseFlags = 0;
}
MTROperationalBrowser::MTROperationalBrowser(MTRDeviceControllerFactory * aFactory, dispatch_queue_t aQueue)
@@ -43,23 +46,30 @@
{
assertChipStackLockedByCurrentThread();
- ChipLogProgress(Controller, "Trying to start operational browse");
+ ChipLogProgress(Controller, "Trying to start persistent operational browse");
- auto err
- = DNSServiceBrowse(&mBrowseRef, kBrowseFlags, kDNSServiceInterfaceIndexAny, kOperationalType, kLocalDot, OnBrowse, this);
+ auto err = DNSServiceCreateConnection(&mBrowseRef);
if (err != kDNSServiceErr_NoError) {
- ChipLogError(Controller, "Failed to start operational browse: %" PRId32, err);
+ ChipLogError(Controller, "Failed to create connection for persistent operational browse: %" PRId32, err);
return;
}
err = DNSServiceSetDispatchQueue(mBrowseRef, mQueue);
if (err != kDNSServiceErr_NoError) {
- ChipLogError(Controller, "Failed to set up dispatch queue properly");
+ ChipLogError(Controller, "Failed to set up dispatch queue properly for persistent operational browse: %" PRId32, err);
DNSServiceRefDeallocate(mBrowseRef);
return;
}
mInitialized = true;
+
+ for (auto domain : kBrowseDomains) {
+ auto browseRef = mBrowseRef; // Mandatory copy because of kDNSServiceFlagsShareConnection.
+ err = DNSServiceBrowse(&browseRef, kDNSServiceFlagsShareConnection, kDNSServiceInterfaceIndexAny, kOperationalType, domain, OnBrowse, this);
+ if (err != kDNSServiceErr_NoError) {
+ ChipLogError(Controller, "Failed to start persistent operational browse for \"%s\" domain: %" PRId32, StringOrNullMarker(domain), err);
+ }
+ }
}
void MTROperationalBrowser::OnBrowse(DNSServiceRef aServiceRef, DNSServiceFlags aFlags, uint32_t aInterfaceId,