Commit c9cb567f authored by Evan Hunt's avatar Evan Hunt
Browse files

Merge branch '990-return-servfail' into 'master'

force SERVFAIL response in the gotanswer failure case

Closes #990

See merge request !1838
parents f3e2780d 4d358c9b
Pipeline #13713 passed with stages
in 1 minute and 6 seconds
5215. [bug] Change #5124 was incomplete; named could still
return FORMERR instead of SERVFAIL in some cases.
[GL #990]
5214. [bug] win32: named now removes its lock file upon shutdown.
[GL #979]
......
......@@ -1427,7 +1427,12 @@ ns_client_error(ns_client_t *client, isc_result_t result) {
CTRACE("error");
message = client->message;
rcode = dns_result_torcode(result);
if (client->rcode_override == -1) {
rcode = dns_result_torcode(result);
} else {
rcode = (dns_rcode_t)(client->rcode_override & 0xfff);
}
#if NS_CLIENT_DROPPORT
/*
......@@ -1435,13 +1440,15 @@ ns_client_error(ns_client_t *client, isc_result_t result) {
*/
if (rcode == dns_rcode_formerr &&
ns_client_dropport(isc_sockaddr_getport(&client->peeraddr)) !=
DROPPORT_NO) {
DROPPORT_NO)
{
char buf[64];
isc_buffer_t b;
isc_buffer_init(&b, buf, sizeof(buf) - 1);
if (dns_rcode_totext(rcode, &b) != ISC_R_SUCCESS)
if (dns_rcode_totext(rcode, &b) != ISC_R_SUCCESS) {
isc_buffer_putstr(&b, "UNKNOWN RCODE");
}
ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10),
"dropped error (%.*s) response: suspicious port",
......@@ -1462,10 +1469,11 @@ ns_client_error(ns_client_t *client, isc_result_t result) {
INSIST(rcode != dns_rcode_noerror &&
rcode != dns_rcode_nxdomain);
if ((client->sctx->options & NS_SERVER_LOGQUERIES) != 0)
if ((client->sctx->options & NS_SERVER_LOGQUERIES) != 0) {
loglevel = DNS_RRL_LOG_DROP;
else
} else {
loglevel = ISC_LOG_DEBUG(1);
}
wouldlog = isc_log_wouldlog(ns_lctx, loglevel);
rrl_result = dns_rrl(client->view, &client->peeraddr,
TCP_CLIENT(client),
......@@ -1570,12 +1578,14 @@ ns_client_error(ns_client_t *client, isc_result_t result) {
isc_interval_set(&i, client->view->fail_ttl, 0);
result = isc_time_nowplusinterval(&expire, &i);
if (result == ISC_R_SUCCESS)
if (result == ISC_R_SUCCESS) {
dns_badcache_add(client->view->failcache,
client->query.qname,
client->query.qtype,
true, flags, &expire);
}
}
ns_client_send(client);
}
......@@ -3058,6 +3068,7 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp) {
ISC_QLINK_INIT(client, ilink);
client->keytag = NULL;
client->keytag_len = 0;
client->rcode_override = -1; /* not set */
/*
* We call the init routines for the various kinds of client here,
......@@ -3519,12 +3530,13 @@ get_client(ns_clientmgr_t *manager, ns_interface_t *ifp,
* if that fails, make a new one.
*/
client = NULL;
if ((manager->sctx->options & NS_SERVER_CLIENTTEST) == 0)
if ((manager->sctx->options & NS_SERVER_CLIENTTEST) == 0) {
ISC_QUEUE_POP(manager->inactive, ilink, client);
}
if (client != NULL)
if (client != NULL) {
MTRACE("recycle");
else {
} else {
MTRACE("create new");
LOCK(&manager->lock);
......@@ -3545,6 +3557,7 @@ get_client(ns_clientmgr_t *manager, ns_interface_t *ifp,
INSIST(client->recursionquota == NULL);
client->dscp = ifp->dscp;
client->rcode_override = -1; /* not set */
if (tcp) {
client->attributes |= NS_CLIENTATTR_TCP;
......@@ -3615,6 +3628,7 @@ get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp, isc_socket_t *sock) {
client->pipelined = true;
client->mortal = true;
client->sendcb = NULL;
client->rcode_override = -1; /* not set */
isc_socket_attach(ifp->tcpsocket, &client->tcplistener);
isc_socket_attach(sock, &client->tcpsocket);
......
......@@ -170,6 +170,14 @@ struct ns_client {
uint32_t expire;
unsigned char *keytag;
uint16_t keytag_len;
/*%
* Used to override the DNS response code in ns_client_error().
* If set to -1, the rcode is determined from the result code,
* but if set to any other value, the least significant 12
* bits will be used as the rcode in the response message.
*/
int32_t rcode_override;
};
typedef ISC_QUEUE(ns_client_t) client_queue_t;
......
......@@ -6749,10 +6749,6 @@ query_gotanswer(query_ctx_t *qctx, isc_result_t res) {
case DNS_R_DNAME:
return (query_dname(qctx));
case DNS_R_FORMERR:
QUERY_ERROR(qctx, DNS_R_SERVFAIL);
return (ns_query_done(qctx));
default:
/*
* Something has gone wrong.
......@@ -6768,6 +6764,13 @@ query_gotanswer(query_ctx_t *qctx, isc_result_t res) {
*/
return (query_lookup(qctx));
}
/*
* Regardless of the triggering result, we definitely
* want to return SERVFAIL from here.
*/
qctx->client->rcode_override = dns_rcode_servfail;
QUERY_ERROR(qctx, result);
return (ns_query_done(qctx));
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment