Esempio n. 1
0
int main(int argc, char *argv[])
{
	plan(TESTS_COUNT);

	mm_ctx_t mm;
	mm_ctx_mempool(&mm, MM_DEFAULT_BLKSIZE);

	knot_pkt_t *buf = knot_pkt_new(NULL, 512, &mm);
	knot_pkt_put_question(buf, (const uint8_t *)"", 0, 0);

	/* Initialize overlay. */
	struct knot_overlay overlay;
	knot_overlay_init(&overlay, &mm);

	/* Add FSMs. */
	knot_overlay_add(&overlay, &fsm1_module, NULL);
	knot_overlay_add(&overlay, &fsm2_module, NULL);

	/* Run the sequence. */
	int state = knot_overlay_consume(&overlay, buf);
	is_int(KNOT_STATE_DONE, state, "overlay: in");
	state = knot_overlay_reset(&overlay);
	is_int(KNOT_STATE_PRODUCE, state, "overlay: reset");
	state = knot_overlay_produce(&overlay, buf);
	is_int(KNOT_STATE_DONE, state, "overlay: out");
	state = knot_overlay_finish(&overlay);
	is_int(KNOT_STATE_NOOP, state, "overlay: finish");

	/* Cleanup. */
	knot_overlay_deinit(&overlay);
	mp_delete((struct mempool *)mm.ctx);

	return 0;
}
Esempio n. 2
0
static int request_io(struct knot_requestor *req, struct knot_request *last,
                      struct timeval *timeout)
{
	int ret = KNOT_EOK;
	knot_pkt_t *query = last->query;
	knot_pkt_t *resp = last->resp;

	/* Data to be sent. */
	if (req->overlay.state == KNOT_STATE_PRODUCE) {

		/* Process query and send it out. */
		knot_overlay_produce(&req->overlay, query);

		if (req->overlay.state == KNOT_STATE_CONSUME) {
			ret = request_send(last, timeout);
			if (ret != KNOT_EOK) {
				return ret;
			}
		}
	}

	/* Data to be read. */
	if (req->overlay.state == KNOT_STATE_CONSUME) {
		/* Read answer and process it. */
		ret = request_recv(last, timeout);
		if (ret < 0) {
			return ret;
		}

		(void) knot_pkt_parse(resp, 0);
		knot_overlay_consume(&req->overlay, resp);
	}

	return KNOT_EOK;
}
Esempio n. 3
0
/*!
 * \brief TCP event handler function.
 */
static int tcp_handle(tcp_context_t *tcp, int fd,
                      struct iovec *rx, struct iovec *tx)
{
	/* Create query processing parameter. */
	struct sockaddr_storage ss;
	memset(&ss, 0, sizeof(struct sockaddr_storage));
	struct process_query_param param = {0};
	param.socket = fd;
	param.remote = &ss;
	param.server = tcp->server;
	param.thread_id = tcp->thread_id;
	rx->iov_len = KNOT_WIRE_MAX_PKTSIZE;
	tx->iov_len = KNOT_WIRE_MAX_PKTSIZE;

	/* Receive peer name. */
	socklen_t addrlen = sizeof(struct sockaddr_storage);
	if (getpeername(fd, (struct sockaddr *)&ss, &addrlen) < 0) {
		;
	}

	/* Timeout. */
	rcu_read_lock();
	conf_val_t *val = &conf()->cache.srv_tcp_reply_timeout;
	int timeout = conf_int(val) * 1000;
	rcu_read_unlock();

	/* Receive data. */
	int ret = net_dns_tcp_recv(fd, rx->iov_base, rx->iov_len, timeout);
	if (ret <= 0) {
		if (ret == KNOT_EAGAIN) {
			char addr_str[SOCKADDR_STRLEN] = {0};
			sockaddr_tostr(addr_str, sizeof(addr_str), &ss);
			log_warning("TCP, connection timed out, address '%s'",
			            addr_str);
		}
		return KNOT_ECONNREFUSED;
	} else {
		rx->iov_len = ret;
	}

	knot_mm_t *mm = tcp->overlay.mm;

	/* Initialize processing overlay. */
	ret = knot_overlay_init(&tcp->overlay, mm);
	if (ret != KNOT_EOK) {
		return ret;
	}
	ret = knot_overlay_add(&tcp->overlay, NS_PROC_QUERY, &param);
	if (ret != KNOT_EOK) {
		return ret;
	}

	/* Create packets. */
	knot_pkt_t *ans = knot_pkt_new(tx->iov_base, tx->iov_len, mm);
	knot_pkt_t *query = knot_pkt_new(rx->iov_base, rx->iov_len, mm);

	/* Input packet. */
	(void) knot_pkt_parse(query, 0);
	int state = knot_overlay_consume(&tcp->overlay, query);

	/* Resolve until NOOP or finished. */
	ret = KNOT_EOK;
	while (state & (KNOT_STATE_PRODUCE|KNOT_STATE_FAIL)) {
		state = knot_overlay_produce(&tcp->overlay, ans);

		/* Send, if response generation passed and wasn't ignored. */
		if (ans->size > 0 && !(state & (KNOT_STATE_FAIL|KNOT_STATE_NOOP))) {
			if (net_dns_tcp_send(fd, ans->wire, ans->size, timeout) != ans->size) {
				ret = KNOT_ECONNREFUSED;
				break;
			}
		}
	}

	/* Reset after processing. */
	knot_overlay_finish(&tcp->overlay);
	knot_overlay_deinit(&tcp->overlay);

	/* Cleanup. */
	knot_pkt_free(&query);
	knot_pkt_free(&ans);

	return ret;
}