diff --git a/lib/cookies/control.c b/lib/cookies/control.c
index e3ddb72eab848ac111c266dfb597d9afa2319826..a2adb4a67c4a41e46f150476bfa418a827cea087 100644
--- a/lib/cookies/control.c
+++ b/lib/cookies/control.c
@@ -46,6 +46,12 @@ struct kr_cookie_secret dflt_cs = {
 	.data = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
 };
 
+const struct kr_cc_hash_descr kr_cc_hashes[] = {
+	{ kr_cc_compute_fnv64, "FNV-64" },
+	{ kr_cc_compute_hmac_sha256_64, "HMAC-SHA256-64" },
+	{ NULL, NULL }
+};
+
 struct kr_cookie_ctx kr_glob_cookie_ctx = {
 	.enabled = false,
 	.current_cs = &dflt_cs
@@ -100,6 +106,45 @@ static int opt_rr_add_option(knot_rrset_t *opt_rr, uint8_t *option,
 	return KNOT_EOK;
 }
 
+cc_compute_func_t *kr_cc_hash_func(const struct kr_cc_hash_descr cc_hashes[],
+                                   const char *name)
+{
+	if (!cc_hashes || !name) {
+		return NULL;
+	}
+
+	const struct kr_cc_hash_descr *aux_ptr = cc_hashes;
+
+	while (aux_ptr && aux_ptr->hash_func) {
+		assert(aux_ptr->name);
+		if (strcmp(aux_ptr->name, name) == 0) {
+			return aux_ptr->hash_func;
+		}
+		++aux_ptr;
+	}
+
+	return NULL;
+}
+
+const char *kr_cc_hash_name(const struct kr_cc_hash_descr cc_hashes[],
+                            cc_compute_func_t *func)
+{
+	if (!cc_hashes || !func) {
+		return NULL;
+	}
+
+	const struct kr_cc_hash_descr *aux_ptr = cc_hashes;
+	while (aux_ptr && aux_ptr->hash_func) {
+		assert(aux_ptr->name);
+		if (aux_ptr->hash_func == func) {
+			return aux_ptr->name;
+		}
+		++aux_ptr;
+	}
+
+	return NULL;
+}
+
 int kr_address_bytes(const void *sockaddr, const uint8_t **addr, size_t *len)
 {
 	if (!sockaddr || !addr || !len) {
diff --git a/lib/cookies/control.h b/lib/cookies/control.h
index d2ddc2bdf768965056523aed4269cdb5d5fd7ad1..520ae6b54ef7c44eec8564ab19c88222c98caa58 100644
--- a/lib/cookies/control.h
+++ b/lib/cookies/control.h
@@ -43,6 +43,20 @@ extern struct kr_cookie_secret dflt_cs;
 typedef int (cc_compute_func_t)(uint8_t *, const void *, const void *,
                                const struct kr_cookie_secret *);
 
+/** Holds description of client cookie hashing algorithms. */
+struct kr_cc_hash_descr {
+	cc_compute_func_t *hash_func; /**< Pointer to has function. */
+	const char *name; /**< Hash function name. */
+};
+
+/**
+ * List of available client cookie hash functions.
+ *
+ * Last element contains all null entries.
+ */
+KR_EXPORT
+extern const struct kr_cc_hash_descr kr_cc_hashes[];
+
 /** DNS cookies controlling structure. */
 struct kr_cookie_ctx {
 	bool enabled; /**< Enabled/disables DNS cookies functionality. */
@@ -52,14 +66,33 @@ struct kr_cookie_ctx {
 
 	uint32_t cache_ttl; /**< TTL used when caching cookies */
 
-	/**< Client cookie computation callback. */
-	cc_compute_func_t *cc_compute_func;
+	cc_compute_func_t *cc_compute_func; /**< Client cookie hash computation callback. */
 };
 
 /** Global cookie control context. */
 KR_EXPORT
 extern struct kr_cookie_ctx kr_glob_cookie_ctx;
 
+/**
+ * @brief Return pointer to client cookie hash function with given name.
+ * @param cc_hashes list of avilable has functions
+ * @param name has function name
+ * @return pointer to function or NULL if not found
+ */
+KR_EXPORT
+cc_compute_func_t *kr_cc_hash_func(const struct kr_cc_hash_descr cc_hashes[],
+                                   const char *name);
+
+/**
+ * @brief Return name of given client cookie hash function.
+ * @param cc_hashes list of avilable has functions
+ * @param func sought function
+ * @return pointer to string or NULL if not found
+ */
+KR_EXPORT
+const char *kr_cc_hash_name(const struct kr_cc_hash_descr cc_hashes[],
+                            cc_compute_func_t *func);
+
 /**
  * Get pointers to IP address bytes.
  * @param sockaddr socket address
diff --git a/lib/layer/cookiemonster.c b/lib/layer/cookiemonster.c
index 77e5a4c47180793e7dbb83749a452b62ef31b58d..5fe42de9629c5cfa8e8f295412e9df4dad9f50de 100644
--- a/lib/layer/cookiemonster.c
+++ b/lib/layer/cookiemonster.c
@@ -348,7 +348,7 @@ static int check_response(knot_layer_t *ctx, knot_pkt_t *pkt)
 		                                      KNOT_EDNS_OPTION_COOKIE);
 	}
 
-	struct kr_cache *cookie_cache = &req->ctx->cache; //&kr_glob_cookie_ctx.cache;
+	struct kr_cache *cookie_cache = &req->ctx->cache;
 
 	const struct sockaddr *srvr_sockaddr = passed_server_sockaddr(qry);
 
diff --git a/modules/cookiectl/cookiectl.c b/modules/cookiectl/cookiectl.c
index 93892e9571c9b343c418eb72e85dcd9beecd6610..d62273b2ac884378dbd421c47028ff5d0488a724 100644
--- a/modules/cookiectl/cookiectl.c
+++ b/modules/cookiectl/cookiectl.c
@@ -45,6 +45,8 @@ static struct storage_api *find_storage_api(const storage_registry_t *registry,
 
 #define NAME_ENABLED "enabled"
 #define NAME_CLIENT_SECRET "client_secret"
+#define NAME_CLIENT_HASH_FUNC "client_hash_func"
+#define NAME_AVAILABLE_CLIENT_HASH_FUNCS "available_client_hash_funcs"
 #define NAME_CACHE_TTL "cache_ttl"
 
 static bool aply_enabled(struct kr_cookie_ctx *cntrl, const JsonNode *node)
@@ -105,7 +107,8 @@ static struct kr_cookie_secret *new_sq_array(const JsonNode *node)
 	return sq;
 }
 
-static bool apply_client_secret(struct kr_cookie_ctx *cntrl, const JsonNode *node)
+static bool apply_client_secret(struct kr_cookie_ctx *cntrl,
+                                const JsonNode *node)
 {
 	struct kr_cookie_secret *sq = NULL;
 
@@ -142,6 +145,22 @@ static bool apply_client_secret(struct kr_cookie_ctx *cntrl, const JsonNode *nod
 	return true;
 }
 
+static bool apply_client_hash_func(struct kr_cookie_ctx *cntrl,
+                                   const JsonNode *node)
+{
+	if (node->tag == JSON_STRING) {
+		cc_compute_func_t *cc_compute_func = kr_cc_hash_func(kr_cc_hashes,
+		                                                     node->string_);
+		if (!cc_compute_func) {
+			return false;
+		}
+		cntrl->cc_compute_func = cc_compute_func;
+		return true;
+	}
+
+	return false;
+}
+
 static bool apply_cache_ttl(struct kr_cookie_ctx *cntrl, const JsonNode *node)
 {
 	if (node->tag == JSON_NUMBER) {
@@ -165,6 +184,8 @@ static bool apply_configuration(struct kr_cookie_ctx *cntrl, const JsonNode *nod
 		return aply_enabled(cntrl, node);
 	} else if (strcmp(node->key, NAME_CLIENT_SECRET) == 0) {
 		return apply_client_secret(cntrl, node);
+	} else  if (strcmp(node->key, NAME_CLIENT_HASH_FUNC) == 0) {
+		return apply_client_hash_func(cntrl, node);
 	} else if (strcmp(node->key, NAME_CACHE_TTL) == 0) {
 		return apply_cache_ttl(cntrl, node);
 	}
@@ -200,6 +221,38 @@ fail:
 	return false;
 }
 
+static bool read_available_cc_hashes(JsonNode *root,
+                                     struct kr_cookie_ctx *cntrl)
+{
+	assert(root && cntrl);
+
+	JsonNode *array = json_mkarray();
+	if (!array) {
+		return false;
+	}
+
+	const struct kr_cc_hash_descr *aux_ptr = kr_cc_hashes;
+	while (aux_ptr && aux_ptr->hash_func) {
+		assert(aux_ptr->name);
+		JsonNode *element = json_mkstring(aux_ptr->name);
+		if (!element) {
+			goto fail;
+		}
+		json_append_element(array, element);
+		++aux_ptr;
+	}
+
+	json_append_member(root, NAME_AVAILABLE_CLIENT_HASH_FUNCS, array);
+
+	return true;
+
+fail:
+	if (array) {
+		json_delete(array);
+	}
+	return false;
+}
+
 /**
  * Get/set DNS cookie related stuff.
  *
@@ -220,11 +273,23 @@ static char *cookiectl_config(void *env, struct kr_module *module, const char *a
 	/* Return current configuration. */
 	char *result = NULL;
 	JsonNode *root_node = json_mkobject();
+
 	json_append_member(root_node, NAME_ENABLED,
 	                   json_mkbool(kr_glob_cookie_ctx.enabled));
+
 	read_secret(root_node, &kr_glob_cookie_ctx);
+
+	const char *name = kr_cc_hash_name(kr_cc_hashes,
+	                                   kr_glob_cookie_ctx.cc_compute_func);
+	assert(name);
+	json_append_member(root_node, NAME_CLIENT_HASH_FUNC,
+	                   json_mkstring(name));
+
+	read_available_cc_hashes(root_node, &kr_glob_cookie_ctx);
+
 	json_append_member(root_node, NAME_CACHE_TTL,
 	                   json_mknumber(kr_glob_cookie_ctx.cache_ttl));
+
 	result = json_encode(root_node);
 	json_delete(root_node);
 	return result;
@@ -272,11 +337,8 @@ int cookiectl_init(struct kr_module *module)
 	kr_glob_cookie_ctx.enabled = false;
 	kr_glob_cookie_ctx.current_cs = &dflt_cs;
 	kr_glob_cookie_ctx.cache_ttl = DFLT_COOKIE_TTL;
-
 	kr_glob_cookie_ctx.cc_compute_func = kr_cc_compute_fnv64;
 
-//	cookies_cache_init(&kr_glob_cookie_ctx.cache, engine);
-
 	module->data = NULL;
 
 	return kr_ok();
@@ -299,8 +361,6 @@ int cookiectl_deinit(struct kr_module *module)
 	}
 	kr_glob_cookie_ctx.current_cs = &dflt_cs;
 
-//	kr_cache_close(&kr_glob_cookie_ctx.cache);
-
 	return kr_ok();
 }