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,