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
/*
*/
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",
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),
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);
}
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,
* 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);
INSIST(client->recursionquota == NULL);
client->dscp = ifp->dscp;
+ client->rcode_override = -1; /* not set */
if (tcp) {
client->attributes |= NS_CLIENTATTR_TCP;
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);
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.
*/
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));
}