From b896698909502ad42e4e1277220aebaf4a5a6f51 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Mon, 6 May 2024 15:07:56 -0400 Subject: [PATCH] Matter.framework should explicitly look for things in the SRP domain. 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. --- .../CHIP/MTRDeviceConnectivityMonitor.mm | 58 ++++++++++++------- .../Framework/CHIP/MTROperationalBrowser.mm | 24 +++++--- 2 files changed, 53 insertions(+), 29 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRDeviceConnectivityMonitor.mm b/src/darwin/Framework/CHIP/MTRDeviceConnectivityMonitor.mm index 38c73b63a899d3..0d65304c843d04 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceConnectivityMonitor.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceConnectivityMonitor.mm @@ -23,10 +23,12 @@ #import #include +#include +#include @implementation MTRDeviceConnectivityMonitor { NSString * _instanceName; - DNSServiceRef _resolver; + std::vector _resolvers; NSMutableDictionary * _connections; MTRDeviceConnectivityMonitorHandler _monitorHandler; @@ -34,7 +36,10 @@ @implementation MTRDeviceConnectivityMonitor { } 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 @@ - (instancetype)initWithCompressedFabricID:(NSNumber *)compressedFabricID nodeID - (void)dealloc { - if (_resolver) { - DNSServiceRefDeallocate(_resolver); + for (auto & resolver : _resolvers) { + DNSServiceRefDeallocate(resolver); } } @@ -188,32 +193,39 @@ - (void)startMonitoringWithHandler:(MTRDeviceConnectivityMonitorHandler)handler _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(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 @@ - (void)_stopMonitoring _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 689bab9376fd01..1ddc7868d88ecc 100644 --- a/src/darwin/Framework/CHIP/MTROperationalBrowser.mm +++ b/src/darwin/Framework/CHIP/MTROperationalBrowser.mm @@ -21,13 +21,16 @@ #include #include +#include #include #include 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,