2 * Copyright (c) 2019-2020 Apple Inc. All rights reserved.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * https://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #ifndef __MDNS_DNS_SERVICE_H__
18 #define __MDNS_DNS_SERVICE_H__
20 #include "mdns_base.h"
21 #include "mdns_object.h"
22 #include "mdns_resolver.h"
27 #include <uuid/uuid.h>
30 MDNS_DECL(dns_service
);
31 MDNS_DECL(dns_service_manager
);
33 MDNS_ASSUME_NONNULL_BEGIN
39 * Creates a DNS service manager, which manages DNS services from a DNS configuration.
42 * Dispatch queue for event handler.
45 * Pointer to an OSStatus variable, which will be set to the error that was encountered during creation.
48 * A new DNS service manager object or NULL if there was a lack of resources.
50 MDNS_RETURNS_RETAINED MDNS_WARN_RESULT
51 mdns_dns_service_manager_t _Nullable
52 mdns_dns_service_manager_create(dispatch_queue_t queue
, OSStatus
* _Nullable out_error
);
56 * Sets whether a DNS service manager is to report DNS server responsiveness symptoms.
59 * The DNS service manager.
61 * @param report_symptoms
62 * Whether or not a DNS service manager is to report DNS server responsiveness symptoms.
65 * This function has no effect on a manager after a call to
66 * <code>mdns_dns_service_manager_activate()</code>.
69 mdns_dns_service_manager_set_report_symptoms(mdns_dns_service_manager_t manager
, bool report_symptoms
);
71 #if MDNS_RESOLVER_PROBLEMATIC_QTYPE_WORKAROUND
74 * For each Do53 DNS service managed by a DNS service manager, enables or disables a workaround where the
75 * DNS service's queriers will refrain from sending queries of type SVCB and HTTPS to a server if the
76 * server has been determined to not respond to queries of those types.
79 * The DNS service manager.
82 * If greater than zero, the workaround is enabled. Otherwise, the workaround is disabled.
85 * This is a workaround for DNS servers that don't respond to SVCB and HTTPS queries and then become less
86 * responsive to queries of other types as more SVCB and HTTPS retry queries are sent.
88 * The workaround is disabled by default.
90 * This function has no effect on a DNS service manager afer a call to mdns_dns_service_manager_activate().
93 mdns_dns_service_manager_enable_problematic_qtype_workaround(mdns_dns_service_manager_t manager
, int threshold
);
98 * Sets a DNS service manager's event handler.
101 * The DNS service manager.
107 * The event handler will never be invoked prior to a call to either
108 * <code>mdns_dns_service_manager_activate()()</code> or
109 * <code>mdns_dns_service_manager_invalidate()</code>.
111 * The event handler will be invoked on the dispatch queue specified by
112 * <code>mdns_dns_service_manager_create()</code> with event <code>mdns_event_error</code> when a fatal error
113 * occurs, with event <code>mdns_event_invalidated</code> when the interface monitor has been invalidated, and
114 * with <code>mdns_event_update</code> when there are pending DNS service updates.
116 * After an <code>mdns_event_invalidated</code> event, the event handler will never be invoked again.
119 mdns_dns_service_manager_set_event_handler(mdns_dns_service_manager_t manager
, mdns_event_handler_t handler
);
123 * Activates a DNS service manager.
126 * The DNS service manager.
129 * This function should be called on a new DNS service manager after after setting its properties and event
133 mdns_dns_service_manager_activate(mdns_dns_service_manager_t manager
);
137 * Synchronously processes a DNS configuration.
140 * The DNS service manager.
143 * A dnsinfo DNS configuration. See <dnsinfo.h>.
146 * This function ensures that a DNS service object is instantiated for each DNS service contained in this DNS
147 * configuration. DNS service objects that were created for previous DNS configurations, but that are not
148 * present in this configuration, are marked as defunct.
151 mdns_dns_service_manager_apply_dns_config(mdns_dns_service_manager_t manager
, const dns_config_t
*config
);
155 * Add a dynamic resolver configuration to the service manager based on a resolver UUID.
158 * The DNS service manager.
160 * @param resolver_config_uuid
161 * A UUID of a resolver configuration registered with the system.
164 * This function registers a UUID with the service manager if it does not exist already. The UUID will be used
165 * to look up the details of the resolver configuration.
168 mdns_dns_service_manager_register_path_resolver(mdns_dns_service_manager_t manager
,
169 const uuid_t _Nonnull resolver_config_uuid
);
172 * @typedef mdns_dns_service_id_t
175 * A unique per-process identifier for DNS service objects.
178 * Useful as an alternative to a pointer to a DNS service when the DNS service itself isn't actually
179 * needed. This identifier can be used to safely distinguish one DNS service object from another even after
180 * one or both have been released.
182 * The zero value is reserved as an invalid ID.
184 typedef uint64_t mdns_dns_service_id_t
;
186 #define MDNS_DNS_SERVICE_MAX_ID ((mdns_dns_service_id_t)-1)
190 * Registers a custom DNS service based on an nw_resolver_config dictionary with a DNS service manager.
193 * The DNS service manager.
195 * @param resolver_config_dict
196 * The nw_resolver_config dictionary.
199 * If the registration is successful, this function returns a non-zero identifier for the custom DNS
203 * When the custom DNS service is no longer needed by the entity that registered it, it should be
204 * deregistered with <code>mdns_dns_service_manager_deregister_custom_service()</code>.
207 mdns_dns_service_id_t
208 mdns_dns_service_manager_register_custom_service(mdns_dns_service_manager_t manager
, xpc_object_t resolver_config_dict
);
212 * Deregisters a custom DNS service from a DNS service manager.
215 * The DNS service manager.
218 * The identifier returned by <code>mdns_dns_service_manager_register_custom_service()</code> when the
219 * custom DNS service was registered.
222 mdns_dns_service_manager_deregister_custom_service(mdns_dns_service_manager_t manager
, mdns_dns_service_id_t ident
);
226 * Add a custom resolver configuration to the service manager associated with a particular handle.
229 * The DNS service manager.
232 * A URI of a DoH server, as a string.
235 * A domain to link to a DoH server.
238 * This function registers a DoH URI with the service manager if it does not exist already.
241 mdns_dns_service_manager_register_doh_uri(const mdns_dns_service_manager_t manager
,
242 const char *doh_uri
, const char * _Nullable domain
);
246 * Asynchronously invalidates a DNS service manager.
249 * The DNS service manager.
252 * This function should be called when a DNS service manager is no longer needed.
254 * As a result of calling this function, the DNS service manager's event handler will be invoked with a
255 * <code>mdns_event_invalidated</code> event, after which the DNS service manager's event handler will never
258 * This function has no effect on a DNS service manager that has already been invalidated.
261 mdns_dns_service_manager_invalidate(mdns_dns_service_manager_t manager
);
265 * Gets the most suitable unscoped DNS service that can be used to query for a record with the given domain
269 * The DNS service manager.
272 * The domain name in label format.
275 * This function returns the most suitable unscoped DNS service from the latest DNS configuration that can be
276 * used to query for a record with the given domain name if such a service even exists.
278 * If a service is returned, there's no guarantee that the reference will be valid after the next call to
279 * either <code>mdns_dns_service_manager_apply_dns_config()</code> or
280 * <code>mdns_dns_service_manager_apply_pending_updates()</code> unless the service is retained by the caller.
283 * A non-retained service if a suitable service exists. Otherwise, NULL.
285 mdns_dns_service_t _Nullable
286 mdns_dns_service_manager_get_unscoped_service(mdns_dns_service_manager_t manager
, const uint8_t *name
);
290 * Gets the most suitable interface-scoped DNS service that can be used to query for a record with the given
294 * The DNS service manager.
297 * The domain name in label format.
300 * The index of the interface to which the interface-scoped service must be scoped.
303 * This function returns the most suitable interface-scoped DNS service from the latest DNS configuration that
304 * can be used to query for a record with the given domain name if such a service even exists.
306 * If a service is returned, there's no guarantee that the reference will be valid after the next call to
307 * either <code>mdns_dns_service_manager_apply_dns_config()</code> or
308 * <code>mdns_dns_service_manager_apply_pending_updates()</code> unless the service is retained by the caller.
311 * A non-retained service if a suitable service exists. Otherwise, NULL.
313 mdns_dns_service_t _Nullable
314 mdns_dns_service_manager_get_interface_scoped_service(mdns_dns_service_manager_t manager
, const uint8_t *name
,
319 * Gets the most suitable service-scoped DNS service that can be used to query for a record with the given
323 * The DNS service manager.
326 * The domain name in label format.
329 * The ID of the service for which the service-scoped service must be scoped.
332 * This function returns the most suitable service-scoped DNS service from the latest DNS configuration that
333 * can be used to query for a record with the given domain name if such a service even exists.
335 * Note: service-scoped DNS services are for specialized VPN applications, such as Per-App VPN.
337 * If a service is returned, there's no guarantee that the reference will be valid after the next call to
338 * either <code>mdns_dns_service_manager_apply_dns_config()</code> or
339 * <code>mdns_dns_service_manager_apply_pending_updates()</code> unless the service is retained by the caller.
342 * A non-retained service if a suitable service exists. Otherwise, NULL.
344 mdns_dns_service_t _Nullable
345 mdns_dns_service_manager_get_service_scoped_service(mdns_dns_service_manager_t manager
, const uint8_t *name
,
346 uint32_t service_id
);
350 * Gets a custom DNS service with a given identifier from a DNS service manager.
353 * The DNS service manager.
356 * The custom DNS service's identifier, i.e., the identifier returned by
357 * <code>mdns_dns_service_manager_register_custom_service()</code> when the custom DNS service was
361 * A non-retained reference to the custom DNS service if the custom DNS service is still registered.
364 mdns_dns_service_t _Nullable
365 mdns_dns_service_manager_get_custom_service(mdns_dns_service_manager_t manager
, mdns_dns_service_id_t ident
);
369 * Gets the config-specified DNS service that can be used to query for a record with the given
373 * The DNS service manager.
376 * The UUID of the resolver config to select.
379 * If a service is returned, there's no guarantee that the reference will be valid after the next call to
380 * either <code>mdns_dns_service_manager_apply_dns_config()</code> or
381 * <code>mdns_dns_service_manager_apply_pending_updates()</code> unless the service is retained by the caller.
384 * A non-retained service if a suitable service exists. Otherwise, NULL.
386 mdns_dns_service_t _Nullable
387 mdns_dns_service_manager_get_uuid_scoped_service(mdns_dns_service_manager_t manager
, const uuid_t _Nonnull uuid
);
391 * Fills out the UUID of a DNS service that should be used to query for a record with the given
395 * The DNS service manager.
398 * The domain name in label format.
401 * The UUID of the resolver config to select.
404 * Returns true if the UUID was filled out.
407 mdns_dns_service_manager_fillout_discovered_service_for_name(mdns_dns_service_manager_t manager
, const uint8_t * const name
,
408 uuid_t _Nonnull out_uuid
);
412 * Applies pending updates to the DNS service manager's DNS services.
415 * The DNS service manager.
418 * This function applies pending updates having to do with each managed DNS service's interface properties,
419 * e.g., expensive, constrained, and clat46.
421 * This function should be called when handling an <code>mdns_event_update</code> event.
424 mdns_dns_service_manager_apply_pending_updates(mdns_dns_service_manager_t manager
);
428 * The type for a block that handles a DNS service when iterating over a DNS service manager's services.
434 * If true, then iteration will stop prematurely. If false, then iteration will continue.
437 (^mdns_dns_service_applier_t
)(mdns_dns_service_t service
);
441 * Iterates over each DNS service managed by a DNS service manager.
444 * The DNS service manager.
447 * Block to invoke for each DNS service.
450 mdns_dns_service_manager_iterate(mdns_dns_service_manager_t manager
, mdns_dns_service_applier_t applier
);
454 * Returns the number of DNS services being managed by a DNS service manager.
457 * The DNS service manager.
460 mdns_dns_service_manager_get_count(mdns_dns_service_manager_t manager
);
464 * Performs tasks necessary for a DNS service manager to prepare for system sleep.
467 * The DNS service manager.
470 mdns_dns_service_manager_handle_sleep(mdns_dns_service_manager_t manager
);
474 * Performs tasks necessary for a DNS service manager to prepare for system wake.
477 * The DNS service manager.
480 mdns_dns_service_manager_handle_wake(mdns_dns_service_manager_t manager
);
484 * Sets a DNS service's user-defined context.
490 * The user-defined context.
493 * The last context set with this function can be retrieved with mdns_dns_service_get_context().
495 * A DNS service's context is NULL by default.
498 mdns_dns_service_set_context(mdns_dns_service_t service
, void *context
);
502 * Gets a DNS service's user-defined context.
508 * Returns the last context set with mdns_dns_service_set_context().
511 mdns_dns_service_get_context(mdns_dns_service_t service
);
515 * The type for a function that finalizes a user-defined context.
518 * The user-defined context.
521 (*mdns_context_finalizer_t
)(void *context
);
525 * Sets a DNS service's context finalizer function.
534 * If a DNS service's context finalizer is not NULL and the service's context, which can be set with
535 * mdns_dns_service_set_context(), is not NULL when the service's last reference is released, then the
536 * finalizer will be invoked exactly once using the DNS service's context as an argument. The finalizer
537 * will be invoked under no other conditions.
540 mdns_dns_service_set_context_finalizer(mdns_dns_service_t service
, mdns_context_finalizer_t _Nullable finalizer
);
544 * Creates a querier to query a DNS service represented by a DNS service object.
550 * Pointer to an OSStatus variable, which will be set to the error that was encountered during creation.
553 * If the DNS service is defunct, then no querier will be created.
556 * A new querier object if the DNS service is not defunct and resources are available. Otherwise, NULL.
558 MDNS_RETURNS_RETAINED MDNS_WARN_RESULT
559 mdns_querier_t _Nullable
560 mdns_dns_service_create_querier(mdns_dns_service_t service
, OSStatus
* _Nullable out_error
);
564 * Indicates a DNS service's scoping.
566 * @const mdns_dns_service_scope_null
567 * An invalid scope to be used only as a placeholder.
569 * @const mdns_dns_service_scope_none
570 * For unscoped DNS services.
572 * @const mdns_dns_service_scope_interface
573 * For interface-scoped DNS services.
575 * @const mdns_dns_service_scope_service
576 * For services-scoped DNS services.
578 * @const mdns_dns_service_scope_uuid
579 * For UUID-scoped DNS services.
581 * @const mdns_dns_service_scope_custom
582 * For custom DNS services.
584 OS_CLOSED_ENUM(mdns_dns_service_scope
, int,
585 mdns_dns_service_scope_null
= 0,
586 mdns_dns_service_scope_none
= 1,
587 mdns_dns_service_scope_interface
= 2,
588 mdns_dns_service_scope_service
= 3,
589 mdns_dns_service_scope_uuid
= 4,
590 mdns_dns_service_scope_custom
= 5
595 * Gets a DNS service's scope.
600 mdns_dns_service_scope_t
601 mdns_dns_service_get_scope(mdns_dns_service_t service
);
605 * Gets the index of the network interface used to access a DNS service.
611 mdns_dns_service_get_interface_index(mdns_dns_service_t service
);
615 * Gets a DNS service's unique per-process ID.
621 * If service is non-NULL, then the service's ID is returned. Otherwise, 0, which is an invalid ID, is
624 mdns_dns_service_id_t
625 mdns_dns_service_get_id(mdns_dns_service_t _Nullable service
);
629 * Determines whether or not a DNS service is defunct.
635 * A DNS service becomes defunct when the DNS service manager that created it later applies a DNS
636 * configuration (with <code>mdns_dns_service_manager_apply_dns_config()</code>) that doesn't contain the DNS
639 * When a DNS service is defunct, it is no longer usable, i.e., it is no longer capable of creating queriers.
642 mdns_dns_service_is_defunct(mdns_dns_service_t service
);
646 * Check if a DNS service uses an encrypted protocol.
652 mdns_dns_service_is_encrypted(mdns_dns_service_t service
);
656 * Determines whether or not A record queries are advised for a DNS service.
662 * Mirrors the meaning of the DNS_RESOLVER_FLAGS_REQUEST_A_RECORDS flag in a DNS configuration.
665 mdns_dns_service_a_queries_advised(mdns_dns_service_t service
);
669 * Determines whether or not AAAA record queries are advised for a DNS service.
675 * Mirrors the meaning of the DNS_RESOLVER_FLAGS_REQUEST_AAAA_RECORDS flag in a DNS configuration.
678 mdns_dns_service_aaaa_queries_advised(mdns_dns_service_t service
);
682 * Determines whether or not a DNS service is currently experiencing connection problems.
688 * This function currently only applies to DNS services that use DNS over HTTPS.
690 * Since connection problems may be transient, a service with connection problems may still be used to
694 mdns_dns_service_has_connection_problems(mdns_dns_service_t service
);
698 * Determines whether or not a DNS service's interface has IPv4 connectivity.
704 mdns_dns_service_interface_has_ipv4_connectivity(mdns_dns_service_t service
);
708 * Determines whether or not a DNS service's interface has IPv6 connectivity.
714 mdns_dns_service_interface_has_ipv6_connectivity(mdns_dns_service_t service
);
718 * Determines whether or not a DNS service's interface is a cellular interface.
724 mdns_dns_service_interface_is_cellular(mdns_dns_service_t service
);
728 * Determines whether or not a DNS service's interface is expensive.
734 mdns_dns_service_interface_is_expensive(mdns_dns_service_t service
);
738 * Determines whether or not a DNS service's interface is constrained.
744 mdns_dns_service_interface_is_constrained(mdns_dns_service_t service
);
748 * Determines whether or not a DNS service's interface is clat46.
754 mdns_dns_service_interface_is_clat46(mdns_dns_service_t service
);
758 * Determines whether or not a DNS service's interface is a VPN interface.
764 mdns_dns_service_interface_is_vpn(mdns_dns_service_t service
);
768 * Access the provider name, if applicable, used by this service.
773 const char * _Nullable
774 mdns_dns_service_get_provider_name(mdns_dns_service_t service
);
778 * Gets the resolver type used by a DNS service.
784 mdns_dns_service_get_resolver_type(mdns_dns_service_t service
);
788 MDNS_ASSUME_NONNULL_END
790 #endif // __MDNS_DNS_SERVICE_H__