blob: dc474505b7ec29f1b3ec68d06c336597485166f1 [file] [log] [blame] [edit]
/*
* Copyright (c) 2021-2024 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MRC_DNS_PROXY_H
#define MRC_DNS_PROXY_H
#if !defined(MRC_ALLOW_HEADER_INCLUDES) || !MRC_ALLOW_HEADER_INCLUDES
#error "Please include <mrc/private.h> instead of this file directly."
#endif
#include <mrc/object.h>
#include <dispatch/dispatch.h>
#include <MacTypes.h>
#include <mdns/base.h>
MRC_DECL(dns_proxy);
MRC_DECL(dns_proxy_parameters);
MRC_DECL(dns_proxy_state_inquiry);
MDNS_ASSUME_NONNULL_BEGIN
__BEGIN_DECLS
/*!
* @brief
* Creates a DNS proxy based on the specified DNS proxy parameters.
*
* @param params
* The parameters.
*
* @param out_error
* A variable to set to either kNoErr if creation succeeds, or a non-zero error code to indicate why
* creation failed.
*
* @result
* A reference to the new DNS proxy object, or NULL if creation failed.
*
* @discussion
* The parameters are copied by the DNS proxy object during its creation, so the DNS proxy will not be
* affected by later changes to the parameters object.
*
* If not using Objective-C ARC, use mrc_retain() and mrc_release() to retain and release references to the
* object.
*/
MDNS_SPI_AVAILABLE_FALL_2022
MDNS_RETURNS_RETAINED MDNS_WARN_RESULT
mrc_dns_proxy_t _Nullable
mrc_dns_proxy_create(mrc_dns_proxy_parameters_t params, OSStatus * _Nullable out_error);
/*!
* @brief
* Sets a DNS proxy's dispatch queue on which to invoke the DNS proxy's event handler.
*
* @param proxy
* The DNS proxy.
*
* @param queue
* The dispatch queue.
*
* @discussion
* A dispatch queue must be set in order for the event handler to be invoked.
*
* This function has no effect on a DNS proxy that has been activated or invalidated.
*/
MDNS_SPI_AVAILABLE_FALL_2022
void
mrc_dns_proxy_set_queue(mrc_dns_proxy_t proxy, dispatch_queue_t queue);
OS_CLOSED_ENUM(mrc_dns_proxy_event, int,
mrc_dns_proxy_event_invalidation = -1,
mrc_dns_proxy_event_none = 0,
mrc_dns_proxy_event_started = 1,
mrc_dns_proxy_event_interruption = 2
);
static inline const char *
mrc_dns_proxy_event_to_string(const mrc_dns_proxy_event_t event)
{
switch (event) {
case mrc_dns_proxy_event_invalidation: return "invalidation";
case mrc_dns_proxy_event_none: return "none";
case mrc_dns_proxy_event_started: return "started";
case mrc_dns_proxy_event_interruption: return "interruption";
MDNS_COVERED_SWITCH_DEFAULT: return "<INVALID EVENT>";
}
}
/*!
* @brief
* A DNS proxy event handler.
*
* @param event
* The event.
*
* @param error
* An error code associated with the event.
*/
typedef void
(^mrc_dns_proxy_event_handler_t)(mrc_dns_proxy_event_t event, OSStatus error);
/*!
* @brief
* Sets a DNS proxy's event handler.
*
* @param proxy
* The DNS proxy.
*
* @param handler
* The event handler.
*
* @discussion
* The event handler will never be invoked before the first call to either mrc_dns_proxy_activate()
* or mrc_dns_proxy_invalidate().
*
* The handler will be invoked with the mrc_dns_proxy_event_invalidation event at most once if either a
* fatal error occurs or if the the DNS proxy was manually invalidated with mrc_dns_proxy_invalidate().
* If a fatal error occurred, the event handler's error code argument will be non-zero to indicate the
* error that occurred. If the DNS proxy was gracefully invalidated with mrc_dns_proxy_invalidate(), then
* the event handler's error code will be kNoErr (0).
*
* After the handler is invoked with the mrc_dns_proxy_event_invalidation event, the handler will be
* released by the DNS proxy, and will never be invoked by the DNS proxy ever again.
*
* The handler will be invoked with the mrc_dns_proxy_event_started event each time a remote instance of
* the DNS proxy has successfully started.
*
* The handler will be invoked with the mrc_dns_proxy_event_interruption event if the connection to the
* daemon was interrupted. For example, the daemon may have crashed. This event exists to inform the user
* that the remote instance of the DNS proxy may have suffered some downtime. The DNS proxy object will try
* to re-establish the connection as well as a new remote instance of the DNS proxy.
*
* The mrc_dns_proxy_event_none event simply exists as a placeholder event value. The event handler will
* never be invoked with the mrc_dns_proxy_event_none event.
*
* Currently, the event handler's error code argument is only meaningful for the
* mrc_dns_proxy_event_invalidation event.
*
* This function has no effect on a DNS proxy that has been activated or invalidated.
*/
MDNS_SPI_AVAILABLE_FALL_2022
void
mrc_dns_proxy_set_event_handler(mrc_dns_proxy_t proxy, mrc_dns_proxy_event_handler_t handler);
/*!
* @brief
* Activates a DNS proxy.
*
* @param proxy
* The DNS proxy.
*
* @discussion
* Activating a DNS proxy object causes it to try to instantiate a remote instance of itself on the system
* daemon that implements DNS proxies.
*
* This function has no effect on a DNS proxy that has already been activated or invalidated.
*/
MDNS_SPI_AVAILABLE_FALL_2022
void
mrc_dns_proxy_activate(mrc_dns_proxy_t proxy);
/*!
* @brief
* Invalidates a DNS proxy.
*
* @param proxy
* The DNS proxy.
*
* @discussion
* Invalidating a DNS proxy object causes it to tear down the remote instance of itself on the system
* daemon if such an instance exists.
*
* This function exists to gracefully invalidate a DNS proxy. This function can safely be called even if
* the DNS proxy was already forcibly invalidated due to a fatal error.
*
* This function has no effect on a DNS proxy that has already been invalidated.
*/
MDNS_SPI_AVAILABLE_FALL_2022
void
mrc_dns_proxy_invalidate(mrc_dns_proxy_t proxy);
/*!
* @brief
* Creates an empty modifiable set of DNS proxy parameters.
*
* @param out_error
* A variable to set to either kNoErr if creation succeeds, or a non-zero error code to indicate why
* creation failed.
*
* @result
* A reference to the new DNS proxy parameters, or NULL if creation failed.
*
* @discussion
* If not using Objective-C ARC, use mrc_retain() and mrc_release() to retain and release references to the
* object.
*/
MDNS_SPI_AVAILABLE_FALL_2022
MDNS_RETURNS_RETAINED MDNS_WARN_RESULT
mrc_dns_proxy_parameters_t _Nullable
mrc_dns_proxy_parameters_create(OSStatus *out_error);
/*!
* @brief
* Adds an input interface to a set of DNS proxy parameters.
*
* @param params
* The parameters.
*
* @param ifindex
* The input interface's index.
*
* @discussion
* This function can be called more than once to specify a set of multiple input interfaces.
*/
MDNS_SPI_AVAILABLE_FALL_2022
void
mrc_dns_proxy_parameters_add_input_interface(mrc_dns_proxy_parameters_t params, uint32_t ifindex);
/*!
* @brief
* Sets the output interface in a set of DNS proxy parameters.
*
* @param params
* The parameters.
*
* @param ifindex
* The output interface's index.
*
* @discussion
* By default, the output interface index is 0, which means that the remote DNS proxy instance will use the
* most suitable interface for its DNS network traffic.
*/
MDNS_SPI_AVAILABLE_FALL_2022
void
mrc_dns_proxy_parameters_set_output_interface(mrc_dns_proxy_parameters_t params, uint32_t ifindex);
/*!
* @brief
* Sets the NAT64 IPv6 prefix in a set of DNS proxy parameters.
*
* @param params
* The parameters.
*
* @param prefix
* A pointer to the prefix.
*
* @param prefix_bit_length
* The bit length of the prefix. Values greater than 128 will be treated as 128.
*
* @discussion
* If a NAT64 prefix is set, then the remote instance of the DNS proxy will carry out DNS64 functionality
* using the specified NAT64 prefix. If it's not set, then no DNS64 functionality will be performed.
*/
MDNS_SPI_AVAILABLE_FALL_2022
void
mrc_dns_proxy_parameters_set_nat64_prefix(mrc_dns_proxy_parameters_t params, const uint8_t *prefix,
size_t prefix_bit_length);
/*!
* @brief
* Sets whether or not AAAA synthesis should be forced in a set of DNS proxy parameters.
*
* @param params
* The parameters.
*
* @param value
* The truth value.
*
* @discussion
* Forcing AAAA synthesis only applies if the remote instance of the DNS proxy has DNS64 functionality
* enabled by specifying a NAT64 prefix with mrc_dns_proxy_parameters_set_nat64_prefix().
*
* By default, AAAA synthesis is not forced.
*/
MDNS_SPI_AVAILABLE_FALL_2022
void
mrc_dns_proxy_parameters_set_force_aaaa_synthesis(mrc_dns_proxy_parameters_t params, bool value);
/*!
* @brief
* A block used for enumerating interface indexes.
*
* @param ifindex
* An enumerated interface index.
*
* @result
* True if enumeration should continue onto the next interface index, if any. False if enumeration should
* not continue.
*/
typedef bool
(^mrc_dns_proxy_parameters_interface_applier_t)(uint32_t ifindex);
/*!
* @brief
* Enumerates the input interface indexes in a set of DNS proxy parameters.
*
* @param params
* The parameters.
*
* @param applier
* An applier to synchronously invoke once for each input interface index until either no interface indexes
* remains or the applier returns false. Note that if there are no input interface indexes, then the
* applier will not be invoked.
*
* @result
* True if the applier never returned false during enumeration. Otherwise, false.
*/
MDNS_SPI_AVAILABLE_FALL_2022
bool
mrc_dns_proxy_parameters_enumerate_input_interfaces(mrc_dns_proxy_parameters_t params,
mrc_dns_proxy_parameters_interface_applier_t applier);
/*!
* @brief
* Gets the output interface index from a set of DNS proxy parameters.
*
* @param params
* The parameters.
*
* @result
* The output interface index.
*
* @discussion
* By default, the output interface index is 0, which means that the remote DNS proxy instance will use the
* most suitable interface for its DNS network traffic.
*/
MDNS_SPI_AVAILABLE_FALL_2022
uint32_t
mrc_dns_proxy_parameters_get_output_interface(mrc_dns_proxy_parameters_t params);
/*!
* @brief
* Gets the truth value of whether or not AAAA synthesis should be forced in a set of DNS proxy parameters.
*
* @param params
* The parameters.
*
* @result
* The truth value.
*
* @discussion
* By default, AAAA synthesis is not forced.
*/
MDNS_SPI_AVAILABLE_FALL_2022
bool
mrc_dns_proxy_parameters_get_force_aaaa_synthesis(mrc_dns_proxy_parameters_t params);
/*!
* @brief
* Creates a DNS proxy state inquiry object, whose purpose is to inquire about the current state of all of
* the system's DNS proxies.
*
* @result
* A reference to the new inquiry, or NULL if creation failed.
*
* @discussion
* The state that is obtained by this object is human-readable text meant for diagnostic purposes.
*
* If not using Objective-C ARC, use mrc_retain() and mrc_release() to retain and release references to the
* object.
*/
MDNS_SPI_AVAILABLE_MIDFALL_2022
MDNS_RETURNS_RETAINED MDNS_WARN_RESULT
mrc_dns_proxy_state_inquiry_t
mrc_dns_proxy_state_inquiry_create(void);
/*!
* @brief
* Sets a DNS proxy state inquiry's queue on which to invoke its response handler.
*
* @param inquiry
* The DNS proxy state inquiry.
*
* @param queue
* The dispatch queue.
*
* @discussion
* A dispatch queue must be set in order for an inquiry's response handler to be invoked.
*
* This function should be called before the inquiry is activated. This function has no effect on an
* inquiry that has been activated or invalidated.
*/
MDNS_SPI_AVAILABLE_MIDFALL_2022
void
mrc_dns_proxy_state_inquiry_set_queue(mrc_dns_proxy_state_inquiry_t inquiry, dispatch_queue_t queue);
/*!
* @brief
* A DNS proxy state inquiry response handler.
*
* @param state
* The state as a human-readable C string.
*
* @param error
* An error code, which will be non-zero if a fatal error occurred, or zero, otherwise.
*
* @discussion
* The lifetime of the state C string is not guaranteed beyond the invocation of this handler. If it is
* needed beyond the invocation of this handler, then it should be duplicated.
*/
typedef void
(^mrc_dns_proxy_state_inquiry_response_handler_t)(const char * _Nullable state, OSStatus error);
/*!
* @brief
* Sets a DNS proxy state inquiry's response handler.
*
* @param inquiry
* The DNS proxy state inquiry.
*
* @param handler
* The response handler.
*
* @discussion
* The response handler will never be invoked before the first call to either
* mrc_dns_proxy_state_inquiry_activate() or mrc_dns_proxy_state_inquiry_invalidate().
*
* The response handler will be submitted to the inquiry's queue no more than once for one of the following
* events, whichever occurs first:
*
* 1. The system daemon that implements DNS proxies responds with the current state of the DNS proxies. In
* this case, the handler will be invoked with a non-NULL state string and a kNoErr error code.
*
* 2. A fatal error occurs that halts the inquiry's progress. In this case, the handler will be invoked
* with a NULL state string and a non-zero error code that indicates the type of error that occurred.
*
* 3. The inquiry is invalidated with mrc_dns_proxy_state_inquiry_invalidate(). In this case, the handler
* will be invoked with a NULL state string and a kNoErr error code.
*
* This function should be called before the inquiry is activated. This function has no effect on an
* inquiry that has been activated or invalidated.
*/
MDNS_SPI_AVAILABLE_MIDFALL_2022
void
mrc_dns_proxy_state_inquiry_set_handler(mrc_dns_proxy_state_inquiry_t inquiry,
mrc_dns_proxy_state_inquiry_response_handler_t handler);
/*!
* @brief
* Activates a DNS proxy state inquiry.
*
* @param inquiry
* The DNS proxy state inquiry.
*
* @discussion
* Activating an inquiry causes it to ask the system daemon that implements DNS proxies about the current
* state of those proxies.
*
* This function has no effect on an inquiry that has already been activated or invalidated.
*/
MDNS_SPI_AVAILABLE_MIDFALL_2022
void
mrc_dns_proxy_state_inquiry_activate(mrc_dns_proxy_state_inquiry_t inquiry);
/*!
* @brief
* Invalidates a DNS proxy state inquiry.
*
* @param inquiry
* The DNS proxy state inquiry.
*
* @discussion
* This function exists to gracefully invalidate an inquiry.
*
* If the inquiry's response handler hasn't already been invoked and isn't on its way to be invoked, then
* this function will force it to be invoked (asynchronously, of course) with a NULL state string. If the
* response handler has already been called, then calling this function is unnecessary, but harmless.
*
* This function has no effect on an inquiry that has already been invalidated.
*/
MDNS_SPI_AVAILABLE_MIDFALL_2022
void
mrc_dns_proxy_state_inquiry_invalidate(mrc_dns_proxy_state_inquiry_t inquiry);
__END_DECLS
MDNS_ASSUME_NONNULL_END
#endif // MRC_DNS_PROXY_H