1 /*
2 * Copyright (c) 2023, The OpenThread Authors.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. Neither the name of the copyright holder nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 /**
30 * @file
31 * This file implements infrastructure DNS-SD module.
32 */
33
34 #include "dnssd.hpp"
35
36 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE || OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
37
38 #include "instance/instance.hpp"
39
40 namespace ot {
41
42 //---------------------------------------------------------------------------------------------------------------------
43 // Dnssd::RequestIdRange
44
Add(RequestId aId)45 void Dnssd::RequestIdRange::Add(RequestId aId)
46 {
47 if (IsEmpty())
48 {
49 mStart = aId;
50 mEnd = aId + 1;
51 }
52 else if (SerialNumber::IsLess(aId, mStart)) // Equivalent to (aId < mStart)
53 {
54 mStart = aId;
55 }
56 else if (!SerialNumber::IsLess(aId, mEnd)) // Equivalent to !(aId < mEd) -> (aId >= mEnd)
57 {
58 mEnd = aId + 1;
59 }
60 }
61
Remove(RequestId aId)62 void Dnssd::RequestIdRange::Remove(RequestId aId)
63 {
64 if (!IsEmpty())
65 {
66 if (aId == mStart)
67 {
68 mStart++;
69 }
70 else if (aId + 1 == mEnd)
71 {
72 mEnd--;
73 }
74 }
75 }
76
Contains(RequestId aId) const77 bool Dnssd::RequestIdRange::Contains(RequestId aId) const
78 {
79 // Equivalent to `(aId >= mStart) && (aId < mEnd)`
80
81 return (!SerialNumber::IsLess(aId, mStart) && SerialNumber::IsLess(aId, mEnd));
82 }
83
84 //---------------------------------------------------------------------------------------------------------------------
85 // Dnssd
86
Dnssd(Instance & aInstance)87 Dnssd::Dnssd(Instance &aInstance)
88 : InstanceLocator(aInstance)
89 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ALLOW_RUN_TIME_SELECTION
90 , mUseNativeMdns(true)
91 #endif
92 {
93 }
94
GetState(void) const95 Dnssd::State Dnssd::GetState(void) const
96 {
97 State state;
98
99 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ALLOW_RUN_TIME_SELECTION
100 if (mUseNativeMdns)
101 #endif
102 #if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
103 {
104 state = Get<Dns::Multicast::Core>().IsEnabled() ? kReady : kStopped;
105 ExitNow();
106 }
107 #endif
108
109 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
110 state = MapEnum(otPlatDnssdGetState(&GetInstance()));
111 ExitNow();
112 #endif
113
114 exit:
115 return state;
116 }
117
RegisterService(const Service & aService,RequestId aRequestId,RegisterCallback aCallback)118 void Dnssd::RegisterService(const Service &aService, RequestId aRequestId, RegisterCallback aCallback)
119 {
120 VerifyOrExit(IsReady());
121
122 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ALLOW_RUN_TIME_SELECTION
123 if (mUseNativeMdns)
124 #endif
125 #if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
126 {
127 IgnoreError(Get<Dns::Multicast::Core>().RegisterService(aService, aRequestId, aCallback));
128 ExitNow();
129 }
130 #endif
131
132 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
133 otPlatDnssdRegisterService(&GetInstance(), &aService, aRequestId, aCallback);
134 #endif
135
136 exit:
137 return;
138 }
139
UnregisterService(const Service & aService,RequestId aRequestId,RegisterCallback aCallback)140 void Dnssd::UnregisterService(const Service &aService, RequestId aRequestId, RegisterCallback aCallback)
141 {
142 VerifyOrExit(IsReady());
143
144 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ALLOW_RUN_TIME_SELECTION
145 if (mUseNativeMdns)
146 #endif
147 #if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
148 {
149 IgnoreError(Get<Dns::Multicast::Core>().UnregisterService(aService));
150 VerifyOrExit(aCallback != nullptr);
151 aCallback(&GetInstance(), aRequestId, kErrorNone);
152 ExitNow();
153 }
154 #endif
155
156 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
157 otPlatDnssdUnregisterService(&GetInstance(), &aService, aRequestId, aCallback);
158 #endif
159
160 exit:
161 return;
162 }
163
RegisterHost(const Host & aHost,RequestId aRequestId,RegisterCallback aCallback)164 void Dnssd::RegisterHost(const Host &aHost, RequestId aRequestId, RegisterCallback aCallback)
165 {
166 VerifyOrExit(IsReady());
167
168 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ALLOW_RUN_TIME_SELECTION
169 if (mUseNativeMdns)
170 #endif
171 #if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
172 {
173 IgnoreError(Get<Dns::Multicast::Core>().RegisterHost(aHost, aRequestId, aCallback));
174 ExitNow();
175 }
176 #endif
177
178 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
179 otPlatDnssdRegisterHost(&GetInstance(), &aHost, aRequestId, aCallback);
180 #endif
181
182 exit:
183 return;
184 }
185
UnregisterHost(const Host & aHost,RequestId aRequestId,RegisterCallback aCallback)186 void Dnssd::UnregisterHost(const Host &aHost, RequestId aRequestId, RegisterCallback aCallback)
187 {
188 VerifyOrExit(IsReady());
189
190 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ALLOW_RUN_TIME_SELECTION
191 if (mUseNativeMdns)
192 #endif
193 #if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
194 {
195 IgnoreError(Get<Dns::Multicast::Core>().UnregisterHost(aHost));
196 VerifyOrExit(aCallback != nullptr);
197 aCallback(&GetInstance(), aRequestId, kErrorNone);
198 ExitNow();
199 }
200 #endif
201
202 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
203 otPlatDnssdUnregisterHost(&GetInstance(), &aHost, aRequestId, aCallback);
204 #endif
205
206 exit:
207 return;
208 }
209
RegisterKey(const Key & aKey,RequestId aRequestId,RegisterCallback aCallback)210 void Dnssd::RegisterKey(const Key &aKey, RequestId aRequestId, RegisterCallback aCallback)
211 {
212 VerifyOrExit(IsReady());
213
214 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ALLOW_RUN_TIME_SELECTION
215 if (mUseNativeMdns)
216 #endif
217 #if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
218 {
219 IgnoreError(Get<Dns::Multicast::Core>().RegisterKey(aKey, aRequestId, aCallback));
220 ExitNow();
221 }
222 #endif
223
224 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
225 otPlatDnssdRegisterKey(&GetInstance(), &aKey, aRequestId, aCallback);
226 #endif
227
228 exit:
229 return;
230 }
231
UnregisterKey(const Key & aKey,RequestId aRequestId,RegisterCallback aCallback)232 void Dnssd::UnregisterKey(const Key &aKey, RequestId aRequestId, RegisterCallback aCallback)
233 {
234 VerifyOrExit(IsReady());
235
236 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ALLOW_RUN_TIME_SELECTION
237 if (mUseNativeMdns)
238 #endif
239 #if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
240 {
241 IgnoreError(Get<Dns::Multicast::Core>().UnregisterKey(aKey));
242 VerifyOrExit(aCallback != nullptr);
243 aCallback(&GetInstance(), aRequestId, kErrorNone);
244 ExitNow();
245 }
246 #endif
247
248 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
249 otPlatDnssdUnregisterKey(&GetInstance(), &aKey, aRequestId, aCallback);
250 #endif
251
252 exit:
253 return;
254 }
255
StartBrowser(const Browser & aBrowser)256 void Dnssd::StartBrowser(const Browser &aBrowser)
257 {
258 VerifyOrExit(IsReady());
259
260 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ALLOW_RUN_TIME_SELECTION
261 if (mUseNativeMdns)
262 #endif
263 #if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
264 {
265 IgnoreError(Get<Dns::Multicast::Core>().StartBrowser(aBrowser));
266 ExitNow();
267 }
268 #endif
269
270 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
271 otPlatDnssdStartBrowser(&GetInstance(), &aBrowser);
272 #endif
273
274 exit:
275 return;
276 }
277
StopBrowser(const Browser & aBrowser)278 void Dnssd::StopBrowser(const Browser &aBrowser)
279 {
280 VerifyOrExit(IsReady());
281
282 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ALLOW_RUN_TIME_SELECTION
283 if (mUseNativeMdns)
284 #endif
285 #if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
286 {
287 IgnoreError(Get<Dns::Multicast::Core>().StopBrowser(aBrowser));
288 ExitNow();
289 }
290 #endif
291
292 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
293 otPlatDnssdStopBrowser(&GetInstance(), &aBrowser);
294 #endif
295
296 exit:
297 return;
298 }
299
StartSrvResolver(const SrvResolver & aResolver)300 void Dnssd::StartSrvResolver(const SrvResolver &aResolver)
301 {
302 VerifyOrExit(IsReady());
303
304 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ALLOW_RUN_TIME_SELECTION
305 if (mUseNativeMdns)
306 #endif
307 #if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
308 {
309 IgnoreError(Get<Dns::Multicast::Core>().StartSrvResolver(aResolver));
310 ExitNow();
311 }
312 #endif
313
314 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
315 otPlatDnssdStartSrvResolver(&GetInstance(), &aResolver);
316 #endif
317
318 exit:
319 return;
320 }
321
StopSrvResolver(const SrvResolver & aResolver)322 void Dnssd::StopSrvResolver(const SrvResolver &aResolver)
323 {
324 VerifyOrExit(IsReady());
325
326 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ALLOW_RUN_TIME_SELECTION
327 if (mUseNativeMdns)
328 #endif
329 #if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
330 {
331 IgnoreError(Get<Dns::Multicast::Core>().StopSrvResolver(aResolver));
332 ExitNow();
333 }
334 #endif
335
336 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
337 otPlatDnssdStopSrvResolver(&GetInstance(), &aResolver);
338 #endif
339
340 exit:
341 return;
342 }
343
StartTxtResolver(const TxtResolver & aResolver)344 void Dnssd::StartTxtResolver(const TxtResolver &aResolver)
345 {
346 VerifyOrExit(IsReady());
347
348 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ALLOW_RUN_TIME_SELECTION
349 if (mUseNativeMdns)
350 #endif
351 #if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
352 {
353 IgnoreError(Get<Dns::Multicast::Core>().StartTxtResolver(aResolver));
354 ExitNow();
355 }
356 #endif
357
358 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
359 otPlatDnssdStartTxtResolver(&GetInstance(), &aResolver);
360 #endif
361
362 exit:
363 return;
364 }
365
StopTxtResolver(const TxtResolver & aResolver)366 void Dnssd::StopTxtResolver(const TxtResolver &aResolver)
367 {
368 VerifyOrExit(IsReady());
369
370 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ALLOW_RUN_TIME_SELECTION
371 if (mUseNativeMdns)
372 #endif
373 #if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
374 {
375 IgnoreError(Get<Dns::Multicast::Core>().StopTxtResolver(aResolver));
376 ExitNow();
377 }
378 #endif
379
380 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
381 otPlatDnssdStopTxtResolver(&GetInstance(), &aResolver);
382 #endif
383
384 exit:
385 return;
386 }
387
StartIp6AddressResolver(const AddressResolver & aResolver)388 void Dnssd::StartIp6AddressResolver(const AddressResolver &aResolver)
389 {
390 VerifyOrExit(IsReady());
391
392 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ALLOW_RUN_TIME_SELECTION
393 if (mUseNativeMdns)
394 #endif
395 #if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
396 {
397 IgnoreError(Get<Dns::Multicast::Core>().StartIp6AddressResolver(aResolver));
398 ExitNow();
399 }
400 #endif
401
402 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
403 otPlatDnssdStartIp6AddressResolver(&GetInstance(), &aResolver);
404 #endif
405
406 exit:
407 return;
408 }
409
StopIp6AddressResolver(const AddressResolver & aResolver)410 void Dnssd::StopIp6AddressResolver(const AddressResolver &aResolver)
411 {
412 VerifyOrExit(IsReady());
413
414 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ALLOW_RUN_TIME_SELECTION
415 if (mUseNativeMdns)
416 #endif
417 #if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
418 {
419 IgnoreError(Get<Dns::Multicast::Core>().StopIp6AddressResolver(aResolver));
420 ExitNow();
421 }
422 #endif
423
424 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
425 otPlatDnssdStopIp6AddressResolver(&GetInstance(), &aResolver);
426 #endif
427
428 exit:
429 return;
430 }
431
StartIp4AddressResolver(const AddressResolver & aResolver)432 void Dnssd::StartIp4AddressResolver(const AddressResolver &aResolver)
433 {
434 VerifyOrExit(IsReady());
435
436 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ALLOW_RUN_TIME_SELECTION
437 if (mUseNativeMdns)
438 #endif
439 #if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
440 {
441 IgnoreError(Get<Dns::Multicast::Core>().StartIp4AddressResolver(aResolver));
442 ExitNow();
443 }
444 #endif
445
446 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
447 otPlatDnssdStartIp4AddressResolver(&GetInstance(), &aResolver);
448 #endif
449
450 exit:
451 return;
452 }
453
StopIp4AddressResolver(const AddressResolver & aResolver)454 void Dnssd::StopIp4AddressResolver(const AddressResolver &aResolver)
455 {
456 VerifyOrExit(IsReady());
457
458 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ALLOW_RUN_TIME_SELECTION
459 if (mUseNativeMdns)
460 #endif
461 #if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
462 {
463 IgnoreError(Get<Dns::Multicast::Core>().StopIp4AddressResolver(aResolver));
464 ExitNow();
465 }
466 #endif
467
468 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
469 otPlatDnssdStopIp4AddressResolver(&GetInstance(), &aResolver);
470 #endif
471
472 exit:
473 return;
474 }
475
HandleStateChange(void)476 void Dnssd::HandleStateChange(void)
477 {
478 #if OPENTHREAD_CONFIG_SRP_SERVER_ADVERTISING_PROXY_ENABLE
479 Get<Srp::AdvertisingProxy>().HandleDnssdPlatformStateChange();
480 #endif
481
482 #if OPENTHREAD_CONFIG_DNSSD_SERVER_ENABLE && OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE
483 Get<Dns::ServiceDiscovery::Server>().HandleDnssdPlatformStateChange();
484 #endif
485 }
486
487 #if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
HandleMdnsCoreStateChange(void)488 void Dnssd::HandleMdnsCoreStateChange(void)
489 {
490 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ALLOW_RUN_TIME_SELECTION
491 if (mUseNativeMdns)
492 #endif
493 {
494 HandleStateChange();
495 }
496 }
497 #endif
498
499 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
otPlatDnssdStateHandleStateChange(otInstance * aInstance)500 extern "C" void otPlatDnssdStateHandleStateChange(otInstance *aInstance)
501 {
502 AsCoreType(aInstance).Get<Dnssd>().HandleStateChange();
503 }
504 #endif
505
506 } // namespace ot
507
508 #endif // OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE || OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
509