示例#1
0
文件: conf.c 项目: idtek/knot
conf_remote_t conf_remote_txn(
	conf_t *conf,
	knot_db_txn_t *txn,
	conf_val_t *id,
	size_t index)
{
	assert(id != NULL && id->item != NULL);
	assert(id->item->type == YP_TSTR ||
	       (id->item->type == YP_TREF &&
	        id->item->var.r.ref->var.g.id->type == YP_TSTR));

	conf_remote_t out = { { AF_UNSPEC } };

	conf_val_t rundir_val = conf_get_txn(conf, txn, C_SRV, C_RUNDIR);
	char *rundir = conf_abs_path(&rundir_val, NULL);

	// Get indexed remote address.
	conf_val_t val = conf_id_get_txn(conf, txn, C_RMT, C_ADDR, id);
	for (size_t i = 0; val.code == KNOT_EOK && i < index; i++) {
		if (i == 0) {
			conf_val(&val);
		}
		conf_val_next(&val);
	}
	// Index overflow causes empty socket.
	out.addr = conf_addr(&val, rundir);

	// Get outgoing address if family matches (optional).
	val = conf_id_get_txn(conf, txn, C_RMT, C_VIA, id);
	while (val.code == KNOT_EOK) {
		struct sockaddr_storage via = conf_addr(&val, rundir);
		if (via.ss_family == out.addr.ss_family) {
			out.via = conf_addr(&val, rundir);
			break;
		}
		conf_val_next(&val);
	}

	// Get TSIG key (optional).
	conf_val_t key_id = conf_id_get_txn(conf, txn, C_RMT, C_KEY, id);
	if (key_id.code == KNOT_EOK) {
		out.key.name = (knot_dname_t *)conf_dname(&key_id);

		val = conf_id_get_txn(conf, txn, C_KEY, C_ALG, &key_id);
		out.key.algorithm = conf_opt(&val);

		val = conf_id_get_txn(conf, txn, C_KEY, C_SECRET, &key_id);
		out.key.secret.data = (uint8_t *)conf_bin(&val, &out.key.secret.size);
	}

	free(rundir);

	return out;
}
示例#2
0
int dnsproxy_load(struct query_plan *plan, struct query_module *self)
{
	if (plan == NULL || self == NULL) {
		return KNOT_EINVAL;
	}

	struct dnsproxy *proxy = mm_alloc(self->mm, sizeof(struct dnsproxy));
	if (proxy == NULL) {
		MODULE_ERR("not enough memory");
		return KNOT_ENOMEM;
	}
	memset(proxy, 0, sizeof(struct dnsproxy));

	conf_val_t val = conf_mod_get(self->config, MOD_REMOTE, self->id);
	if (val.code != KNOT_EOK) {
		if (val.code == KNOT_EINVAL) {
			MODULE_ERR("no remote proxy address for '%s'",
			           self->id->data);
		}
		mm_free(self->mm, proxy);
		return val.code;
	}
	proxy->remote = conf_addr(&val, NULL);

	self->ctx = proxy;

	return query_plan_step(plan, QPLAN_BEGIN, dnsproxy_fwd, self->ctx);
}
示例#3
0
文件: main.c 项目: gitter-badger/knot
/*! \brief Event loop listening for signals and remote commands. */
static void event_loop(server_t *server)
{
	uint8_t buf[KNOT_WIRE_MAX_PKTSIZE];
	size_t buflen = sizeof(buf);

	/* Read control socket configuration. */
	conf_val_t listen_val = conf_get(conf(), C_CTL, C_LISTEN);
	conf_val_t rundir_val = conf_get(conf(), C_SRV, C_RUNDIR);
	char *rundir = conf_abs_path(&rundir_val, NULL);
	struct sockaddr_storage addr = conf_addr(&listen_val, rundir);
	free(rundir);

	/* Bind to control interface (error logging is inside the function. */
	int remote = remote_bind(&addr);

	sigset_t empty;
	(void)sigemptyset(&empty);

	/* Run event loop. */
	for (;;) {
		int ret = remote_poll(remote, &empty);

		/* Events. */
		if (ret > 0) {
			ret = remote_process(server, &addr, remote, buf, buflen);
			if (ret == KNOT_CTL_STOP) {
				break;
			}
		}

		/* Interrupts. */
		if (sig_req_stop) {
			break;
		}
		if (sig_req_reload) {
			sig_req_reload = false;
			server_reload(server, conf()->filename);
		}
	}

	server_stop(server);

	/* Close remote control interface. */
	remote_unbind(&addr, remote);

	/* Wait for server to finish. */
	server_wait(server);
}