blob: 2739632a438fabdab56651b0606a74b90a65ed27 [file] [log] [blame]
/*
* Copyright (c) 2022-2023 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.
*/
#include "mDNSFeatures.h"
#if MDNSRESPONDER_SUPPORTS(APPLE, DNS_PUSH)
//======================================================================================================================
// MARK: - Headers
#include "dns_push_obj_context.h"
#include "dns_common.h"
#include "dns_obj_domain_name.h"
#include "dns_obj_log.h"
#include "dns_push_obj.h"
#include "uDNS.h"
#include <stdint.h>
#include <stdlib.h>
#include "dns_assert_macros.h"
#include "general.h"
#include "mdns_strict.h"
//======================================================================================================================
// MARK: - DNS Push Context Kind Definition
struct dns_push_obj_context_s {
struct ref_count_obj_s base; // The reference count and kind support base.
dns_obj_rr_soa_t authority_soa;
dns_obj_domain_name_t authoritative_zone;
dns_push_obj_discovered_service_manager_t service_manager;
mDNS * m; // The mDNSStorage pointer for the mDNSCore.
DNSQuestion * original_question; // The question that enables DNS push.
DNSQuestion * soa_question; // The secondary question for authoritative zone
// discovery
};
DNS_PUSH_OBJECT_DEFINE_FULL(context);
//======================================================================================================================
// MARK: - DNS Push Question Context Public Methods
dns_push_obj_context_t
dns_push_obj_context_create(mDNS *const m, DNSQuestion * const q, dns_obj_error_t * const out_error)
{
dns_obj_error_t err;
dns_obj_domain_name_t q_name = NULL;
dns_push_obj_context_t context = NULL;
dns_push_obj_context_t obj = NULL;
q_name = dns_obj_domain_name_create_with_labels(q->qname.c, true, &err);
require_noerr(err, exit);
const uint16_t q_type = q->qtype;
const bool is_single_label = (dns_obj_domain_name_is_single_label(q_name));
require_action(!is_single_label, exit,
log_error("Unable to start DNS push server discovery for the single-label name (TLD) -- "
"qname: " PRI_DNS_DM_NAME ", qtype: " PUB_DNS_TYPE, DNS_DM_NAME_PARAM(q_name), DNS_TYPE_PARAM(q_type));
err = DNS_OBJ_ERROR_PARAM_ERR);
obj = _dns_push_obj_context_new();
require_action(obj != NULL, exit, err = DNS_OBJ_ERROR_NO_MEMORY);
obj->m = m;
obj->original_question = q;
context = obj;
obj = NULL;
err = DNS_OBJ_ERROR_NO_ERROR;
exit:
mdns_assign(out_error, err);
MDNS_DISPOSE_DNS_OBJ(q_name);
MDNS_DISPOSE_DNS_PUSH_OBJ(obj);
return context;
}
//======================================================================================================================
void
dns_push_obj_context_set_soa_question(const dns_push_obj_context_t me, DNSQuestion * const soa_question)
{
me->soa_question = soa_question;
}
//======================================================================================================================
DNSQuestion *
dns_push_obj_context_get_soa_question(const dns_push_obj_context_t me)
{
return me->soa_question;
}
//======================================================================================================================
DNSQuestion *
dns_push_obj_context_get_original_question(const dns_push_obj_context_t me)
{
return me->original_question;
}
//======================================================================================================================
void
dns_push_obj_context_set_authoritative_zone(const dns_push_obj_context_t me, const dns_obj_domain_name_t zone)
{
dns_obj_replace(&me->authoritative_zone, zone);
}
//======================================================================================================================
dns_obj_domain_name_t NULLABLE
dns_push_obj_context_get_authoritative_zone(const dns_push_obj_context_t me)
{
return me->authoritative_zone;
}
//======================================================================================================================
void
dns_push_obj_context_set_service_manager(const dns_push_obj_context_t me,
const dns_push_obj_discovered_service_manager_t manager)
{
dns_push_obj_replace(&me->service_manager, manager);
}
//======================================================================================================================
dns_push_obj_discovered_service_manager_t
dns_push_obj_context_get_service_manager(const dns_push_obj_context_t me)
{
return me->service_manager;
}
//======================================================================================================================
// MARK: - DNS Push Question Context Private Methods
static compare_result_t
_dns_push_obj_context_compare(const dns_push_obj_context_t me, const dns_push_obj_context_t other, const bool UNUSED check_equality_only)
{
// Context can only be checked for the equality.
return me == other ? compare_result_equal : compare_result_notequal;
}
//======================================================================================================================
static void
_dns_push_obj_context_finalize(const dns_push_obj_context_t me)
{
dns_obj_forget(&me->authority_soa);
dns_obj_forget(&me->authoritative_zone);
}
#endif // MDNSRESPONDER_SUPPORTS(APPLE, DNS_PUSH)