dlz_dlopen_driver.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2011-2014  Internet Systems Consortium, Inc. ("ISC")
00003  *
00004  * Permission to use, copy, modify, and/or distribute this software for any
00005  * purpose with or without fee is hereby granted, provided that the above
00006  * copyright notice and this permission notice appear in all copies.
00007  *
00008  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
00009  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
00010  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
00011  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
00012  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
00013  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
00014  * PERFORMANCE OF THIS SOFTWARE.
00015  */
00016 
00017 /* $Id$ */
00018 
00019 #include <config.h>
00020 
00021 #include <stdio.h>
00022 #include <string.h>
00023 #include <stdlib.h>
00024 #include <dlfcn.h>
00025 
00026 #include <dns/log.h>
00027 #include <dns/result.h>
00028 #include <dns/dlz_dlopen.h>
00029 
00030 #include <isc/mem.h>
00031 #include <isc/print.h>
00032 #include <isc/result.h>
00033 #include <isc/util.h>
00034 
00035 #include <named/globals.h>
00036 
00037 #include <dlz/dlz_dlopen_driver.h>
00038 
00039 #ifdef ISC_DLZ_DLOPEN
00040 static dns_sdlzimplementation_t *dlz_dlopen = NULL;
00041 
00042 
00043 typedef struct dlopen_data {
00044         isc_mem_t *mctx;
00045         char *dl_path;
00046         char *dlzname;
00047         void *dl_handle;
00048         void *dbdata;
00049         unsigned int flags;
00050         isc_mutex_t lock;
00051         int version;
00052         isc_boolean_t in_configure;
00053 
00054         dlz_dlopen_version_t *dlz_version;
00055         dlz_dlopen_create_t *dlz_create;
00056         dlz_dlopen_findzonedb_t *dlz_findzonedb;
00057         dlz_dlopen_lookup_t *dlz_lookup;
00058         dlz_dlopen_authority_t *dlz_authority;
00059         dlz_dlopen_allnodes_t *dlz_allnodes;
00060         dlz_dlopen_allowzonexfr_t *dlz_allowzonexfr;
00061         dlz_dlopen_newversion_t *dlz_newversion;
00062         dlz_dlopen_closeversion_t *dlz_closeversion;
00063         dlz_dlopen_configure_t *dlz_configure;
00064         dlz_dlopen_ssumatch_t *dlz_ssumatch;
00065         dlz_dlopen_addrdataset_t *dlz_addrdataset;
00066         dlz_dlopen_subrdataset_t *dlz_subrdataset;
00067         dlz_dlopen_delrdataset_t *dlz_delrdataset;
00068         dlz_dlopen_destroy_t *dlz_destroy;
00069 } dlopen_data_t;
00070 
00071 /* Modules can choose whether they are lock-safe or not. */
00072 #define MAYBE_LOCK(cd) \
00073         do { \
00074                 if ((cd->flags & DNS_SDLZFLAG_THREADSAFE) == 0 && \
00075                     cd->in_configure == ISC_FALSE) \
00076                         LOCK(&cd->lock); \
00077         } while (0)
00078 
00079 #define MAYBE_UNLOCK(cd) \
00080         do { \
00081                 if ((cd->flags & DNS_SDLZFLAG_THREADSAFE) == 0 && \
00082                     cd->in_configure == ISC_FALSE) \
00083                         UNLOCK(&cd->lock); \
00084         } while (0)
00085 
00086 /*
00087  * Log a message at the given level.
00088  */
00089 static void dlopen_log(int level, const char *fmt, ...)
00090 {
00091         va_list ap;
00092         va_start(ap, fmt);
00093         isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_DATABASE,
00094                        DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(level),
00095                        fmt, ap);
00096         va_end(ap);
00097 }
00098 
00099 /*
00100  * SDLZ methods
00101  */
00102 
00103 static isc_result_t
00104 dlopen_dlz_allnodes(const char *zone, void *driverarg, void *dbdata,
00105                     dns_sdlzallnodes_t *allnodes)
00106 {
00107         dlopen_data_t *cd = (dlopen_data_t *) dbdata;
00108         isc_result_t result;
00109 
00110 
00111         UNUSED(driverarg);
00112 
00113         if (cd->dlz_allnodes == NULL) {
00114                 return (ISC_R_NOPERM);
00115         }
00116 
00117         MAYBE_LOCK(cd);
00118         result = cd->dlz_allnodes(zone, cd->dbdata, allnodes);
00119         MAYBE_UNLOCK(cd);
00120         return (result);
00121 }
00122 
00123 
00124 static isc_result_t
00125 dlopen_dlz_allowzonexfr(void *driverarg, void *dbdata, const char *name,
00126                         const char *client)
00127 {
00128         dlopen_data_t *cd = (dlopen_data_t *) dbdata;
00129         isc_result_t result;
00130 
00131         UNUSED(driverarg);
00132 
00133 
00134         if (cd->dlz_allowzonexfr == NULL) {
00135                 return (ISC_R_NOPERM);
00136         }
00137 
00138         MAYBE_LOCK(cd);
00139         result = cd->dlz_allowzonexfr(cd->dbdata, name, client);
00140         MAYBE_UNLOCK(cd);
00141         return (result);
00142 }
00143 
00144 static isc_result_t
00145 dlopen_dlz_authority(const char *zone, void *driverarg, void *dbdata,
00146                      dns_sdlzlookup_t *lookup)
00147 {
00148         dlopen_data_t *cd = (dlopen_data_t *) dbdata;
00149         isc_result_t result;
00150 
00151         UNUSED(driverarg);
00152 
00153         if (cd->dlz_authority == NULL) {
00154                 return (ISC_R_NOTIMPLEMENTED);
00155         }
00156 
00157         MAYBE_LOCK(cd);
00158         result = cd->dlz_authority(zone, cd->dbdata, lookup);
00159         MAYBE_UNLOCK(cd);
00160         return (result);
00161 }
00162 
00163 static isc_result_t
00164 dlopen_dlz_findzonedb(void *driverarg, void *dbdata, const char *name,
00165                       dns_clientinfomethods_t *methods,
00166                       dns_clientinfo_t *clientinfo)
00167 {
00168         dlopen_data_t *cd = (dlopen_data_t *) dbdata;
00169         isc_result_t result;
00170 
00171         UNUSED(driverarg);
00172 
00173         MAYBE_LOCK(cd);
00174         result = cd->dlz_findzonedb(cd->dbdata, name, methods, clientinfo);
00175         MAYBE_UNLOCK(cd);
00176         return (result);
00177 }
00178 
00179 
00180 static isc_result_t
00181 dlopen_dlz_lookup(const char *zone, const char *name, void *driverarg,
00182                   void *dbdata, dns_sdlzlookup_t *lookup,
00183                   dns_clientinfomethods_t *methods,
00184                   dns_clientinfo_t *clientinfo)
00185 {
00186         dlopen_data_t *cd = (dlopen_data_t *) dbdata;
00187         isc_result_t result;
00188 
00189         UNUSED(driverarg);
00190 
00191         MAYBE_LOCK(cd);
00192         result = cd->dlz_lookup(zone, name, cd->dbdata, lookup,
00193                                 methods, clientinfo);
00194         MAYBE_UNLOCK(cd);
00195         return (result);
00196 }
00197 
00198 /*
00199  * Load a symbol from the library
00200  */
00201 static void *
00202 dl_load_symbol(dlopen_data_t *cd, const char *symbol, isc_boolean_t mandatory) {
00203         void *ptr = dlsym(cd->dl_handle, symbol);
00204         if (ptr == NULL && mandatory) {
00205                 dlopen_log(ISC_LOG_ERROR,
00206                            "dlz_dlopen: library '%s' is missing "
00207                            "required symbol '%s'", cd->dl_path, symbol);
00208         }
00209         return (ptr);
00210 }
00211 
00212 /*
00213  * Called at startup for each dlopen zone in named.conf
00214  */
00215 static isc_result_t
00216 dlopen_dlz_create(const char *dlzname, unsigned int argc, char *argv[],
00217                   void *driverarg, void **dbdata)
00218 {
00219         dlopen_data_t *cd;
00220         isc_mem_t *mctx = NULL;
00221         isc_result_t result = ISC_R_FAILURE;
00222         int dlopen_flags = 0;
00223 
00224         UNUSED(driverarg);
00225 
00226         if (argc < 2) {
00227                 dlopen_log(ISC_LOG_ERROR,
00228                            "dlz_dlopen driver for '%s' needs a path to "
00229                            "the shared library", dlzname);
00230                 return (ISC_R_FAILURE);
00231         }
00232 
00233         result = isc_mem_create(0, 0, &mctx);
00234         if (result != ISC_R_SUCCESS)
00235                 return (result);
00236 
00237         cd = isc_mem_get(mctx, sizeof(*cd));
00238         if (cd == NULL) {
00239                 isc_mem_destroy(&mctx);
00240                 return (ISC_R_NOMEMORY);
00241         }
00242         memset(cd, 0, sizeof(*cd));
00243 
00244         cd->mctx = mctx;
00245 
00246         cd->dl_path = isc_mem_strdup(cd->mctx, argv[1]);
00247         if (cd->dl_path == NULL) {
00248                 result = ISC_R_NOMEMORY;
00249                 goto failed;
00250         }
00251 
00252         cd->dlzname = isc_mem_strdup(cd->mctx, dlzname);
00253         if (cd->dlzname == NULL) {
00254                 result = ISC_R_NOMEMORY;
00255                 goto failed;
00256         }
00257 
00258         /* Initialize the lock */
00259         result = isc_mutex_init(&cd->lock);
00260         if (result != ISC_R_SUCCESS)
00261                 goto failed;
00262 
00263         /* Open the library */
00264         dlopen_flags = RTLD_NOW|RTLD_GLOBAL;
00265 
00266 #ifdef RTLD_DEEPBIND
00267         /*
00268          * If RTLD_DEEPBIND is available then use it. This can avoid
00269          * issues with a module using a different version of a system
00270          * library than one that bind9 uses. For example, bind9 may link
00271          * to MIT kerberos, but the module may use Heimdal. If we don't
00272          * use RTLD_DEEPBIND then we could end up with Heimdal functions
00273          * calling MIT functions, which leads to bizarre results (usually
00274          * a segfault).
00275          */
00276         dlopen_flags |= RTLD_DEEPBIND;
00277 #endif
00278 
00279         cd->dl_handle = dlopen(cd->dl_path, dlopen_flags);
00280         if (cd->dl_handle == NULL) {
00281                 dlopen_log(ISC_LOG_ERROR,
00282                            "dlz_dlopen failed to open library '%s' - %s",
00283                            cd->dl_path, dlerror());
00284                 result = ISC_R_FAILURE;
00285                 goto failed;
00286         }
00287 
00288         /* Find the symbols */
00289         cd->dlz_version = (dlz_dlopen_version_t *)
00290                 dl_load_symbol(cd, "dlz_version", ISC_TRUE);
00291         cd->dlz_create = (dlz_dlopen_create_t *)
00292                 dl_load_symbol(cd, "dlz_create", ISC_TRUE);
00293         cd->dlz_lookup = (dlz_dlopen_lookup_t *)
00294                 dl_load_symbol(cd, "dlz_lookup", ISC_TRUE);
00295         cd->dlz_findzonedb = (dlz_dlopen_findzonedb_t *)
00296                 dl_load_symbol(cd, "dlz_findzonedb", ISC_TRUE);
00297 
00298         if (cd->dlz_create == NULL ||
00299             cd->dlz_version == NULL ||
00300             cd->dlz_lookup == NULL ||
00301             cd->dlz_findzonedb == NULL)
00302         {
00303                 /* We're missing a required symbol */
00304                 result = ISC_R_FAILURE;
00305                 goto failed;
00306         }
00307 
00308         cd->dlz_allowzonexfr = (dlz_dlopen_allowzonexfr_t *)
00309                 dl_load_symbol(cd, "dlz_allowzonexfr", ISC_FALSE);
00310         cd->dlz_allnodes = (dlz_dlopen_allnodes_t *)
00311                 dl_load_symbol(cd, "dlz_allnodes",
00312                                ISC_TF(cd->dlz_allowzonexfr != NULL));
00313         cd->dlz_authority = (dlz_dlopen_authority_t *)
00314                 dl_load_symbol(cd, "dlz_authority", ISC_FALSE);
00315         cd->dlz_newversion = (dlz_dlopen_newversion_t *)
00316                 dl_load_symbol(cd, "dlz_newversion", ISC_FALSE);
00317         cd->dlz_closeversion = (dlz_dlopen_closeversion_t *)
00318                 dl_load_symbol(cd, "dlz_closeversion",
00319                                ISC_TF(cd->dlz_newversion != NULL));
00320         cd->dlz_configure = (dlz_dlopen_configure_t *)
00321                 dl_load_symbol(cd, "dlz_configure", ISC_FALSE);
00322         cd->dlz_ssumatch = (dlz_dlopen_ssumatch_t *)
00323                 dl_load_symbol(cd, "dlz_ssumatch", ISC_FALSE);
00324         cd->dlz_addrdataset = (dlz_dlopen_addrdataset_t *)
00325                 dl_load_symbol(cd, "dlz_addrdataset", ISC_FALSE);
00326         cd->dlz_subrdataset = (dlz_dlopen_subrdataset_t *)
00327                 dl_load_symbol(cd, "dlz_subrdataset", ISC_FALSE);
00328         cd->dlz_delrdataset = (dlz_dlopen_delrdataset_t *)
00329                 dl_load_symbol(cd, "dlz_delrdataset", ISC_FALSE);
00330         cd->dlz_destroy = (dlz_dlopen_destroy_t *)
00331                 dl_load_symbol(cd, "dlz_destroy", ISC_FALSE);
00332 
00333         /* Check the version of the API is the same */
00334         cd->version = cd->dlz_version(&cd->flags);
00335         if (cd->version < (DLZ_DLOPEN_VERSION - DLZ_DLOPEN_AGE) ||
00336             cd->version > DLZ_DLOPEN_VERSION)
00337         {
00338                 dlopen_log(ISC_LOG_ERROR,
00339                            "dlz_dlopen: %s: incorrect driver API version %d, "
00340                            "requires %d",
00341                            cd->dl_path, cd->version, DLZ_DLOPEN_VERSION);
00342                 result = ISC_R_FAILURE;
00343                 goto failed;
00344         }
00345 
00346         /*
00347          * Call the library's create function. Note that this is an
00348          * extended version of dlz create, with the addition of
00349          * named function pointers for helper functions that the
00350          * driver will need. This avoids the need for the backend to
00351          * link the BIND9 libraries
00352          */
00353         MAYBE_LOCK(cd);
00354         result = cd->dlz_create(dlzname, argc-1, argv+1,
00355                                 &cd->dbdata,
00356                                 "log", dlopen_log,
00357                                 "putrr", dns_sdlz_putrr,
00358                                 "putnamedrr", dns_sdlz_putnamedrr,
00359                                 "writeable_zone", dns_dlz_writeablezone,
00360                                 NULL);
00361         MAYBE_UNLOCK(cd);
00362         if (result != ISC_R_SUCCESS)
00363                 goto failed;
00364 
00365         *dbdata = cd;
00366 
00367         return (ISC_R_SUCCESS);
00368 
00369 failed:
00370         dlopen_log(ISC_LOG_ERROR, "dlz_dlopen of '%s' failed", dlzname);
00371         if (cd->dl_path != NULL)
00372                 isc_mem_free(mctx, cd->dl_path);
00373         if (cd->dlzname != NULL)
00374                 isc_mem_free(mctx, cd->dlzname);
00375         if (dlopen_flags != 0)
00376                 (void) isc_mutex_destroy(&cd->lock);
00377 #ifdef HAVE_DLCLOSE
00378         if (cd->dl_handle)
00379                 dlclose(cd->dl_handle);
00380 #endif
00381         isc_mem_put(mctx, cd, sizeof(*cd));
00382         isc_mem_destroy(&mctx);
00383         return (result);
00384 }
00385 
00386 /*
00387  * Called when bind is shutting down
00388  */
00389 static void
00390 dlopen_dlz_destroy(void *driverarg, void *dbdata) {
00391         dlopen_data_t *cd = (dlopen_data_t *) dbdata;
00392         isc_mem_t *mctx;
00393 
00394         UNUSED(driverarg);
00395 
00396         if (cd->dlz_destroy) {
00397                 MAYBE_LOCK(cd);
00398                 cd->dlz_destroy(cd->dbdata);
00399                 MAYBE_UNLOCK(cd);
00400         }
00401 
00402         if (cd->dl_path)
00403                 isc_mem_free(cd->mctx, cd->dl_path);
00404         if (cd->dlzname)
00405                 isc_mem_free(cd->mctx, cd->dlzname);
00406 
00407 #ifdef HAVE_DLCLOSE
00408         if (cd->dl_handle)
00409                 dlclose(cd->dl_handle);
00410 #endif
00411 
00412         (void) isc_mutex_destroy(&cd->lock);
00413 
00414         mctx = cd->mctx;
00415         isc_mem_put(mctx, cd, sizeof(*cd));
00416         isc_mem_destroy(&mctx);
00417 }
00418 
00419 /*
00420  * Called to start a transaction
00421  */
00422 static isc_result_t
00423 dlopen_dlz_newversion(const char *zone, void *driverarg, void *dbdata,
00424                       void **versionp)
00425 {
00426         dlopen_data_t *cd = (dlopen_data_t *) dbdata;
00427         isc_result_t result;
00428 
00429         UNUSED(driverarg);
00430 
00431         if (cd->dlz_newversion == NULL)
00432                 return (ISC_R_NOTIMPLEMENTED);
00433 
00434         MAYBE_LOCK(cd);
00435         result = cd->dlz_newversion(zone, cd->dbdata, versionp);
00436         MAYBE_UNLOCK(cd);
00437         return (result);
00438 }
00439 
00440 /*
00441  * Called to end a transaction
00442  */
00443 static void
00444 dlopen_dlz_closeversion(const char *zone, isc_boolean_t commit,
00445                         void *driverarg, void *dbdata, void **versionp)
00446 {
00447         dlopen_data_t *cd = (dlopen_data_t *) dbdata;
00448 
00449         UNUSED(driverarg);
00450 
00451         if (cd->dlz_newversion == NULL) {
00452                 *versionp = NULL;
00453                 return;
00454         }
00455 
00456         MAYBE_LOCK(cd);
00457         cd->dlz_closeversion(zone, commit, cd->dbdata, versionp);
00458         MAYBE_UNLOCK(cd);
00459 }
00460 
00461 /*
00462  * Called on startup to configure any writeable zones
00463  */
00464 static isc_result_t
00465 dlopen_dlz_configure(dns_view_t *view, dns_dlzdb_t *dlzdb,
00466                      void *driverarg, void *dbdata)
00467 {
00468         dlopen_data_t *cd = (dlopen_data_t *) dbdata;
00469         isc_result_t result;
00470 
00471         UNUSED(driverarg);
00472 
00473         if (cd->dlz_configure == NULL)
00474                 return (ISC_R_SUCCESS);
00475 
00476         MAYBE_LOCK(cd);
00477         cd->in_configure = ISC_TRUE;
00478         result = cd->dlz_configure(view, dlzdb, cd->dbdata);
00479         cd->in_configure = ISC_FALSE;
00480         MAYBE_UNLOCK(cd);
00481 
00482         return (result);
00483 }
00484 
00485 
00486 /*
00487  * Check for authority to change a name
00488  */
00489 static isc_boolean_t
00490 dlopen_dlz_ssumatch(const char *signer, const char *name, const char *tcpaddr,
00491                     const char *type, const char *key, isc_uint32_t keydatalen,
00492                     unsigned char *keydata, void *driverarg, void *dbdata)
00493 {
00494         dlopen_data_t *cd = (dlopen_data_t *) dbdata;
00495         isc_boolean_t ret;
00496 
00497         UNUSED(driverarg);
00498 
00499         if (cd->dlz_ssumatch == NULL)
00500                 return (ISC_FALSE);
00501 
00502         MAYBE_LOCK(cd);
00503         ret = cd->dlz_ssumatch(signer, name, tcpaddr, type, key, keydatalen,
00504                                keydata, cd->dbdata);
00505         MAYBE_UNLOCK(cd);
00506 
00507         return (ret);
00508 }
00509 
00510 
00511 /*
00512  * Add an rdataset
00513  */
00514 static isc_result_t
00515 dlopen_dlz_addrdataset(const char *name, const char *rdatastr,
00516                        void *driverarg, void *dbdata, void *version)
00517 {
00518         dlopen_data_t *cd = (dlopen_data_t *) dbdata;
00519         isc_result_t result;
00520 
00521         UNUSED(driverarg);
00522 
00523         if (cd->dlz_addrdataset == NULL)
00524                 return (ISC_R_NOTIMPLEMENTED);
00525 
00526         MAYBE_LOCK(cd);
00527         result = cd->dlz_addrdataset(name, rdatastr, cd->dbdata, version);
00528         MAYBE_UNLOCK(cd);
00529 
00530         return (result);
00531 }
00532 
00533 /*
00534  * Subtract an rdataset
00535  */
00536 static isc_result_t
00537 dlopen_dlz_subrdataset(const char *name, const char *rdatastr,
00538                        void *driverarg, void *dbdata, void *version)
00539 {
00540         dlopen_data_t *cd = (dlopen_data_t *) dbdata;
00541         isc_result_t result;
00542 
00543         UNUSED(driverarg);
00544 
00545         if (cd->dlz_subrdataset == NULL)
00546                 return (ISC_R_NOTIMPLEMENTED);
00547 
00548         MAYBE_LOCK(cd);
00549         result = cd->dlz_subrdataset(name, rdatastr, cd->dbdata, version);
00550         MAYBE_UNLOCK(cd);
00551 
00552         return (result);
00553 }
00554 
00555 /*
00556   delete a rdataset
00557  */
00558 static isc_result_t
00559 dlopen_dlz_delrdataset(const char *name, const char *type,
00560                        void *driverarg, void *dbdata, void *version)
00561 {
00562         dlopen_data_t *cd = (dlopen_data_t *) dbdata;
00563         isc_result_t result;
00564 
00565         UNUSED(driverarg);
00566 
00567         if (cd->dlz_delrdataset == NULL)
00568                 return (ISC_R_NOTIMPLEMENTED);
00569 
00570         MAYBE_LOCK(cd);
00571         result = cd->dlz_delrdataset(name, type, cd->dbdata, version);
00572         MAYBE_UNLOCK(cd);
00573 
00574         return (result);
00575 }
00576 
00577 
00578 static dns_sdlzmethods_t dlz_dlopen_methods = {
00579         dlopen_dlz_create,
00580         dlopen_dlz_destroy,
00581         dlopen_dlz_findzonedb,
00582         dlopen_dlz_lookup,
00583         dlopen_dlz_authority,
00584         dlopen_dlz_allnodes,
00585         dlopen_dlz_allowzonexfr,
00586         dlopen_dlz_newversion,
00587         dlopen_dlz_closeversion,
00588         dlopen_dlz_configure,
00589         dlopen_dlz_ssumatch,
00590         dlopen_dlz_addrdataset,
00591         dlopen_dlz_subrdataset,
00592         dlopen_dlz_delrdataset
00593 };
00594 #endif
00595 
00596 /*
00597  * Register driver with BIND
00598  */
00599 isc_result_t
00600 dlz_dlopen_init(isc_mem_t *mctx) {
00601 #ifndef ISC_DLZ_DLOPEN
00602         UNUSED(mctx);
00603         return (ISC_R_NOTIMPLEMENTED);
00604 #else
00605         isc_result_t result;
00606 
00607         dlopen_log(2, "Registering DLZ_dlopen driver");
00608 
00609         result = dns_sdlzregister("dlopen", &dlz_dlopen_methods, NULL,
00610                                   DNS_SDLZFLAG_RELATIVEOWNER |
00611                                   DNS_SDLZFLAG_RELATIVERDATA |
00612                                   DNS_SDLZFLAG_THREADSAFE,
00613                                   mctx, &dlz_dlopen);
00614 
00615         if (result != ISC_R_SUCCESS) {
00616                 UNEXPECTED_ERROR(__FILE__, __LINE__,
00617                                  "dns_sdlzregister() failed: %s",
00618                                  isc_result_totext(result));
00619                 result = ISC_R_UNEXPECTED;
00620         }
00621 
00622         return (result);
00623 #endif
00624 }
00625 
00626 
00627 /*
00628  * Unregister the driver
00629  */
00630 void
00631 dlz_dlopen_clear(void) {
00632 #ifdef ISC_DLZ_DLOPEN
00633         dlopen_log(2, "Unregistering DLZ_dlopen driver");
00634         if (dlz_dlopen != NULL)
00635                 dns_sdlzunregister(&dlz_dlopen);
00636 #endif
00637 }

Generated on Tue Apr 28 17:40:55 2015 by Doxygen 1.5.4 for BIND9 Internals 9.11.0pre-alpha