return 0;
}
query_error(c->buffer, LDNS_RCODE_FORMERR, 0);
+ sldns_buffer_copy(c->dnscrypt_buffer, c->buffer);
return 1;
}
dname_str(qinfo.qname, buf);
query_error(c->buffer, LDNS_RCODE_SERVFAIL,
qinfo.qname_len);
worker->stats.num_query_dnscrypt_cleartext++;
+ sldns_buffer_copy(c->dnscrypt_buffer, c->buffer);
return 1;
}
worker->stats.num_query_dnscrypt_cert++;
server_stats_insquery(&worker->stats, c, qinfo.qtype,
qinfo.qclass, &edns, repinfo);
if(c->type != comm_udp)
+#ifdef USE_DNSCRYPT
+ edns.udp_size = (c->dnscrypt && repinfo->is_dnscrypted)
+ ? sldns_buffer_capacity(c->buffer) - DNSCRYPT_REPLY_HEADER_SIZE
+ : 65535;
+#else
edns.udp_size = 65535; /* max size for TCP replies */
+#endif
if(qinfo.qclass == LDNS_RR_CLASS_CH && answer_chaos(worker, &qinfo,
&edns, repinfo, c->buffer)) {
regional_free_all(worker->scratchpad);
}
}
#ifdef USE_DNSCRYPT
- if(!dnsc_handle_uncurved_request(repinfo)) {
+ if(!dnsc_handle_uncurved_request(repinfo, c->buffer)) {
return 0;
}
#endif
uint8_t *const buf = sldns_buffer_begin(buffer);
size_t len = sldns_buffer_limit(buffer);
+ if(len + DNSCRYPT_REPLY_HEADER_SIZE > sldns_buffer_capacity(buffer))
+ return -1;
+ sldns_buffer_clear(buffer);
+
if(udp){
if (max_len > max_reply_size)
max_len = max_reply_size;
}
+ if(max_len > sldns_buffer_capacity(buffer))
+ max_len = sldns_buffer_capacity(buffer);
+ if(max_len > 65535)
+ max_len = 65535;
memcpy(nonce, client_nonce, crypto_box_HALF_NONCEBYTES);
DNSCRYPT_MAGIC_HEADER_LEN,
nonce,
crypto_box_NONCEBYTES);
+ sldns_buffer_flip(buffer);
sldns_buffer_set_limit(buffer, len + DNSCRYPT_REPLY_HEADER_SIZE);
return 0;
}
}
int
-dnsc_handle_uncurved_request(struct comm_reply *repinfo)
+dnsc_handle_uncurved_request(struct comm_reply *repinfo,
+ struct sldns_buffer* buffer)
{
if(!repinfo->c->dnscrypt) {
return 1;
}
- sldns_buffer_copy(repinfo->c->dnscrypt_buffer, repinfo->c->buffer);
+ sldns_buffer_copy(repinfo->c->dnscrypt_buffer, buffer);
if(!repinfo->is_dnscrypted) {
return 1;
}
* \return 0 in case of failure.
*/
-int dnsc_handle_uncurved_request(struct comm_reply *repinfo);
+int dnsc_handle_uncurved_request(struct comm_reply *repinfo,
+ struct sldns_buffer* buffer);
/**
* Computes the size of the shared secret cache entry.
# do the test
-# Query plain request over DNSCrypt channel get closed
-# We use TCP to avoid hanging on waiting for UDP.
-# We expect `outfile` to contain no DNS payload
-echo "> dig TCP www.example.com. DNSCrypt port"
-dig +tcp @127.0.0.1 -p $DNSCRYPT_PORT www.example.com. A | tee outfile
+# Query plain request over DNSCrypt.
+# This used to close the channel; now it returns SERVFAIL.
+# Old: We use TCP to avoid hanging on waiting for UDP.
+# We expect `outfile` to contain no DNS payload
+echo "> dig www.example.com. DNSCrypt port"
+dig @127.0.0.1 -p $DNSCRYPT_PORT www.example.com. A | tee outfile
echo "> cat logfiles"
cat fwd.log
cat unbound.log
echo "> check answer"
-if grep "QUESTION SECTION" outfile; then
+if grep "SERVFAIL" outfile; then
+ echo "OK"
+else
echo "NOK"
exit 1
-else
- echo "OK"
fi
# do the test
-# Query plain request over DNSCrypt channel get closed
-# We use TCP to avoid hanging on waiting for UDP.
-# We expect `outfile` to contain no DNS payload
-echo "> dig TCP www.example.com. DNSCrypt port"
-dig +tcp @127.0.0.1 -p $DNSCRYPT_PORT www.example.com. A | tee outfile
+# Query plain request over DNSCrypt.
+# This used to close the channel; now it returns SERVFAIL.
+# Old: We use TCP to avoid hanging on waiting for UDP.
+# We expect `outfile` to contain no DNS payload
+echo "> dig www.example.com. DNSCrypt port"
+dig @127.0.0.1 -p $DNSCRYPT_PORT www.example.com. A | tee outfile
echo "> cat logfiles"
cat fwd.log
cat unbound.log
echo "> check answer"
-if grep "QUESTION SECTION" outfile; then
+if grep "SERVFAIL" outfile; then
+ echo "OK"
+else
echo "NOK"
exit 1
-else
- echo "OK"
fi
log_assert(repinfo && repinfo->c);
#ifdef USE_DNSCRYPT
buffer = repinfo->c->dnscrypt_buffer;
- if(!dnsc_handle_uncurved_request(repinfo)) {
+ if(!dnsc_handle_uncurved_request(repinfo,
+ repinfo->c->tcp_req_info?
+ repinfo->c->tcp_req_info->spool_buffer:repinfo->c->buffer)) {
return;
}
#else