📄 sdlz.c
字号:
NULL, NULL, NULL};static voidlist_tordataset(dns_rdatalist_t *rdatalist, dns_db_t *db, dns_dbnode_t *node, dns_rdataset_t *rdataset){ /* * The sdlz rdataset is an rdatalist with some additions. * - private1 & private2 are used by the rdatalist. * - private3 & private 4 are unused. * - private5 is the node. */ /* This should never fail. */ RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset) == ISC_R_SUCCESS); rdataset->methods = &rdataset_methods; dns_db_attachnode(db, node, &rdataset->private5);}/* * SDLZ core methods. This is the core of the new DLZ functionality. *//*% * Build a 'bind' database driver structure to be returned by * either the find zone or the allow zone transfer method. * This method is only available in this source file, it is * not made available anywhere else. */static isc_result_tdns_sdlzcreateDBP(isc_mem_t *mctx, void *driverarg, void *dbdata, dns_name_t *name, dns_rdataclass_t rdclass, dns_db_t **dbp){ isc_result_t result; dns_sdlz_db_t *sdlzdb; dns_sdlzimplementation_t *imp; /* check that things are as we expect */ REQUIRE(dbp != NULL && *dbp == NULL); REQUIRE(name != NULL); imp = (dns_sdlzimplementation_t *) driverarg; /* allocate and zero memory for driver structure */ sdlzdb = isc_mem_get(mctx, sizeof(dns_sdlz_db_t)); if (sdlzdb == NULL) return (ISC_R_NOMEMORY); memset(sdlzdb, 0, sizeof(dns_sdlz_db_t)); /* initialize and set origin */ dns_name_init(&sdlzdb->common.origin, NULL); result = dns_name_dupwithoffsets(name, mctx, &sdlzdb->common.origin); if (result != ISC_R_SUCCESS) goto mem_cleanup; /* initialize the reference count mutex */ result = isc_mutex_init(&sdlzdb->refcnt_lock); if (result != ISC_R_SUCCESS) goto name_cleanup; /* set the rest of the database structure attributes */ sdlzdb->dlzimp = imp; sdlzdb->common.methods = &sdlzdb_methods; sdlzdb->common.attributes = 0; sdlzdb->common.rdclass = rdclass; sdlzdb->common.mctx = NULL; sdlzdb->dbdata = dbdata; sdlzdb->references = 1; /* attach to the memory context */ isc_mem_attach(mctx, &sdlzdb->common.mctx); /* mark structure as valid */ sdlzdb->common.magic = DNS_DB_MAGIC; sdlzdb->common.impmagic = SDLZDB_MAGIC; *dbp = (dns_db_t *) sdlzdb; return (result); /* * reference count mutex could not be initialized, clean up * name memory */ name_cleanup: dns_name_free(&sdlzdb->common.origin, mctx); mem_cleanup: isc_mem_put(mctx, sdlzdb, sizeof(dns_sdlz_db_t)); return (result);}static isc_result_tdns_sdlzallowzonexfr(void *driverarg, void *dbdata, isc_mem_t *mctx, dns_rdataclass_t rdclass, dns_name_t *name, isc_sockaddr_t *clientaddr, dns_db_t **dbp){ isc_buffer_t b; isc_buffer_t b2; char namestr[DNS_NAME_MAXTEXT + 1]; char clientstr[(sizeof "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255") + 1]; isc_netaddr_t netaddr; isc_result_t result; dns_sdlzimplementation_t *imp; /* * Perform checks to make sure data is as we expect it to be. */ REQUIRE(driverarg != NULL); REQUIRE(name != NULL); REQUIRE(clientaddr != NULL); REQUIRE(dbp != NULL && *dbp == NULL); imp = (dns_sdlzimplementation_t *) driverarg; /* Convert DNS name to ascii text */ isc_buffer_init(&b, namestr, sizeof(namestr)); result = dns_name_totext(name, ISC_TRUE, &b); if (result != ISC_R_SUCCESS) return (result); isc_buffer_putuint8(&b, 0); /* convert client address to ascii text */ isc_buffer_init(&b2, clientstr, sizeof(clientstr)); isc_netaddr_fromsockaddr(&netaddr, clientaddr); result = isc_netaddr_totext(&netaddr, &b2); if (result != ISC_R_SUCCESS) return (result); isc_buffer_putuint8(&b2, 0); /* make sure strings are always lowercase */ dns_sdlz_tolower(namestr); dns_sdlz_tolower(clientstr); /* Call SDLZ driver's find zone method */ if (imp->methods->allowzonexfr != NULL) { MAYBE_LOCK(imp); result = imp->methods->allowzonexfr(imp->driverarg, dbdata, namestr, clientstr); MAYBE_UNLOCK(imp); /* * if zone is supported and transfers allowed build a 'bind' * database driver */ if (result == ISC_R_SUCCESS) result = dns_sdlzcreateDBP(mctx, driverarg, dbdata, name, rdclass, dbp); return (result); } return (ISC_R_NOTIMPLEMENTED);}static isc_result_tdns_sdlzcreate(isc_mem_t *mctx, const char *dlzname, unsigned int argc, char *argv[], void *driverarg, void **dbdata){ dns_sdlzimplementation_t *imp; isc_result_t result = ISC_R_NOTFOUND; /* Write debugging message to log */ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2), "Loading SDLZ driver."); /* * Performs checks to make sure data is as we expect it to be. */ REQUIRE(driverarg != NULL); REQUIRE(dlzname != NULL); REQUIRE(dbdata != NULL); UNUSED(mctx); imp = driverarg; /* If the create method exists, call it. */ if (imp->methods->create != NULL) { MAYBE_LOCK(imp); result = imp->methods->create(dlzname, argc, argv, imp->driverarg, dbdata); MAYBE_UNLOCK(imp); } /* Write debugging message to log */ if (result == ISC_R_SUCCESS) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2), "SDLZ driver loaded successfully."); } else { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "SDLZ driver failed to load."); } return (result);}static voiddns_sdlzdestroy(void *driverdata, void **dbdata){ dns_sdlzimplementation_t *imp; /* Write debugging message to log */ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2), "Unloading SDLZ driver."); imp = driverdata; /* If the destroy method exists, call it. */ if (imp->methods->destroy != NULL) { MAYBE_LOCK(imp); imp->methods->destroy(imp->driverarg, dbdata); MAYBE_UNLOCK(imp); }}static isc_result_tdns_sdlzfindzone(void *driverarg, void *dbdata, isc_mem_t *mctx, dns_rdataclass_t rdclass, dns_name_t *name, dns_db_t **dbp){ isc_buffer_t b; char namestr[DNS_NAME_MAXTEXT + 1]; isc_result_t result; dns_sdlzimplementation_t *imp; /* * Perform checks to make sure data is as we expect it to be. */ REQUIRE(driverarg != NULL); REQUIRE(name != NULL); REQUIRE(dbp != NULL && *dbp == NULL); imp = (dns_sdlzimplementation_t *) driverarg; /* Convert DNS name to ascii text */ isc_buffer_init(&b, namestr, sizeof(namestr)); result = dns_name_totext(name, ISC_TRUE, &b); if (result != ISC_R_SUCCESS) return (result); isc_buffer_putuint8(&b, 0); /* make sure strings are always lowercase */ dns_sdlz_tolower(namestr); /* Call SDLZ driver's find zone method */ MAYBE_LOCK(imp); result = imp->methods->findzone(imp->driverarg, dbdata, namestr); MAYBE_UNLOCK(imp); /* * if zone is supported build a 'bind' database driver * structure to return */ if (result == ISC_R_SUCCESS) result = dns_sdlzcreateDBP(mctx, driverarg, dbdata, name, rdclass, dbp); return (result);}static dns_dlzmethods_t sdlzmethods = { dns_sdlzcreate, dns_sdlzdestroy, dns_sdlzfindzone, dns_sdlzallowzonexfr};/* * Public functions. */isc_result_tdns_sdlz_putrr(dns_sdlzlookup_t *lookup, const char *type, dns_ttl_t ttl, const char *data){ dns_rdatalist_t *rdatalist; dns_rdata_t *rdata; dns_rdatatype_t typeval; isc_consttextregion_t r; isc_buffer_t b; isc_buffer_t *rdatabuf = NULL; isc_lex_t *lex; isc_result_t result; unsigned int size; isc_mem_t *mctx; dns_name_t *origin; REQUIRE(VALID_SDLZLOOKUP(lookup)); REQUIRE(type != NULL); REQUIRE(data != NULL); mctx = lookup->sdlz->common.mctx; r.base = type; r.length = strlen(type); result = dns_rdatatype_fromtext(&typeval, (void *) &r); if (result != ISC_R_SUCCESS) return (result); rdatalist = ISC_LIST_HEAD(lookup->lists); while (rdatalist != NULL) { if (rdatalist->type == typeval) break; rdatalist = ISC_LIST_NEXT(rdatalist, link); } if (rdatalist == NULL) { rdatalist = isc_mem_get(mctx, sizeof(dns_rdatalist_t)); if (rdatalist == NULL) return (ISC_R_NOMEMORY); rdatalist->rdclass = lookup->sdlz->common.rdclass; rdatalist->type = typeval; rdatalist->covers = 0; rdatalist->ttl = ttl; ISC_LIST_INIT(rdatalist->rdata); ISC_LINK_INIT(rdatalist, link); ISC_LIST_APPEND(lookup->lists, rdatalist, link); } else if (rdatalist->ttl != ttl) return (DNS_R_BADTTL); rdata = isc_mem_get(mctx, sizeof(dns_rdata_t)); if (rdata == NULL) return (ISC_R_NOMEMORY); dns_rdata_init(rdata); if ((lookup->sdlz->dlzimp->flags & DNS_SDLZFLAG_RELATIVERDATA) != 0) origin = &lookup->sdlz->common.origin; else origin = dns_rootname; lex = NULL; result = isc_lex_create(mctx, 64, &lex); if (result != ISC_R_SUCCESS) goto failure; size = initial_size(data); do { isc_buffer_init(&b, data, strlen(data)); isc_buffer_add(&b, strlen(data)); result = isc_lex_openbuffer(lex, &b); if (result != ISC_R_SUCCESS) goto failure; rdatabuf = NULL; result = isc_buffer_allocate(mctx, &rdatabuf, size); if (result != ISC_R_SUCCESS) goto failure; result = dns_rdata_fromtext(rdata, rdatalist->rdclass, rdatalist->type, lex, origin, ISC_FALSE, mctx, rdatabuf, &lookup->callbacks); if (result != ISC_R_SUCCESS) isc_buffer_free(&rdatabuf); size *= 2; } while (result == ISC_R_NOSPACE); if (result != ISC_R_SUCCESS) goto failure; ISC_LIST_APPEND(rdatalist->rdata, rdata, link); ISC_LIST_APPEND(lookup->buffers, rdatabuf, link); if (lex != NULL) isc_lex_destroy(&lex); return (ISC_R_SUCCESS); failure: if (rdatabuf != NULL) isc_buffer_free(&rdatabuf); if (lex != NULL) isc_lex_destroy(&lex); isc_mem_put(mctx, rdata, sizeof(dns_rdata_t)); return (result);}isc_result_tdns_sdlz_putnamedrr(dns_sdlzallnodes_t *allnodes, const char *name, const char *type, dns_ttl_t ttl, const char *data){ dns_name_t *newname, *origin; dns_fixedname_t fnewname; dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)allnodes->common.db; dns_sdlznode_t *sdlznode; isc_mem_t *mctx = sdlz->common.mctx; isc_buffer_t b; isc_result_t result; dns_fixedname_init(&fnewname); newname = dns_fixedname_name(&fnewname); if ((sdlz->dlzimp->flags & DNS_SDLZFLAG_RELATIVERDATA) != 0) origin = &sdlz->common.origin; else origin = dns_rootname; isc_buffer_init(&b, name, strlen(name)); isc_buffer_add(&b, strlen(name)); result = dns_name_fromtext(newname, &b, origin, ISC_FALSE, NULL); if (result != ISC_R_SUCCESS) return (result); if (allnodes->common.relative_names) { /* All names are relative to the root */ unsigned int nlabels = dns_name_countlabels(newname); dns_name_getlabelsequence(newname, 0, nlabels - 1, newname); } sdlznode = ISC_LIST_HEAD(allnodes->nodelist); if (sdlznode == NULL || !dns_name_equal(sdlznode->name, newname)) { sdlznode = NULL; result = createnode(sdlz, &sdlznode); if (result != ISC_R_SUCCESS) return (result); sdlznode->name = isc_mem_get(mctx, sizeof(dns_name_t)); if (sdlznode->name == NULL) { destroynode(sdlznode); return (ISC_R_NOMEMORY); } dns_name_init(sdlznode->name, NULL); result = dns_name_dup(newname, mctx, sdlznode->name); if (result != ISC_R_SUCCESS) { isc_mem_put(mctx, sdlznode->name, sizeof(dns_name_t)); destroynode(sdlznode); return (result); } ISC_LIST_PREPEND(allnodes->nodelist, sdlznode, link); if (allnodes->origin == NULL && dns_name_equal(newname, &sdlz->common.origin)) allnodes->origin = sdlznode; } return (dns_sdlz_putrr(sdlznode, type, ttl, data));}isc_result_tdns_sdlz_putsoa(dns_sdlzlookup_t *lookup, const char *mname, const char *rname, isc_uint32_t serial){ char str[2 * DNS_NAME_MAXTEXT + 5 * (sizeof("2147483647")) + 7]; int n; REQUIRE(mname != NULL); REQUIRE(rname != NULL); n = snprintf(str, sizeof str, "%s %s %u %u %u %u %u", mname, rname, serial, SDLZ_DEFAULT_REFRESH, SDLZ_DEFAULT_RETRY, SDLZ_DEFAULT_EXPIRE, SDLZ_DEFAULT_MINIMUM); if (n >= (int)sizeof(str) || n < 0) return (ISC_R_NOSPACE); return (dns_sdlz_putrr(lookup, "SOA", SDLZ_DEFAULT_TTL, str));}isc_result_tdns_sdlzregister(const char *drivername, const dns_sdlzmethods_t *methods, void *driverarg, unsigned int flags, isc_mem_t *mctx, dns_sdlzimplementation_t **sdlzimp){ dns_sdlzimplementation_t *imp; isc_result_t result; /* * Performs checks to make sure data is as we expect it to be. */ REQUIRE(drivername != NULL); REQUIRE(methods != NULL); REQUIRE(methods->findzone != NULL); REQUIRE(methods->lookup != NULL); REQUIRE(mctx != NULL); REQUIRE(sdlzimp != NULL && *sdlzimp == NULL); REQUIRE((flags & ~(DNS_SDLZFLAG_RELATIVEOWNER | DNS_SDLZFLAG_RELATIVERDATA | DNS_SDLZFLAG_THREADSAFE)) == 0); /* Write debugging message to log */ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2), "Registering SDLZ driver '%s'", drivername); /* * Allocate memory for a sdlz_implementation object. Error if * we cannot. */ imp = isc_mem_get(mctx, sizeof(dns_sdlzimplementation_t)); if (imp == NULL) return (ISC_R_NOMEMORY); /* Make sure memory region is set to all 0's */ memset(imp, 0, sizeof(dns_sdlzimplementation_t)); /* Store the data passed into this method */ imp->methods = methods; imp->driverarg = driverarg; imp->flags = flags; imp->mctx = NULL; /* attach the new sdlz_implementation object to a memory context */ isc_mem_attach(mctx, &imp->mctx); /* * initialize the driver lock, error if we cannot * (used if a driver does not support multiple threads) */ result = isc_mutex_init(&imp->driverlock); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_mutex_init() failed: %s", isc_result_totext(result)); goto cleanup_mctx; } imp->dlz_imp = NULL; /* * register the DLZ driver. Pass in our "extra" sdlz information as * a driverarg. (that's why we stored the passed in driver arg in our * sdlz_implementation structure) Also, store the dlz_implementation * structure in our sdlz_implementation. */ result = dns_dlzregister(drivername, &sdlzmethods, imp, mctx, &imp->dlz_imp); /* if registration fails, cleanup and get outta here. */ if (result != ISC_R_SUCCESS) goto cleanup_mutex; *sdlzimp = imp; return (ISC_R_SUCCESS); cleanup_mutex: /* destroy the driver lock, we don't need it anymore */ DESTROYLOCK(&imp->driverlock); cleanup_mctx: /* * return the memory back to the available memory pool and * remove it from the memory context. */ isc_mem_put(mctx, imp, sizeof(dns_sdlzimplementation_t)); isc_mem_detach(&mctx); return (result);}voiddns_sdlzunregister(dns_sdlzimplementation_t **sdlzimp) { dns_sdlzimplementation_t *imp; isc_mem_t *mctx; /* Write debugging message to log */ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2), "Unregistering SDLZ driver."); /* * Performs checks to make sure data is as we expect it to be. */ REQUIRE(sdlzimp != NULL && *sdlzimp != NULL); imp = *sdlzimp; /* Unregister the DLZ driver implementation */ dns_dlzunregister(&imp->dlz_imp); /* destroy the driver lock, we don't need it anymore */ DESTROYLOCK(&imp->driverlock); mctx = imp->mctx; /* * return the memory back to the available memory pool and * remove it from the memory context. */ isc_mem_put(mctx, imp, sizeof(dns_sdlzimplementation_t)); isc_mem_detach(&mctx); *sdlzimp = NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -