23
23
#import < os/lock.h>
24
24
25
25
#include < lib/dnssd/ServiceNaming.h>
26
+ #include < lib/support/CodeUtils.h>
27
+ #include < vector>
26
28
27
29
@implementation MTRDeviceConnectivityMonitor {
28
30
NSString * _instanceName;
29
- DNSServiceRef _resolver ;
31
+ std::vector< DNSServiceRef> _resolvers ;
30
32
NSMutableDictionary <NSString *, nw_connection_t > * _connections;
31
33
32
34
MTRDeviceConnectivityMonitorHandler _monitorHandler;
33
35
dispatch_queue_t _handlerQueue;
34
36
}
35
37
36
38
namespace {
37
- constexpr char kLocalDot [] = " local." ;
39
+ constexpr const char * kResolveDomains [] = {
40
+ " default.service.arpa." , // SRP
41
+ " local." ,
42
+ };
38
43
constexpr char kOperationalType [] = " _matter._tcp" ;
39
44
constexpr int64_t kSharedConnectionLingerIntervalSeconds = (10 );
40
45
}
@@ -68,8 +73,8 @@ - (instancetype)initWithCompressedFabricID:(NSNumber *)compressedFabricID nodeID
68
73
69
74
- (void )dealloc
70
75
{
71
- if (_resolver ) {
72
- DNSServiceRefDeallocate (_resolver );
76
+ for ( auto & resolver : _resolvers ) {
77
+ DNSServiceRefDeallocate (resolver );
73
78
}
74
79
}
75
80
@@ -188,32 +193,39 @@ - (void)startMonitoringWithHandler:(MTRDeviceConnectivityMonitorHandler)handler
188
193
_handlerQueue = queue;
189
194
190
195
// If there's already a resolver running, just return
191
- if (_resolver ) {
196
+ if (_resolvers. size () != 0 ) {
192
197
MTR_LOG_INFO (" %@ connectivity monitor already running" , self);
193
198
return ;
194
199
}
195
200
196
201
MTR_LOG_INFO (" %@ start connectivity monitoring for %@ (%lu monitoring objects)" , self, _instanceName, static_cast <unsigned long >(sConnectivityMonitorCount ));
197
202
198
- _resolver = [MTRDeviceConnectivityMonitor _sharedResolverConnection ];
199
- if (!_resolver ) {
203
+ auto sharedConnection = [MTRDeviceConnectivityMonitor _sharedResolverConnection ];
204
+ if (!sharedConnection ) {
200
205
MTR_LOG_ERROR (" %@ failed to get shared resolver connection" , self);
201
206
return ;
202
207
}
203
- DNSServiceErrorType dnsError = DNSServiceResolve (&_resolver,
204
- kDNSServiceFlagsShareConnection ,
205
- kDNSServiceInterfaceIndexAny ,
206
- _instanceName.UTF8String ,
207
- kOperationalType ,
208
- kLocalDot ,
209
- ResolveCallback,
210
- (__bridge void *) self);
211
- if (dnsError != kDNSServiceErr_NoError ) {
212
- MTR_LOG_ERROR (" %@ failed to create resolver" , self);
213
- return ;
208
+
209
+ for (auto domain : kResolveDomains ) {
210
+ DNSServiceRef resolver = sharedConnection;
211
+ DNSServiceErrorType dnsError = DNSServiceResolve (&resolver,
212
+ kDNSServiceFlagsShareConnection ,
213
+ kDNSServiceInterfaceIndexAny ,
214
+ _instanceName.UTF8String ,
215
+ kOperationalType ,
216
+ domain,
217
+ ResolveCallback,
218
+ (__bridge void *) self);
219
+ if (dnsError == kDNSServiceErr_NoError ) {
220
+ _resolvers.emplace_back (std::move (resolver));
221
+ } else {
222
+ MTR_LOG_ERROR (" %@ failed to create resolver for \" %s\" domain: %" PRId32, self, StringOrNullMarker (domain), dnsError);
223
+ }
214
224
}
215
225
216
- sConnectivityMonitorCount ++;
226
+ if (_resolvers.size () != 0 ) {
227
+ sConnectivityMonitorCount ++;
228
+ }
217
229
}
218
230
219
231
- (void )_stopMonitoring
@@ -227,9 +239,11 @@ - (void)_stopMonitoring
227
239
_monitorHandler = nil ;
228
240
_handlerQueue = nil ;
229
241
230
- if (_resolver) {
231
- DNSServiceRefDeallocate (_resolver);
232
- _resolver = NULL ;
242
+ if (_resolvers.size () != 0 ) {
243
+ for (auto & resolver : _resolvers) {
244
+ DNSServiceRefDeallocate (resolver);
245
+ }
246
+ _resolvers.clear ();
233
247
234
248
// If no monitor objects exist, schedule to deallocate shared connection and queue
235
249
sConnectivityMonitorCount --;
0 commit comments