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