diff --git a/lib/cookies/cache.c b/lib/cookies/cache.c
new file mode 100644
index 0000000000000000000000000000000000000000..8e03467cc14c62c655f8f368570b4f0bf59dc561
--- /dev/null
+++ b/lib/cookies/cache.c
@@ -0,0 +1,209 @@
+/*  Copyright (C) 2014 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <assert.h>
+#include <libknot/db/db_lmdb.h>
+
+#include "lib/cookies/cache.h"
+#include "lib/cookies/control.h"
+
+/* Key size */
+#define KEY_HSIZE (sizeof(uint8_t))
+#define KEY_SIZE (KEY_HSIZE + 16)
+#define txn_api(txn) ((txn)->owner->api)
+#define txn_is_valid(txn) ((txn) && (txn)->owner && txn_api(txn))
+
+/**
+ * @internal Composed key as { u8 tag, u8[4,16] IP address }
+ */
+static size_t cache_key(uint8_t *buf, uint8_t tag, const void *sockaddr)
+{
+	assert(buf && sockaddr);
+
+	const uint8_t *addr = NULL;
+	size_t addr_len = 0;
+
+	if (kr_ok() != kr_address_bytes(sockaddr, &addr, &addr_len)) {
+		return 0;
+	}
+	assert(addr_len > 0);
+
+	buf[0] = tag;
+	memcpy(buf + sizeof(uint8_t), addr, addr_len);
+
+	return addr_len + KEY_HSIZE;
+}
+
+static struct kr_cache_entry *lookup(struct kr_cache_txn *txn, uint8_t tag,
+                                     const void *sockaddr)
+{
+	if (!txn_is_valid(txn) || !sockaddr) {
+		return NULL;
+	}
+
+	uint8_t keybuf[KEY_SIZE];
+	size_t key_len = cache_key(keybuf, tag, sockaddr);
+
+	/* Look up and return value */
+	knot_db_val_t key = { keybuf, key_len };
+	knot_db_val_t val = { NULL, 0 };
+	int ret = txn_api(txn)->find(&txn->t, &key, &val, 0);
+	if (ret != KNOT_EOK) {
+		return NULL;
+	}
+
+	return (struct kr_cache_entry *)val.data;
+}
+
+static int check_lifetime(struct kr_cache_entry *found, uint32_t *timestamp)
+{
+	/* No time constraint */
+	if (!timestamp) {
+		return kr_ok();
+	} else if (*timestamp <= found->timestamp) {
+		/* John Connor record cached in the future. */
+		*timestamp = 0;
+		return kr_ok();
+	} else {
+		/* Check if the record is still valid. */
+		uint32_t drift = *timestamp - found->timestamp;
+		if (drift <= found->ttl) {
+			*timestamp = drift;
+			return kr_ok();
+		}
+	}
+	return kr_error(ESTALE);
+}
+
+int kr_cookie_cache_peek(struct kr_cache_txn *txn, uint8_t tag, const void *sockaddr,
+                         struct kr_cache_entry **entry, uint32_t *timestamp)
+{
+	if (!txn_is_valid(txn) || !sockaddr || !entry) {
+		return kr_error(EINVAL);
+	}
+
+	struct kr_cache_entry *found = lookup(txn, tag, sockaddr);
+	if (!found) {
+		txn->owner->stats.miss += 1;
+		return kr_error(ENOENT);
+	}
+
+	/* Check entry lifetime */
+	*entry = found;
+	int ret = check_lifetime(found, timestamp);
+	if (ret == 0) {
+		txn->owner->stats.hit += 1;
+	} else {
+		txn->owner->stats.miss += 1;
+	}
+	return ret;
+}
+
+static void entry_write(struct kr_cache_entry *dst, struct kr_cache_entry *header, knot_db_val_t data)
+{
+	assert(dst && header);
+	memcpy(dst, header, sizeof(*header));
+	if (data.data)
+		memcpy(dst->data, data.data, data.len);
+}
+
+int kr_cookie_cache_insert(struct kr_cache_txn *txn,
+                           uint8_t tag, const void *sockaddr,
+                           struct kr_cache_entry *header, knot_db_val_t data)
+{
+	if (!txn_is_valid(txn) || !sockaddr || !header) {
+		return kr_error(EINVAL);
+	}
+
+	/* Insert key */
+	uint8_t keybuf[KEY_SIZE];
+	size_t key_len = cache_key(keybuf, tag, sockaddr);
+	if (key_len == 0) {
+		return kr_error(EILSEQ);
+	}
+	knot_db_val_t key = { keybuf, key_len };
+	knot_db_val_t entry = { NULL, sizeof(*header) + data.len };
+	const knot_db_api_t *db_api = txn_api(txn);
+
+	/* LMDB can do late write and avoid copy */
+	txn->owner->stats.insert += 1;
+	if (db_api == knot_db_lmdb_api()) {
+		int ret = db_api->insert(&txn->t, &key, &entry, 0);
+		if (ret != 0) {
+			return ret;
+		}
+		entry_write(entry.data, header, data);
+	} else {
+		/* Other backends must prepare contiguous data first */
+		entry.data = malloc(entry.len);
+		if (!entry.data) {
+			return kr_error(ENOMEM);
+		}
+		entry_write(entry.data, header, data);
+		int ret = db_api->insert(&txn->t, &key, &entry, 0);
+		free(entry.data);
+		if (ret != 0) {
+			return ret;
+		}
+	}
+
+	return kr_ok();
+}
+
+int kr_cookie_cache_peek_cookie(struct kr_cache_txn *txn, const void *sockaddr,
+                                const uint8_t **cookie_opt, uint32_t *timestamp)
+{
+	if (!txn_is_valid(txn) || !sockaddr || !cookie_opt || !timestamp) {
+		return kr_error(EINVAL);
+	}
+
+	/* Check if the RRSet is in the cache. */
+	struct kr_cache_entry *entry = NULL;
+	int ret = kr_cookie_cache_peek(txn, KR_CACHE_COOKIE, sockaddr, &entry, timestamp);
+	if (ret != 0) {
+		return ret;
+	}
+	*cookie_opt = entry->data;
+	return kr_ok();
+}
+
+int kr_cookie_cache_insert_cookie(struct kr_cache_txn *txn, const void *sockaddr,
+                                  uint8_t *cookie_opt, uint32_t timestamp)
+{
+	if (!txn_is_valid(txn) || !sockaddr) {
+		return kr_error(EINVAL);
+	}
+
+	/* Ignore empty cookie data. */
+	if (!cookie_opt) {
+		return kr_ok();
+	}
+
+	/* Prepare header to write. */
+	struct kr_cache_entry header = {
+		.timestamp = timestamp,
+		.ttl = 72000,
+		.rank = KR_RANK_BAD,
+		.flags = KR_CACHE_FLAG_NONE,
+		.count = 1
+	};
+
+	size_t cookie_opt_size = knot_edns_opt_get_length(cookie_opt) + KNOT_EDNS_OPTION_HDRLEN;
+
+	knot_db_val_t data = { cookie_opt, cookie_opt_size };
+	return kr_cookie_cache_insert(txn, KR_CACHE_COOKIE, sockaddr, &header,
+	                              data);
+}
diff --git a/lib/cookies/cache.h b/lib/cookies/cache.h
new file mode 100644
index 0000000000000000000000000000000000000000..59278b7b289092323a13a0962abc2f3dcdcae859
--- /dev/null
+++ b/lib/cookies/cache.h
@@ -0,0 +1,47 @@
+/*  Copyright (C) 2016 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "lib/cache.h"
+
+#define KR_CACHE_COOKIE (KR_CACHE_USER + 'C')
+
+KR_EXPORT
+int kr_cookie_cache_peek(struct kr_cache_txn *txn, uint8_t tag, const void *sockaddr,
+                         struct kr_cache_entry **entry, uint32_t *timestamp);
+
+KR_EXPORT
+int kr_cookie_cache_insert(struct kr_cache_txn *txn,
+                           uint8_t tag, const void *sockaddr,
+                           struct kr_cache_entry *header, knot_db_val_t data);
+
+KR_EXPORT
+int kr_cookie_cache_peek_cookie(struct kr_cache_txn *txn, const void *sockaddr,
+                                const uint8_t **cookie_opt, uint32_t *timestamp);
+
+/**
+ * Insert a DNS cookie (client and server) entry for the given server signature (IP address).
+ * @param txn transaction instance
+ * @param sockaddr server IP address
+ * @param cookie_opt whole EDNS cookie option (header, client and server)
+ * @param cookie_size size of the cookie
+ * @param timestamp current time
+ * @return 0 or an errcode
+ */
+KR_EXPORT
+int kr_cookie_cache_insert_cookie(struct kr_cache_txn *txn, const void *sockaddr,
+                                  uint8_t *cookie_opt, uint32_t timestamp);
diff --git a/lib/cookies/control.c b/lib/cookies/control.c
index 40c2f031c41732392bb86998f9d4d29f51f7769c..20fdaa23affed2fb9d72b58b5058264d20bca7f9 100644
--- a/lib/cookies/control.c
+++ b/lib/cookies/control.c
@@ -19,9 +19,11 @@
 #include <netinet/in.h>
 #include <assert.h>
 #include <stdint.h>
+#include <string.h>
 #include <libknot/error.h>
 
 #include "contrib/fnv/fnv.h"
+#include "lib/cookies/cache.h"
 #include "lib/cookies/control.h"
 #include "lib/layer.h"
 #include "lib/utils.h"
@@ -30,14 +32,14 @@
 
 static uint8_t cc[KNOT_OPT_COOKIE_CLNT] = { 1, 2, 3, 4, 5, 6, 7, 8};
 
-static struct secret_quantity client = {
+static struct secret_quantity client_secret = {
 	.size = KNOT_OPT_COOKIE_CLNT,
 	.data = cc
 };
 
 struct cookies_control kr_cookies_control = {
 	.enabled = true,
-	.client = &client
+	.secret = &client_secret
 };
 
 static int opt_rr_add_cookies(knot_rrset_t *opt_rr,
@@ -45,14 +47,13 @@ static int opt_rr_add_cookies(knot_rrset_t *opt_rr,
                               uint8_t *sc, uint16_t sc_len,
                               knot_mm_t *mm)
 {
-	int ret;
 	uint16_t cookies_size = 0;
 	uint8_t *cookies_data = NULL;
 
 	cookies_size = knot_edns_opt_cookie_data_len(sc_len);
 
-	ret = knot_edns_reserve_option(opt_rr, KNOT_EDNS_OPTION_COOKIE,
-	                               cookies_size, &cookies_data, mm);
+	int ret = knot_edns_reserve_option(opt_rr, KNOT_EDNS_OPTION_COOKIE,
+	                                   cookies_size, &cookies_data, mm);
 	if (ret != KNOT_EOK) {
 		return ret;
 	}
@@ -69,8 +70,33 @@ static int opt_rr_add_cookies(knot_rrset_t *opt_rr,
 	return KNOT_EOK;
 }
 
-static void obtain_address(void *sockaddr, uint8_t **addr, size_t *len)
+static int opt_rr_add_option(knot_rrset_t *opt_rr, uint8_t *option,
+                             knot_mm_t *mm)
 {
+	assert(opt_rr && option);
+
+	uint8_t *reserved_data = NULL;
+	uint16_t opt_code = knot_edns_opt_get_code(option);
+	uint16_t opt_len = knot_edns_opt_get_length(option);
+	uint8_t *opt_data = knot_edns_opt_get_data(option);
+
+	int ret = knot_edns_reserve_option(opt_rr, opt_code,
+	                                   opt_len, &reserved_data, mm);
+	if (ret != KNOT_EOK) {
+		return ret;
+	}
+	assert(reserved_data);
+
+	memcpy(reserved_data, opt_data, opt_len);
+	return KNOT_EOK;
+}
+
+int kr_address_bytes(const void *sockaddr, const uint8_t **addr, size_t *len)
+{
+	if (!sockaddr || !addr || !len) {
+		return kr_error(EINVAL);
+	}
+
 	assert(sockaddr && addr && len);
 
 	int addr_family = ((struct sockaddr *) sockaddr)->sa_family;
@@ -89,7 +115,7 @@ static void obtain_address(void *sockaddr, uint8_t **addr, size_t *len)
 		*len = 0;
 		addr_family = AF_UNSPEC;
 		DEBUG_MSG(NULL, "%s\n", "could obtain IP address");
-		return;
+		return kr_error(EINVAL);
 		break;
 	}
 
@@ -98,6 +124,8 @@ static void obtain_address(void *sockaddr, uint8_t **addr, size_t *len)
 		inet_ntop(addr_family, *addr, ns_str, sizeof(ns_str));
 		DEBUG_MSG(NULL, "obtaned IP address '%s'\n", ns_str);
 	}
+
+	return kr_ok();
 }
 
 int kr_client_cokie_fnv64(uint8_t cc_buf[KNOT_OPT_COOKIE_CLNT],
@@ -113,7 +141,7 @@ int kr_client_cokie_fnv64(uint8_t cc_buf[KNOT_OPT_COOKIE_CLNT],
 		return kr_error(EINVAL);
 	}
 
-	uint8_t *addr = NULL;
+	const uint8_t *addr = NULL;
 	size_t size = 0;
 
 	Fnv64_t hash_val = FNV1A_64_INIT;
@@ -121,23 +149,23 @@ int kr_client_cokie_fnv64(uint8_t cc_buf[KNOT_OPT_COOKIE_CLNT],
 	/* Client address currently always ignored. */
 #if 0
 	if (clnt_sockaddr) {
-		obtain_address(clnt_sockaddr, &addr, &size);
-		if (addr && size) {
+		if (kr_ok() == kr_address_bytes(clnt_sockaddr, &addr, &size)) {
+			assert(addr && size);
 			hash_val = fnv_64a_buf(addr, size, hash_val);
 		}
 	}
 #endif
 
 	if (srvr_sockaddr) {
-		obtain_address(srvr_sockaddr, &addr, &size);
-		if (addr && size) {
-			hash_val = fnv_64a_buf(addr, size, hash_val);
+		if (kr_ok() == kr_address_bytes(srvr_sockaddr, &addr, &size)) {
+			assert(addr && size);
+			hash_val = fnv_64a_buf((void *) addr, size, hash_val);
 		}
 	}
 
 	if (secret && secret->size && secret->data) {
 		DEBUG_MSG(NULL, "%s\n", "adding client secret into cookie");
-		hash_val = fnv_64a_buf(addr, size, hash_val);
+		hash_val = fnv_64a_buf((void *) addr, size, hash_val);
 	}
 
 	assert(KNOT_OPT_COOKIE_CLNT == sizeof(hash_val));
@@ -153,18 +181,23 @@ int kr_request_put_cookie(struct cookies_control *cntrl, void *clnt_sockaddr,
 	assert(cntrl);
 	assert(pkt);
 
-	uint8_t cc[KNOT_OPT_COOKIE_CLNT];
-
 	if (!pkt->opt_rr) {
 		return kr_ok();
 	}
 
-	if (!cntrl->client) {
+	if (!cntrl->secret) {
 		return kr_error(EINVAL);
 	}
 
-	int ret = kr_client_cokie_fnv64(cc, clnt_sockaddr, srvr_sockaddr,
-	                                cntrl->client);
+//
+	struct kr_cache_txn txn;
+	const uint8_t *cached_cookie = NULL;
+	uint32_t timestamp = 0;
+	kr_cache_txn_begin(&kr_cookies_control.cache, &txn, KNOT_DB_RDONLY);
+	int ret = kr_cookie_cache_peek_cookie(&txn, srvr_sockaddr,
+	                                      &cached_cookie, &timestamp);
+	bool cached = (ret == kr_ok());
+//
 
 	/* This is a very nasty hack that prevents the packet to be corrupted
 	 * when using contemporary 'Cookie interface'. */
@@ -181,9 +214,21 @@ int kr_request_put_cookie(struct cookies_control *cntrl, void *clnt_sockaddr,
 	}
 #endif
 
-	/* TODO -- generate client cookie from client address, server address
-	 * and secret quantity. */
-	ret = opt_rr_add_cookies(pkt->opt_rr, cc, NULL, 0, &pkt->mm);
+	if (cached) {
+		ret = opt_rr_add_option(pkt->opt_rr, (uint8_t *) cached_cookie,
+		                        &pkt->mm);
+	} else {
+		/* Generate new client cookie only. */
+		uint8_t cc[KNOT_OPT_COOKIE_CLNT];
+		ret = kr_client_cokie_fnv64(cc, clnt_sockaddr, srvr_sockaddr,
+	                            cntrl->secret);
+
+		/* TODO -- generate client cookie from client address, server address
+		 * and secret quantity. */
+		ret = opt_rr_add_cookies(pkt->opt_rr, cc, NULL, 0, &pkt->mm);
+	}
+
+	kr_cache_txn_abort(&txn);
 
 	/* Write to packet. */
 	assert(pkt->current == KNOT_ADDITIONAL);
diff --git a/lib/cookies/control.h b/lib/cookies/control.h
index 98a16648ef52aff29eed97bec6fffb2a1afab6d0..9703bf535b8b1a26e5eae8b50a3d5cceeb1e869d 100644
--- a/lib/cookies/control.h
+++ b/lib/cookies/control.h
@@ -34,7 +34,7 @@ struct secret_quantity {
 /** DNSSEC cookies controlling structure. */
 struct cookies_control {
 	bool enabled; /*!< Enabled/disables DNS cookies functionality. */
-	struct secret_quantity *client; /*!< Client secret quantity. */
+	struct secret_quantity *secret; /*!< Client secret quantity. */
 
 	struct kr_cache cache; /*!< Server cookies cache. */
 };
@@ -43,6 +43,14 @@ struct cookies_control {
 KR_EXPORT
 extern struct cookies_control kr_cookies_control;
 
+/**
+ * Get pointers to IP address bytes.
+ * @param sockaddr socket address
+ * @param addr pointer to address
+ * @param len address length
+ */
+int kr_address_bytes(const void *sockaddr, const uint8_t **addr, size_t *len);
+
 /**
  * Compute client cookie.
  * @not At least one of the arguments must be non-null.
diff --git a/lib/lib.mk b/lib/lib.mk
index 0408aa71ecf297325077dcca40da9babec1ba11b..4dafe5c8e37d4bafb14f30fbf389d1f020d87eee 100644
--- a/lib/lib.mk
+++ b/lib/lib.mk
@@ -5,6 +5,7 @@ libkres_SOURCES := \
 	lib/layer/validate.c   \
 	lib/layer/rrcache.c    \
 	lib/layer/pktcache.c   \
+	lib/cookies/cache.c    \
 	lib/cookies/control.c  \
 	lib/dnssec/nsec.c      \
 	lib/dnssec/nsec3.c     \
@@ -25,6 +26,7 @@ libkres_HEADERS := \
 	lib/generic/map.h      \
 	lib/generic/set.h      \
 	lib/layer.h            \
+	lib/cookies/cache.h    \
 	lib/cookies/control.h  \
 	lib/dnssec/nsec.h      \
 	lib/dnssec/nsec3.h     \
diff --git a/modules/cookies/cookies.c b/modules/cookies/cookies.c
index b2ee1a10332b83ec54a85e08499aa052723503ad..8ebcd01ac11f15566b255e9c0e6b290987e06ea2 100644
--- a/modules/cookies/cookies.c
+++ b/modules/cookies/cookies.c
@@ -27,6 +27,7 @@
 #include <time.h>
 
 #include "daemon/engine.h"
+#include "lib/cookies/cache.h"
 #include "lib/cookies/control.h"
 #include "lib/module.h"
 #include "lib/layer.h"
@@ -69,6 +70,39 @@ static int check_client_cookie(const uint8_t cc[KNOT_OPT_COOKIE_CLNT],
 	return kr_error(EINVAL);
 }
 
+/**
+ * Tries to guess the name server address from the reputation mechanism.
+ */
+static const struct sockaddr *guess_server_addr(const uint8_t cc[KNOT_OPT_COOKIE_CLNT],
+                                                struct kr_nsrep *nsrep,
+                                                struct secret_quantity *secret)
+{
+	assert(cc && nsrep && secret);
+
+	const struct sockaddr *sockaddr = NULL;
+
+	/* Abusing name server reputation mechanism to obtain IP addresses. */
+	for (int i = 0; i < KR_NSREP_MAXADDR; ++i) {
+		if (nsrep->addr[i].ip.sa_family == AF_UNSPEC) {
+			break;
+		}
+		int ret = check_client_cookie(cc, NULL, &nsrep->addr[i], secret);
+		WITH_DEBUG {
+			char addr_str[INET6_ADDRSTRLEN];
+			inet_ntop(nsrep->addr[i].ip.sa_family,
+			          kr_nsrep_inaddr(nsrep->addr[i]), addr_str,
+			          sizeof(addr_str));
+			DEBUG_MSG(NULL, "nsrep address '%s' %d\n", addr_str, ret);
+		}
+		if (ret == kr_ok()) {
+			sockaddr = (struct sockaddr *) &nsrep->addr[i];
+			break;
+		}
+	}
+
+	return sockaddr;
+}
+
 /** Process response. */
 static int check_response(knot_layer_t *ctx, knot_pkt_t *pkt)
 {
@@ -104,31 +138,14 @@ static int check_response(knot_layer_t *ctx, knot_pkt_t *pkt)
 
 	DEBUG_MSG(NULL, "%s\n", "checking response for received cookies");
 
-	const void *srvr_sockaddr = NULL;
+	const struct sockaddr *srvr_sockaddr = NULL;
 
 	struct kr_request *req = ctx->data;
 	struct kr_query *qry = req->current_query;
 	struct kr_nsrep *ns = &qry->ns;
 
 	/* Abusing name server reputation mechanism to obtain IP addresses. */
-	for (int i = 0; i < KR_NSREP_MAXADDR; ++i) {
-		if (ns->addr[i].ip.sa_family == AF_UNSPEC) {
-			break;
-		}
-		ret = check_client_cookie(cc, NULL, &ns->addr[i], kr_cookies_control.client);
-		WITH_DEBUG {
-			char addr_str[INET6_ADDRSTRLEN];
-			inet_ntop(ns->addr[i].ip.sa_family,
-			          kr_nsrep_inaddr(ns->addr[i]), addr_str,
-			          sizeof(addr_str));
-			DEBUG_MSG(NULL, "nsrep address '%s' %d\n", addr_str, ret);
-		}
-		if (ret == kr_ok()) {
-			srvr_sockaddr = &ns->addr[i];
-			break;
-		}
-	}
-
+	srvr_sockaddr = guess_server_addr(cc, ns, kr_cookies_control.secret);
 	if (!srvr_sockaddr) {
 		DEBUG_MSG(NULL, "%s\n",
 		          "could not ensure any server for received cookie");
@@ -136,8 +153,26 @@ static int check_response(knot_layer_t *ctx, knot_pkt_t *pkt)
 		return ctx->state;
 	}
 
+	struct kr_cache_txn txn;
+	if (kr_cache_txn_begin(&kr_cookies_control.cache, &txn, 0) != 0) {
+		/* Could not acquire cache. */
+		return ctx->state;
+	}
+
 	DEBUG_MSG(NULL, "%s\n", "caching server cookie");
 
+	/* TODO -- Cache only missing or change cookie. */
+
+	ret = kr_cookie_cache_insert_cookie(&txn, srvr_sockaddr, cookie_opt,
+	                                    qry->timestamp.tv_sec);
+	if (ret != kr_ok()) {
+		kr_cache_txn_abort(&txn);
+	} else {
+		DEBUG_MSG(NULL, "%s\n", "cookie_cached");
+		kr_cache_txn_commit(&txn);
+	}
+
+
 	print_packet_dflt(pkt);
 
 	return ctx->state;