dlz_bdb_driver.c

来自「非常好的dns解析软件」· C语言 代码 · 共 798 行 · 第 1/2 页

C
798
字号
/* * Copyright (C) 2002 Stichting NLnet, Netherlands, stichting@nlnet.nl. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the * above copyright notice and this permission notice appear in all * copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND STICHTING NLNET * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL * STICHTING NLNET BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE * USE OR PERFORMANCE OF THIS SOFTWARE. * * The development of Dynamically Loadable Zones (DLZ) for Bind 9 was * conceived and contributed by Rob Butler. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the * above copyright notice and this permission notice appear in all * copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ROB BUTLER * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL * ROB BUTLER BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE * USE OR PERFORMANCE OF THIS SOFTWARE. *//* * Copyright (C) 1999-2001  Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */#ifdef DLZ_BDB#include <config.h>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <dns/log.h>#include <dns/sdlz.h>#include <dns/result.h>#include <isc/mem.h>#include <isc/print.h>#include <isc/result.h>#include <isc/util.h>#include <named/globals.h>#include <dlz/dlz_bdb_driver.h>#include <db.h>static dns_sdlzimplementation_t *dlz_bdb = NULL;/* should the bdb driver use threads. */#ifdef ISC_PLATFORM_USETHREADS#define bdb_threads DB_THREAD#else#define bdb_threads 0#endif/* BDB database names */#define dlz_data "dns_data"#define dlz_zone "dns_zone"#define dlz_host "dns_host"#define dlz_client "dns_client"/*% * This structure contains all the Berkeley DB handles * for this instance of the BDB driver. */typedef struct bdb_instance {	DB_ENV	*dbenv;		/*%< BDB environment */	DB	*data;		/*%< dns_data database handle */	DB	*zone;		/*%< zone database handle */	DB	*host;		/*%< host database handle */	DB	*client;	/*%< client database handle */	isc_mem_t *mctx;	/*%< memory context */} bdb_instance_t;typedef struct parsed_data {	char *zone;	char *host;	char *type;	int ttl;	char *data;} parsed_data_t;/* forward reference */static isc_result_tbdb_findzone(void *driverarg, void *dbdata, const char *name);/*% * Parses the DBT from the Berkeley DB into a parsed_data record * The parsed_data record should be allocated before and passed into the * bdb_parse_data function.  The char (type & data) fields should not * be "free"d as that memory is part of the DBT data field.  It will be * "free"d when the DBT is freed. */static isc_result_tbdb_parse_data(char *in, parsed_data_t *pd) {	char *endp, *ttlStr;	char *tmp = in;	char *lastchar = (char *) &tmp[strlen(tmp) + 1];	/*%	 * String should be formated as:	 * zone(a space)host(a space)ttl(a space)type(a space)remaining data	 * examples:	 * example.com www 10 A 127.0.0.1	 * example.com mail 10 A 127.0.0.2	 * example.com @ 10 MX 20 mail.example.com	 */	/* save pointer to zone */	pd->zone = tmp;	/* find space after zone and change it to a '\0' */	tmp = strchr(tmp, ' ');	/* verify we found a space */	if (tmp == NULL)		return ISC_R_FAILURE;	/* change the space to a null (string terminator) */	tmp[0] = '\0';	/* make sure it is safe to increment pointer */	if (++tmp > lastchar)		return ISC_R_FAILURE;	/* save pointer to host */	pd->host = tmp;	/* find space after type and change it to a '\0' */	tmp = strchr(tmp, ' ');	/* verify we found a space */	if (tmp == NULL)		return ISC_R_FAILURE;	/* change the space to a null (string terminator) */	tmp[0] = '\0';	/* make sure it is safe to increment pointer */	if (++tmp > lastchar)		return ISC_R_FAILURE;	/* save pointer to dns type */	pd->type = tmp;	/* find space after type and change it to a '\0' */	tmp = strchr(tmp, ' ');	/* verify we found a space */	if (tmp == NULL)		return ISC_R_FAILURE;	/* change the space to a null (string terminator) */	tmp[0] = '\0';	/* make sure it is safe to increment pointer */	if (++tmp > lastchar)		return ISC_R_FAILURE;	/* save pointer to dns ttl */	ttlStr = tmp;	/* find space after ttl and change it to a '\0' */	tmp = strchr(tmp, ' ');	/* verify we found a space */	if (tmp == NULL)		return ISC_R_FAILURE;	/* change the space to a null (string terminator) */	tmp[0] = '\0';	/* make sure it is safe to increment pointer */	if (++tmp > lastchar)		return ISC_R_FAILURE;	/* save pointer to remainder of DNS data */	pd->data = tmp;	/* convert ttl string to integer */	pd->ttl = strtol(ttlStr, &endp, 10);	if (*endp != '\0' || pd->ttl < 0) {		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,			      DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,			      "BDB driver ttl must be a postive number");		return ISC_R_FAILURE;	}	/* if we get this far everything should have worked. */	return ISC_R_SUCCESS;}/* * DLZ methods */static isc_result_tbdb_allowzonexfr(void *driverarg, void *dbdata, const char *name,		 const char *client){	isc_result_t result;	bdb_instance_t *db = (bdb_instance_t *) dbdata;	DBC *client_cursor = NULL;	DBT key, data;	/* check to see if we are authoritative for the zone first. */	result = bdb_findzone(driverarg, dbdata, name);	if (result != ISC_R_SUCCESS)		return (ISC_R_NOTFOUND);	memset(&key, 0, sizeof(DBT));	key.flags = DB_DBT_MALLOC;	key.data = strdup(name);	if (key.data == NULL) {		result = ISC_R_NOMEMORY;		goto xfr_cleanup;	}	key.size = strlen(key.data);	memset(&data, 0, sizeof(DBT));	data.flags = DB_DBT_MALLOC;	data.data = strdup(client);	if (data.data == NULL) {		result = ISC_R_NOMEMORY;		goto xfr_cleanup;	}	data.size = strlen(data.data);	/* get a cursor to loop through zone data */	if (db->client->cursor(db->client, NULL, &client_cursor, 0) != 0) {		result = ISC_R_FAILURE;		goto xfr_cleanup;	}	switch(client_cursor->c_get(client_cursor, &key, &data, DB_GET_BOTH)) {	case DB_NOTFOUND:	case DB_SECONDARY_BAD:		result = ISC_R_NOTFOUND;		break;	case 0:		result = ISC_R_SUCCESS;		break;	default:		result = ISC_R_FAILURE;	} xfr_cleanup:	/* free any memory duplicate string in the key field */	if (key.data != NULL)		free(key.data);	/* free any memory allocated to the data field. */	if (data.data != NULL)		free(data.data);	/* get rid of zone_cursor */	if (client_cursor != NULL)		client_cursor->c_close(client_cursor);	return result;}static isc_result_tbdb_allnodes(const char *zone, void *driverarg, void *dbdata,	     dns_sdlzallnodes_t *allnodes){	isc_result_t result = ISC_R_NOTFOUND;	bdb_instance_t *db = (bdb_instance_t *) dbdata;	DBC *zone_cursor = NULL;	DBT key, data;	int flags;	int bdbres;	parsed_data_t pd;	char *tmp = NULL, *tmp_zone;	UNUSED(driverarg);	memset(&key, 0, sizeof(DBT));	memset(&data, 0, sizeof(DBT));	key.data = tmp_zone = strdup(zone);	if (key.data == NULL)		return (ISC_R_NOMEMORY);	key.size = strlen(key.data);	/* get a cursor to loop through zone data */	if (db->zone->cursor(db->zone, NULL, &zone_cursor, 0) != 0) {		result = ISC_R_FAILURE;		goto allnodes_cleanup;	}	flags = DB_SET;	while ((bdbres = zone_cursor->c_get(zone_cursor, &key, &data,					    flags)) == 0) {		flags = DB_NEXT_DUP;		tmp = realloc(tmp, data.size + 1);		if (tmp == NULL)			goto allnodes_cleanup;		strncpy(tmp, data.data, data.size);		tmp[data.size] = '\0';		if (bdb_parse_data(tmp, &pd) != ISC_R_SUCCESS)			goto allnodes_cleanup;		result = dns_sdlz_putnamedrr(allnodes, pd.host, pd.type,					     pd.ttl, pd.data);		if (result != ISC_R_SUCCESS)			goto allnodes_cleanup;	} /* end while loop */ allnodes_cleanup:	if (tmp != NULL)		free(tmp);	/* free any memory duplicate string in the key field */	if (tmp_zone != NULL)		free(tmp_zone);	/* get rid of zone_cursor */	if (zone_cursor != NULL)		zone_cursor->c_close(zone_cursor);	return result;}/*% * Performs BDB cleanup. * Used by bdb_create if there is an error starting up. * Used by bdb_destroy when the driver is shutting down. */static voidbdb_cleanup(bdb_instance_t *db) {	isc_mem_t *mctx;	/* close databases */	if (db->data != NULL)		db->data->close(db->data, 0);	if (db->host != NULL)		db->host->close(db->host, 0);	if (db->zone != NULL)		db->zone->close(db->zone, 0);	if (db->client != NULL)		db->client->close(db->client, 0);	/* close environment */	if (db->dbenv != NULL)		db->dbenv->close(db->dbenv, 0);	/* cleanup memory */	if (db->mctx != NULL) {		/* save mctx for later */		mctx = db->mctx;		/* return, and detach the memory */		isc_mem_put(mctx, db, sizeof(bdb_instance_t));		isc_mem_detach(&mctx);	}}static isc_result_tbdb_findzone(void *driverarg, void *dbdata, const char *name){	isc_result_t result;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?