⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zone.c

📁 bind-3.2.
💻 C
📖 第 1 页 / 共 5 页
字号:
	zone->view = NULL;	ISC_LINK_INIT(zone, statelink);	zone->statelist = NULL;	zone->counters = NULL;	zone->magic = ZONE_MAGIC;	/* Must be after magic is set. */	result = dns_zone_setdbtype(zone, dbargc_default, dbargv_default);	if (result != ISC_R_SUCCESS)		goto free_mutex;		ISC_EVENT_INIT(&zone->ctlevent, sizeof(zone->ctlevent), 0, NULL,		       DNS_EVENT_ZONECONTROL, zone_shutdown, zone, zone,		       NULL, NULL);	*zonep = zone;	return (ISC_R_SUCCESS); free_mutex:	DESTROYLOCK(&zone->lock);	return (ISC_R_NOMEMORY);}/* * Free a zone.  Because we require that there be no more * outstanding events or references, no locking is necessary. */static voidzone_free(dns_zone_t *zone) {	isc_mem_t *mctx = NULL;	REQUIRE(DNS_ZONE_VALID(zone));	REQUIRE(isc_refcount_current(&zone->erefs) == 0);	REQUIRE(zone->irefs == 0);	REQUIRE(!LOCKED_ZONE(zone));	REQUIRE(zone->timer == NULL);	/*	 * Managed objects.  Order is important.	 */	if (zone->request != NULL)		dns_request_destroy(&zone->request); /* XXXMPA */	INSIST(zone->readio == NULL);	INSIST(zone->statelist == NULL);	if (zone->task != NULL)		isc_task_detach(&zone->task);	if (zone->zmgr)		dns_zonemgr_releasezone(zone->zmgr, zone);	/* Unmanaged objects */	if (zone->masterfile != NULL)		isc_mem_free(zone->mctx, zone->masterfile);	zone->masterfile = NULL;	zone->journalsize = -1;	if (zone->journal != NULL)		isc_mem_free(zone->mctx, zone->journal);	zone->journal = NULL;	if (zone->counters != NULL)		dns_stats_freecounters(zone->mctx, &zone->counters);	if (zone->db != NULL)		dns_db_detach(&zone->db);	zone_freedbargs(zone);	dns_zone_setmasterswithkeys(zone, NULL, NULL, 0);	dns_zone_setalsonotify(zone, NULL, 0);	zone->check_names = dns_severity_ignore;	if (zone->update_acl != NULL)		dns_acl_detach(&zone->update_acl);	if (zone->forward_acl != NULL)		dns_acl_detach(&zone->forward_acl);	if (zone->notify_acl != NULL)		dns_acl_detach(&zone->notify_acl);	if (zone->query_acl != NULL)		dns_acl_detach(&zone->query_acl);	if (zone->xfr_acl != NULL)		dns_acl_detach(&zone->xfr_acl);	if (dns_name_dynamic(&zone->origin))		dns_name_free(&zone->origin, zone->mctx);	if (zone->ssutable != NULL)		dns_ssutable_detach(&zone->ssutable);	/* last stuff */	DESTROYLOCK(&zone->lock);	isc_refcount_destroy(&zone->erefs);	zone->magic = 0;	mctx = zone->mctx;	isc_mem_put(mctx, zone, sizeof *zone);	isc_mem_detach(&mctx);}/* *	Single shot. */voiddns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass) {	REQUIRE(DNS_ZONE_VALID(zone));	REQUIRE(rdclass != dns_rdataclass_none);	/*	 * Test and set.	 */	LOCK_ZONE(zone);	REQUIRE(zone->rdclass == dns_rdataclass_none ||		zone->rdclass == rdclass);	zone->rdclass = rdclass;	UNLOCK_ZONE(zone);}dns_rdataclass_tdns_zone_getclass(dns_zone_t *zone){	REQUIRE(DNS_ZONE_VALID(zone));	return (zone->rdclass);}voiddns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) {	REQUIRE(DNS_ZONE_VALID(zone));	LOCK_ZONE(zone);	zone->notifytype = notifytype;	UNLOCK_ZONE(zone);}/* *	Single shot. */voiddns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) {	REQUIRE(DNS_ZONE_VALID(zone));	REQUIRE(type != dns_zone_none);	/*	 * Test and set.	 */	LOCK_ZONE(zone);	REQUIRE(zone->type == dns_zone_none || zone->type == type);	zone->type = type;	UNLOCK_ZONE(zone);}static voidzone_freedbargs(dns_zone_t *zone) {	unsigned int i;	/* Free the old database argument list. */	if (zone->db_argv != NULL) {		for (i = 0; i < zone->db_argc; i++)			isc_mem_free(zone->mctx, zone->db_argv[i]);		isc_mem_put(zone->mctx, zone->db_argv,			    zone->db_argc * sizeof *zone->db_argv);	}	zone->db_argc = 0;	zone->db_argv = NULL;}isc_result_tdns_zone_setdbtype(dns_zone_t *zone,		   unsigned int dbargc, const char * const *dbargv) {	isc_result_t result = ISC_R_SUCCESS;	char **new = NULL;	unsigned int i;	REQUIRE(DNS_ZONE_VALID(zone));	REQUIRE(dbargc >= 1);	REQUIRE(dbargv != NULL);	LOCK_ZONE(zone);	/* Set up a new database argument list. */	new = isc_mem_get(zone->mctx, dbargc * sizeof *new);	if (new == NULL)		goto nomem;	for (i = 0; i < dbargc; i++)		new[i] = NULL;	for (i = 0; i < dbargc; i++) {		new[i] = isc_mem_strdup(zone->mctx, dbargv[i]);		if (new[i] == NULL)			goto nomem;	}	/* Free the old list. */	zone_freedbargs(zone);	zone->db_argc = dbargc;	zone->db_argv = new;	result = ISC_R_SUCCESS;	goto unlock;	 nomem:	if (new != NULL) {		for (i = 0; i < dbargc; i++) {			if (zone->db_argv[i] != NULL)				isc_mem_free(zone->mctx, new[i]);			isc_mem_put(zone->mctx, new, 				    dbargc * sizeof *new);		}	}	result = ISC_R_NOMEMORY;	 unlock:	UNLOCK_ZONE(zone);	return (result);}voiddns_zone_setview(dns_zone_t *zone, dns_view_t *view) {	REQUIRE(DNS_ZONE_VALID(zone));	LOCK_ZONE(zone);	if (zone->view != NULL)		dns_view_weakdetach(&zone->view);	dns_view_weakattach(view, &zone->view);	UNLOCK_ZONE(zone);}dns_view_t *dns_zone_getview(dns_zone_t *zone) {	REQUIRE(DNS_ZONE_VALID(zone));	return (zone->view);}isc_result_tdns_zone_setorigin(dns_zone_t *zone, dns_name_t *origin) {	isc_result_t result;	REQUIRE(DNS_ZONE_VALID(zone));	REQUIRE(origin != NULL);	LOCK_ZONE(zone);	if (dns_name_dynamic(&zone->origin)) {		dns_name_free(&zone->origin, zone->mctx);		dns_name_init(&zone->origin, NULL);	}	result = dns_name_dup(origin, zone->mctx, &zone->origin);	UNLOCK_ZONE(zone);	return (result);}	static isc_result_tdns_zone_setstring(dns_zone_t *zone, char **field, const char *value) {	char *copy;	if (value != NULL) {		copy = isc_mem_strdup(zone->mctx, value);		if (copy == NULL)			return (ISC_R_NOMEMORY);	} else {		copy = NULL;	}	if (*field != NULL)		isc_mem_free(zone->mctx, *field);	*field = copy;	return (ISC_R_SUCCESS);}	isc_result_tdns_zone_setfile(dns_zone_t *zone, const char *file) {	isc_result_t result = ISC_R_SUCCESS;	REQUIRE(DNS_ZONE_VALID(zone));	LOCK_ZONE(zone);	result = dns_zone_setstring(zone, &zone->masterfile, file);	if (result == ISC_R_SUCCESS)		result = default_journal(zone);	UNLOCK_ZONE(zone);	return (result);}const char *dns_zone_getfile(dns_zone_t *zone) {	REQUIRE(DNS_ZONE_VALID(zone));	return (zone->masterfile);}static isc_result_tdefault_journal(dns_zone_t *zone) {	isc_result_t result;	char *journal;	REQUIRE(DNS_ZONE_VALID(zone));	REQUIRE(LOCKED_ZONE(zone));	if (zone->masterfile != NULL) {		/* Calculate string length including '\0'. */		int len = strlen(zone->masterfile) + sizeof ".jnl";		journal = isc_mem_allocate(zone->mctx, len);		if (journal == NULL)			return (ISC_R_NOMEMORY);		strcpy(journal, zone->masterfile);		strcat(journal, ".jnl");	} else {		journal = NULL;	}	result = dns_zone_setstring(zone, &zone->journal, journal);	if (journal != NULL)		isc_mem_free(zone->mctx, journal);	return (result);}isc_result_tdns_zone_setjournal(dns_zone_t *zone, const char *journal) {	isc_result_t result = ISC_R_SUCCESS;	REQUIRE(DNS_ZONE_VALID(zone));	LOCK_ZONE(zone);	result = dns_zone_setstring(zone, &zone->journal, journal);		UNLOCK_ZONE(zone);	return (result);}char *dns_zone_getjournal(dns_zone_t *zone) {	REQUIRE(DNS_ZONE_VALID(zone));	return (zone->journal);}/* * Return true iff the zone is "dynamic", in the sense that the zone's * master file (if any) is written by the server, rather than being * updated manually and read by the server. * * This is true for slave zones, stub zones, and zones that allow * dynamic updates either by having an update policy ("ssutable") * or an "allow-update" ACL with a value other than exactly "{ none; }". */static isc_boolean_tzone_isdynamic(dns_zone_t *zone) {	REQUIRE(DNS_ZONE_VALID(zone));	return (ISC_TF(zone->type == dns_zone_slave ||		       zone->type == dns_zone_stub ||		       zone->ssutable != NULL ||		       (zone->update_acl != NULL &&			! (zone->update_acl->length == 1 && 			   zone->update_acl->elements[0].negative == ISC_TRUE			   &&			   zone->update_acl->elements[0].type ==			   dns_aclelementtype_any))));}static isc_result_tzone_load(dns_zone_t *zone, unsigned int flags) {	isc_result_t result;	isc_time_t now;	isc_time_t loadtime, filetime;	dns_db_t *db = NULL;	REQUIRE(DNS_ZONE_VALID(zone));	LOCK_ZONE(zone);	isc_time_now(&now);	INSIST(zone->type != dns_zone_none);	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {		result = ISC_R_SUCCESS;		goto cleanup;	}	if (zone->db != NULL && zone->masterfile == NULL) {		/*		 * The zone has no master file configured, but it already		 * has a database.  It could be the built-in		 * version.bind. CH zone, a zone with a persistent		 * database being reloaded, or maybe a zone that		 * used to have a master file but whose configuration		 * was changed so that it no longer has one.  Do nothing.		 */		result = ISC_R_SUCCESS;		goto cleanup;	}	if (zone->db != NULL && zone_isdynamic(zone)) {		/*		 * This is a slave, stub, or dynamically updated		 * zone being reloaded.  Do nothing - the database		 * we already have is guaranteed to be up-to-date.		 */		result = ISC_R_SUCCESS;		goto cleanup;	}			/*	 * Don't do the load if the file that stores the zone is older	 * than the last time the zone was loaded.  If the zone has not	 * been loaded yet, zone->loadtime will be the epoch.	 */	if (zone->masterfile != NULL && ! isc_time_isepoch(&zone->loadtime)) {		/*		 * The file is already loaded.  If we are just doing a		 * "rndc reconfig", we are done.		 */		if ((flags & DNS_ZONELOADFLAG_NOSTAT) != 0) {			result = ISC_R_SUCCESS;			goto cleanup;		}		if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE)) {			result = isc_file_getmodtime(zone->masterfile,						     &filetime);			if (result == ISC_R_SUCCESS &&			    isc_time_compare(&filetime, &zone->loadtime) < 0) {				dns_zone_log(zone, ISC_LOG_DEBUG(1),					     "skipping load: master file older "					     "than last load");				result = ISC_R_SUCCESS;				goto cleanup;			}		}	} 	INSIST(zone->db_argc >= 1);	if ((zone->type == dns_zone_slave || zone->type == dns_zone_stub) &&	    (strcmp(zone->db_argv[0], "rbt") == 0 ||	     strcmp(zone->db_argv[0], "rbt64") == 0)) {		if (zone->masterfile == NULL ||		    !isc_file_exists(zone->masterfile)) {			if (zone->masterfile != NULL)				dns_zone_log(zone, ISC_LOG_DEBUG(1),					     "no master file");			zone->refreshtime = now;			if (zone->task != NULL)				zone_settimer(zone, &now);			result = ISC_R_SUCCESS;			goto cleanup;		}	}	dns_zone_log(zone, ISC_LOG_DEBUG(1), "starting load");	/*	 * Store the current time before the zone is loaded, so that if the	 * file changes between the time of the load and the time that	 * zone->loadtime is set, then the file will still be reloaded	 * the next time dns_zone_load is called.	 */	result = isc_time_now(&loadtime);	if (result != ISC_R_SUCCESS)		goto cleanup;	result = dns_db_create(zone->mctx, zone->db_argv[0],			       &zone->origin, (zone->type == dns_zone_stub) ?			       dns_dbtype_stub : dns_dbtype_zone,			       zone->rdclass,			       zone->db_argc - 1, zone->db_argv + 1,			       &db);	if (result != ISC_R_SUCCESS) {		dns_zone_log(zone, ISC_LOG_ERROR,			     "loading zone: creating database: %s",			     isc_result_totext(result));		goto cleanup;	}	if (! dns_db_ispersistent(db)) {		if (zone->masterfile != NULL) {			result = zone_startload(db, zone, loadtime);		} else {			result = DNS_R_NOMASTERFILE;			if (zone->type == dns_zone_master) {				dns_zone_log(zone, ISC_LOG_ERROR,					     "loading zone: "					     "no master file configured");				goto cleanup;			}			dns_zone_log(zone, ISC_LOG_INFO, "loading zone: "				     "no master file configured: continuing");		}	}	if (result == DNS_R_CONTINUE) {		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADING);		result = ISC_R_SUCCESS;		goto cleanup;	}	result = zone_postload(zone, db, loadtime, result); cleanup:	UNLOCK_ZONE(zone);	if (db != NULL)		dns_db_detach(&db);	return (result);}isc_result_tdns_zone_load(dns_zone_t *zone) {	return (zone_load(zone, 0));}isc_result_tdns_zone_loadnew(dns_zone_t *zone) {	return (zone_load(zone, DNS_ZONELOADFLAG_NOSTAT));}static voidzone_gotreadhandle(isc_task_t *task, isc_event_t *event) {	dns_load_t *load = event->ev_arg;	isc_result_t result = ISC_R_SUCCESS;	unsigned int options;	REQUIRE(DNS_LOAD_VALID(load));	if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)		result = ISC_R_CANCELED;	isc_event_free(&event);	if (result == ISC_R_CANCELED)		goto fail;	options = DNS_MASTER_ZONE;	if (load->zone->type == dns_zone_slave)		options |= DNS_MASTER_SLAVE;

⌨️ 快捷键说明

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