1 /* $NetBSD: lib.c,v 1.7 2014/12/10 04:37:58 christos Exp $ */ 2 3 /* 4 * Copyright (C) 2004, 2005, 2007, 2009, 2013, 2014 Internet Systems Consortium, Inc. ("ISC") 5 * Copyright (C) 1999-2001 Internet Software Consortium. 6 * 7 * Permission to use, copy, modify, and/or distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /* Id: lib.c,v 1.19 2009/09/03 00:12:23 each Exp */ 21 22 /*! \file */ 23 24 #include <config.h> 25 26 #include <stddef.h> 27 28 #include <isc/hash.h> 29 #include <isc/mem.h> 30 #include <isc/msgcat.h> 31 #include <isc/mutex.h> 32 #include <isc/once.h> 33 #include <isc/util.h> 34 35 #include <dns/db.h> 36 #include <dns/ecdb.h> 37 #include <dns/lib.h> 38 #include <dns/result.h> 39 40 #include <dst/dst.h> 41 42 43 /*** 44 *** Globals 45 ***/ 46 47 LIBDNS_EXTERNAL_DATA unsigned int dns_pps = 0U; 48 LIBDNS_EXTERNAL_DATA isc_msgcat_t * dns_msgcat = NULL; 49 50 51 /*** 52 *** Private 53 ***/ 54 55 static isc_once_t msgcat_once = ISC_ONCE_INIT; 56 57 58 /*** 59 *** Functions 60 ***/ 61 62 static void 63 open_msgcat(void) { 64 isc_msgcat_open("libdns.cat", &dns_msgcat); 65 } 66 67 void 68 dns_lib_initmsgcat(void) { 69 70 /* 71 * Initialize the DNS library's message catalog, dns_msgcat, if it 72 * has not already been initialized. 73 */ 74 75 RUNTIME_CHECK(isc_once_do(&msgcat_once, open_msgcat) == ISC_R_SUCCESS); 76 } 77 78 static isc_once_t init_once = ISC_ONCE_INIT; 79 static isc_mem_t *dns_g_mctx = NULL; 80 static dns_dbimplementation_t *dbimp = NULL; 81 static isc_boolean_t initialize_done = ISC_FALSE; 82 static isc_mutex_t reflock; 83 static unsigned int references = 0; 84 85 static void 86 initialize(void) { 87 isc_result_t result; 88 89 REQUIRE(initialize_done == ISC_FALSE); 90 91 result = isc_mem_create(0, 0, &dns_g_mctx); 92 if (result != ISC_R_SUCCESS) 93 return; 94 dns_result_register(); 95 result = dns_ecdb_register(dns_g_mctx, &dbimp); 96 if (result != ISC_R_SUCCESS) 97 goto cleanup_mctx; 98 result = isc_hash_create(dns_g_mctx, NULL, DNS_NAME_MAXWIRE); 99 if (result != ISC_R_SUCCESS) 100 goto cleanup_db; 101 102 result = dst_lib_init(dns_g_mctx, NULL, 0); 103 if (result != ISC_R_SUCCESS) 104 goto cleanup_hash; 105 106 result = isc_mutex_init(&reflock); 107 if (result != ISC_R_SUCCESS) 108 goto cleanup_dst; 109 110 initialize_done = ISC_TRUE; 111 return; 112 113 cleanup_dst: 114 dst_lib_destroy(); 115 cleanup_hash: 116 isc_hash_destroy(); 117 cleanup_db: 118 if (dbimp != NULL) 119 dns_ecdb_unregister(&dbimp); 120 cleanup_mctx: 121 if (dns_g_mctx != NULL) 122 isc_mem_detach(&dns_g_mctx); 123 } 124 125 isc_result_t 126 dns_lib_init(void) { 127 isc_result_t result; 128 129 /* 130 * Since this routine is expected to be used by a normal application, 131 * it should be better to return an error, instead of an emergency 132 * abort, on any failure. 133 */ 134 result = isc_once_do(&init_once, initialize); 135 if (result != ISC_R_SUCCESS) 136 return (result); 137 138 if (!initialize_done) 139 return (ISC_R_FAILURE); 140 141 LOCK(&reflock); 142 references++; 143 UNLOCK(&reflock); 144 145 return (ISC_R_SUCCESS); 146 } 147 148 void 149 dns_lib_shutdown(void) { 150 isc_boolean_t cleanup_ok = ISC_FALSE; 151 152 LOCK(&reflock); 153 if (--references == 0) 154 cleanup_ok = ISC_TRUE; 155 UNLOCK(&reflock); 156 157 if (!cleanup_ok) 158 return; 159 160 dst_lib_destroy(); 161 isc_hash_destroy(); 162 if (dbimp != NULL) 163 dns_ecdb_unregister(&dbimp); 164 if (dns_g_mctx != NULL) 165 isc_mem_detach(&dns_g_mctx); 166 } 167