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