示例#1
0
文件: context.c 项目: JeanCaron/bind9
void
irs_context_destroy(irs_context_t **contextp) {
	irs_context_t *context;

	REQUIRE(contextp != NULL);
	context = *contextp;
	REQUIRE(IRS_CONTEXT_VALID(context));

	isc_task_detach(&context->task);
	irs_dnsconf_destroy(&context->dnsconf);
	irs_resconf_destroy(&context->resconf);
	dns_client_destroy(&context->dnsclient);

	ctxs_destroy(NULL, &context->actx, &context->taskmgr,
		     &context->socketmgr, &context->timermgr);

	context->magic = 0;

	isc_mem_putanddetach(&context->mctx, context, sizeof(*context));

	*contextp = NULL;

#ifndef ISC_PLATFORM_USETHREADS
	irs_g_context = NULL;
#else
	(void)isc_thread_key_setspecific(irs_context_key, NULL);
#endif
}
/*% parses a file and fills in the data structure. */
isc_result_t
irs_resconf_load(isc_mem_t *mctx, const char *filename, irs_resconf_t **confp)
{
	FILE *fp = NULL;
	char word[256];
	isc_result_t rval, ret = ISC_R_SUCCESS;
	irs_resconf_t *conf;
	int i, stopchar;

	REQUIRE(mctx != NULL);
	REQUIRE(filename != NULL);
	REQUIRE(strlen(filename) > 0U);
	REQUIRE(confp != NULL && *confp == NULL);

	conf = isc_mem_get(mctx, sizeof(*conf));
	if (conf == NULL)
		return (ISC_R_NOMEMORY);

	conf->mctx = mctx;
	ISC_LIST_INIT(conf->nameservers);
	conf->numns = 0;
	conf->domainname = NULL;
	conf->searchnxt = 0;
	conf->resdebug = 0;
	conf->ndots = 1;
	for (i = 0; i < RESCONFMAXSEARCH; i++)
		conf->search[i] = NULL;

	errno = 0;
	if ((fp = fopen(filename, "r")) != NULL) {
		do {
			stopchar = getword(fp, word, sizeof(word));
			if (stopchar == EOF) {
				rval = ISC_R_SUCCESS;
				POST(rval);
				break;
			}

			if (strlen(word) == 0U)
				rval = ISC_R_SUCCESS;
			else if (strcmp(word, "nameserver") == 0)
				rval = resconf_parsenameserver(conf, fp);
			else if (strcmp(word, "domain") == 0)
				rval = resconf_parsedomain(conf, fp);
			else if (strcmp(word, "search") == 0)
				rval = resconf_parsesearch(conf, fp);
			else if (strcmp(word, "sortlist") == 0)
				rval = resconf_parsesortlist(conf, fp);
			else if (strcmp(word, "options") == 0)
				rval = resconf_parseoption(conf, fp);
			else {
				/* unrecognised word. Ignore entire line */
				rval = ISC_R_SUCCESS;
				stopchar = eatline(fp);
				if (stopchar == EOF) {
					break;
				}
			}
			if (ret == ISC_R_SUCCESS && rval != ISC_R_SUCCESS)
				ret = rval;
		} while (1);

		fclose(fp);
	} else {
		switch (errno) {
		case ENOENT:
			break;
		default:
			isc_mem_put(mctx, conf, sizeof(*conf));
			return (ISC_R_INVALIDFILE);
		}
	}

	/* If we don't find a nameserver fall back to localhost */
	if (conf->numns == 0) {
		INSIST(ISC_LIST_EMPTY(conf->nameservers));

		/* XXX: should we catch errors? */
		(void)add_server(conf->mctx, "127.0.0.1", &conf->nameservers);
		(void)add_server(conf->mctx, "::1", &conf->nameservers);
	}

	/*
	 * Construct unified search list from domain or configured
	 * search list
	 */
	ISC_LIST_INIT(conf->searchlist);
	if (conf->domainname != NULL) {
		ret = add_search(conf, conf->domainname);
	} else if (conf->searchnxt > 0) {
		for (i = 0; i < conf->searchnxt; i++) {
			ret = add_search(conf, conf->search[i]);
			if (ret != ISC_R_SUCCESS)
				break;
		}
	}

	conf->magic = IRS_RESCONF_MAGIC;

	if (ret != ISC_R_SUCCESS)
		irs_resconf_destroy(&conf);
	else {
		if (fp == NULL)
			ret = ISC_R_FILENOTFOUND;
		*confp = conf;
	}

	return (ret);
}
示例#3
0
文件: context.c 项目: JeanCaron/bind9
isc_result_t
irs_context_create(irs_context_t **contextp) {
	isc_result_t result;
	irs_context_t *context;
	isc_appctx_t *actx = NULL;
	isc_mem_t *mctx = NULL;
	isc_taskmgr_t *taskmgr = NULL;
	isc_socketmgr_t *socketmgr = NULL;
	isc_timermgr_t *timermgr = NULL;
	dns_client_t *client = NULL;
	isc_sockaddrlist_t *nameservers;
	irs_dnsconf_dnskeylist_t *trustedkeys;
	irs_dnsconf_dnskey_t *trustedkey;

	isc_lib_register();
	result = dns_lib_init();
	if (result != ISC_R_SUCCESS)
		return (result);

	result = ctxs_init(&mctx, &actx, &taskmgr, &socketmgr, &timermgr);
	if (result != ISC_R_SUCCESS)
		return (result);

	result = isc_app_ctxstart(actx);
	if (result != ISC_R_SUCCESS) {
		ctxs_destroy(&mctx, &actx, &taskmgr, &socketmgr, &timermgr);
		return (result);
	}

	context = isc_mem_get(mctx, sizeof(*context));
	if (context == NULL) {
		ctxs_destroy(&mctx, &actx, &taskmgr, &socketmgr, &timermgr);
		return (ISC_R_NOMEMORY);
	}

	context->mctx = mctx;
	context->actx = actx;
	context->taskmgr = taskmgr;
	context->socketmgr = socketmgr;
	context->timermgr = timermgr;
	context->resconf = NULL;
	context->dnsconf = NULL;
	context->task = NULL;
	result = isc_task_create(taskmgr, 0, &context->task);
	if (result != ISC_R_SUCCESS)
		goto fail;

	/* Create a DNS client object */
	result = dns_client_createx(mctx, actx, taskmgr, socketmgr, timermgr,
				    0, &client);
	if (result != ISC_R_SUCCESS)
		goto fail;
	context->dnsclient = client;

	/* Read resolver configuration file */
	result = irs_resconf_load(mctx, RESOLV_CONF, &context->resconf);
	if (result != ISC_R_SUCCESS)
		goto fail;
	/* Set nameservers */
	nameservers = irs_resconf_getnameservers(context->resconf);
	result = dns_client_setservers(client, dns_rdataclass_in, NULL,
				       nameservers);
	if (result != ISC_R_SUCCESS)
		goto fail;

	/* Read advanced DNS configuration (if any) */
	result = irs_dnsconf_load(mctx, DNS_CONF, &context->dnsconf);
	if (result != ISC_R_SUCCESS)
		goto fail;
	trustedkeys = irs_dnsconf_gettrustedkeys(context->dnsconf);
	for (trustedkey = ISC_LIST_HEAD(*trustedkeys);
	     trustedkey != NULL;
	     trustedkey = ISC_LIST_NEXT(trustedkey, link)) {
		result = dns_client_addtrustedkey(client, dns_rdataclass_in,
						  trustedkey->keyname,
						  trustedkey->keydatabuf);
		if (result != ISC_R_SUCCESS)
			goto fail;
	}

	context->magic = IRS_CONTEXT_MAGIC;
	*contextp = context;

	return (ISC_R_SUCCESS);

  fail:
	if (context->task != NULL)
		isc_task_detach(&context->task);
	if (context->resconf != NULL)
		irs_resconf_destroy(&context->resconf);
	if (context->dnsconf != NULL)
		irs_dnsconf_destroy(&context->dnsconf);
	if (client != NULL)
		dns_client_destroy(&client);
	ctxs_destroy(NULL, &actx, &taskmgr, &socketmgr, &timermgr);
	isc_mem_putanddetach(&mctx, context, sizeof(*context));

	return (result);
}
示例#4
0
static isc_result_t
findserver(dns_client_t *client) {
	isc_result_t result;
	irs_resconf_t *resconf = NULL;
	isc_sockaddrlist_t *nameservers;
	isc_sockaddr_t *sa, *next;
	isc_uint32_t destport;

	result = parse_uint(&destport, port, 0xffff, "port");
	if (result != ISC_R_SUCCESS)
		fatal("Couldn't parse port number");

	result = irs_resconf_load(mctx, "/etc/resolv.conf", &resconf);
	if (result != ISC_R_SUCCESS && result != ISC_R_FILENOTFOUND) {
		delv_log(ISC_LOG_ERROR, "irs_resconf_load: %s",
			  isc_result_totext(result));
		goto cleanup;
	}

	/* Get nameservers from resolv.conf */
	nameservers = irs_resconf_getnameservers(resconf);
	for (sa = ISC_LIST_HEAD(*nameservers); sa != NULL; sa = next) {
		next = ISC_LIST_NEXT(sa, link);

		/* Set destination port */
		if (sa->type.sa.sa_family == AF_INET && use_ipv4) {
			sa->type.sin.sin_port = htons(destport);
			continue;
		}
		if (sa->type.sa.sa_family == AF_INET6 && use_ipv6) {
			sa->type.sin6.sin6_port = htons(destport);
			continue;
		}

		/* Incompatible protocol family */
		ISC_LIST_UNLINK(*nameservers, sa, link);
		isc_mem_put(mctx, sa, sizeof(*sa));
	}

	/* None found, use localhost */
	if (ISC_LIST_EMPTY(*nameservers)) {
		if (use_ipv4) {
			struct in_addr localhost;
			localhost.s_addr = htonl(INADDR_LOOPBACK);
			sa = isc_mem_get(mctx, sizeof(*sa));
			if (sa == NULL) {
				result = ISC_R_NOMEMORY;
				goto cleanup;
			}
			isc_sockaddr_fromin(sa, &localhost, destport);

			ISC_LINK_INIT(sa, link);
			ISC_LIST_APPEND(*nameservers, sa, link);
		}

		if (use_ipv6) {
			sa = isc_mem_get(mctx, sizeof(*sa));
			if (sa == NULL) {
				result = ISC_R_NOMEMORY;
				goto cleanup;
			}
			isc_sockaddr_fromin6(sa, &in6addr_loopback, destport);

			ISC_LINK_INIT(sa, link);
			ISC_LIST_APPEND(*nameservers, sa, link);
		}
	}

	result = dns_client_setservers(client, dns_rdataclass_in, NULL,
				       nameservers);
	if (result != ISC_R_SUCCESS)
		delv_log(ISC_LOG_ERROR, "dns_client_setservers: %s",
			  isc_result_totext(result));

cleanup:
	if (resconf != NULL)
		irs_resconf_destroy(&resconf);
	return (result);
}