xref: /netbsd-src/external/mpl/dhcp/bind/dist/lib/dns/lib.c (revision 4afad4b7fa6d4a0d3dedf41d1587a7250710ae54)
1 /*	$NetBSD: lib.c,v 1.1 2024/02/18 20:57:32 christos Exp $	*/
2 
3 /*
4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5  *
6  * SPDX-License-Identifier: MPL-2.0
7  *
8  * This Source Code Form is subject to the terms of the Mozilla Public
9  * License, v. 2.0.  If a copy of the MPL was not distributed with this
10  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
11  *
12  * See the COPYRIGHT file distributed with this work for additional
13  * information regarding copyright ownership.
14  */
15 
16 /*! \file */
17 
18 #include <stdbool.h>
19 #include <stddef.h>
20 
21 #include <isc/hash.h>
22 #include <isc/mem.h>
23 #include <isc/mutex.h>
24 #include <isc/once.h>
25 #include <isc/refcount.h>
26 #include <isc/util.h>
27 
28 #include <dns/db.h>
29 #include <dns/ecdb.h>
30 #include <dns/lib.h>
31 #include <dns/result.h>
32 
33 #include <dst/dst.h>
34 
35 /***
36  *** Globals
37  ***/
38 
39 LIBDNS_EXTERNAL_DATA unsigned int dns_pps = 0U;
40 
41 /***
42  *** Functions
43  ***/
44 
45 static isc_once_t init_once = ISC_ONCE_INIT;
46 static isc_mem_t *dns_g_mctx = NULL;
47 static dns_dbimplementation_t *dbimp = NULL;
48 static bool initialize_done = false;
49 static isc_refcount_t references;
50 
51 static void
initialize(void)52 initialize(void) {
53 	isc_result_t result;
54 
55 	REQUIRE(!initialize_done);
56 
57 	isc_refcount_init(&references, 0);
58 
59 	isc_mem_create(&dns_g_mctx);
60 	dns_result_register();
61 	result = dns_ecdb_register(dns_g_mctx, &dbimp);
62 	if (result != ISC_R_SUCCESS) {
63 		goto cleanup_mctx;
64 	}
65 
66 	result = dst_lib_init(dns_g_mctx, NULL);
67 	if (result != ISC_R_SUCCESS) {
68 		goto cleanup_db;
69 	}
70 
71 	initialize_done = true;
72 	return;
73 
74 cleanup_db:
75 	if (dbimp != NULL) {
76 		dns_ecdb_unregister(&dbimp);
77 	}
78 cleanup_mctx:
79 	if (dns_g_mctx != NULL) {
80 		isc_mem_detach(&dns_g_mctx);
81 	}
82 }
83 
84 isc_result_t
dns_lib_init(void)85 dns_lib_init(void) {
86 	isc_result_t result;
87 
88 	/*
89 	 * Since this routine is expected to be used by a normal application,
90 	 * it should be better to return an error, instead of an emergency
91 	 * abort, on any failure.
92 	 */
93 	result = isc_once_do(&init_once, initialize);
94 	if (result != ISC_R_SUCCESS) {
95 		return (result);
96 	}
97 
98 	if (!initialize_done) {
99 		return (ISC_R_FAILURE);
100 	}
101 
102 	isc_refcount_increment0(&references);
103 
104 	return (ISC_R_SUCCESS);
105 }
106 
107 void
dns_lib_shutdown(void)108 dns_lib_shutdown(void) {
109 	if (isc_refcount_decrement(&references) == 1) {
110 		dst_lib_destroy();
111 
112 		isc_refcount_destroy(&references);
113 
114 		if (dbimp != NULL) {
115 			dns_ecdb_unregister(&dbimp);
116 		}
117 		if (dns_g_mctx != NULL) {
118 			isc_mem_detach(&dns_g_mctx);
119 		}
120 	}
121 }
122