diff --git a/src/knot/server/tcp-handler.c b/src/knot/server/tcp-handler.c
index 60f43011211dbd380bed922ecca38bbab66aa6c5..d299bb4c37e833ef18296ae542d79e704733cc70 100644
--- a/src/knot/server/tcp-handler.c
+++ b/src/knot/server/tcp-handler.c
@@ -252,10 +252,12 @@ static int tcp_handle(tcp_worker_t *w, int fd, uint8_t *qbuf, size_t qbuf_maxlen
 		return xfr_answer(ns, &xfr);
 		
 	case KNOT_QUERY_UPDATE:
-		knot_ns_error_response_from_query(ns, packet,
-		                                  KNOT_RCODE_NOTIMPL,
-		                                  qbuf, &resp_len);
-		res = KNOTD_EOK;
+//		knot_ns_error_response_from_query(ns, packet,
+//		                                  KNOT_RCODE_NOTIMPL,
+//		                                  qbuf, &resp_len);
+		res = zones_process_update(ns, packet, &addr, qbuf, &resp_len,
+		                           NS_TRANSPORT_UDP);
+//		res = KNOTD_EOK;
 		break;
 		
 	case KNOT_QUERY_NOTIFY:
diff --git a/src/knot/server/udp-handler.c b/src/knot/server/udp-handler.c
index fc4e9b1d7eb025ac99be4dd8f3a040960271f277..d6b995c4cbd23e3202ddba1292b6d3157a28fe0b 100644
--- a/src/knot/server/udp-handler.c
+++ b/src/knot/server/udp-handler.c
@@ -164,11 +164,12 @@ int udp_handle(int fd, uint8_t *qbuf, size_t qbuflen, size_t *resp_len,
 		break;
 		
 	case KNOT_QUERY_UPDATE:
-		dbg_net("udp: UPDATE query on fd=%d not implemented\n", fd);
-		knot_ns_error_response_from_query(ns, packet,
-		                                  KNOT_RCODE_NOTIMPL, qbuf,
-		                                  resp_len);
-		res = KNOTD_EOK;
+//		dbg_net("udp: UPDATE query on fd=%d not implemented\n", fd);
+//		knot_ns_error_response_from_query(ns, packet,
+//		                                  KNOT_RCODE_NOTIMPL, qbuf,
+//		                                  resp_len);
+		res = zones_process_update(ns, packet, addr, qbuf, resp_len,
+		                           NS_TRANSPORT_UDP);
 		break;
 		
 	/* Unhandled opcodes. */
diff --git a/src/knot/server/zones.c b/src/knot/server/zones.c
index 2c6fec2ff565178ead754b48cb7ab239cb0355fa..02e64f9d5b93e026cecdfdd0f19d3129b4ae2559 100644
--- a/src/knot/server/zones.c
+++ b/src/knot/server/zones.c
@@ -2795,7 +2795,7 @@ int zones_process_update(knot_nameserver_t *nameserver,
 	knot_packet_free(&resp);
 	rcu_read_unlock();
 
-	return KNOT_EOK;
+	return KNOTD_EOK;
 }
 
 /*----------------------------------------------------------------------------*/
diff --git a/src/knot/server/zones.h b/src/knot/server/zones.h
index e46d2f61966401896f9692cdb8689beac6a0f8ee..41ce0232eafe888722e210a0a7fbe33f77121890 100644
--- a/src/knot/server/zones.h
+++ b/src/knot/server/zones.h
@@ -154,6 +154,14 @@ int zones_normal_query_answer(knot_nameserver_t *nameserver,
                               uint8_t *response_wire, size_t *rsize,
                               knot_ns_transport_t transport);
 
+/*!
+ * \todo Document me.
+ */
+int zones_process_update(knot_nameserver_t *nameserver,
+                         knot_packet_t *query, const sockaddr_t *addr,
+                         uint8_t *resp_wire, size_t *rsize,
+                         knot_ns_transport_t transport);
+
 /*!
  * \brief Processes normal response packet.
  *
diff --git a/src/libknot/nameserver/name-server.c b/src/libknot/nameserver/name-server.c
index e56d1f37518464ad61deae0a8af883ac768b9823..3abd018589729ac2263b83beb2981457a5d68162 100644
--- a/src/libknot/nameserver/name-server.c
+++ b/src/libknot/nameserver/name-server.c
@@ -4213,7 +4213,7 @@ int knot_ns_process_ixfrin(knot_nameserver_t *nameserver,
  * This function should process the contents, prepare prerequisities, prepare
  * changeset and return to the caller.
  */
-int knot_ns_process_update(knot_packet_t *query, 
+int knot_ns_process_update(const knot_packet_t *query, 
                            const knot_zone_contents_t *zone, 
                            knot_changeset_t *changeset, knot_rcode_t *rcode)
 {
diff --git a/src/libknot/nameserver/name-server.h b/src/libknot/nameserver/name-server.h
index 939975a5dc966a15604801260e8d1a73a3a4b7cf..7bddc0badf74519499a5dd849039829f691c6a5d 100644
--- a/src/libknot/nameserver/name-server.h
+++ b/src/libknot/nameserver/name-server.h
@@ -344,7 +344,7 @@ int knot_ns_switch_zone(knot_nameserver_t *nameserver,
 int knot_ns_process_ixfrin(knot_nameserver_t *nameserver, 
                              knot_ns_xfr_t *xfr);
 
-int knot_ns_process_update(knot_packet_t *query, 
+int knot_ns_process_update(const knot_packet_t *query, 
                            const knot_zone_contents_t *zone, 
                            knot_changeset_t *changeset, knot_rcode_t *rcode);
 
diff --git a/src/libknot/packet/packet.c b/src/libknot/packet/packet.c
index 6c7fd020d5fa3703fe9eea6e98c5e26db8bd5727..4eee3fc1fefe33e3c4d89d30141bfdb099413ab3 100644
--- a/src/libknot/packet/packet.c
+++ b/src/libknot/packet/packet.c
@@ -1254,7 +1254,7 @@ const knot_rrset_t *knot_packet_answer_rrset(
 /*----------------------------------------------------------------------------*/
 
 const knot_rrset_t *knot_packet_authority_rrset(
-	knot_packet_t *packet, short pos)
+	const knot_packet_t *packet, short pos)
 {
 	if (packet == NULL || pos > packet->ns_rrsets) {
 		return NULL;
@@ -1266,7 +1266,7 @@ const knot_rrset_t *knot_packet_authority_rrset(
 /*----------------------------------------------------------------------------*/
 
 const knot_rrset_t *knot_packet_additional_rrset(
-    knot_packet_t *packet, short pos)
+    const knot_packet_t *packet, short pos)
 {
 	if (packet == NULL || pos > packet->ar_rrsets) {
 		return NULL;
diff --git a/src/libknot/packet/packet.h b/src/libknot/packet/packet.h
index d76209af5d13a1c9492688b45bddcda53a27321e..e494e2317dd252cc55183cbf73a3881885a96ea2 100644
--- a/src/libknot/packet/packet.h
+++ b/src/libknot/packet/packet.h
@@ -445,7 +445,7 @@ const knot_rrset_t *knot_packet_answer_rrset(
  *         or NULL if there is no such RRSet.
  */
 const knot_rrset_t *knot_packet_authority_rrset(
-	knot_packet_t *packet, short pos);
+	const knot_packet_t *packet, short pos);
 
 /*!
  * \brief Returns the requested Additional RRset.
@@ -459,7 +459,7 @@ const knot_rrset_t *knot_packet_authority_rrset(
  *         or NULL if there is no such RRSet.
  */
 const knot_rrset_t *knot_packet_additional_rrset(
-    knot_packet_t *packet, short pos);
+	const knot_packet_t *packet, short pos);
 
 /*!
  * \brief Checks if the packet already contains the given RRSet.
diff --git a/src/libknot/updates/ddns.c b/src/libknot/updates/ddns.c
index 2566045531cebc2a9d525fb6566740508a21f33d..73b213d45fc12756280b401cb1c1f806807df1ba 100644
--- a/src/libknot/updates/ddns.c
+++ b/src/libknot/updates/ddns.c
@@ -411,7 +411,7 @@ static int knot_ddns_check_not_in_use(const knot_zone_contents_t *zone,
 /*----------------------------------------------------------------------------*/
 
 int knot_ddns_check_zone(const knot_zone_contents_t *zone, 
-                         knot_packet_t *query, knot_rcode_t *rcode)
+                         const knot_packet_t *query, knot_rcode_t *rcode)
 {
 	if (zone == NULL || query == NULL || rcode == NULL) {
 		return KNOT_EBADARG;
@@ -434,7 +434,7 @@ int knot_ddns_check_zone(const knot_zone_contents_t *zone,
 
 /*----------------------------------------------------------------------------*/
 
-int knot_ddns_process_prereqs(knot_packet_t *query,
+int knot_ddns_process_prereqs(const knot_packet_t *query,
                               knot_ddns_prereq_t **prereqs, knot_rcode_t *rcode)
 {
 	/*! \todo Consider not parsing the whole packet at once, but
@@ -561,7 +561,7 @@ static int knot_ddns_check_update(const knot_rrset_t *rrset,
 
 /*----------------------------------------------------------------------------*/
 
-int knot_ddns_process_update(knot_packet_t *query,
+int knot_ddns_process_update(const knot_packet_t *query,
                              knot_changeset_t *changeset, knot_rcode_t *rcode)
 {
 	// just put all RRSets from query's Authority section
diff --git a/src/libknot/updates/ddns.h b/src/libknot/updates/ddns.h
index 030525548fab2eb4f5193387eefc540768146b8d..6b4400f25384ec02587d39cbb0c3e4c1cdd29c17 100644
--- a/src/libknot/updates/ddns.h
+++ b/src/libknot/updates/ddns.h
@@ -56,16 +56,16 @@ typedef struct knot_ddns_prereq_t {
 	size_t not_in_use_allocd;
 } knot_ddns_prereq_t;
 
-int knot_ddns_check_zone(const knot_zone_contents_t *zone, knot_packet_t *query,
-                         knot_rcode_t *rcode);
+int knot_ddns_check_zone(const knot_zone_contents_t *zone, 
+                         const knot_packet_t *query, knot_rcode_t *rcode);
 
-int knot_ddns_process_prereqs(knot_packet_t *query,
+int knot_ddns_process_prereqs(const knot_packet_t *query,
                               knot_ddns_prereq_t **prereqs, knot_rcode_t *rcode);
 
 int knot_ddns_check_prereqs(const knot_zone_contents_t *zone,
                             knot_ddns_prereq_t **prereqs, knot_rcode_t *rcode);
 
-int knot_ddns_process_update(knot_packet_t *query,
+int knot_ddns_process_update(const knot_packet_t *query,
                              knot_changeset_t *changeset, knot_rcode_t *rcode);
 
 void knot_ddns_prereqs_free(knot_ddns_prereq_t **prereq);