diff --git a/knot-resolver.files b/knot-resolver.files
index cfde92e6f74a4990973d93f8fa0f2bd0c23b7297..0046274403daa6663e8a21b5f348ae9013e05691 100644
--- a/knot-resolver.files
+++ b/knot-resolver.files
@@ -15,3 +15,5 @@ lib/resolve.c
 lib/resolve.h
 tests/context.c
 tests/resolve.c
+lib/nslist.h
+lib/nslist.c
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 817be935671a9865717940c65b14f0ceb26de2f2..1aa76b50413976e2c74dfbb83db53c0375ad3cd1 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -11,4 +11,6 @@ libknotresolve_la_SOURCES =		\
 	context.h 		\
 	context.c 		\
 	resolve.h 		\
-	resolve.c
+	resolve.c		\
+	nslist.c		\
+	nslist.h
diff --git a/lib/context.c b/lib/context.c
index 91d55eb321f9f84a74b75c95e978a2f7f39ae233..56d19fb2a6a5298632e3605c2e72563fb59f8f05 100644
--- a/lib/context.c
+++ b/lib/context.c
@@ -2,89 +2,7 @@
 #include <sys/time.h>
 
 #include <common/sockaddr.h>
-#include "context.h"
-
-/* TODO: debug, remove */
-#ifndef NDEBUG
-static void print_slist(struct kr_context *ctx)
-{
-	char *sname = knot_dname_to_str(ctx->sname);
-	printf("SLIST(%s): \n", sname);
-	free(sname);
-	struct kr_ns *ns = NULL;
-	WALK_LIST(ns, ctx->slist) {
-		char *strname = knot_dname_to_str(ns->name);
-		char addr_str[SOCKADDR_STRLEN];
-		sockaddr_tostr(&ns->addr, addr_str, sizeof(addr_str));
-		printf("[%d] %s:%s ", ns->closeness, strname, addr_str);
-		free(strname);
-	}
-	printf("\n");
-}
-#endif
-
-/*! \brief Initialize NS descriptor. */
-static struct kr_ns *init_ns(mm_ctx_t *mm, const knot_dname_t *name,
-                             const struct sockaddr *addr)
-{
-	struct kr_ns *ns = mm_alloc(mm, sizeof(struct kr_ns));
-	if (ns == NULL) {
-		return NULL;
-	}
-
-	memset(ns, 0, sizeof(struct kr_ns));
-	ns->name = knot_dname_copy(name, mm);
-	if (ns->name == NULL) {
-		mm_free(mm, ns);
-		return NULL;
-	}
-
-	memcpy(&ns->addr, addr, sockaddr_len(addr));
-
-	return ns;
-}
-
-/*! \brief Insert before an item. */
-static void insert_before(struct kr_ns *cur, struct kr_ns *inserted)
-{
-	insert_node((node_t *)inserted, (node_t *)cur);
-	rem_node((node_t *)cur);
-	insert_node((node_t *)cur, (node_t *)inserted);
-}
-
-/*! \brief Calculate closeness (# of common labels with sname). */
-static unsigned closeness_score(const knot_dname_t *sname, const knot_dname_t *zone)
-{
-	/* Longer or non-equal names of the same length can't contain delegations. */
-	if (sname && (knot_dname_is_sub(sname, zone) || knot_dname_is_equal(zone, sname))) {
-		return KNOT_DNAME_MAXLABELS - knot_dname_matched_labels(zone, sname);
-	}
-
-	return KNOT_DNAME_MAXLABELS + 1; /* N/A */
-}
-
-/* \brief (Re)insert name server to SLIST. */
-static void insert_ns(struct kr_context *ctx, struct kr_ns *ns)
-{
-	struct kr_ns *it = NULL;
-	WALK_LIST(it, ctx->slist) {
-		if (it->closeness > ns->closeness) {
-			insert_before(it, ns);
-			return;
-		}
-	}
-
-	/* No closer match found. */
-	add_tail(&ctx->slist, (node_t *)ns);
-}
-
-/*! \brief Remove NS descriptor. */
-static void remove_ns(mm_ctx_t *mm, struct kr_ns *ns)
-{
-	rem_node((node_t *)ns);
-	mm_free(mm, ns->name);
-	mm_free(mm, ns);
-}
+#include "lib/context.h"
 
 int kr_context_init(struct kr_context *ctx, mm_ctx_t *mm)
 {
@@ -136,67 +54,3 @@ int kr_result_deinit(struct kr_result *result)
 
 	return 0;
 }
-
-int kr_slist_init(struct kr_context *ctx)
-{
-	init_list(&ctx->slist);
-
-	return 0;
-}
-
-int kr_slist_clear(struct kr_context *ctx)
-{
-	while(kr_slist_pop(ctx) == 0)
-		;
-
-	return 0;
-}
-
-int kr_slist_add(struct kr_context *ctx, const knot_dname_t *name, const struct sockaddr *addr)
-{
-	struct kr_ns *ns = init_ns(ctx->pool, name, addr);
-	if (ns == NULL) {
-		return -1;
-	}
-
-	insert_ns(ctx, ns);
-
-	return 0;
-}
-
-struct kr_ns *kr_slist_top(struct kr_context *ctx)
-{
-	if (EMPTY_LIST(ctx->slist)) {
-		return NULL;
-	}
-
-	return (struct kr_ns *)HEAD(ctx->slist);
-}
-
-int kr_slist_sort(struct kr_context *ctx)
-{
-	list_t copy = ctx->slist;
-	init_list(&ctx->slist);
-
-	/* Recalculate closeness and reinsert. */
-	struct kr_ns *it = NULL, *next = NULL;
-	WALK_LIST_DELSAFE(it, next, copy) {
-		it->closeness = closeness_score(ctx->sname, it->name);
-		insert_ns(ctx, it);
-	}
-
-	return 0;
-}
-
-int kr_slist_pop(struct kr_context *ctx)
-{
-	struct kr_ns *top = kr_slist_top(ctx);
-	if (top == NULL) {
-		return -1;
-	}
-
-
-	remove_ns(ctx->pool, top);
-
-	return 0;
-}
diff --git a/lib/context.h b/lib/context.h
index 75133166e9e65f07881c96265d67ba7fa37dd679..3ac513cc115eed33d42d3ea5a39dcf8feed3ee64 100644
--- a/lib/context.h
+++ b/lib/context.h
@@ -17,20 +17,11 @@ limitations under the License.
 
 #include <stdint.h>
 #include <libknot/mempattern.h>
-#include <libknot/packet/pkt.h>
 
 #warning TODO: this is private define
-#include <common/lists.h>
 #include <common/sockaddr.h>
 
-/*! \brief Name server information. */
-struct kr_ns {
-	node_t node;
-	knot_dname_t *name;
-	struct sockaddr_storage addr;
-	unsigned mean_rtt;
-	unsigned closeness;
-};
+#include "lib/nslist.h"
 
 /*! \brief Name resolution result. */
 struct kr_result {
@@ -59,11 +50,4 @@ int kr_context_reset(struct kr_context *ctx);
 int kr_context_deinit(struct kr_context *ctx);
 
 int kr_result_init(struct kr_context *ctx, struct kr_result *result);
-int kr_result_deinit(struct kr_result *result);
-
-int kr_slist_init(struct kr_context *ctx);
-int kr_slist_clear(struct kr_context *ctx);
-int kr_slist_add(struct kr_context *ctx, const knot_dname_t *name, const struct sockaddr *addr);
-struct kr_ns *kr_slist_top(struct kr_context *ctx);
-int kr_slist_sort(struct kr_context *ctx);
-int kr_slist_pop(struct kr_context *ctx);
\ No newline at end of file
+int kr_result_deinit(struct kr_result *result);
\ No newline at end of file
diff --git a/lib/nslist.c b/lib/nslist.c
new file mode 100644
index 0000000000000000000000000000000000000000..1edc371b75e7a96b23bebe9321a9b8b4cc59f966
--- /dev/null
+++ b/lib/nslist.c
@@ -0,0 +1,150 @@
+#include "lib/nslist.h"
+#include "lib/context.h"
+
+
+/* TODO: debug, remove */
+#ifndef NDEBUG
+static void print_slist(struct kr_context *ctx)
+{
+	char *sname = knot_dname_to_str(ctx->sname);
+	printf("SLIST(%s): \n", sname);
+	free(sname);
+	struct kr_ns *ns = NULL;
+	WALK_LIST(ns, ctx->slist) {
+		char *strname = knot_dname_to_str(ns->name);
+		char addr_str[SOCKADDR_STRLEN];
+		sockaddr_tostr(&ns->addr, addr_str, sizeof(addr_str));
+		printf("[%d] %s:%s ", ns->closeness, strname, addr_str);
+		free(strname);
+	}
+	printf("\n");
+}
+#endif
+
+/*! \brief Initialize NS descriptor. */
+static struct kr_ns *init_ns(mm_ctx_t *mm, const knot_dname_t *name,
+                             const struct sockaddr *addr)
+{
+	struct kr_ns *ns = mm_alloc(mm, sizeof(struct kr_ns));
+	if (ns == NULL) {
+		return NULL;
+	}
+
+	memset(ns, 0, sizeof(struct kr_ns));
+	ns->name = knot_dname_copy(name, mm);
+	if (ns->name == NULL) {
+		mm_free(mm, ns);
+		return NULL;
+	}
+
+	memcpy(&ns->addr, addr, sockaddr_len(addr));
+
+	return ns;
+}
+
+
+/*! \brief Insert before an item. */
+static void insert_before(struct kr_ns *cur, struct kr_ns *inserted)
+{
+	insert_node((node_t *)inserted, (node_t *)cur);
+	rem_node((node_t *)cur);
+	insert_node((node_t *)cur, (node_t *)inserted);
+}
+
+/*! \brief Calculate closeness (# of common labels with sname). */
+static unsigned closeness_score(const knot_dname_t *sname, const knot_dname_t *zone)
+{
+	/* Longer or non-equal names of the same length can't contain delegations. */
+	if (sname && (knot_dname_is_sub(sname, zone) || knot_dname_is_equal(zone, sname))) {
+		return KNOT_DNAME_MAXLABELS - knot_dname_matched_labels(zone, sname);
+	}
+
+	return KNOT_DNAME_MAXLABELS + 1; /* N/A */
+}
+
+/* \brief (Re)insert name server to SLIST. */
+static void insert_ns(struct kr_context *ctx, struct kr_ns *ns)
+{
+	struct kr_ns *it = NULL;
+	WALK_LIST(it, ctx->slist) {
+		if (it->closeness > ns->closeness) {
+			insert_before(it, ns);
+			return;
+		}
+	}
+
+	/* No closer match found. */
+	add_tail(&ctx->slist, (node_t *)ns);
+}
+
+/*! \brief Remove NS descriptor. */
+static void remove_ns(mm_ctx_t *mm, struct kr_ns *ns)
+{
+	rem_node((node_t *)ns);
+	mm_free(mm, ns->name);
+	mm_free(mm, ns);
+}
+
+int kr_slist_init(struct kr_context *ctx)
+{
+	init_list(&ctx->slist);
+
+	return 0;
+}
+
+int kr_slist_clear(struct kr_context *ctx)
+{
+	while(kr_slist_pop(ctx) == 0)
+		;
+
+	return 0;
+}
+
+int kr_slist_add(struct kr_context *ctx, const knot_dname_t *name, const struct sockaddr *addr)
+{
+	struct kr_ns *ns = init_ns(ctx->pool, name, addr);
+	if (ns == NULL) {
+		return -1;
+	}
+
+	insert_ns(ctx, ns);
+
+	return 0;
+}
+
+struct kr_ns *kr_slist_top(struct kr_context *ctx)
+{
+	if (EMPTY_LIST(ctx->slist)) {
+		return NULL;
+	}
+
+	return (struct kr_ns *)HEAD(ctx->slist);
+}
+
+int kr_slist_sort(struct kr_context *ctx)
+{
+	list_t copy = ctx->slist;
+	init_list(&ctx->slist);
+
+	/* Recalculate closeness and reinsert. */
+	struct kr_ns *it = NULL, *next = NULL;
+	WALK_LIST_DELSAFE(it, next, copy) {
+		it->closeness = closeness_score(ctx->sname, it->name);
+		insert_ns(ctx, it);
+	}
+
+	return 0;
+}
+
+int kr_slist_pop(struct kr_context *ctx)
+{
+	struct kr_ns *top = kr_slist_top(ctx);
+	if (top == NULL) {
+		return -1;
+	}
+
+
+	remove_ns(ctx->pool, top);
+
+	return 0;
+}
\ No newline at end of file
diff --git a/lib/nslist.h b/lib/nslist.h
new file mode 100644
index 0000000000000000000000000000000000000000..9910e380cd0bc869e9e71740416435d0608c02ba
--- /dev/null
+++ b/lib/nslist.h
@@ -0,0 +1,40 @@
+/* Copyright 2014 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+#pragma once
+
+#include <libknot/packet/pkt.h>
+
+#warning TODO: this is private define
+#include <common/lists.h>
+#include <common/sockaddr.h>
+
+struct kr_context;
+
+/*! \brief Name server information. */
+struct kr_ns {
+	node_t node;
+	knot_dname_t *name;
+	struct sockaddr_storage addr;
+	unsigned mean_rtt;
+	unsigned closeness;
+};
+
+int kr_slist_init(struct kr_context *ctx);
+int kr_slist_clear(struct kr_context *ctx);
+int kr_slist_add(struct kr_context *ctx, const knot_dname_t *name, const struct sockaddr *addr);
+struct kr_ns *kr_slist_top(struct kr_context *ctx);
+int kr_slist_sort(struct kr_context *ctx);
+int kr_slist_pop(struct kr_context *ctx);
\ No newline at end of file