Esempio n. 1
0
File: db.c Progetto: idtek/knot
int main(int argc, char *argv[])
{
	plan_lazy();

	knot_mm_t pool;
	mm_ctx_mempool(&pool, MM_DEFAULT_BLKSIZE);

	char *dbid = test_mkdtemp();
	ok(dbid != NULL, "make temporary directory");

	/* Random keys. */
	unsigned nkeys = 10000;
	char **keys = mm_alloc(&pool, sizeof(char*) * nkeys);
	for (unsigned i = 0; i < nkeys; ++i) {
		keys[i] = str_key_rand(KEY_MAXLEN, &pool);
	}

	/* Sort random keys. */
	str_key_sort(keys, nkeys);

	/* Execute test set for all backends. */
	struct knot_db_lmdb_opts lmdb_opts = KNOT_DB_LMDB_OPTS_INITIALIZER;
	lmdb_opts.path = dbid;
	struct knot_db_trie_opts trie_opts = KNOT_DB_TRIE_OPTS_INITIALIZER;
	knot_db_test_set(nkeys, keys, &lmdb_opts, knot_db_lmdb_api(), &pool);
	knot_db_test_set(nkeys, keys, &trie_opts, knot_db_trie_api(), &pool);

	/* Cleanup. */
	mp_delete(pool.ctx);
	test_rm_rf(dbid);
	free(dbid);

	return 0;
}
Esempio n. 2
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. 3
0
int main(int argc, char *argv[])
{
	plan(TESTS_COUNT + 1);

	mm_ctx_t mm;
	mm_ctx_mempool(&mm, MM_DEFAULT_BLKSIZE);

	conf_remote_t remote;
	memset(&remote, 0, sizeof(conf_remote_t));
	sockaddr_set(&remote.addr, AF_INET, "127.0.0.1", 0);
	sockaddr_set(&remote.via, AF_INET, "127.0.0.1", 0);

	/* Create fake server environment. */
	server_t server;
	int ret = create_fake_server(&server, &mm);
	ok(ret == KNOT_EOK, "requestor: initialize fake server");

	/* Initialize requestor. */
	struct knot_requestor requestor;
	knot_requestor_init(&requestor, &mm);
	knot_requestor_overlay(&requestor, &dummy_module, NULL);

	/* Test requestor in disconnected environment. */
	test_disconnected(&requestor, &remote);

	/* Bind to random port. */
	int origin_fd = net_bound_socket(SOCK_STREAM, &remote.addr, 0);
	assert(origin_fd > 0);
	socklen_t addr_len = sockaddr_len((struct sockaddr *)&remote.addr);
	getsockname(origin_fd, (struct sockaddr *)&remote.addr, &addr_len);
	ret = listen(origin_fd, 10);
	assert(ret == 0);

	/* Responder thread. */
	pthread_t thread;
	pthread_create(&thread, 0, responder_thread, &origin_fd);

	/* Test requestor in connected environment. */
	test_connected(&requestor, &remote);

	/*! \todo #243 TSIG secured requests test should be implemented. */

	/* Terminate responder. */
	int responder = net_connected_socket(SOCK_STREAM, &remote.addr, NULL, 0);
	assert(responder > 0);
	tcp_send_msg(responder, (const uint8_t *)"", 1, NULL);
	(void) pthread_join(thread, 0);
	close(responder);

	/* Close requestor. */
	knot_requestor_clear(&requestor);
	close(origin_fd);

	/* Cleanup. */
	mp_delete((struct mempool *)mm.ctx);
	server_deinit(&server);
	conf_free(conf(), false);

	return 0;
}
Esempio n. 4
0
File: pkt.c Progetto: idtek/knot
int main(int argc, char *argv[])
{
	plan(25);

	/* Create memory pool context. */
	int ret = 0;
	knot_mm_t mm;
	mm_ctx_mempool(&mm, MM_DEFAULT_BLKSIZE);

	/* Create names and data. */
	knot_dname_t* dnames[NAMECOUNT] = {0};
	knot_rrset_t* rrsets[NAMECOUNT] = {0};
	for (unsigned i = 0; i < NAMECOUNT; ++i) {
		dnames[i] = knot_dname_from_str_alloc(g_names[i]);
	}

	uint8_t *edns_str = (uint8_t *)"ab";
	/* Create OPT RR. */
	knot_rrset_t opt_rr;
	ret = knot_edns_init(&opt_rr, 1024, 0, 0, &mm);
	if (ret != KNOT_EOK) {
		skip_block(25, "Failed to initialize OPT RR.");
		return 0;
	}
	/* Add NSID */
	ret = knot_edns_add_option(&opt_rr, KNOT_EDNS_OPTION_NSID,
	                           strlen((char *)edns_str), edns_str, &mm);
	if (ret != KNOT_EOK) {
		knot_rrset_clear(&opt_rr, &mm);
		skip_block(25, "Failed to add NSID to OPT RR.");
		return 0;
	}

	/*
	 * Packet writer tests.
	 */

	/* Create packet. */
	knot_pkt_t *out = knot_pkt_new(NULL, MM_DEFAULT_BLKSIZE, &mm);
	ok(out != NULL, "pkt: new");

	/* Mark as response (not part of the test). */
	knot_wire_set_qr(out->wire);

	/* Secure packet. */
	const char *tsig_secret = "abcd";
	knot_tsig_key_t tsig_key;
	tsig_key.algorithm = DNSSEC_TSIG_HMAC_MD5;
	tsig_key.name = dnames[0];
	tsig_key.secret.data = (uint8_t *)strdup(tsig_secret);
	tsig_key.secret.size = strlen(tsig_secret);
	ret = knot_pkt_reserve(out, knot_tsig_wire_maxsize(&tsig_key));
	ok(ret == KNOT_EOK, "pkt: set TSIG key");

	/* Write question. */
	ret = knot_pkt_put_question(out, dnames[0], KNOT_CLASS_IN, KNOT_RRTYPE_A);
	ok(ret == KNOT_EOK, "pkt: put question");

	/* Add OPT to packet (empty NSID). */
	ret = knot_pkt_reserve(out, knot_edns_wire_size(&opt_rr));
	ok(ret == KNOT_EOK, "pkt: reserve OPT RR");

	/* Begin ANSWER section. */
	ret = knot_pkt_begin(out, KNOT_ANSWER);
	ok(ret == KNOT_EOK, "pkt: begin ANSWER");

	/* Write ANSWER section. */
	rrsets[0] = knot_rrset_new(dnames[0], KNOT_RRTYPE_A, KNOT_CLASS_IN, NULL);
	knot_dname_free(&dnames[0], NULL);
	knot_rrset_add_rdata(rrsets[0], RDVAL(0), RDLEN(0), TTL, NULL);
	ret = knot_pkt_put(out, KNOT_COMPR_HINT_QNAME, rrsets[0], 0);
	ok(ret == KNOT_EOK, "pkt: write ANSWER");

	/* Begin AUTHORITY. */
	ret = knot_pkt_begin(out, KNOT_AUTHORITY);
	ok(ret == KNOT_EOK, "pkt: begin AUTHORITY");

	/* Write rest to AUTHORITY. */
	ret = KNOT_EOK;
	for (unsigned i = 1; i < NAMECOUNT; ++i) {
		rrsets[i] = knot_rrset_new(dnames[i], KNOT_RRTYPE_NS, KNOT_CLASS_IN, NULL);
		knot_dname_free(&dnames[i], NULL);
		knot_rrset_add_rdata(rrsets[i], RDVAL(i), RDLEN(i), TTL, NULL);
		ret |= knot_pkt_put(out, KNOT_COMPR_HINT_NONE, rrsets[i], 0);
	}
	ok(ret == KNOT_EOK, "pkt: write AUTHORITY(%u)", NAMECOUNT - 1);

	/* Begin ADDITIONALS */
	ret = knot_pkt_begin(out, KNOT_ADDITIONAL);
	ok(ret == KNOT_EOK, "pkt: begin ADDITIONALS");

	/* Encode OPT RR. */
	ret = knot_pkt_put(out, KNOT_COMPR_HINT_NONE, &opt_rr, 0);
	ok(ret == KNOT_EOK, "pkt: write OPT RR");

	/*
	 * Packet reader tests.
	 */

	/* Create new packet from query packet. */
	knot_pkt_t *in = knot_pkt_new(out->wire, out->size, &out->mm);
	ok(in != NULL, "pkt: create packet for parsing");

	/* Read packet header. */
	ret = knot_pkt_parse_question(in);
	ok(ret == KNOT_EOK, "pkt: read header");

	/* Read packet payload. */
	ret = knot_pkt_parse_payload(in, 0);
	ok(ret == KNOT_EOK, "pkt: read payload");

	/* Compare parsed packet to written packet. */
	packet_match(in, out);

	/*
	 * Copied packet tests.
	 */
	knot_pkt_t *copy = knot_pkt_new(NULL, in->max_size, &in->mm);
	ret = knot_pkt_copy(copy, in);
	ok(ret == KNOT_EOK, "pkt: create packet copy");

	/* Compare copied packet to original. */
	packet_match(in, copy);

	/* Free packets. */
	knot_pkt_free(&copy);
	knot_pkt_free(&out);
	knot_pkt_free(&in);
	ok(in == NULL && out == NULL && copy == NULL, "pkt: free");

	/* Free extra data. */
	for (unsigned i = 0; i < NAMECOUNT; ++i) {
		knot_rrset_free(&rrsets[i], NULL);
	}
	free(tsig_key.secret.data);
	mp_delete((struct mempool *)mm.ctx);

	return 0;
}
Esempio n. 5
0
int tcp_master(dthread_t *thread)
{
	if (!thread || !thread->data) {
		return KNOT_EINVAL;
	}

	iohandler_t *handler = (iohandler_t *)thread->data;
	unsigned *iostate = &handler->thread_state[dt_get_id(thread)];

	int ret = KNOT_EOK;
	ref_t *ref = NULL;
	tcp_context_t tcp;
	memset(&tcp, 0, sizeof(tcp_context_t));

	/* Create big enough memory cushion. */
	knot_mm_t mm;
	mm_ctx_mempool(&mm, 16 * MM_DEFAULT_BLKSIZE);

	/* Create TCP answering context. */
	tcp.server = handler->server;
	tcp.thread_id = handler->thread_id[dt_get_id(thread)];
	tcp.overlay.mm = &mm;

	/* Prepare structures for bound sockets. */
	conf_val_t val = conf_get(conf(), C_SRV, C_LISTEN);
	fdset_init(&tcp.set, conf_val_count(&val) + CONF_XFERS);

	/* Create iovec abstraction. */
	for (unsigned i = 0; i < 2; ++i) {
		tcp.iov[i].iov_len = KNOT_WIRE_MAX_PKTSIZE;
		tcp.iov[i].iov_base = malloc(tcp.iov[i].iov_len);
		if (tcp.iov[i].iov_base == NULL) {
			ret = KNOT_ENOMEM;
			goto finish;
		}
	}

	/* Initialize sweep interval. */
	timev_t next_sweep = {0};
	time_now(&next_sweep);
	next_sweep.tv_sec += TCP_SWEEP_INTERVAL;

	for(;;) {

		/* Check handler state. */
		if (unlikely(*iostate & ServerReload)) {
			*iostate &= ~ServerReload;

			/* Cancel client connections. */
			for (unsigned i = tcp.client_threshold; i < tcp.set.n; ++i) {
				close(tcp.set.pfd[i].fd);
			}

			ref_release(ref);
			ref = server_set_ifaces(handler->server, &tcp.set, IO_TCP, tcp.thread_id);
			if (tcp.set.n == 0) {
				break; /* Terminate on zero interfaces. */
			}

			tcp.client_threshold = tcp.set.n;
		}

		/* Check for cancellation. */
		if (dt_is_cancelled(thread)) {
			break;
		}

		/* Serve client requests. */
		tcp_wait_for_events(&tcp);

		/* Sweep inactive clients. */
		if (tcp.last_poll_time.tv_sec >= next_sweep.tv_sec) {
			fdset_sweep(&tcp.set, &tcp_sweep, NULL);
			time_now(&next_sweep);
			next_sweep.tv_sec += TCP_SWEEP_INTERVAL;
		}
	}

finish:
	free(tcp.iov[0].iov_base);
	free(tcp.iov[1].iov_base);
	mp_delete(mm.ctx);
	fdset_clear(&tcp.set);
	ref_release(ref);

	return ret;
}
Esempio n. 6
0
/*!
 * \brief Create a zone event query, send it, wait for the response and process it.
 *
 * \note Everything in this function is executed synchronously, returns when
 *       the query processing is either complete or an error occurs.
 */
static int zone_query_execute(conf_t *conf, zone_t *zone, uint16_t pkt_type,
                              const conf_remote_t *remote)
{
	/* Create a memory pool for this task. */
	knot_mm_t mm;
	mm_ctx_mempool(&mm, MM_DEFAULT_BLKSIZE);

	/* Create a query message. */
	knot_pkt_t *query = zone_query(zone, pkt_type, &mm);
	if (query == NULL) {
		mp_delete(mm.ctx);
		return KNOT_ENOMEM;
	}

	/* Set EDNS section. */
	int ret = prepare_edns(conf, zone, query);
	if (ret != KNOT_EOK) {
		knot_pkt_free(&query);
		mp_delete(mm.ctx);
		return ret;
	}

	/* Answer processing parameters. */
	struct process_answer_param param = {
		.zone = zone,
		.conf = conf,
		.query = query,
		.remote = &remote->addr
	};

	const knot_tsig_key_t *key = remote->key.name != NULL ?
	                             &remote->key : NULL;
	tsig_init(&param.tsig_ctx, key);

	ret = tsig_sign_packet(&param.tsig_ctx, query);
	if (ret != KNOT_EOK) {
		tsig_cleanup(&param.tsig_ctx);
		knot_pkt_free(&query);
		mp_delete(mm.ctx);
		return ret;
	}

	/* Process the query. */
	ret = zone_query_request(query, remote, &param, &mm);

	/* Cleanup. */
	tsig_cleanup(&param.tsig_ctx);
	knot_pkt_free(&query);
	mp_delete(mm.ctx);

	return ret;
}

/* @note Module specific, expects some variables set. */
#define ZONE_XFER_LOG(severity, pkt_type, msg, ...) \
	if (pkt_type == KNOT_QUERY_AXFR) { \
		ZONE_QUERY_LOG(severity, zone, master, "AXFR, incoming", msg, ##__VA_ARGS__); \
	} else { \
		ZONE_QUERY_LOG(severity, zone, master, "IXFR, incoming", msg, ##__VA_ARGS__); \
	}

/*! \brief Execute zone transfer request. */
static int zone_query_transfer(conf_t *conf, zone_t *zone, const conf_remote_t *master,
                               uint16_t pkt_type)
{
	assert(zone);
	assert(master);

	int ret = zone_query_execute(conf, zone, pkt_type, master);
	if (ret != KNOT_EOK) {
		/* IXFR failed, revert to AXFR. */
		if (pkt_type == KNOT_QUERY_IXFR) {
			ZONE_XFER_LOG(LOG_NOTICE, pkt_type, "fallback to AXFR");
			return zone_query_transfer(conf, zone, master, KNOT_QUERY_AXFR);
		}

		/* Log connection errors. */
		ZONE_XFER_LOG(LOG_WARNING, pkt_type, "failed (%s)", knot_strerror(ret));
	}

	return ret;
}
Esempio n. 7
0
int main(int argc, char *argv[])
{
	plan(8*6 + 3); /* exec_query = 6 TAP tests */

	/* Create processing context. */
	knot_process_t query_ctx;
	memset(&query_ctx, 0, sizeof(knot_process_t));
	mm_ctx_mempool(&query_ctx.mm, sizeof(knot_pkt_t));

	/* Create name server. */
	server_t server;
	server_init(&server);
	server.opt_rr = knot_edns_new();
	knot_edns_set_version(server.opt_rr, EDNS_VERSION);
	knot_edns_set_payload(server.opt_rr, 4096);
	conf()->identity = strdup("bogus.ns");
	conf()->version = strdup("0.11");

	/* Insert root zone. */
	create_root_zone(&server, &query_ctx.mm);
	zone_t *zone = knot_zonedb_find(server.zone_db, ROOT_DNAME);

	/* Prepare. */
	int state = NS_PROC_FAIL;
	uint8_t query_wire[KNOT_WIRE_MAX_PKTSIZE];
	uint16_t query_len = KNOT_WIRE_MAX_PKTSIZE;
	knot_pkt_t *query = knot_pkt_new(query_wire, query_len, &query_ctx.mm);

	/* Create query processing parameter. */
	struct sockaddr_storage ss;
	memset(&ss, 0, sizeof(struct sockaddr_storage));
	sockaddr_set(&ss, AF_INET, "127.0.0.1", 53);
	struct process_query_param param = {0};
	param.query_source = &ss;
	param.server = &server;

	/* Query processor (CH zone) */
	state = knot_process_begin(&query_ctx, &param, NS_PROC_QUERY);
	const uint8_t chaos_dname[] = "\2""id""\6""server"; /* id.server */
	knot_pkt_clear(query);
	knot_pkt_put_question(query, chaos_dname, KNOT_CLASS_CH, KNOT_RRTYPE_TXT);
	exec_query(&query_ctx, "CH TXT", query->wire, query->size, KNOT_RCODE_NOERROR);

	/* Query processor (valid input). */
	state = knot_process_reset(&query_ctx);
	knot_pkt_clear(query);
	knot_pkt_put_question(query, ROOT_DNAME, KNOT_CLASS_IN, KNOT_RRTYPE_SOA);
	exec_query(&query_ctx, "IN/root", query->wire, query->size, KNOT_RCODE_NOERROR);

	/* Query processor (-1 bytes, not enough data). */
	state = knot_process_reset(&query_ctx);
	exec_query(&query_ctx, "IN/few-data", query->wire, query->size - 1, KNOT_RCODE_FORMERR);

	/* Query processor (+1 bytes trailing). */
	state = knot_process_reset(&query_ctx);
	query->wire[query->size] = '\1'; /* Initialize the "garbage" value. */
	exec_query(&query_ctx, "IN/trail-garbage", query->wire, query->size + 1, KNOT_RCODE_FORMERR);

	/* Forge NOTIFY query from SOA query. */
	state = knot_process_reset(&query_ctx);
	knot_wire_set_opcode(query->wire, KNOT_OPCODE_NOTIFY);
	exec_query(&query_ctx, "IN/notify", query->wire, query->size, KNOT_RCODE_NOTAUTH);

	/* Forge AXFR query. */
	knot_process_reset(&query_ctx);
	knot_pkt_clear(query);
	knot_pkt_put_question(query, ROOT_DNAME, KNOT_CLASS_IN, KNOT_RRTYPE_AXFR);
	exec_query(&query_ctx, "IN/axfr", query->wire, query->size, KNOT_RCODE_NOTAUTH);

	/* Forge IXFR query (badly formed, no SOA in AUTHORITY section). */
	knot_process_reset(&query_ctx);
	knot_pkt_clear(query);
	knot_pkt_put_question(query, ROOT_DNAME, KNOT_CLASS_IN, KNOT_RRTYPE_IXFR);
	exec_query(&query_ctx, "IN/ixfr-formerr", query->wire, query->size, KNOT_RCODE_FORMERR);

	/* Forge IXFR query (well formed). */
	knot_process_reset(&query_ctx);
	/* Append SOA RR. */
	knot_rrset_t soa_rr = node_rrset(zone->contents->apex, KNOT_RRTYPE_SOA);
	knot_pkt_begin(query, KNOT_AUTHORITY);
	knot_pkt_put(query, COMPR_HINT_NONE, &soa_rr, 0);
	exec_query(&query_ctx, "IN/ixfr", query->wire, query->size, KNOT_RCODE_NOTAUTH);

	/* \note Tests below are not possible without proper zone and zone data. */
	/* #189 Process UPDATE query. */
	/* #189 Process AXFR client. */
	/* #189 Process IXFR client. */

	/* Query processor (smaller than DNS header, ignore). */
	state = knot_process_reset(&query_ctx);
	knot_pkt_clear(query);
	knot_pkt_put_question(query, ROOT_DNAME, KNOT_CLASS_IN, KNOT_RRTYPE_SOA);
	state = knot_process_in(query->wire, KNOT_WIRE_HEADER_SIZE - 1, &query_ctx);
	ok(state == NS_PROC_NOOP, "ns: IN/less-than-header query ignored");

	/* Query processor (response, ignore). */
	state = knot_process_reset(&query_ctx);
	knot_wire_set_qr(query->wire);
	state = knot_process_in(query->wire, query->size, &query_ctx);
	ok(state == NS_PROC_NOOP, "ns: IN/less-than-header query ignored");

	/* Finish. */
	state = knot_process_finish(&query_ctx);
	ok(state == NS_PROC_NOOP, "ns: processing end" );

	/* Cleanup. */
	mp_delete((struct mempool *)query_ctx.mm.ctx);
	server_deinit(&server);

	return 0;
}
Esempio n. 8
0
int main(int argc, char *argv[])
{
	plan(8*6 + 4); /* exec_query = 6 TAP tests */

	knot_mm_t mm;
	mm_ctx_mempool(&mm, MM_DEFAULT_BLKSIZE);

	/* Create processing context. */
	knot_layer_t proc;
	memset(&proc, 0, sizeof(knot_layer_t));
	proc.mm = &mm;

	/* Create fake server environment. */
	server_t server;
	int ret = create_fake_server(&server, proc.mm);
	ok(ret == KNOT_EOK, "ns: fake server initialization");

	zone_t *zone = knot_zonedb_find(server.zone_db, ROOT_DNAME);

	/* Prepare. */
	knot_pkt_t *query = knot_pkt_new(NULL, KNOT_WIRE_MAX_PKTSIZE, proc.mm);

	/* Create query processing parameter. */
	struct sockaddr_storage ss;
	memset(&ss, 0, sizeof(struct sockaddr_storage));
	sockaddr_set(&ss, AF_INET, "127.0.0.1", 53);
	struct process_query_param param = {0};
	param.remote = &ss;
	param.server = &server;

	/* Query processor (CH zone) */
	knot_layer_begin(&proc, NS_PROC_QUERY, &param);
	knot_pkt_clear(query);
	knot_pkt_put_question(query, IDSERVER_DNAME, KNOT_CLASS_CH, KNOT_RRTYPE_TXT);
	exec_query(&proc, "CH TXT", query, KNOT_RCODE_NOERROR);

	/* Query processor (valid input). */
	knot_layer_reset(&proc);
	knot_pkt_clear(query);
	knot_pkt_put_question(query, ROOT_DNAME, KNOT_CLASS_IN, KNOT_RRTYPE_SOA);
	exec_query(&proc, "IN/root", query, KNOT_RCODE_NOERROR);

	/* Query processor (-1 bytes, not enough data). */
	knot_layer_reset(&proc);
	query->size -= 1;
	exec_query(&proc, "IN/few-data", query, KNOT_RCODE_FORMERR);
	query->size += 1;

	/* Query processor (+1 bytes trailing). */
	knot_layer_reset(&proc);
	query->wire[query->size] = '\1'; /* Initialize the "garbage" value. */
	query->size += 1;
	exec_query(&proc, "IN/trail-garbage", query, KNOT_RCODE_FORMERR);
	query->size -= 1;

	/* Forge NOTIFY query from SOA query. */
	knot_layer_reset(&proc);
	knot_wire_set_opcode(query->wire, KNOT_OPCODE_NOTIFY);
	exec_query(&proc, "IN/notify", query, KNOT_RCODE_NOTAUTH);

	/* Forge AXFR query. */
	knot_layer_reset(&proc);
	knot_pkt_clear(query);
	knot_pkt_put_question(query, ROOT_DNAME, KNOT_CLASS_IN, KNOT_RRTYPE_AXFR);
	exec_query(&proc, "IN/axfr", query, KNOT_RCODE_NOTAUTH);

	/* Forge IXFR query (badly formed, no SOA in AUTHORITY section). */
	knot_layer_reset(&proc);
	knot_pkt_clear(query);
	knot_pkt_put_question(query, ROOT_DNAME, KNOT_CLASS_IN, KNOT_RRTYPE_IXFR);
	exec_query(&proc, "IN/ixfr-formerr", query, KNOT_RCODE_FORMERR);

	/* Forge IXFR query (well formed). */
	knot_layer_reset(&proc);
	knot_pkt_clear(query);
	knot_pkt_put_question(query, ROOT_DNAME, KNOT_CLASS_IN, KNOT_RRTYPE_IXFR);
	/* Append SOA RR. */
	knot_rrset_t soa_rr = node_rrset(zone->contents->apex, KNOT_RRTYPE_SOA);
	knot_pkt_begin(query, KNOT_AUTHORITY);
	knot_pkt_put(query, KNOT_COMPR_HINT_NONE, &soa_rr, 0);
	exec_query(&proc, "IN/ixfr", query, KNOT_RCODE_NOTAUTH);

	/* \note Tests below are not possible without proper zone and zone data. */
	/* #189 Process UPDATE query. */
	/* #189 Process AXFR client. */
	/* #189 Process IXFR client. */

	/* Query processor (smaller than DNS header, ignore). */
	knot_layer_reset(&proc);
	knot_pkt_clear(query);
	knot_pkt_put_question(query, ROOT_DNAME, KNOT_CLASS_IN, KNOT_RRTYPE_SOA);
	size_t orig_query_size = query->size;
	query->size = KNOT_WIRE_HEADER_SIZE - 1;
	int state = knot_layer_consume(&proc, query);
	ok(state == KNOT_STATE_NOOP, "ns: IN/less-than-header query ignored");
	query->size = orig_query_size;

	/* Query processor (response, ignore). */
	knot_layer_reset(&proc);
	knot_wire_set_qr(query->wire);
	state = knot_layer_consume(&proc, query);
	ok(state == KNOT_STATE_NOOP, "ns: IN/less-than-header query ignored");

	/* Finish. */
	state = knot_layer_finish(&proc);
	ok(state == KNOT_STATE_NOOP, "ns: processing end" );

	/* Cleanup. */
	mp_delete((struct mempool *)mm.ctx);
	server_deinit(&server);
	conf_free(conf());

	return 0;
}