1 /* 2 * Copyright (c) 2021, 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 #ifndef DNS_SERVER_HPP_ 30 #define DNS_SERVER_HPP_ 31 32 #include "openthread-core-config.h" 33 34 #if OPENTHREAD_CONFIG_DNSSD_SERVER_ENABLE 35 36 #if OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE 37 38 #if !OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE && !OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE 39 #error "OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE requires either PLATFORM_DNSSD_ENABLE or MULTICAST_DNS_ENABLE" 40 #endif 41 #if !OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE 42 #error "OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE requires OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE" 43 #endif 44 45 #endif // OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE 46 47 #include <openthread/dnssd_server.h> 48 49 #include "border_router/infra_if.hpp" 50 #include "common/as_core_type.hpp" 51 #include "common/callback.hpp" 52 #include "common/equatable.hpp" 53 #include "common/message.hpp" 54 #include "common/non_copyable.hpp" 55 #include "common/owned_ptr.hpp" 56 #include "common/timer.hpp" 57 #include "net/dns_types.hpp" 58 #include "net/dnssd.hpp" 59 #include "net/ip6.hpp" 60 #include "net/netif.hpp" 61 #include "net/srp_server.hpp" 62 63 /** 64 * @file 65 * This file includes definitions for the DNS-SD server. 66 */ 67 68 struct otPlatDnsUpstreamQuery 69 { 70 }; 71 72 namespace ot { 73 74 namespace Srp { 75 class Server; 76 } 77 78 namespace Dns { 79 namespace ServiceDiscovery { 80 81 /** 82 * Implements DNS-SD server. 83 * 84 */ 85 class Server : public InstanceLocator, private NonCopyable 86 { 87 friend class Srp::Server; 88 #if OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE 89 friend class ot::Dnssd; 90 friend class ot::BorderRouter::InfraIf; 91 #endif 92 93 public: 94 /** 95 * Contains the counters of the DNS-SD server. 96 * 97 */ 98 class Counters : public otDnssdCounters, public Clearable<Counters> 99 { 100 public: 101 /** 102 * Returns the total number of processed queries (successful or failed responses). 103 * 104 * @return The total number of queries. 105 * 106 */ GetTotalQueries(void) const107 uint32_t GetTotalQueries(void) const { return mSuccessResponse + GetTotalFailedQueries(); } 108 109 /** 110 * Returns the total number of failed queries (any error response code). 111 * 112 * @return The total number of failed queries. 113 * 114 */ GetTotalFailedQueries(void) const115 uint32_t GetTotalFailedQueries(void) const 116 { 117 return mServerFailureResponse + mFormatErrorResponse + mNameErrorResponse + mNotImplementedResponse + 118 mOtherResponse; 119 } 120 }; 121 122 #if OPENTHREAD_CONFIG_DNS_UPSTREAM_QUERY_ENABLE 123 /** 124 * Represents an upstream query transaction. The methods should only be used by 125 * `Dns::ServiceDiscovery::Server`. 126 * 127 */ 128 class UpstreamQueryTransaction : public otPlatDnsUpstreamQuery 129 { 130 public: 131 /** 132 * Returns whether the transaction is valid. 133 * 134 * @retval TRUE The transaction is valid. 135 * @retval FALSE The transaction is not valid. 136 * 137 */ IsValid(void) const138 bool IsValid(void) const { return mValid; } 139 140 /** 141 * Returns the time when the transaction expires. 142 * 143 * @returns The expire time of the transaction. 144 * 145 */ GetExpireTime(void) const146 TimeMilli GetExpireTime(void) const { return mExpireTime; } 147 148 /** 149 * Resets the transaction with a reason. The transaction will be invalid and can be reused for 150 * another upstream query after this call. 151 * 152 */ Reset(void)153 void Reset(void) { mValid = false; } 154 155 /** 156 * Initializes the transaction. 157 * 158 * @param[in] aMessageInfo The IP message info of the query. 159 * 160 */ 161 void Init(const Ip6::MessageInfo &aMessageInfo); 162 163 /** 164 * Returns the message info of the query. 165 * 166 * @returns The message info of the query. 167 * 168 */ GetMessageInfo(void) const169 const Ip6::MessageInfo &GetMessageInfo(void) const { return mMessageInfo; } 170 171 private: 172 Ip6::MessageInfo mMessageInfo; 173 TimeMilli mExpireTime; 174 bool mValid; 175 }; 176 #endif 177 178 /** 179 * Specifies a DNS-SD query type. 180 * 181 */ 182 enum DnsQueryType : uint8_t 183 { 184 kDnsQueryNone = OT_DNSSD_QUERY_TYPE_NONE, ///< Service type unspecified. 185 kDnsQueryBrowse = OT_DNSSD_QUERY_TYPE_BROWSE, ///< Service type browse service. 186 kDnsQueryResolve = OT_DNSSD_QUERY_TYPE_RESOLVE, ///< Service type resolve service instance. 187 kDnsQueryResolveHost = OT_DNSSD_QUERY_TYPE_RESOLVE_HOST, ///< Service type resolve hostname. 188 }; 189 190 typedef otDnssdServiceInstanceInfo ServiceInstanceInfo; ///< A discovered service instance for a DNS-SD query. 191 typedef otDnssdHostInfo HostInfo; ///< A discover host for a DNS-SD query. 192 193 typedef otDnssdQuerySubscribeCallback SubscribeCallback; 194 typedef otDnssdQueryUnsubscribeCallback UnsubscribeCallback; 195 196 static constexpr uint16_t kPort = OPENTHREAD_CONFIG_DNSSD_SERVER_PORT; ///< The DNS-SD server port. 197 198 /** 199 * Initializes the object. 200 * 201 * @param[in] aInstance A reference to the OpenThread instance. 202 * 203 */ 204 explicit Server(Instance &aInstance); 205 206 /** 207 * Starts the DNS-SD server. 208 * 209 * @retval kErrorNone Successfully started the DNS-SD server. 210 * @retval kErrorFailed If failed to open or bind the UDP socket. 211 * 212 */ 213 Error Start(void); 214 215 /** 216 * Stops the DNS-SD server. 217 * 218 */ 219 void Stop(void); 220 221 /** 222 * Sets DNS-SD query callbacks. 223 * 224 * @param[in] aSubscribe A pointer to the callback function to subscribe a service or service instance. 225 * @param[in] aUnsubscribe A pointer to the callback function to unsubscribe a service or service instance. 226 * @param[in] aContext A pointer to the application-specific context. 227 * 228 */ 229 void SetQueryCallbacks(SubscribeCallback aSubscribe, UnsubscribeCallback aUnsubscribe, void *aContext); 230 231 /** 232 * Notifies a discovered service instance. 233 * 234 * @param[in] aServiceFullName The null-terminated full service name. 235 * @param[in] aInstanceInfo A reference to the discovered service instance information. 236 * 237 */ 238 void HandleDiscoveredServiceInstance(const char *aServiceFullName, const ServiceInstanceInfo &aInstanceInfo); 239 240 #if OPENTHREAD_CONFIG_DNS_UPSTREAM_QUERY_ENABLE 241 /** 242 * Notifies an answer of an upstream DNS query. 243 * 244 * The Transaction will be released. 245 * 246 * @param[in] aQueryTransaction A reference to upstream DNS query transaction. 247 * @param[in] aResponseMessage A pointer to response UDP message, should be allocated from Udp::NewMessage. 248 * Passing a nullptr means close the transaction without a response. 249 * 250 */ 251 void OnUpstreamQueryDone(UpstreamQueryTransaction &aQueryTransaction, Message *aResponseMessage); 252 253 /** 254 * Indicates whether the server will forward DNS queries to platform DNS upstream API. 255 * 256 * @retval TRUE If the server will forward DNS queries. 257 * @retval FALSE If the server will not forward DNS queries. 258 * 259 */ IsUpstreamQueryEnabled(void) const260 bool IsUpstreamQueryEnabled(void) const { return mEnableUpstreamQuery; } 261 262 /** 263 * Enables or disables forwarding DNS queries to platform DNS upstream API. 264 * 265 * @param[in] aEnabled A boolean to enable/disable forwarding DNS queries to upstream. 266 * 267 */ SetUpstreamQueryEnabled(bool aEnabled)268 void SetUpstreamQueryEnabled(bool aEnabled) { mEnableUpstreamQuery = aEnabled; } 269 #endif // OPENTHREAD_CONFIG_DNS_UPSTREAM_QUERY_ENABLE 270 271 /** 272 * Notifies a discovered host. 273 * 274 * @param[in] aHostFullName The null-terminated full host name. 275 * @param[in] aHostInfo A reference to the discovered host information. 276 * 277 */ 278 void HandleDiscoveredHost(const char *aHostFullName, const HostInfo &aHostInfo); 279 280 /** 281 * Acquires the next query in the server. 282 * 283 * @param[in] aQuery The query pointer. Pass `nullptr` to get the first query. 284 * 285 * @returns A pointer to the query or `nullptr` if no more queries. 286 * 287 */ 288 const otDnssdQuery *GetNextQuery(const otDnssdQuery *aQuery) const; 289 290 /** 291 * Acquires the DNS-SD query type and name for a specific query. 292 * 293 * @param[in] aQuery The query pointer. 294 * @param[out] aName The name output buffer. 295 * 296 * @returns The DNS-SD query type. 297 * 298 */ 299 static DnsQueryType GetQueryTypeAndName(const otDnssdQuery *aQuery, Dns::Name::Buffer &aName); 300 301 /** 302 * Returns the counters of the DNS-SD server. 303 * 304 * @returns A reference to the `Counters` instance. 305 * 306 */ GetCounters(void) const307 const Counters &GetCounters(void) const { return mCounters; }; 308 309 /** 310 * Represents different test mode flags for use in `SetTestMode()`. 311 * 312 */ 313 enum TestModeFlags : uint8_t 314 { 315 kTestModeRejectMultiQuestionQuery = 1 << 0, ///< Send `FormatError` for a query with multiple questions. 316 kTestModeIgnoreMultiQuestionQuery = 1 << 1, ///< Ignore a query with multiple questions (send no response). 317 kTestModeEmptyAdditionalSection = 1 << 2, ///< Do not include any RR in additional section. 318 }; 319 320 static constexpr uint8_t kTestModeDisabled = 0; ///< Test mode is disabled (no flags). 321 322 /** 323 * Sets the test mode for `Server`. 324 * 325 * The test mode flags are intended for testing the client by having server behave in certain ways, e.g., reject 326 * messages with certain format (e.g., more than one question in query). 327 * 328 * @param[in] aTestMode The new test mode (combination of `TestModeFlags`). 329 * 330 */ SetTestMode(uint8_t aTestMode)331 void SetTestMode(uint8_t aTestMode) { mTestMode = aTestMode; } 332 333 private: 334 static constexpr bool kBindUnspecifiedNetif = OPENTHREAD_CONFIG_DNSSD_SERVER_BIND_UNSPECIFIED_NETIF; 335 static constexpr uint32_t kQueryTimeout = OPENTHREAD_CONFIG_DNSSD_QUERY_TIMEOUT; 336 static constexpr uint16_t kMaxConcurrentUpstreamQueries = 32; 337 338 typedef Header::Response ResponseCode; 339 340 typedef Message ProxyQuery; 341 typedef MessageQueue ProxyQueryList; 342 343 enum QueryType : uint8_t 344 { 345 kPtrQuery, 346 kSrvQuery, 347 kTxtQuery, 348 kSrvTxtQuery, 349 kAaaaQuery, 350 kAQuery, 351 }; 352 353 enum Section : uint8_t 354 { 355 kAnswerSection, 356 kAdditionalDataSection, 357 }; 358 359 enum AddrType : uint8_t 360 { 361 kIp6AddrType, 362 kIp4AddrType, 363 }; 364 365 #if OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE 366 enum ProxyAction : uint8_t 367 { 368 kNoAction, 369 kBrowsing, 370 kResolvingSrv, 371 kResolvingTxt, 372 kResolvingIp6Address, 373 kResolvingIp4Address 374 }; 375 #endif 376 377 struct Request 378 { 379 ResponseCode ParseQuestions(uint8_t aTestMode, bool &aShouldRespond); 380 381 const Message *mMessage; 382 const Ip6::MessageInfo *mMessageInfo; 383 Header mHeader; 384 QueryType mType; 385 }; 386 387 struct ProxyQueryInfo; 388 389 struct NameOffsets : public Clearable<NameOffsets> 390 { 391 uint16_t mDomainName; 392 uint16_t mServiceName; 393 uint16_t mInstanceName; 394 uint16_t mHostName; 395 }; 396 397 #if OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE 398 union ProxyResult 399 { ProxyResult(const Dnssd::BrowseResult & aBrowseResult)400 explicit ProxyResult(const Dnssd::BrowseResult &aBrowseResult) { mBrowseResult = &aBrowseResult; } ProxyResult(const Dnssd::SrvResult & aSrvResult)401 explicit ProxyResult(const Dnssd::SrvResult &aSrvResult) { mSrvResult = &aSrvResult; } ProxyResult(const Dnssd::TxtResult & aTxtResult)402 explicit ProxyResult(const Dnssd::TxtResult &aTxtResult) { mTxtResult = &aTxtResult; } ProxyResult(const Dnssd::AddressResult & aAddressResult)403 explicit ProxyResult(const Dnssd::AddressResult &aAddressResult) { mAddressResult = &aAddressResult; } 404 405 const Dnssd::BrowseResult *mBrowseResult; 406 const Dnssd::SrvResult *mSrvResult; 407 const Dnssd::TxtResult *mTxtResult; 408 const Dnssd::AddressResult *mAddressResult; 409 }; 410 #endif 411 412 class Response : public InstanceLocator, private NonCopyable 413 { 414 public: 415 explicit Response(Instance &aInstance); 416 ResponseCode AddQuestionsFrom(const Request &aRequest); 417 418 Error AllocateAndInitFrom(const Request &aRequest); 419 void InitFrom(ProxyQuery &aQuery, const ProxyQueryInfo &aInfo); SetResponseCode(ResponseCode aResponseCode)420 void SetResponseCode(ResponseCode aResponseCode) { mHeader.SetResponseCode(aResponseCode); } 421 Error ParseQueryName(void); 422 void ReadQueryName(Name::Buffer &aName) const; 423 bool QueryNameMatches(const char *aName) const; 424 Error AppendQueryName(void); 425 Error AppendPtrRecord(const char *aInstanceLabel, uint32_t aTtl); 426 Error AppendSrvRecord(const ServiceInstanceInfo &aInstanceInfo); 427 Error AppendSrvRecord(const char *aHostName, 428 uint32_t aTtl, 429 uint16_t aPriority, 430 uint16_t aWeight, 431 uint16_t aPort); 432 Error AppendTxtRecord(const ServiceInstanceInfo &aInstanceInfo); 433 Error AppendTxtRecord(const void *aTxtData, uint16_t aTxtLength, uint32_t aTtl); 434 Error AppendHostAddresses(AddrType aAddrType, const HostInfo &aHostInfo); 435 Error AppendHostAddresses(const ServiceInstanceInfo &aInstanceInfo); 436 Error AppendHostAddresses(AddrType aAddrType, const Ip6::Address *aAddrs, uint16_t aAddrsLength, uint32_t aTtl); 437 Error AppendAaaaRecord(const Ip6::Address &aAddress, uint32_t aTtl); 438 Error AppendARecord(const Ip6::Address &aAddress, uint32_t aTtl); 439 void UpdateRecordLength(ResourceRecord &aRecord, uint16_t aOffset); 440 void IncResourceRecordCount(void); 441 void Send(const Ip6::MessageInfo &aMessageInfo); 442 void Answer(const HostInfo &aHostInfo, const Ip6::MessageInfo &aMessageInfo); 443 void Answer(const ServiceInstanceInfo &aInstanceInfo, const Ip6::MessageInfo &aMessageInfo); 444 Error ExtractServiceInstanceLabel(const char *aInstanceName, Name::LabelBuffer &aLabel); 445 #if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE 446 Error ResolveBySrp(void); 447 bool QueryNameMatchesService(const Srp::Server::Service &aService) const; 448 Error AppendSrvRecord(const Srp::Server::Service &aService); 449 Error AppendTxtRecord(const Srp::Server::Service &aService); 450 Error AppendHostAddresses(const Srp::Server::Host &aHost); 451 #endif 452 #if OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE 453 Error AppendPtrRecord(const ProxyResult &aResult); 454 Error AppendSrvRecord(const ProxyResult &aResult); 455 Error AppendTxtRecord(const ProxyResult &aResult); 456 Error AppendHostIp6Addresses(const ProxyResult &aResult); 457 Error AppendHostIp4Addresses(const ProxyResult &aResult); 458 #endif 459 460 #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO) 461 void Log(void) const; 462 static const char *QueryTypeToString(QueryType aType); 463 #endif 464 465 OwnedPtr<Message> mMessage; 466 Header mHeader; 467 QueryType mType; 468 Section mSection; 469 NameOffsets mOffsets; 470 }; 471 472 struct ProxyQueryInfo 473 { 474 void ReadFrom(const ProxyQuery &aQuery); 475 void RemoveFrom(ProxyQuery &aQuery) const; 476 void UpdateIn(ProxyQuery &aQuery) const; 477 478 QueryType mType; 479 Ip6::MessageInfo mMessageInfo; 480 TimeMilli mExpireTime; 481 NameOffsets mOffsets; 482 #if OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE 483 ProxyAction mAction; 484 #endif 485 }; 486 487 #if OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE 488 class DiscoveryProxy : public InstanceLocator, private NonCopyable 489 { 490 friend ot::Dnssd; 491 492 public: 493 explicit DiscoveryProxy(Instance &aInstance); 494 IsRunning(void) const495 bool IsRunning(void) const { return mIsRunning; } 496 void UpdateState(void); 497 void Start(void); 498 void Stop(void); 499 void Resolve(ProxyQuery &aQuery, ProxyQueryInfo &aInfo); 500 void CancelAction(ProxyQuery &aQuery, ProxyQueryInfo &aInfo); 501 502 private: 503 enum Command : uint8_t 504 { 505 kStart, 506 kStop, 507 }; 508 509 typedef Error (Response::*ResponseAppender)(const ProxyResult &aResult); 510 511 void Perform(ProxyAction aAction, ProxyQuery &aQuery, ProxyQueryInfo &aInfo); 512 void ReadNameFor(ProxyAction aAction, ProxyQuery &aQuery, ProxyQueryInfo &aInfo, Name::Buffer &aName) const; 513 bool HasActive(ProxyAction aAction, const Name::Buffer &aName) const; 514 bool QueryMatches(const ProxyQuery &aQuery, 515 const ProxyQueryInfo &aInfo, 516 ProxyAction aAction, 517 const Name::Buffer &aName) const; 518 void UpdateProxy(Command aCommand, 519 ProxyAction aAction, 520 const ProxyQuery &aQuery, 521 const ProxyQueryInfo &aInfo, 522 Name::Buffer &aName); 523 void StartOrStopBrowser(Command aCommand, Name::Buffer &aServiceName); 524 void StartOrStopSrvResolver(Command aCommand, const ProxyQuery &aQuery, const ProxyQueryInfo &aInfo); 525 void StartOrStopTxtResolver(Command aCommand, const ProxyQuery &aQuery, const ProxyQueryInfo &aInfo); 526 void StartOrStopIp6Resolver(Command aCommand, Name::Buffer &aHostName); 527 void StartOrStopIp4Resolver(Command aCommand, Name::Buffer &aHostName); 528 529 static void HandleBrowseResult(otInstance *aInstance, const otPlatDnssdBrowseResult *aResult); 530 static void HandleSrvResult(otInstance *aInstance, const otPlatDnssdSrvResult *aResult); 531 static void HandleTxtResult(otInstance *aInstance, const otPlatDnssdTxtResult *aResult); 532 static void HandleIp6AddressResult(otInstance *aInstance, const otPlatDnssdAddressResult *aResult); 533 static void HandleIp4AddressResult(otInstance *aInstance, const otPlatDnssdAddressResult *aResult); 534 535 void HandleBrowseResult(const Dnssd::BrowseResult &aResult); 536 void HandleSrvResult(const Dnssd::SrvResult &aResult); 537 void HandleTxtResult(const Dnssd::TxtResult &aResult); 538 void HandleIp6AddressResult(const Dnssd::AddressResult &aResult); 539 void HandleIp4AddressResult(const Dnssd::AddressResult &aResult); 540 void HandleResult(ProxyAction aAction, 541 const Name::Buffer &aName, 542 ResponseAppender aAppender, 543 const ProxyResult &aResult); 544 545 static bool IsActionForAdditionalSection(ProxyAction aAction, QueryType aQueryType); 546 547 bool mIsRunning; 548 }; 549 #endif 550 IsRunning(void) const551 bool IsRunning(void) const { return mSocket.IsBound(); } 552 void HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo); 553 void ProcessQuery(Request &aRequest); 554 void ResolveByProxy(Response &aResponse, const Ip6::MessageInfo &aMessageInfo); 555 void RemoveQueryAndPrepareResponse(ProxyQuery &aQuery, ProxyQueryInfo &aInfo, Response &aResponse); 556 void Finalize(ProxyQuery &aQuery, ResponseCode aResponseCode); 557 558 static void ReadQueryName(const Message &aQuery, Name::Buffer &aName); 559 static bool QueryNameMatches(const Message &aQuery, const char *aName); 560 static void ReadQueryInstanceName(const ProxyQuery &aQuery, const ProxyQueryInfo &aInfo, Name::Buffer &aName); 561 static void ReadQueryInstanceName(const ProxyQuery &aQuery, 562 const ProxyQueryInfo &aInfo, 563 Name::LabelBuffer &aInstanceLabel, 564 Name::Buffer &aServiceType); 565 static bool QueryInstanceNameMatches(const ProxyQuery &aQuery, const ProxyQueryInfo &aInfo, const char *aName); 566 static void ReadQueryHostName(const ProxyQuery &aQuery, const ProxyQueryInfo &aInfo, Name::Buffer &aName); 567 static bool QueryHostNameMatches(const ProxyQuery &aQuery, const ProxyQueryInfo &aInfo, const char *aName); 568 static Error StripDomainName(const char *aFullName, Name::Buffer &aLabels); 569 static Error StripDomainName(Name::Buffer &aName); 570 static void ConstructFullName(const char *aLabels, Name::Buffer &aFullName); 571 static void ConstructFullInstanceName(const char *aInstanceLabel, 572 const char *aServiceType, 573 Name::Buffer &aFullName); 574 static void ConstructFullServiceSubTypeName(const char *aServiceType, 575 const char *aSubTypeLabel, 576 Name::Buffer &aFullName); 577 578 #if OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE HandleInfraIfStateChanged(void)579 void HandleInfraIfStateChanged(void) { mDiscoveryProxy.UpdateState(); } HandleDnssdPlatformStateChange(void)580 void HandleDnssdPlatformStateChange(void) { mDiscoveryProxy.UpdateState(); } 581 static bool IsProxyAddressValid(const Ip6::Address &aAddress); 582 #endif 583 584 #if OPENTHREAD_CONFIG_DNS_UPSTREAM_QUERY_ENABLE 585 static bool ShouldForwardToUpstream(const Request &aRequest); 586 UpstreamQueryTransaction *AllocateUpstreamQueryTransaction(const Ip6::MessageInfo &aMessageInfo); 587 void ResetUpstreamQueryTransaction(UpstreamQueryTransaction &aTxn, Error aError); 588 Error ResolveByUpstream(const Request &aRequest); 589 #endif 590 591 void HandleTimer(void); 592 void ResetTimer(void); 593 594 void UpdateResponseCounters(ResponseCode aResponseCode); 595 596 using ServerTimer = TimerMilliIn<Server, &Server::HandleTimer>; 597 using ServerSocket = Ip6::Udp::SocketIn<Server, &Server::HandleUdpReceive>; 598 599 static const char kDefaultDomainName[]; 600 static const char kSubLabel[]; 601 #if OPENTHREAD_CONFIG_DNS_UPSTREAM_QUERY_ENABLE 602 static const char *kBlockedDomains[]; 603 #endif 604 605 ServerSocket mSocket; 606 607 ProxyQueryList mProxyQueries; 608 Callback<SubscribeCallback> mQuerySubscribe; 609 Callback<UnsubscribeCallback> mQueryUnsubscribe; 610 611 #if OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE 612 DiscoveryProxy mDiscoveryProxy; 613 #endif 614 615 #if OPENTHREAD_CONFIG_DNS_UPSTREAM_QUERY_ENABLE 616 bool mEnableUpstreamQuery; 617 UpstreamQueryTransaction mUpstreamQueryTransactions[kMaxConcurrentUpstreamQueries]; 618 #endif 619 620 ServerTimer mTimer; 621 Counters mCounters; 622 uint8_t mTestMode; 623 }; 624 625 } // namespace ServiceDiscovery 626 } // namespace Dns 627 628 DefineMapEnum(otDnssdQueryType, Dns::ServiceDiscovery::Server::DnsQueryType); 629 #if OPENTHREAD_CONFIG_DNS_UPSTREAM_QUERY_ENABLE 630 DefineCoreType(otPlatDnsUpstreamQuery, Dns::ServiceDiscovery::Server::UpstreamQueryTransaction); 631 #endif 632 633 } // namespace ot 634 635 #endif // OPENTHREAD_CONFIG_DNSSD_SERVER_ENABLE 636 637 #endif // DNS_SERVER_HPP_ 638