Index: uspace/srv/net/dnsres/dns_msg.c
===================================================================
--- uspace/srv/net/dnsres/dns_msg.c	(revision 7262f89f382dcb4ff1d35a91b1432f6c669f70a5)
+++ uspace/srv/net/dnsres/dns_msg.c	(revision dc95342d483b757291ef4b2e55e39d02aef56862)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2012 Jiri Svoboda
+ * Copyright (c) 2013 Jiri Svoboda
  * All rights reserved.
  *
@@ -489,5 +489,9 @@
 		dns_question_t *q = list_get_instance(link, dns_question_t, msg);
 		rc = dns_question_encode(q, data + di, size - di, &q_size);
-		assert(rc == EOK);
+		if (rc != EOK) {
+			assert(rc == ENOMEM || rc == EINVAL);
+			free(data);
+			return rc;
+		}
 
 		di += q_size;
@@ -578,6 +582,56 @@
 	return EOK;
 error:
-	/* XXX Destroy message */
+	dns_message_destroy(msg);
 	return rc;
+}
+
+static void dns_question_destroy(dns_question_t *question)
+{
+	free(question->qname);
+	free(question);
+}
+
+static void dns_rr_destroy(dns_rr_t *rr)
+{
+	free(rr->name);
+	free(rr->rdata);
+	free(rr);
+}
+
+void dns_message_destroy(dns_message_t *msg)
+{
+	link_t *link;
+	dns_question_t *question;
+	dns_rr_t *rr;
+
+	while (!list_empty(&msg->question)) {
+		link = list_first(&msg->question);
+		question = list_get_instance(link, dns_question_t, msg);
+		list_remove(&question->msg);
+		dns_question_destroy(question);
+	}
+
+	while (!list_empty(&msg->answer)) {
+		link = list_first(&msg->answer);
+		rr = list_get_instance(link, dns_rr_t, msg);
+		list_remove(&rr->msg);
+		dns_rr_destroy(rr);
+	}
+
+	while (!list_empty(&msg->authority)) {
+		link = list_first(&msg->authority);
+		rr = list_get_instance(link, dns_rr_t, msg);
+		list_remove(&rr->msg);
+		dns_rr_destroy(rr);
+	}
+
+	while (!list_empty(&msg->additional)) {
+		link = list_first(&msg->additional);
+		rr = list_get_instance(link, dns_rr_t, msg);
+		list_remove(&rr->msg);
+		dns_rr_destroy(rr);
+	}
+
+	free(msg);
 }
 
Index: uspace/srv/net/dnsres/dns_msg.h
===================================================================
--- uspace/srv/net/dnsres/dns_msg.h	(revision 7262f89f382dcb4ff1d35a91b1432f6c669f70a5)
+++ uspace/srv/net/dnsres/dns_msg.h	(revision dc95342d483b757291ef4b2e55e39d02aef56862)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2012 Jiri Svoboda
+ * Copyright (c) 2013 Jiri Svoboda
  * All rights reserved.
  *
@@ -45,4 +45,5 @@
 extern int dns_message_encode(dns_message_t *, void **, size_t *);
 extern int dns_message_decode(void *, size_t, dns_message_t **);
+extern void dns_message_destroy(dns_message_t *);
 extern uint32_t dns_uint32_t_decode(uint8_t *, size_t);
 
Index: uspace/srv/net/dnsres/dnsres.c
===================================================================
--- uspace/srv/net/dnsres/dnsres.c	(revision 7262f89f382dcb4ff1d35a91b1432f6c669f70a5)
+++ uspace/srv/net/dnsres/dnsres.c	(revision dc95342d483b757291ef4b2e55e39d02aef56862)
@@ -60,5 +60,5 @@
 int main(int argc, char *argv[])
 {
-	dns_host_info_t hinfo;
+	dns_host_info_t *hinfo;
 	char *astr;
 	int rc;
@@ -69,13 +69,15 @@
 
 	if (rc == EOK) {
-		rc = addr_format(&hinfo.addr, &astr);
+		rc = addr_format(&hinfo->addr, &astr);
 		if (rc != EOK) {
+			dns_hostinfo_destroy(hinfo);
 			printf("Out of memory\n");
 			return ENOMEM;
 		}
 
-		printf("hostname: %s\n", hinfo.name);
+		printf("hostname: %s\n", hinfo->name);
 		printf("IPv4 address: %s\n", astr);
 		free(astr);
+		dns_hostinfo_destroy(hinfo);
 	}
 
Index: uspace/srv/net/dnsres/query.c
===================================================================
--- uspace/srv/net/dnsres/query.c	(revision 7262f89f382dcb4ff1d35a91b1432f6c669f70a5)
+++ uspace/srv/net/dnsres/query.c	(revision dc95342d483b757291ef4b2e55e39d02aef56862)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2012 Jiri Svoboda
+ * Copyright (c) 2013 Jiri Svoboda
  * All rights reserved.
  *
@@ -36,4 +36,5 @@
 #include <errno.h>
 #include <mem.h>
+#include <stdlib.h>
 #include <str.h>
 
@@ -47,9 +48,10 @@
 
 #include <stdio.h>
-int dns_name2host(const char *name, dns_host_info_t *info)
+int dns_name2host(const char *name, dns_host_info_t **rinfo)
 {
 	dns_message_t msg;
 	dns_message_t *amsg;
 	dns_question_t question;
+	dns_host_info_t *info;
 	int rc;
 
@@ -81,8 +83,11 @@
 			rr->name, rr->rtype, rr->rclass, rr->rdata_size);
 
-		if (rr->rtype == DTYPE_A && rr->rclass == DC_IN) {
-			if (rr->rdata_size != sizeof(uint32_t)) {
-				printf("rdata_size = %u - fail\n", rr->rdata_size);
-				return EIO;
+		if (rr->rtype == DTYPE_A && rr->rclass == DC_IN &&
+			rr->rdata_size == sizeof(uint32_t)) {
+
+			info = calloc(1, sizeof(dns_host_info_t));
+			if (info == NULL) {
+				dns_message_destroy(amsg);
+				return ENOMEM;
 			}
 
@@ -90,8 +95,12 @@
 			info->addr.ipv4 = dns_uint32_t_decode(rr->rdata, rr->rdata_size);
 			printf("info->addr = %x\n", info->addr.ipv4);
+
+			dns_message_destroy(amsg);
+			*rinfo = info;
 			return EOK;
 		}
 	}
 
+	dns_message_destroy(amsg);
 	printf("no A/IN found, fail\n");
 
@@ -99,4 +108,10 @@
 }
 
+void dns_hostinfo_destroy(dns_host_info_t *info)
+{
+	free(info->name);
+	free(info);
+}
+
 /** @}
  */
Index: uspace/srv/net/dnsres/query.h
===================================================================
--- uspace/srv/net/dnsres/query.h	(revision 7262f89f382dcb4ff1d35a91b1432f6c669f70a5)
+++ uspace/srv/net/dnsres/query.h	(revision dc95342d483b757291ef4b2e55e39d02aef56862)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2012 Jiri Svoboda
+ * Copyright (c) 2013 Jiri Svoboda
  * All rights reserved.
  *
@@ -39,5 +39,6 @@
 #include "dns_type.h"
 
-extern int dns_name2host(const char *, dns_host_info_t *);
+extern int dns_name2host(const char *, dns_host_info_t **);
+extern void dns_hostinfo_destroy(dns_host_info_t *);
 
 #endif
Index: uspace/srv/net/dnsres/transport.c
===================================================================
--- uspace/srv/net/dnsres/transport.c	(revision 7262f89f382dcb4ff1d35a91b1432f6c669f70a5)
+++ uspace/srv/net/dnsres/transport.c	(revision dc95342d483b757291ef4b2e55e39d02aef56862)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2012 Jiri Svoboda
+ * Copyright (c) 2013 Jiri Svoboda
  * All rights reserved.
  *
@@ -120,6 +120,8 @@
 
 	rc = dns_message_decode(recv_buf, recv_size, &resp);
-	if (rc != EOK)
-		return EIO;
+	if (rc != EOK) {
+		rc = EIO;
+		goto error;
+	}
 
 	*rresp = resp;
