Beispiel #1
0
isc_event_t *
isc_event_allocate(isc_mem_t *mctx, void *sender, isc_eventtype_t type,
		   isc_taskaction_t action, const void *arg, size_t size)
{
	isc_event_t *event;
	void *deconst_arg;

	REQUIRE(size >= sizeof(struct isc_event));
	REQUIRE(action != NULL);

	event = isc_mem_get(mctx, size);
	if (event == NULL)
		return (NULL);

	/*
	 * Removing the const attribute from "arg" is the best of two
	 * evils here.  If the event->ev_arg member is made const, then
	 * it affects a great many users of the task/event subsystem
	 * which are not passing in an "arg" which starts its life as
	 * const.  Changing isc_event_allocate() and isc_task_onshutdown()
	 * to not have "arg" prototyped as const (which is quite legitimate,
	 * because neither of those functions modify arg) can cause
	 * compiler whining anytime someone does want to use a const
	 * arg that they themselves never modify, such as with
	 * gcc -Wwrite-strings and using a string "arg".
	 */
	DE_CONST(arg, deconst_arg);

	ISC_EVENT_INIT(event, size, 0, NULL, type, action, deconst_arg,
		       sender, destroy, mctx);

	return (event);
}
Beispiel #2
0
isc_result_t
isc_ratelimiter_create(isc_mem_t *mctx, isc_timermgr_t *timermgr,
		       isc_task_t *task, isc_ratelimiter_t **ratelimiterp)
{
	isc_result_t result;
	isc_ratelimiter_t *rl;
	INSIST(ratelimiterp != NULL && *ratelimiterp == NULL);

	rl = isc_mem_get(mctx, sizeof(*rl));
	if (rl == NULL)
		return ISC_R_NOMEMORY;
	rl->mctx = mctx;
	rl->refs = 1;
	rl->task = task;
	isc_interval_set(&rl->interval, 0, 0);
	rl->timer = NULL;
	rl->pertic = 1;
	rl->state = isc_ratelimiter_idle;
	ISC_LIST_INIT(rl->pending);

	result = isc_mutex_init(&rl->lock);
	if (result != ISC_R_SUCCESS)
		goto free_mem;

	result = isc_timer_create(timermgr, isc_timertype_inactive,
				  NULL, NULL, rl->task, ratelimiter_tick,
				  rl, &rl->timer);
	if (result != ISC_R_SUCCESS)
		goto free_mutex;

	/*
	 * Increment the reference count to indicate that we may
	 * (soon) have events outstanding.
	 */
	rl->refs++;

	ISC_EVENT_INIT(&rl->shutdownevent,
		       sizeof(isc_event_t),
		       0, NULL, ISC_RATELIMITEREVENT_SHUTDOWN,
		       ratelimiter_shutdowncomplete, rl, rl, NULL, NULL);

	*ratelimiterp = rl;
	return (ISC_R_SUCCESS);

free_mutex:
	DESTROYLOCK(&rl->lock);
free_mem:
	isc_mem_put(mctx, rl, sizeof(*rl));
	return (result);
}
isc_result_t
dns_tcpmsg_readmessage(dns_tcpmsg_t *tcpmsg,
		       isc_task_t *task, isc_taskaction_t action, void *arg)
{
	isc_result_t result;
	isc_region_t region;

	REQUIRE(VALID_TCPMSG(tcpmsg));
	REQUIRE(task != NULL);
	REQUIRE(tcpmsg->task == NULL);  /* not currently in use */

	if (tcpmsg->buffer.base != NULL) {
		isc_mem_put(tcpmsg->mctx, tcpmsg->buffer.base,
			    tcpmsg->buffer.length);
		tcpmsg->buffer.base = NULL;
		tcpmsg->buffer.length = 0;
	}

	tcpmsg->task = task;
	tcpmsg->action = action;
	tcpmsg->arg = arg;
	tcpmsg->result = ISC_R_UNEXPECTED;  /* unknown right now */

	ISC_EVENT_INIT(&tcpmsg->event, sizeof(isc_event_t), 0, 0,
		       DNS_EVENT_TCPMSG, action, arg, tcpmsg,
		       NULL, NULL);

	region.base = (unsigned char *)&tcpmsg->size;
	region.length = 2;  /* isc_uint16_t */
	result = isc_socket_recv(tcpmsg->sock, &region, 0,
				 tcpmsg->task, recv_length, tcpmsg);

	if (result != ISC_R_SUCCESS)
		tcpmsg->task = NULL;

	return (result);
}
Beispiel #4
0
isc_result_t
isccc_ccmsg_readmessage(isccc_ccmsg_t *ccmsg,
		       isc_task_t *task, isc_taskaction_t action, void *arg)
{
	isc_result_t result;
	isc_region_t region;

	REQUIRE(VALID_CCMSG(ccmsg));
	REQUIRE(task != NULL);
	REQUIRE(ccmsg->task == NULL);  /* not currently in use */

	if (ccmsg->buffer.base != NULL) {
		isc_mem_put(ccmsg->mctx, ccmsg->buffer.base,
			    ccmsg->buffer.length);
		ccmsg->buffer.base = NULL;
		ccmsg->buffer.length = 0;
	}

	ccmsg->task = task;
	ccmsg->action = action;
	ccmsg->arg = arg;
	ccmsg->result = ISC_R_UNEXPECTED;  /* unknown right now */

	ISC_EVENT_INIT(&ccmsg->event, sizeof(isc_event_t), 0, 0,
		       ISCCC_EVENT_CCMSG, action, arg, ccmsg,
		       NULL, NULL);

	region.base = (unsigned char *)&ccmsg->size;
	region.length = 4;  /* isc_uint32_t */
	result = isc_socket_recv(ccmsg->sock, &region, 0,
				 ccmsg->task, recv_length, ccmsg);

	if (result != ISC_R_SUCCESS)
		ccmsg->task = NULL;

	return (result);
}
Beispiel #5
0
isc_result_t
dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
		const char *name, dns_view_t **viewp)
{
	dns_view_t *view;
	isc_result_t result;

	/*
	 * Create a view.
	 */

	REQUIRE(name != NULL);
	REQUIRE(viewp != NULL && *viewp == NULL);

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

	view->mctx = NULL;
	isc_mem_attach(mctx, &view->mctx);
	view->name = isc_mem_strdup(mctx, name);
	if (view->name == NULL) {
		result = ISC_R_NOMEMORY;
		goto cleanup_view;
	}
	result = isc_mutex_init(&view->lock);
	if (result != ISC_R_SUCCESS)
		goto cleanup_name;

	view->zonetable = NULL;
	if (isc_bind9) {
		result = dns_zt_create(mctx, rdclass, &view->zonetable);
		if (result != ISC_R_SUCCESS) {
			UNEXPECTED_ERROR(__FILE__, __LINE__,
					 "dns_zt_create() failed: %s",
					 isc_result_totext(result));
			result = ISC_R_UNEXPECTED;
			goto cleanup_mutex;
		}
	}
	view->secroots_priv = NULL;
	view->fwdtable = NULL;
	result = dns_fwdtable_create(mctx, &view->fwdtable);
	if (result != ISC_R_SUCCESS) {
		UNEXPECTED_ERROR(__FILE__, __LINE__,
				 "dns_fwdtable_create() failed: %s",
				 isc_result_totext(result));
		result = ISC_R_UNEXPECTED;
		goto cleanup_zt;
	}

	view->acache = NULL;
	view->cache = NULL;
	view->cachedb = NULL;
	ISC_LIST_INIT(view->dlz_searched);
	ISC_LIST_INIT(view->dlz_unsearched);
	view->hints = NULL;
	view->resolver = NULL;
	view->adb = NULL;
	view->requestmgr = NULL;
	view->rdclass = rdclass;
	view->frozen = ISC_FALSE;
	view->task = NULL;
	result = isc_refcount_init(&view->references, 1);
	if (result != ISC_R_SUCCESS)
		goto cleanup_fwdtable;
	view->weakrefs = 0;
	view->attributes = (DNS_VIEWATTR_RESSHUTDOWN|DNS_VIEWATTR_ADBSHUTDOWN|
			    DNS_VIEWATTR_REQSHUTDOWN);
	view->statickeys = NULL;
	view->dynamickeys = NULL;
	view->matchclients = NULL;
	view->matchdestinations = NULL;
	view->matchrecursiveonly = ISC_FALSE;
	result = dns_tsigkeyring_create(view->mctx, &view->dynamickeys);
	if (result != ISC_R_SUCCESS)
		goto cleanup_references;
	view->peers = NULL;
	view->order = NULL;
	view->delonly = NULL;
	view->rootdelonly = ISC_FALSE;
	view->rootexclude = NULL;
	view->adbstats = NULL;
	view->resstats = NULL;
	view->resquerystats = NULL;
	view->cacheshared = ISC_FALSE;
	ISC_LIST_INIT(view->dns64);
	view->dns64cnt = 0;

	/*
	 * Initialize configuration data with default values.
	 */
	view->recursion = ISC_TRUE;
	view->auth_nxdomain = ISC_FALSE; /* Was true in BIND 8 */
	view->additionalfromcache = ISC_TRUE;
	view->additionalfromauth = ISC_TRUE;
	view->enablednssec = ISC_TRUE;
	view->enablevalidation = ISC_TRUE;
	view->acceptexpired = ISC_FALSE;
	view->minimalresponses = ISC_FALSE;
	view->transfer_format = dns_one_answer;
	view->cacheacl = NULL;
	view->cacheonacl = NULL;
	view->queryacl = NULL;
	view->queryonacl = NULL;
	view->recursionacl = NULL;
	view->recursiononacl = NULL;
	view->sortlist = NULL;
	view->transferacl = NULL;
	view->notifyacl = NULL;
	view->updateacl = NULL;
	view->upfwdacl = NULL;
	view->denyansweracl = NULL;
	view->nocasecompress = NULL;
	view->answeracl_exclude = NULL;
	view->denyanswernames = NULL;
	view->answernames_exclude = NULL;
	view->rrl = NULL;
	view->provideixfr = ISC_TRUE;
	view->maxcachettl = 7 * 24 * 3600;
	view->maxncachettl = 3 * 3600;
	view->dstport = 53;
	view->preferred_glue = 0;
	view->flush = ISC_FALSE;
	view->dlv = NULL;
	view->maxudp = 0;
	view->situdp = 0;
	view->maxbits = 0;
	view->v4_aaaa = dns_aaaa_ok;
	view->v6_aaaa = dns_aaaa_ok;
	view->aaaa_acl = NULL;
	view->rpzs = NULL;
	dns_fixedname_init(&view->dlv_fixed);
	view->managed_keys = NULL;
	view->redirect = NULL;
	view->requestnsid = ISC_FALSE;
	view->requestsit = ISC_TRUE;
	view->new_zone_file = NULL;
	view->new_zone_config = NULL;
	view->cfg_destroy = NULL;

	if (isc_bind9) {
		result = dns_order_create(view->mctx, &view->order);
		if (result != ISC_R_SUCCESS)
			goto cleanup_dynkeys;
	}

	result = dns_peerlist_new(view->mctx, &view->peers);
	if (result != ISC_R_SUCCESS)
		goto cleanup_order;

	result = dns_aclenv_init(view->mctx, &view->aclenv);
	if (result != ISC_R_SUCCESS)
		goto cleanup_peerlist;

	ISC_LINK_INIT(view, link);
	ISC_EVENT_INIT(&view->resevent, sizeof(view->resevent), 0, NULL,
		       DNS_EVENT_VIEWRESSHUTDOWN, resolver_shutdown,
		       view, NULL, NULL, NULL);
	ISC_EVENT_INIT(&view->adbevent, sizeof(view->adbevent), 0, NULL,
		       DNS_EVENT_VIEWADBSHUTDOWN, adb_shutdown,
		       view, NULL, NULL, NULL);
	ISC_EVENT_INIT(&view->reqevent, sizeof(view->reqevent), 0, NULL,
		       DNS_EVENT_VIEWREQSHUTDOWN, req_shutdown,
		       view, NULL, NULL, NULL);
	view->viewlist = NULL;
	view->magic = DNS_VIEW_MAGIC;

	*viewp = view;

	return (ISC_R_SUCCESS);

 cleanup_peerlist:
	if (view->peers != NULL)
		dns_peerlist_detach(&view->peers);

 cleanup_order:
	if (view->order != NULL)
		dns_order_detach(&view->order);

 cleanup_dynkeys:
	if (view->dynamickeys != NULL)
		dns_tsigkeyring_detach(&view->dynamickeys);

 cleanup_references:
	isc_refcount_destroy(&view->references);

 cleanup_fwdtable:
	if (view->fwdtable != NULL)
		dns_fwdtable_destroy(&view->fwdtable);

 cleanup_zt:
	if (view->zonetable != NULL)
		dns_zt_detach(&view->zonetable);

 cleanup_mutex:
	DESTROYLOCK(&view->lock);

 cleanup_name:
	isc_mem_free(mctx, view->name);

 cleanup_view:
	isc_mem_putanddetach(&view->mctx, view, sizeof(*view));

	return (result);
}