From aaa63cbb5dd76ee693f1cae4993b2bd305f1fddd Mon Sep 17 00:00:00 2001
From: Marek Vavrusa <marek.vavrusa@nic.cz>
Date: Fri, 26 Jul 2013 15:27:29 +0200
Subject: [PATCH] Fixed correct error response question section.

The packet size was previously zero and question size included
header size.
---
 src/libknot/nameserver/name-server.c | 28 +++++++++-------------------
 src/libknot/packet/response.c        |  6 ++++--
 2 files changed, 13 insertions(+), 21 deletions(-)

diff --git a/src/libknot/nameserver/name-server.c b/src/libknot/nameserver/name-server.c
index cf8abd84f..6d2231368 100644
--- a/src/libknot/nameserver/name-server.c
+++ b/src/libknot/nameserver/name-server.c
@@ -3339,35 +3339,25 @@ int knot_ns_error_response_from_query(const knot_nameserver_t *nameserver,
 
 	size_t max_size = *rsize;
 	uint8_t flags1 = knot_wire_get_flags1(knot_packet_wireformat(query));
+	const size_t question_off = KNOT_WIRE_HEADER_SIZE;
 
 	// prepare the generic error response
 	knot_ns_error_response(nameserver, knot_packet_id(query),
 	                       &flags1, rcode, response_wire,
 	                       rsize);
 
-	if (query->parsed > KNOT_WIRE_HEADER_SIZE
-	                    + KNOT_WIRE_QUESTION_MIN_SIZE) {
-		// in this case the whole question was parsed, append it
-		size_t question_size = knot_packet_question_size(query);
+	if (query->parsed > KNOT_WIRE_HEADER_SIZE + question_off) {
 
-		if (max_size > KNOT_WIRE_HEADER_SIZE + question_size) {
-			/*
-			 * At this point, the wireformat of query may be in the
-			 * same place where the response is assembled. This does
-			 * not matter before this point, although the query
-			 * wireformat is rewritten. Now we just need to copy
-			 * the original Question section. So if the pointers are
-			 * the same, we may just leave it and increase the
-			 * response wire size. Otherwise we must copy the data.
-			 */
+		/* Append question only (do not rewrite header). */
+		size_t question_size = knot_packet_question_size(query);
+		question_size -= question_off;
+		if (max_size >= *rsize + question_size) {
 			if (response_wire != knot_packet_wireformat(query)) {
-				memcpy(response_wire + KNOT_WIRE_HEADER_SIZE,
-				       knot_packet_wireformat(query)
-				       + KNOT_WIRE_HEADER_SIZE, question_size);
+				memcpy(response_wire + question_off,
+				       knot_packet_wireformat(query) + question_off,
+				       question_size);
 			}
 			*rsize += question_size;
-
-			// adjust QDCOUNT
 			knot_wire_set_qdcount(response_wire, 1);
 		}
 	}
diff --git a/src/libknot/packet/response.c b/src/libknot/packet/response.c
index 70a02692d..55d6230bd 100644
--- a/src/libknot/packet/response.c
+++ b/src/libknot/packet/response.c
@@ -271,10 +271,12 @@ int knot_response_init(knot_packet_t *response)
 		return KNOT_ESPACE;
 	}
 
-	// set the qr bit to 1
+	/* Empty packet header. */
 	memset(response->wireformat, 0, KNOT_WIRE_HEADER_SIZE);
+	response->size = KNOT_WIRE_HEADER_SIZE;
 
-	uint8_t flags = knot_wire_get_flags1(response->wireformat);
+	/* Set the qr bit to 1. */
+	uint8_t flags = 0;
 	knot_wire_flags_set_qr(&flags);
 	knot_wire_set_flags1(response->wireformat, flags);
 
-- 
GitLab