Blame lib/dns/lib.c

Packit 5ce601
/*
Packit 5ce601
 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
Packit 5ce601
 *
Packit 5ce601
 * This Source Code Form is subject to the terms of the Mozilla Public
Packit 5ce601
 * License, v. 2.0. If a copy of the MPL was not distributed with this
Packit Service 704ed8
 * file, you can obtain one at https://mozilla.org/MPL/2.0/.
Packit 5ce601
 *
Packit 5ce601
 * See the COPYRIGHT file distributed with this work for additional
Packit 5ce601
 * information regarding copyright ownership.
Packit 5ce601
 */
Packit 5ce601
Packit 5ce601
/*! \file */
Packit 5ce601
Packit 5ce601
#include <config.h>
Packit 5ce601
Packit 5ce601
#include <stdbool.h>
Packit 5ce601
#include <stddef.h>
Packit 5ce601
Packit 5ce601
#include <isc/hash.h>
Packit 5ce601
#include <isc/mem.h>
Packit 5ce601
#include <isc/msgcat.h>
Packit 5ce601
#include <isc/mutex.h>
Packit 5ce601
#include <isc/once.h>
Packit 5ce601
#include <isc/util.h>
Packit 5ce601
Packit 5ce601
#include <dns/db.h>
Packit 5ce601
#include <dns/ecdb.h>
Packit 5ce601
#include <dns/lib.h>
Packit 5ce601
#include <dns/result.h>
Packit 5ce601
Packit 5ce601
#include <dst/dst.h>
Packit 5ce601
Packit 5ce601
Packit 5ce601
/***
Packit 5ce601
 *** Globals
Packit 5ce601
 ***/
Packit 5ce601
Packit 5ce601
LIBDNS_EXTERNAL_DATA unsigned int			dns_pps = 0U;
Packit 5ce601
LIBDNS_EXTERNAL_DATA isc_msgcat_t *			dns_msgcat = NULL;
Packit 5ce601
Packit 5ce601
Packit 5ce601
/***
Packit 5ce601
 *** Private
Packit 5ce601
 ***/
Packit 5ce601
Packit 5ce601
static isc_once_t		msgcat_once = ISC_ONCE_INIT;
Packit 5ce601
Packit 5ce601
Packit 5ce601
/***
Packit 5ce601
 *** Functions
Packit 5ce601
 ***/
Packit 5ce601
Packit 5ce601
static void
Packit 5ce601
open_msgcat(void) {
Packit 5ce601
	isc_msgcat_open("libdns.cat", &dns_msgcat);
Packit 5ce601
}
Packit 5ce601
Packit 5ce601
void
Packit 5ce601
dns_lib_initmsgcat(void) {
Packit 5ce601
Packit 5ce601
	/*
Packit 5ce601
	 * Initialize the DNS library's message catalog, dns_msgcat, if it
Packit 5ce601
	 * has not already been initialized.
Packit 5ce601
	 */
Packit 5ce601
Packit 5ce601
	RUNTIME_CHECK(isc_once_do(&msgcat_once, open_msgcat) == ISC_R_SUCCESS);
Packit 5ce601
}
Packit 5ce601
Packit 5ce601
static isc_once_t init_once = ISC_ONCE_INIT;
Packit 5ce601
static isc_mem_t *dns_g_mctx = NULL;
Packit 5ce601
static dns_dbimplementation_t *dbimp = NULL;
Packit 5ce601
static bool initialize_done = false;
Packit 5ce601
static isc_mutex_t reflock;
Packit 5ce601
static unsigned int references = 0;
Packit 5ce601
Packit 5ce601
static void
Packit 5ce601
initialize(void) {
Packit 5ce601
	isc_result_t result;
Packit 5ce601
Packit 5ce601
	REQUIRE(initialize_done == false);
Packit 5ce601
Packit 5ce601
	result = isc_mem_create(0, 0, &dns_g_mctx);
Packit 5ce601
	if (result != ISC_R_SUCCESS)
Packit 5ce601
		return;
Packit 5ce601
	dns_result_register();
Packit 5ce601
	result = dns_ecdb_register(dns_g_mctx, &dbimp);
Packit 5ce601
	if (result != ISC_R_SUCCESS)
Packit 5ce601
		goto cleanup_mctx;
Packit Service 111ee5
	result = isc_hash_create(dns_g_mctx, NULL, DNS_NAME_MAXWIRE);
Packit Service 111ee5
	if (result != ISC_R_SUCCESS)
Packit Service d3afd5
		goto cleanup_db;
Packit 5ce601
Packit Service d3afd5
	result = dst_lib_init(dns_g_mctx, NULL, 0);
Packit 5ce601
	if (result != ISC_R_SUCCESS)
Packit 5ce601
		goto cleanup_hash;
Packit 5ce601
Packit 5ce601
	result = isc_mutex_init(&reflock);
Packit 5ce601
	if (result != ISC_R_SUCCESS)
Packit 5ce601
		goto cleanup_dst;
Packit 5ce601
Packit 5ce601
	initialize_done = true;
Packit 5ce601
	return;
Packit 5ce601
Packit 5ce601
  cleanup_dst:
Packit 5ce601
	dst_lib_destroy();
Packit 5ce601
  cleanup_hash:
Packit 5ce601
	isc_hash_destroy();
Packit 5ce601
  cleanup_db:
Packit 5ce601
	if (dbimp != NULL)
Packit 5ce601
		dns_ecdb_unregister(&dbimp);
Packit 5ce601
  cleanup_mctx:
Packit 5ce601
	if (dns_g_mctx != NULL)
Packit 5ce601
		isc_mem_detach(&dns_g_mctx);
Packit 5ce601
}
Packit 5ce601
Packit 5ce601
isc_result_t
Packit 5ce601
dns_lib_init(void) {
Packit 5ce601
	isc_result_t result;
Packit 5ce601
Packit 5ce601
	/*
Packit 5ce601
	 * Since this routine is expected to be used by a normal application,
Packit 5ce601
	 * it should be better to return an error, instead of an emergency
Packit 5ce601
	 * abort, on any failure.
Packit 5ce601
	 */
Packit 5ce601
	result = isc_once_do(&init_once, initialize);
Packit 5ce601
	if (result != ISC_R_SUCCESS)
Packit 5ce601
		return (result);
Packit 5ce601
Packit 5ce601
	if (!initialize_done)
Packit 5ce601
		return (ISC_R_FAILURE);
Packit 5ce601
Packit 5ce601
	LOCK(&reflock);
Packit 5ce601
	references++;
Packit 5ce601
	UNLOCK(&reflock);
Packit 5ce601
Packit 5ce601
	return (ISC_R_SUCCESS);
Packit 5ce601
}
Packit 5ce601
Packit 5ce601
void
Packit 5ce601
dns_lib_shutdown(void) {
Packit 5ce601
	bool cleanup_ok = false;
Packit 5ce601
Packit 5ce601
	LOCK(&reflock);
Packit 5ce601
	if (--references == 0)
Packit 5ce601
		cleanup_ok = true;
Packit 5ce601
	UNLOCK(&reflock);
Packit 5ce601
Packit 5ce601
	if (!cleanup_ok)
Packit 5ce601
		return;
Packit 5ce601
Packit 5ce601
	dst_lib_destroy();
Packit 5ce601
Packit 5ce601
	if (isc_hashctx != NULL)
Packit 5ce601
		isc_hash_destroy();
Packit 5ce601
	if (dbimp != NULL)
Packit 5ce601
		dns_ecdb_unregister(&dbimp);
Packit 5ce601
	if (dns_g_mctx != NULL)
Packit 5ce601
		isc_mem_detach(&dns_g_mctx);
Packit 5ce601
}