Exemplo n.º 1
0
_public_
int knot_requestor_dequeue(struct knot_requestor *requestor)
{
	if (knot_requestor_finished(requestor)) {
		return KNOT_ENOENT;
	}

	struct knot_request *last = HEAD(requestor->pending);
	return knot_request_free(requestor->mm, last);
}
Exemplo n.º 2
0
static int dnsproxy_fwd(int state, knot_pkt_t *pkt, struct query_data *qdata, void *ctx)
{
	if (pkt == NULL || qdata == NULL || ctx == NULL) {
		return KNOT_STATE_FAIL;
	}

	/* If not already satisfied. */
	if (state == KNOT_STATE_DONE) {
		return state;
	}

	struct dnsproxy *proxy = ctx;

	/* Create a forwarding request. */
	struct knot_requestor re;
	knot_requestor_init(&re, qdata->mm);
	struct capture_param param;
	param.sink = pkt;
	int ret = knot_requestor_overlay(&re, LAYER_CAPTURE, &param);
	if (ret != KNOT_EOK) {
		return KNOT_STATE_FAIL;
	}

	bool is_tcp = net_is_connected(qdata->param->socket);
	struct knot_request *req;
	req = knot_request_make(re.mm, (const struct sockaddr *)&proxy->remote,
	                        NULL, qdata->query, is_tcp ? 0 : KNOT_RQ_UDP);
	if (req == NULL) {
		return state; /* Ignore, not enough memory. */
	}

	/* Forward request. */
	ret = knot_requestor_enqueue(&re, req);
	if (ret == KNOT_EOK) {
		conf_val_t val = conf_get(conf(), C_SRV, C_TCP_HSHAKE_TIMEOUT);
		struct timeval tv = { conf_int(&val), 0 };
		ret = knot_requestor_exec(&re, &tv);
	} else {
		knot_request_free(re.mm, req);
	}

	knot_requestor_clear(&re);

	/* Check result. */
	if (ret != KNOT_EOK) {
		qdata->rcode = KNOT_RCODE_SERVFAIL;
		return KNOT_STATE_FAIL; /* Forwarding failed, SERVFAIL. */
	}

	return KNOT_STATE_DONE;
}
Exemplo n.º 3
0
/*! \brief Process query using requestor. */
static int zone_query_request(knot_pkt_t *query, const conf_remote_t *remote,
                              struct process_answer_param *param, knot_mm_t *mm)
{
	/* Create requestor instance. */
	struct knot_requestor re;
	int ret = knot_requestor_init(&re, mm);
	if (ret != KNOT_EOK) {
		return ret;
	}
	ret = knot_requestor_overlay(&re, KNOT_STATE_ANSWER, param);
	if (ret != KNOT_EOK) {
		knot_requestor_clear(&re);
		return ret;
	}

	/* Create a request. */
	const struct sockaddr *dst = (const struct sockaddr *)&remote->addr;
	const struct sockaddr *src = (const struct sockaddr *)&remote->via;
	struct knot_request *req = knot_request_make(re.mm, dst, src, query, 0);
	if (req == NULL) {
		knot_requestor_clear(&re);
		return KNOT_ENOMEM;
	}

	/* Send the queries and process responses. */
	ret = knot_requestor_enqueue(&re, req);
	if (ret == KNOT_EOK) {
		conf_val_t *val = &param->conf->cache.srv_tcp_reply_timeout;
		int timeout = conf_int(val) * 1000;
		ret = knot_requestor_exec(&re, timeout);
	} else {
		knot_request_free(req, re.mm);
	}

	/* Cleanup. */
	knot_requestor_clear(&re);

	return ret;
}