diff --git a/Knot.files b/Knot.files
index 856043c8f0d01cac454bcad8517d0c9ee44172de..2dc8800f2d07dfbc1cf3b97b9075b6e6086b212a 100644
--- a/Knot.files
+++ b/Knot.files
@@ -125,6 +125,8 @@ src/knot/nameserver/process_query.c
 src/knot/nameserver/process_query.h
 src/knot/nameserver/query_module.c
 src/knot/nameserver/query_module.h
+src/knot/nameserver/requestor.c
+src/knot/nameserver/requestor.h
 src/knot/nameserver/update.c
 src/knot/nameserver/update.h
 src/knot/other/debug.h
@@ -308,6 +310,7 @@ tests/pkt.c
 tests/process_answer.c
 tests/process_query.c
 tests/query_module.c
+tests/requestor.c
 tests/rrl.c
 tests/rrset.c
 tests/sample_conf.h
diff --git a/src/knot/nameserver/requestor.c b/src/knot/nameserver/requestor.c
index 422130bf27027746a3ae6d66cb7152c4772842e4..02ff932484b8428a6875ed1f8034e022111875e1 100644
--- a/src/knot/nameserver/requestor.c
+++ b/src/knot/nameserver/requestor.c
@@ -23,6 +23,7 @@ struct request {
 	node_t node;
 	int fd;
 	int state;
+	const struct sockaddr_storage *remote, *origin;
 	knot_pkt_t *query;
 	knot_process_t process;
 	uint8_t *pkt_buf;
@@ -118,12 +119,13 @@ static int request_recv(struct request *request, struct timeval *timeout)
 		return NS_PROC_FAIL;
 	}
 
-	return KNOT_EOK;
+	return ret;
 }
 
-void requestor_init(struct requestor *requestor, mm_ctx_t *mm)
+void requestor_init(struct requestor *requestor, const knot_process_module_t *module, mm_ctx_t *mm)
 {
 	memset(requestor, 0, sizeof(struct requestor));
+	requestor->module = module;
 	requestor->mm = mm;
 	init_list(&requestor->pending);
 }
@@ -139,33 +141,47 @@ bool requestor_finished(struct requestor *requestor)
 	return requestor == NULL || EMPTY_LIST(requestor->pending);
 }
 
-int requestor_enqueue(struct requestor *requestor, knot_pkt_t *query,
-                      const knot_process_module_t *module, void *param)
+struct request *requestor_make(struct requestor *requestor,
+                               const struct sockaddr_storage *from,
+                               const struct sockaddr_storage *to,
+                               knot_pkt_t *query)
+{
+	if (requestor == NULL || query == NULL || to == NULL) {
+		return NULL;
+	}
+
+	/* Form a pending request. */
+	struct request *request = request_make(requestor->mm);
+	if (request == NULL) {
+		return NULL;
+	}
+
+	request->origin = from;
+	request->remote = to;
+	request->fd = -1;
+	request->query = query;
+	return request;
+}
+
+int requestor_enqueue(struct requestor *requestor, struct request * request, void *param)
 {
-	if (requestor == NULL || query == NULL) {
+	if (requestor == NULL || request == NULL) {
 		return KNOT_EINVAL;
 	}
 
 	/* Fetch a bound socket. */
-	int fd = net_connected_socket(SOCK_STREAM, requestor->remote,
-	                              requestor->origin, O_NONBLOCK);
+	int fd = net_connected_socket(SOCK_STREAM, request->remote,
+	                              request->origin, O_NONBLOCK);
 	if (fd < 0) {
 		return KNOT_ECONN;
 	}
 
 	/* Form a pending request. */
-	struct request *request = request_make(requestor->mm);
-	if (request == NULL) {
-		close(fd);
-		return KNOT_ENOMEM;
-	}
-
 	request->fd = fd;
-	request->query = query;
 	request->state = NS_PROC_FULL; /* We have a query to be sent. */
 	memcpy(&request->process.mm, requestor->mm, sizeof(mm_ctx_t));
 
-	knot_process_begin(&request->process, param, module);
+	knot_process_begin(&request->process, param, requestor->module);
 
 	add_tail(&requestor->pending, &request->node);
 
@@ -198,15 +214,18 @@ static int exec_request(struct request *last, struct timeval *timeout)
 
 	/* Receive and process expected answers. */
 	while(last->state == NS_PROC_MORE) {
-		ret = request_recv(last, timeout);
-		if (ret != KNOT_EOK) {
-			return ret;
+		int rcvd = request_recv(last, timeout);
+		if (rcvd <= 0) {
+			return rcvd;
 		}
 
-		last->state = knot_process_in(last->pkt_buf, ret, &last->process);
+		last->state = knot_process_in(last->pkt_buf, rcvd, &last->process);
+		if (last->state == NS_PROC_FAIL) {
+			return KNOT_ERROR;
+		}
 	}
 
-	return ret;
+	return KNOT_EOK;
 }
 
 int requestor_exec(struct requestor *requestor, struct timeval *timeout)
diff --git a/src/knot/nameserver/requestor.h b/src/knot/nameserver/requestor.h
index e5616e4b071848b3f6c48447fc1bef12cd7712bb..f0b45378a7cb0a60d4008b0395c0279936416bae 100644
--- a/src/knot/nameserver/requestor.h
+++ b/src/knot/nameserver/requestor.h
@@ -20,13 +20,15 @@
 #include "knot/nameserver/process_answer.h"
 #include "common/lists.h"
 
+struct request;
+
 /*! \brief Requestor structure.
  *
  *  Requestor holds a FIFO of pending queries with given remote.
  */
 struct requestor {
 	/* Requestor target and source address. */
-	const struct sockaddr_storage *remote, *origin;
+	const knot_process_module_t *module;
 
 	//knot_sign_context_t tsig; /* @note not implemented */
 
@@ -37,7 +39,7 @@ struct requestor {
 /*!
  * \brief Initialize requestor structure.
  */
-void requestor_init(struct requestor *requestor, mm_ctx_t *mm);
+void requestor_init(struct requestor *requestor, const knot_process_module_t *module, mm_ctx_t *mm);
 
 /*!
  * \brief Clear the requestor structure and close pending queries.
@@ -47,6 +49,13 @@ void requestor_clear(struct requestor *requestor);
 /*! \brief Return true if there are no pending queries. */
 bool requestor_finished(struct requestor *requestor);
 
+
+/*! \brief Make request out of endpoints and query. */
+struct request *requestor_make(struct requestor *requestor,
+                               const struct sockaddr_storage *from,
+                               const struct sockaddr_storage *to,
+                               knot_pkt_t *query);
+
 /*!
  * \brief Enqueue a query for processing.
  *
@@ -60,8 +69,7 @@ bool requestor_finished(struct requestor *requestor);
  *
  * \return KNOT_EOK or error
  */
-int requestor_enqueue(struct requestor *requestor, knot_pkt_t *query,
-                      const knot_process_module_t *module, void *param);
+int requestor_enqueue(struct requestor *requestor, struct request *request, void *param);
 
 /*!
  * \brief Close first pending request.
diff --git a/tests/requestor.c b/tests/requestor.c
index 0393a383a6d13bb6df9998e2492388aa3d279c17..a8b32236f47f41db66f2163694bc2a0ad7bcabbe 100644
--- a/tests/requestor.c
+++ b/tests/requestor.c
@@ -64,18 +64,19 @@ static void* responder_thread(void *arg)
 #define CONNECTED_TESTS    4
 #define TESTS_COUNT DISCONNECTED_TESTS + CONNECTED_TESTS
 
-static knot_pkt_t *make_query(mm_ctx_t *mm)
+static struct request *make_query(struct requestor *requestor, struct sockaddr_storage *remote)
 {
-	knot_pkt_t *pkt = knot_pkt_new(NULL, KNOT_WIRE_MAX_PKTSIZE, mm);
+	knot_pkt_t *pkt = knot_pkt_new(NULL, KNOT_WIRE_MAX_PKTSIZE, requestor->mm);
 	assert(pkt);
 	knot_pkt_put_question(pkt, ROOT_DNAME, KNOT_CLASS_IN, KNOT_RRTYPE_SOA);
-	return pkt;
+
+	return requestor_make(requestor, NULL, remote, pkt);
 }
 
-static void test_disconnected(struct requestor *requestor)
+static void test_disconnected(struct requestor *requestor, struct sockaddr_storage *remote)
 {
 	/* Enqueue packet. */
-	int ret = requestor_enqueue(requestor, make_query(requestor->mm), &dummy_module, NULL);
+	int ret = requestor_enqueue(requestor, make_query(requestor, remote), NULL);
 	is_int(KNOT_EOK, ret, "requestor: disconnected/enqueue");
 
 	/* Wait for completion. */
@@ -84,10 +85,10 @@ static void test_disconnected(struct requestor *requestor)
 	is_int(KNOT_ECONNREFUSED, ret, "requestor: disconnected/wait");
 }
 
-static void test_connected(struct requestor *requestor)
+static void test_connected(struct requestor *requestor, struct sockaddr_storage *remote)
 {
 	/* Enqueue packet. */
-	int ret = requestor_enqueue(requestor, make_query(requestor->mm), &dummy_module, NULL);
+	int ret = requestor_enqueue(requestor, make_query(requestor, remote), NULL);;
 	is_int(KNOT_EOK, ret, "requestor: connected/enqueue");
 
 	/* Wait for completion. */
@@ -98,7 +99,7 @@ static void test_connected(struct requestor *requestor)
 	/* Enqueue multiple queries. */
 	ret = KNOT_EOK;
 	for (unsigned i = 0; i < 10; ++i) {
-		ret |= requestor_enqueue(requestor, make_query(requestor->mm), &dummy_module, NULL);
+		ret |= requestor_enqueue(requestor, make_query(requestor, remote), NULL);;
 	}
 	is_int(KNOT_EOK, ret, "requestor: multiple enqueue");
 
@@ -127,12 +128,10 @@ int main(int argc, char *argv[])
 
 	/* Initialize requestor. */
 	struct requestor requestor;
-	requestor_init(&requestor, &mm);
-	requestor.remote = &remote;
-	requestor.origin = NULL;
+	requestor_init(&requestor, &dummy_module, &mm);
 
 	/* Test requestor in disconnected environment. */
-	test_disconnected(&requestor);
+	test_disconnected(&requestor, &remote);
 
 	/* Bind to random port. */
 	int origin_fd = net_bound_socket(SOCK_STREAM, &remote);
@@ -147,7 +146,7 @@ int main(int argc, char *argv[])
 	pthread_create(&thread, 0, responder_thread, &origin_fd);
 
 	/* Test requestor in connected environment. */
-	test_connected(&requestor);
+	test_connected(&requestor, &remote);
 
 	/* TSIG secured. */
 #warning TODO: when ported sign_packet/verify_packet