diff --git a/edns.c b/edns.c
index 035ce4f4..e9e322d8 100644
--- a/edns.c
+++ b/edns.c
@@ -71,6 +71,7 @@ edns_init_record(edns_record_type *edns)
 	edns->dnssec_ok = 0;
 	edns->nsid = 0;
 	edns->zoneversion = 0;
+	edns->cookie_seen = 0;
 	edns->cookie_status = COOKIE_NOT_PRESENT;
 	edns->cookie_len = 0;
 	edns->ede = -1; /* -1 means no Extended DNS Error */
@@ -88,7 +89,7 @@ edns_handle_option(uint16_t optcode, uint16_t optlen, buffer_type* packet,
 	switch(optcode) {
 	case NSID_CODE:
 		/* is NSID enabled? */
-		if(nsd->nsid_len > 0) {
+		if(nsd->nsid_len > 0 && !edns->nsid) {
 			edns->nsid = 1;
 			/* we have to check optlen, and move the buffer along */
 			buffer_skip(packet, optlen);
@@ -101,7 +102,8 @@ edns_handle_option(uint16_t optcode, uint16_t optlen, buffer_type* packet,
 		break;
 	case COOKIE_CODE:
 		/* Cookies enabled? */
-		if(nsd->do_answer_cookie) {
+		if(nsd->do_answer_cookie && !edns->cookie_seen) {
+			edns->cookie_seen = 1;
 			if (optlen == 8) 
 				edns->cookie_status = COOKIE_INVALID;
 			else if (optlen < 16 || optlen > 40)
diff --git a/edns.h b/edns.h
index 3e1f5e79..1b182e1b 100644
--- a/edns.h
+++ b/edns.h
@@ -64,6 +64,7 @@ struct edns_record
 	int                dnssec_ok;
 	int                nsid;
 	int                zoneversion;
+	int		   cookie_seen;
 	cookie_status_type cookie_status;
 	size_t             cookie_len;
 	uint8_t            cookie[40];
diff --git a/options.c b/options.c
index ccfa13eb..486b61cf 100644
--- a/options.c
+++ b/options.c
@@ -2221,9 +2221,9 @@ acl_addr_match_range_v4(uint32_t* minval, uint32_t* x, uint32_t* maxval, size_t
 	/* check treats x as one huge number */
 
 	/* if outside bounds, we are done */
-	if(*minval > *x)
+	if(ntohl(*minval) > ntohl(*x))
 		return 0;
-	if(*maxval < *x)
+	if(ntohl(*maxval) < ntohl(*x))
 		return 0;
 
 	return 1;
@@ -2244,10 +2244,10 @@ acl_addr_match_range_v6(uint32_t* minval, uint32_t* x, uint32_t* maxval, size_t
 	{
 		/* if outside bounds, we are done */
 		if(checkmin)
-			if(minval[i] > x[i])
+			if(ntohl(minval[i]) > ntohl(x[i]))
 				return 0;
 		if(checkmax)
-			if(maxval[i] < x[i])
+			if(ntohl(maxval[i]) < ntohl(x[i]))
 				return 0;
 		/* if x is equal to a bound, that bound needs further checks */
 		if(checkmin && minval[i]!=x[i])
diff --git a/query.c b/query.c
index 9954c5f0..fd90a3a8 100644
--- a/query.c
+++ b/query.c
@@ -249,7 +249,8 @@ query_reset(query_type *q, size_t maxlen, int is_tcp)
 	region_free_all(q->region);
 	q->remote_addrlen = (socklen_t)sizeof(q->remote_addr);
 	q->client_addrlen = (socklen_t)sizeof(q->client_addr);
-	q->is_proxied = 0;
+	if(!is_tcp)
+		q->is_proxied = 0;
 	q->maxlen = maxlen;
 	q->reserved_space = 0;
 	buffer_clear(q->packet);
@@ -1776,6 +1777,16 @@ query_process(query_type *q, nsd_type *nsd, uint32_t *now_p)
 		cookie_verify(q, nsd, now_p);
 
 	query_prepare_response(q);
+	if(q->reserved_space + QHEADERSZ + (size_t)q->qname->name_size +
+		2 /* qtype */ + 2 /* qclass */ > q->maxlen) {
+		/* Clear out some space, and return error, it does not fit. */
+		q->edns.status = EDNS_NOT_PRESENT;
+		q->tsig.status = TSIG_NOT_PRESENT;
+		if(q->tcp)
+			return query_error(q, NSD_RC_SERVFAIL);
+		TC_SET(q->packet);
+		return query_error(q, NSD_RC_OK);
+	}
 
 	if (q->qclass != CLASS_IN && q->qclass != CLASS_ANY) {
 		if (q->qclass == CLASS_CH) {
diff --git a/server.c b/server.c
index ccf6e2dc..ea9a858a 100644
--- a/server.c
+++ b/server.c
@@ -4813,7 +4813,8 @@ handle_tcp_writing(int fd, short event, void* arg)
 		}
 
 #ifdef HAVE_WRITEV
-		sent -= sizeof(n_tcplen);
+		/* The number of bytes transmitted for the message content. */
+		sent = data->bytes_transmitted - sizeof(n_tcplen);
 		/* handle potential 'packet done' code */
 		goto packet_could_be_done;
 #endif
diff --git a/xfrd-tcp.c b/xfrd-tcp.c
index acea5e2d..5f3abb51 100644
--- a/xfrd-tcp.c
+++ b/xfrd-tcp.c
@@ -1252,8 +1252,8 @@ int conn_write(struct xfrd_tcp* tcp)
 		}
 
 		tcp->total_bytes += sent;
-		if(sent > (ssize_t)sizeof(tcp->msglen))
-			buffer_skip(tcp->packet, sent-sizeof(tcp->msglen));
+		if(tcp->total_bytes > (ssize_t)sizeof(tcp->msglen))
+			buffer_skip(tcp->packet, tcp->total_bytes-sizeof(tcp->msglen));
 		if(tcp->total_bytes < sizeof(tcp->msglen)) {
 			/* incomplete write, resume later */
 			return 0;
