Replace query and client attribute bitfield with named bools

Replace the unsigned int attributes field in struct ns_query with
individual bool bitfields.  This removes the NS_QUERYATTR_* constants
and the 12 accessor macros (USECACHE, RECURSIONOK, RECURSING, etc.)
from query.c, replacing all bit manipulation with direct bool access.

And replace the unsigned int attributes field in struct ns_client_inner
with individual bool bitfields.  This removes the NS_CLIENTATTR_*
constants and the accessor macros (TCP, WANTDNSSEC, etc.), replacing
all bit manipulation with direct bool access.
This commit is contained in:
Ondřej Surý 2026-03-21 17:13:56 +01:00
parent 03c495def6
commit 430ce335ad
9 changed files with 454 additions and 507 deletions

View file

@ -87,12 +87,6 @@ typedef struct filter_instance {
#define FILTER_A_RECURSING 0x0001 /* Recursing for AAAA */
#define FILTER_A_FILTERED 0x0002 /* A was removed from answer */
/*
* Client attribute tests.
*/
#define WANTDNSSEC(c) (((c)->inner.attributes & NS_CLIENTATTR_WANTDNSSEC) != 0)
#define RECURSIONOK(c) (((c)->query.attributes & NS_QUERYATTR_RECURSIONOK) != 0)
/*
* Forward declarations of functions referenced in install_hooks().
*/
@ -533,7 +527,7 @@ process_name(query_ctx_t *qctx, filter_a_t mode, const dns_name_t *name,
(void)dns_message_findtype(n, dns_rdatatype_rrsig, type, &sigrdataset);
if (rdataset != NULL &&
(sigrdataset == NULL || !WANTDNSSEC(qctx->client) ||
(sigrdataset == NULL || !qctx->client->inner.wantdnssec ||
mode == BREAK_DNSSEC))
{
/*
@ -683,7 +677,7 @@ filter_respond_begin(void *arg, void *cbdata, isc_result_t *resp) {
if (client_state->mode != BREAK_DNSSEC &&
(client_state->mode != FILTER ||
(WANTDNSSEC(qctx->client) && qctx->sigrdataset != NULL &&
(qctx->client->inner.wantdnssec && qctx->sigrdataset != NULL &&
dns_rdataset_isassociated(qctx->sigrdataset))))
{
return NS_HOOK_CONTINUE;
@ -717,7 +711,8 @@ filter_respond_begin(void *arg, void *cbdata, isc_result_t *resp) {
mark_as_rendered(qctx->rdataset, qctx->sigrdataset);
qctx->client->message->flags &= ~DNS_MESSAGEFLAG_AD;
client_state->flags |= FILTER_A_FILTERED;
} else if (!qctx->authoritative && RECURSIONOK(qctx->client) &&
} else if (!qctx->authoritative &&
qctx->client->query.recursionok &&
(result == DNS_R_DELEGATION ||
result == ISC_R_NOTFOUND))
{
@ -735,8 +730,7 @@ filter_respond_begin(void *arg, void *cbdata, isc_result_t *resp) {
NULL, NULL, qctx->resuming);
if (result == ISC_R_SUCCESS) {
client_state->flags |= FILTER_A_RECURSING;
qctx->client->query.attributes |=
NS_QUERYATTR_RECURSING;
qctx->client->query.recursing = true;
}
}
} else if (qctx->qtype == dns_rdatatype_aaaa &&

View file

@ -87,12 +87,6 @@ typedef struct filter_instance {
#define FILTER_AAAA_RECURSING 0x0001 /* Recursing for A */
#define FILTER_AAAA_FILTERED 0x0002 /* AAAA was removed from answer */
/*
* Client attribute tests.
*/
#define WANTDNSSEC(c) (((c)->inner.attributes & NS_CLIENTATTR_WANTDNSSEC) != 0)
#define RECURSIONOK(c) (((c)->query.attributes & NS_QUERYATTR_RECURSIONOK) != 0)
/*
* Forward declarations of functions referenced in install_hooks().
*/
@ -537,7 +531,7 @@ process_name(query_ctx_t *qctx, filter_aaaa_t mode, const dns_name_t *name,
(void)dns_message_findtype(n, dns_rdatatype_rrsig, type, &sigrdataset);
if (rdataset != NULL &&
(sigrdataset == NULL || !WANTDNSSEC(qctx->client) ||
(sigrdataset == NULL || !qctx->client->inner.wantdnssec ||
mode == BREAK_DNSSEC))
{
/*
@ -687,7 +681,7 @@ filter_respond_begin(void *arg, void *cbdata, isc_result_t *resp) {
if (client_state->mode != BREAK_DNSSEC &&
(client_state->mode != FILTER ||
(WANTDNSSEC(qctx->client) && qctx->sigrdataset != NULL &&
(qctx->client->inner.wantdnssec && qctx->sigrdataset != NULL &&
dns_rdataset_isassociated(qctx->sigrdataset))))
{
return NS_HOOK_CONTINUE;
@ -721,7 +715,8 @@ filter_respond_begin(void *arg, void *cbdata, isc_result_t *resp) {
mark_as_rendered(qctx->rdataset, qctx->sigrdataset);
qctx->client->message->flags &= ~DNS_MESSAGEFLAG_AD;
client_state->flags |= FILTER_AAAA_FILTERED;
} else if (!qctx->authoritative && RECURSIONOK(qctx->client) &&
} else if (!qctx->authoritative &&
qctx->client->query.recursionok &&
(result == DNS_R_DELEGATION ||
result == ISC_R_NOTFOUND))
{
@ -738,8 +733,7 @@ filter_respond_begin(void *arg, void *cbdata, isc_result_t *resp) {
NULL, NULL, qctx->resuming);
if (result == ISC_R_SUCCESS) {
client_state->flags |= FILTER_AAAA_RECURSING;
qctx->client->query.attributes |=
NS_QUERYATTR_RECURSING;
qctx->client->query.recursing = true;
}
}
} else if (qctx->qtype == dns_rdatatype_a &&

View file

@ -86,28 +86,17 @@
#define CTRACE(m) \
ns_client_log(client, NS_LOGCATEGORY_CLIENT, NS_LOGMODULE_CLIENT, \
ISC_LOG_DEBUG(3), "%s", (m))
#define MTRACE(m) \
isc_log_write(ns_lctx, NS_LOGCATEGORY_CLIENT, NS_LOGMODULE_CLIENT, \
#define MTRACE(m) \
isc_log_write(NS_LOGCATEGORY_CLIENT, NS_LOGMODULE_CLIENT, \
ISC_LOG_DEBUG(3), "clientmgr @%p: %s", manager, (m))
#else /* ifdef NS_CLIENT_TRACE */
#define CTRACE(m) ((void)(m))
#define MTRACE(m) ((void)(m))
#endif /* ifdef NS_CLIENT_TRACE */
#define TCP_CLIENT(c) (((c)->inner.attributes & NS_CLIENTATTR_TCP) != 0)
#define COOKIE_SIZE 24U /* 8 + 4 + 4 + 8 */
#define ECS_SIZE 20U /* 2 + 1 + 1 + [0..16] */
#define USEKEEPALIVE(x) \
(((x)->inner.attributes & NS_CLIENTATTR_USEKEEPALIVE) != 0)
#define WANTEXPIRE(x) (((x)->inner.attributes & NS_CLIENTATTR_WANTEXPIRE) != 0)
#define WANTNSID(x) (((x)->inner.attributes & NS_CLIENTATTR_WANTNSID) != 0)
#define WANTPAD(x) (((x)->inner.attributes & NS_CLIENTATTR_WANTPAD) != 0)
#define WANTRC(x) (((x)->inner.attributes & NS_CLIENTATTR_WANTRC) != 0)
#define WANTZONEVERSION(x) \
(((x)->inner.attributes & NS_CLIENTATTR_WANTZONEVERSION) != 0)
#define MANAGER_MAGIC ISC_MAGIC('N', 'S', 'C', 'm')
#define VALID_MANAGER(m) ISC_MAGIC_VALID(m, MANAGER_MAGIC)
@ -151,7 +140,7 @@ ns_client_transport_type(const ns_client_t *client) {
*
* When DoQ support this had to be removed to get correct DoQ entries.
*/
if (!TCP_CLIENT(client)) {
if (!client->inner.tcp) {
return DNS_TRANSPORT_UDP;
}
@ -282,9 +271,13 @@ ns_client_endrequest(ns_client_t *client) {
dns_message_reset(client->message, DNS_MESSAGE_INTENTPARSE);
/*
* Clear all client attributes that are specific to the request
* Clear all client attributes that are specific to the request,
* but keep the async attribute needed for reseting the async
* state later.
*/
client->inner.attributes = 0;
bool async = client->inner.async;
memset(&client->inner.attrs, 0, sizeof(client->inner.attrs));
client->inner.async = async;
#ifdef ENABLE_AFL
if (client->manager->sctx->fuzznotify != NULL &&
(client->manager->sctx->fuzztype == isc_fuzz_client ||
@ -345,11 +338,11 @@ client_senddone(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
isc_histomulti_detach(&hmpin);
}
} else {
if (!TCP_CLIENT(client) && result == ISC_R_MAXSIZE) {
if (!client->inner.tcp && result == ISC_R_MAXSIZE) {
ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
"send exceeded maximum size: truncating");
client->query.attributes &= ~NS_QUERYATTR_ANSWERED;
client->query.answered = false;
client->inner.rcode_override = dns_rcode_noerror;
ns_client_error(client, ISC_R_MAXSIZE);
} else {
@ -395,14 +388,13 @@ client_allocsendbuf(ns_client_t *client, isc_buffer_t *buffer,
REQUIRE(datap != NULL);
if (TCP_CLIENT(client)) {
if (client->inner.tcp) {
client_setup_tcp_buffer(client);
data = client->inner.tcpbuf;
isc_buffer_init(buffer, data, client->inner.tcpbuf_size);
} else {
data = client->sendbuf;
if ((client->inner.attributes & NS_CLIENTATTR_HAVECOOKIE) == 0)
{
if (!client->inner.havecookie) {
if (client->inner.view != NULL) {
bufsize = client->inner.view->nocookieudp;
} else {
@ -582,7 +574,7 @@ ns_client_send(ns_client_t *client) {
REQUIRE(NS_CLIENT_VALID(client));
if ((client->query.attributes & NS_QUERYATTR_ANSWERED) != 0) {
if (client->query.answered) {
return;
}
@ -595,13 +587,11 @@ ns_client_send(ns_client_t *client) {
CTRACE("send");
if (client->message->opcode == dns_opcode_query &&
(client->inner.attributes & NS_CLIENTATTR_RA) != 0)
{
if (client->message->opcode == dns_opcode_query && client->inner.ra) {
client->message->flags |= DNS_MESSAGEFLAG_RA;
}
if ((client->inner.attributes & NS_CLIENTATTR_WANTDNSSEC) != 0) {
if (client->inner.wantdnssec) {
render_opts = 0;
} else {
render_opts = DNS_MESSAGERENDER_OMITDNSSEC;
@ -628,7 +618,7 @@ ns_client_send(ns_client_t *client) {
/*
* Create an OPT for our reply.
*/
if ((client->inner.attributes & NS_CLIENTATTR_WANTOPT) != 0) {
if (client->inner.wantopt) {
CHECK(ns_client_addopt(client, client->message));
opt_included = true;
}
@ -738,7 +728,7 @@ renderend:
if (client->inner.sendcb != NULL) {
client->inner.sendcb(&buffer);
} else if (TCP_CLIENT(client)) {
} else if (client->inner.tcp) {
isc_buffer_usedregion(&buffer, &r);
#ifdef HAVE_DNSTAP
if (client->inner.view != NULL) {
@ -822,7 +812,7 @@ renderend:
ns_statscounter_truncatedresp);
}
client->query.attributes |= NS_QUERYATTR_ANSWERED;
client->query.answered = true;
return;
@ -927,11 +917,11 @@ ns_client_error(ns_client_t *client, isc_result_t result) {
loglevel = ISC_LOG_DEBUG(1);
}
wouldlog = isc_log_wouldlog(loglevel);
rrl_result = dns_rrl(
client->inner.view, NULL, &client->inner.peeraddr,
TCP_CLIENT(client), dns_rdataclass_in,
dns_rdatatype_none, NULL, result, client->inner.now,
wouldlog, log_buf, sizeof(log_buf));
rrl_result = dns_rrl(client->inner.view, NULL,
&client->inner.peeraddr, client->inner.tcp,
dns_rdataclass_in, dns_rdatatype_none,
NULL, result, client->inner.now, wouldlog,
log_buf, sizeof(log_buf));
if (rrl_result != DNS_RRL_RESULT_OK) {
/*
* Log dropped errors in the query-errors category
@ -1021,8 +1011,7 @@ ns_client_error(ns_client_t *client, isc_result_t result) {
client->inner.formerrcache.id = message->id;
} else if (rcode == dns_rcode_servfail && client->query.qname != NULL &&
client->inner.view != NULL &&
client->inner.view->fail_ttl != 0 &&
((client->inner.attributes & NS_CLIENTATTR_NOSETFC) == 0))
client->inner.view->fail_ttl != 0 && !client->inner.nosetfc)
{
/*
* SERVFAIL caching: store qname/qtype of failed queries
@ -1078,7 +1067,7 @@ ns_client_addopt(ns_client_t *client, dns_message_t *message) {
dns_message_ednsinit(message, 0, udpsize, flags, 0);
/* Set EDNS options if applicable */
if (WANTNSID(client)) {
if (client->inner.wantnsid) {
char nsid[_POSIX_HOST_NAME_MAX + 1];
char *nsidp = NULL;
@ -1099,7 +1088,7 @@ ns_client_addopt(ns_client_t *client, dns_message_t *message) {
}
}
if ((client->inner.attributes & NS_CLIENTATTR_WANTCOOKIE) != 0) {
if (client->inner.wantcookie) {
isc_buffer_t buf;
isc_stdtime_t now = isc_stdtime_now();
@ -1114,7 +1103,7 @@ ns_client_addopt(ns_client_t *client, dns_message_t *message) {
RETERR(dns_message_ednsaddopt(message, &option));
}
if ((client->inner.attributes & NS_CLIENTATTR_HAVEEXPIRE) != 0) {
if (client->inner.haveexpire) {
isc_buffer_t buf;
isc_buffer_init(&buf, expire, sizeof(expire));
@ -1126,7 +1115,7 @@ ns_client_addopt(ns_client_t *client, dns_message_t *message) {
RETERR(dns_message_ednsaddopt(message, &option));
}
if (((client->inner.attributes & NS_CLIENTATTR_HAVEECS) != 0) &&
if (client->inner.haveecs &&
(client->inner.ecs.addr.family == AF_INET ||
client->inner.ecs.addr.family == AF_INET6))
{
@ -1180,7 +1169,7 @@ ns_client_addopt(ns_client_t *client, dns_message_t *message) {
RETERR(dns_message_ednsaddopt(message, &option));
}
if (TCP_CLIENT(client) && USEKEEPALIVE(client)) {
if (client->inner.tcp && client->inner.usekeepalive) {
uint32_t advertised_timeout = isc_nm_getadvertisedtimeout();
isc_buffer_t buf;
@ -1206,7 +1195,7 @@ ns_client_addopt(ns_client_t *client, dns_message_t *message) {
.value = ede->value };
RETERR(dns_message_ednsaddopt(message, &option));
}
if ((client->inner.attributes & NS_CLIENTATTR_HAVEZONEVERSION) != 0) {
if (client->inner.havezoneversion) {
dns_ednsopt_t option = {
.code = DNS_OPT_ZONEVERSION,
.length = client->inner.zoneversionlength,
@ -1215,7 +1204,7 @@ ns_client_addopt(ns_client_t *client, dns_message_t *message) {
RETERR(dns_message_ednsaddopt(message, &option));
}
if (WANTRC(client)) {
if (client->inner.wantrc) {
dns_name_t *rad = NULL;
if (dns_name_dynamic(&client->inner.rad)) {
rad = &client->inner.rad;
@ -1231,9 +1220,8 @@ ns_client_addopt(ns_client_t *client, dns_message_t *message) {
}
/* Padding must be added last */
if ((view != NULL) && (view->padding > 0) && WANTPAD(client) &&
(TCP_CLIENT(client) ||
((client->inner.attributes & NS_CLIENTATTR_HAVECOOKIE) != 0)))
if ((view != NULL) && (view->padding > 0) && client->inner.wantpad &&
(client->inner.tcp || client->inner.havecookie))
{
isc_netaddr_t netaddr;
int match;
@ -1312,14 +1300,13 @@ process_cookie(ns_client_t *client, isc_buffer_t *buf, size_t optlen) {
/*
* If we have already seen a cookie option skip this cookie option.
*/
if ((!client->manager->sctx->answercookie) ||
(client->inner.attributes & NS_CLIENTATTR_WANTCOOKIE) != 0)
if ((!client->manager->sctx->answercookie) || client->inner.wantcookie)
{
isc_buffer_forward(buf, (unsigned int)optlen);
return;
}
client->inner.attributes |= NS_CLIENTATTR_WANTCOOKIE;
client->inner.wantcookie = true;
ns_stats_increment(client->manager->sctx->nsstats,
ns_statscounter_cookiein);
@ -1338,7 +1325,7 @@ process_cookie(ns_client_t *client, isc_buffer_t *buf, size_t optlen) {
} else {
ns_stats_increment(client->manager->sctx->nsstats,
ns_statscounter_cookiebadsize);
client->inner.attributes |= NS_CLIENTATTR_BADCOOKIE;
client->inner.badcookie = true;
}
return;
}
@ -1372,7 +1359,7 @@ process_cookie(ns_client_t *client, isc_buffer_t *buf, size_t optlen) {
if (isc_serial_gt(when, now + 300) /* In the future. */ ||
isc_serial_lt(when, now - 3600) /* In the past. */)
{
client->inner.attributes |= NS_CLIENTATTR_BADCOOKIE;
client->inner.badcookie = true;
ns_stats_increment(client->manager->sctx->nsstats,
ns_statscounter_cookiebadtime);
return;
@ -1384,7 +1371,7 @@ process_cookie(ns_client_t *client, isc_buffer_t *buf, size_t optlen) {
if (isc_safe_memequal(old, dbuf, COOKIE_SIZE) || alwaysvalid) {
ns_stats_increment(client->manager->sctx->nsstats,
ns_statscounter_cookiematch);
client->inner.attributes |= NS_CLIENTATTR_HAVECOOKIE;
client->inner.havecookie = true;
return;
}
@ -1394,12 +1381,12 @@ process_cookie(ns_client_t *client, isc_buffer_t *buf, size_t optlen) {
if (isc_safe_memequal(old, dbuf, COOKIE_SIZE)) {
ns_stats_increment(client->manager->sctx->nsstats,
ns_statscounter_cookiematch);
client->inner.attributes |= NS_CLIENTATTR_HAVECOOKIE;
client->inner.havecookie = true;
return;
}
}
client->inner.attributes |= NS_CLIENTATTR_BADCOOKIE;
client->inner.badcookie = true;
ns_stats_increment(client->manager->sctx->nsstats,
ns_statscounter_cookienomatch);
}
@ -1413,7 +1400,7 @@ process_ecs(ns_client_t *client, isc_buffer_t *buf, size_t optlen) {
/*
* If we have already seen a ECS option skip this ECS option.
*/
if ((client->inner.attributes & NS_CLIENTATTR_HAVEECS) != 0) {
if (client->inner.haveecs) {
isc_buffer_forward(buf, (unsigned int)optlen);
return ISC_R_SUCCESS;
}
@ -1500,7 +1487,7 @@ process_ecs(ns_client_t *client, isc_buffer_t *buf, size_t optlen) {
memmove(&client->inner.ecs.addr, &caddr, sizeof(caddr));
client->inner.ecs.source = addrlen;
client->inner.ecs.scope = 0;
client->inner.attributes |= NS_CLIENTATTR_HAVEECS;
client->inner.haveecs = true;
isc_buffer_forward(buf, (unsigned int)optlen);
return ISC_R_SUCCESS;
@ -1587,26 +1574,24 @@ process_opt(ns_client_t *client, dns_rdataset_t *opt) {
}
switch (optcode) {
case DNS_OPT_NSID:
if (!WANTNSID(client)) {
if (!client->inner.wantnsid) {
ns_stats_increment(
client->manager->sctx->nsstats,
ns_statscounter_nsidopt);
}
client->inner.attributes |=
NS_CLIENTATTR_WANTNSID;
client->inner.wantnsid = true;
isc_buffer_forward(&optbuf, optlen);
break;
case DNS_OPT_COOKIE:
process_cookie(client, &optbuf, optlen);
break;
case DNS_OPT_EXPIRE:
if (!WANTEXPIRE(client)) {
if (!client->inner.wantexpire) {
ns_stats_increment(
client->manager->sctx->nsstats,
ns_statscounter_expireopt);
}
client->inner.attributes |=
NS_CLIENTATTR_WANTEXPIRE;
client->inner.wantexpire = true;
isc_buffer_forward(&optbuf, optlen);
break;
case DNS_OPT_CLIENT_SUBNET:
@ -1619,20 +1604,18 @@ process_opt(ns_client_t *client, dns_rdataset_t *opt) {
ns_statscounter_ecsopt);
break;
case DNS_OPT_TCP_KEEPALIVE:
if (!USEKEEPALIVE(client)) {
if (!client->inner.usekeepalive) {
ns_stats_increment(
client->manager->sctx->nsstats,
ns_statscounter_keepaliveopt);
}
client->inner.attributes |=
NS_CLIENTATTR_USEKEEPALIVE;
client->inner.usekeepalive = true;
isc_nmhandle_keepalive(client->inner.handle,
true);
isc_buffer_forward(&optbuf, optlen);
break;
case DNS_OPT_PAD:
client->inner.attributes |=
NS_CLIENTATTR_WANTPAD;
client->inner.wantpad = true;
ns_stats_increment(
client->manager->sctx->nsstats,
ns_statscounter_padopt);
@ -1649,15 +1632,16 @@ process_opt(ns_client_t *client, dns_rdataset_t *opt) {
ns_statscounter_keytagopt);
break;
case DNS_OPT_ZONEVERSION:
if (optlen != 0 || WANTZONEVERSION(client)) {
if (optlen != 0 ||
client->inner.wantzoneversion)
{
result = DNS_R_FORMERR;
goto formerr;
}
ns_stats_increment(
client->manager->sctx->nsstats,
ns_statscounter_zoneversionopt);
client->inner.attributes |=
NS_CLIENTATTR_WANTZONEVERSION;
client->inner.wantzoneversion = true;
isc_buffer_forward(&optbuf, optlen);
break;
default:
@ -1674,14 +1658,14 @@ process_opt(ns_client_t *client, dns_rdataset_t *opt) {
ns_stats_increment(client->manager->sctx->nsstats,
ns_statscounter_badednsver);
result = DNS_R_BADVERS;
client->inner.attributes |= NS_CLIENTATTR_WANTOPT;
client->inner.wantopt = true;
ns_client_error(client, result);
return result;
}
ns_stats_increment(client->manager->sctx->nsstats,
ns_statscounter_edns0in);
client->inner.attributes |= NS_CLIENTATTR_WANTOPT;
client->inner.wantopt = true;
return result;
@ -1689,7 +1673,7 @@ formerr:
if (result == DNS_R_OPTERR) {
result = DNS_R_FORMERR;
}
client->inner.attributes |= NS_CLIENTATTR_WANTOPT;
client->inner.wantopt = true;
ns_client_error(client, result);
return result;
}
@ -1872,7 +1856,7 @@ ns_client_request(isc_nmhandle_t *handle, isc_result_t eresult,
}
if (isc_nmhandle_is_stream(handle)) {
client->inner.attributes |= NS_CLIENTATTR_TCP;
client->inner.tcp = true;
}
INSIST(client->inner.state == NS_CLIENTSTATE_READY);
@ -1923,7 +1907,7 @@ ns_client_request(isc_nmhandle_t *handle, isc_result_t eresult,
ns_client_log(client, NS_LOGCATEGORY_CLIENT, NS_LOGMODULE_CLIENT,
ISC_LOG_DEBUG(3), "%s request",
TCP_CLIENT(client) ? "TCP" : "UDP");
client->inner.tcp ? "TCP" : "UDP");
result = dns_message_peekheader(client->inner.buffer, &id, &flags);
if (result != ISC_R_SUCCESS) {
@ -1967,7 +1951,7 @@ ns_client_request(isc_nmhandle_t *handle, isc_result_t eresult,
ns_stats_increment(client->manager->sctx->nsstats,
ns_statscounter_requestv6);
}
if (TCP_CLIENT(client)) {
if (client->inner.tcp) {
ns_stats_increment(client->manager->sctx->nsstats,
ns_statscounter_requesttcp);
switch (isc_sockaddr_pf(&client->inner.peeraddr)) {
@ -2007,7 +1991,7 @@ ns_client_request(isc_nmhandle_t *handle, isc_result_t eresult,
* (typically FORMERR or SERVFAIL).
*/
if (result == DNS_R_OPTERR) {
client->inner.attributes |= NS_CLIENTATTR_WANTOPT;
client->inner.wantopt = true;
}
ns_client_log(client, NS_LOGCATEGORY_CLIENT,
NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1),
@ -2098,8 +2082,7 @@ ns_client_request(isc_nmhandle_t *handle, isc_result_t eresult,
char classbuf[DNS_RDATACLASS_FORMATSIZE];
switch (client->message->rdclass) {
case dns_rdataclass_reserved0:
if ((client->inner.attributes & NS_CLIENTATTR_WANTCOOKIE) !=
0 &&
if (client->inner.wantcookie &&
client->message->opcode == dns_opcode_query &&
client->message->counts[DNS_SECTION_QUESTION] == 0U)
{
@ -2470,7 +2453,7 @@ ns_client_request_continue(void *arg) {
ra_refusal_reason = ALLOW_QUERY_CACHE_ON;
} else {
ra = true;
client->inner.attributes |= NS_CLIENTATTR_RA;
client->inner.ra = true;
}
ns_client_log(client, DNS_LOGCATEGORY_SECURITY, NS_LOGMODULE_CLIENT,
@ -2637,7 +2620,7 @@ ns__client_setup(ns_client_t *client, ns_clientmgr_t *mgr, bool new) {
dns_ede_reset(&client->edectx);
}
client->query.attributes &= ~NS_QUERYATTR_ANSWERED;
client->query.answered = false;
client->inner.state = NS_CLIENTSTATE_INACTIVE;
client->inner.udpsize = 512;
client->inner.ednsversion = -1;
@ -3018,7 +3001,7 @@ ns_client_qnamereplace(ns_client_t *client, dns_name_t *name) {
dns_message_puttempname(client->message, &client->query.qname);
}
client->query.qname = name;
client->query.attributes &= ~NS_QUERYATTR_REDIRECT;
client->query.is_redirect = false;
UNLOCK(&client->query.fetchlock);
}
@ -3078,7 +3061,7 @@ ns_client_newname(ns_client_t *client, isc_buffer_t *dbuf, isc_buffer_t *nbuf) {
dns_name_t *name = NULL;
isc_region_t r;
REQUIRE((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED) == 0);
REQUIRE(!client->query.namebufused);
CTRACE("ns_client_newname");
@ -3087,7 +3070,7 @@ ns_client_newname(ns_client_t *client, isc_buffer_t *dbuf, isc_buffer_t *nbuf) {
isc_buffer_init(nbuf, r.base, r.length);
dns_name_setbuffer(name, NULL);
dns_name_setbuffer(name, nbuf);
client->query.attributes |= NS_QUERYATTR_NAMEBUFUSED;
client->query.namebufused = true;
CTRACE("ns_client_newname: done");
return name;
@ -3131,12 +3114,12 @@ ns_client_keepname(ns_client_t *client, dns_name_t *name, isc_buffer_t *dbuf) {
* 'name' is using space in 'dbuf', but 'dbuf' has not yet been
* adjusted to take account of that. We do the adjustment.
*/
REQUIRE((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED) != 0);
REQUIRE(client->query.namebufused);
dns_name_toregion(name, &r);
isc_buffer_add(dbuf, r.length);
dns_name_setbuffer(name, NULL);
client->query.attributes &= ~NS_QUERYATTR_NAMEBUFUSED;
client->query.namebufused = false;
}
void
@ -3148,7 +3131,7 @@ ns_client_releasename(ns_client_t *client, dns_name_t **namep) {
*/
CTRACE("ns_client_releasename");
client->query.attributes &= ~NS_QUERYATTR_NAMEBUFUSED;
client->query.namebufused = false;
dns_message_puttempname(client->message, namep);
CTRACE("ns_client_releasename: done");
}

View file

@ -166,13 +166,47 @@ struct ns_client {
unsigned int magic;
struct ns_client_inner {
ns_clientstate_t state;
bool async;
unsigned int attributes;
dns_view_t *view;
dns_dispatch_t *dispatch;
isc_nmhandle_t *handle; /* Permanent pointer to handle */
isc_nmhandle_t *sendhandle; /* Waiting for send callback */
isc_nmhandle_t *reqhandle; /* Waiting for request callback
union {
uint8_t attrs[4];
struct {
bool async : 1;
bool tcp : 1;
bool ra : 1; /*%< Client gets recursive service
*/
bool pktinfo : 1; /*%< pktinfo is valid */
bool multicast : 1; /*%< recv'd from multicast
*/
bool wantdnssec : 1; /*%< include dnssec records
*/
bool wantnsid : 1; /*%< include nameserver ID */
bool badcookie : 1; /*%< bad/out-of-date cookie
*/
bool wantrc : 1; /*%< include Report-Channel */
bool wantad : 1; /*%< want AD in response */
bool wantcookie : 1; /*%< return a COOKIE */
bool havecookie : 1; /*%< has a valid COOKIE */
bool wantexpire : 1; /*%< return seconds to
expire */
bool haveexpire : 1; /*%< return seconds to
expire */
bool wantopt : 1; /*%< add opt to reply */
bool haveecs : 1; /*%< received an ECS option */
bool wantpad : 1; /*%< pad reply */
bool usekeepalive : 1; /*%< use TCP keepalive */
bool nosetfc : 1; /*%< don't set servfail cache
*/
bool needtcp : 1; /*%< send TC=1 */
bool wantzoneversion : 1; /*%< return
zoneversion */
bool havezoneversion : 1; /*%< return
zoneversion */
};
};
dns_view_t *view;
dns_dispatch_t *dispatch;
isc_nmhandle_t *handle; /* Permanent pointer to handle */
isc_nmhandle_t *sendhandle; /* Waiting for send callback */
isc_nmhandle_t *reqhandle; /* Waiting for request callback
(query, update, notify) */
isc_nmhandle_t *updatehandle; /* Waiting for update callback */
isc_nmhandle_t *restarthandle; /* Waiting for restart callback
@ -247,32 +281,14 @@ struct ns_client {
uint8_t sendbuf[NS_CLIENT_SEND_BUFFER_SIZE];
};
STATIC_ASSERT(offsetof(ns_client_t, inner.attrs) +
sizeof(((ns_client_t *)0)->inner.attrs) ==
offsetof(ns_client_t, inner.view),
"ns_query.attrs[] must cover the flags bitfield");
#define NS_CLIENT_MAGIC ISC_MAGIC('N', 'S', 'C', 'c')
#define NS_CLIENT_VALID(c) ISC_MAGIC_VALID(c, NS_CLIENT_MAGIC)
#define NS_CLIENTATTR_TCP 0x000001
#define NS_CLIENTATTR_RA 0x000002 /*%< Client gets recursive service */
#define NS_CLIENTATTR_PKTINFO 0x000004 /*%< pktinfo is valid */
#define NS_CLIENTATTR_MULTICAST 0x000008 /*%< recv'd from multicast */
#define NS_CLIENTATTR_WANTDNSSEC 0x000010 /*%< include dnssec records */
#define NS_CLIENTATTR_WANTNSID 0x000020 /*%< include nameserver ID */
#define NS_CLIENTATTR_BADCOOKIE \
0x000040 /*%< Presented cookie is bad/out-of-date */
#define NS_CLIENTATTR_WANTRC 0x000080 /*%< include Report-Channel */
#define NS_CLIENTATTR_WANTAD 0x000100 /*%< want AD in response if possible */
#define NS_CLIENTATTR_WANTCOOKIE 0x000200 /*%< return a COOKIE */
#define NS_CLIENTATTR_HAVECOOKIE 0x000400 /*%< has a valid COOKIE */
#define NS_CLIENTATTR_WANTEXPIRE 0x000800 /*%< return seconds to expire */
#define NS_CLIENTATTR_HAVEEXPIRE 0x001000 /*%< return seconds to expire */
#define NS_CLIENTATTR_WANTOPT 0x002000 /*%< add opt to reply */
#define NS_CLIENTATTR_HAVEECS 0x004000 /*%< received an ECS option */
#define NS_CLIENTATTR_WANTPAD 0x008000 /*%< pad reply */
#define NS_CLIENTATTR_USEKEEPALIVE 0x010000 /*%< use TCP keepalive */
#define NS_CLIENTATTR_NOSETFC 0x020000 /*%< don't set servfail cache */
#define NS_CLIENTATTR_NEEDTCP 0x040000 /*%< send TC=1 */
#define NS_CLIENTATTR_WANTZONEVERSION 0x100000 /*%< return zoneversion */
#define NS_CLIENTATTR_HAVEZONEVERSION 0x200000 /*%< return zoneversion */
/*
* Flag to use with the SERVFAIL cache to indicate
* that a query had the CD bit set.

View file

@ -103,7 +103,30 @@ typedef struct ns_query_recparam {
/*% nameserver query structure */
struct ns_query {
unsigned int attributes;
union {
uint8_t attrs[4];
struct {
bool recursionok : 1;
bool cacheok : 1;
bool partialanswer : 1;
bool namebufused : 1;
bool recursing : 1;
bool queryokvalid : 1;
bool queryok : 1;
bool wantrecursion : 1;
bool secure : 1;
bool noauthority : 1;
bool noadditional : 1;
bool cacheaclokvalid : 1;
bool cacheaclok : 1;
bool dns64 : 1;
bool dns64exclude : 1;
bool rrl_checked : 1;
bool is_redirect : 1;
bool answered : 1;
};
};
unsigned int restarts;
isc_counter_t *qc;
bool timerset;
@ -156,24 +179,10 @@ struct ns_query {
bool root_key_sentinel_not_ta;
};
#define NS_QUERYATTR_RECURSIONOK 0x000001
#define NS_QUERYATTR_CACHEOK 0x000002
#define NS_QUERYATTR_PARTIALANSWER 0x000004
#define NS_QUERYATTR_NAMEBUFUSED 0x000008
#define NS_QUERYATTR_RECURSING 0x000010
#define NS_QUERYATTR_QUERYOKVALID 0x000040
#define NS_QUERYATTR_QUERYOK 0x000080
#define NS_QUERYATTR_WANTRECURSION 0x000100
#define NS_QUERYATTR_SECURE 0x000200
#define NS_QUERYATTR_NOAUTHORITY 0x000400
#define NS_QUERYATTR_NOADDITIONAL 0x000800
#define NS_QUERYATTR_CACHEACLOKVALID 0x001000
#define NS_QUERYATTR_CACHEACLOK 0x002000
#define NS_QUERYATTR_DNS64 0x004000
#define NS_QUERYATTR_DNS64EXCLUDE 0x008000
#define NS_QUERYATTR_RRL_CHECKED 0x010000
#define NS_QUERYATTR_REDIRECT 0x020000
#define NS_QUERYATTR_ANSWERED 0x040000
STATIC_ASSERT(offsetof(ns_query_t, attrs) +
sizeof(((struct ns_query *)0)->attrs) ==
offsetof(struct ns_query, restarts),
"ns_query.attrs[] must cover the flags bitfield");
typedef struct query_ctx query_ctx_t;

File diff suppressed because it is too large Load diff

View file

@ -180,12 +180,6 @@
goto cleanup; \
} while (0)
/*
* Return TRUE if NS_CLIENTATTR_TCP is set in the attributes other FALSE.
*/
#define TCPCLIENT(client) \
(((client)->inner.attributes & NS_CLIENTATTR_TCP) != 0)
/**************************************************************************/
typedef struct rr rr_t;
@ -1649,7 +1643,7 @@ send_update(ns_client_t *client, dns_zone_t *zone) {
CHECK(checkupdateacl(client, dns_zone_getupdateacl(zone),
"update", dns_zone_getorigin(zone), false,
false));
} else if (client->inner.signer == NULL && !TCPCLIENT(client)) {
} else if (client->inner.signer == NULL && !client->inner.tcp) {
CHECK(checkupdateacl(client, NULL, "update",
dns_zone_getorigin(zone), false, true));
}
@ -1789,7 +1783,7 @@ send_update(ns_client_t *client, dns_zone_t *zone) {
ssuinfo.signer = client->inner.signer;
ssuinfo.addr = &netaddr;
ssuinfo.aclenv = env;
ssuinfo.tcp = TCPCLIENT(client);
ssuinfo.tcp = client->inner.tcp;
ssuinfo.key = tsigkey;
result = foreach_rr(db, ver, name, rdata.type,
@ -1807,7 +1801,7 @@ send_update(ns_client_t *client, dns_zone_t *zone) {
if (flag &&
!dns_ssutable_checkrules(
ssutable, client->inner.signer,
name, &netaddr, TCPCLIENT(client),
name, &netaddr, client->inner.tcp,
env, rdata.type, target, tsigkey,
NULL))
{
@ -1818,7 +1812,7 @@ send_update(ns_client_t *client, dns_zone_t *zone) {
const dns_ssurule_t *ssurule = NULL;
if (!dns_ssutable_checkrules(
ssutable, client->inner.signer,
name, &netaddr, TCPCLIENT(client),
name, &netaddr, client->inner.tcp,
env, rdata.type, target, tsigkey,
&ssurule))
{
@ -1831,7 +1825,7 @@ send_update(ns_client_t *client, dns_zone_t *zone) {
if (!ssu_checkall(db, ver, name, ssutable,
client->inner.signer,
&netaddr, env,
TCPCLIENT(client), tsigkey))
client->inner.tcp, tsigkey))
{
FAILC(DNS_R_REFUSED,
"rejected by secure update");

View file

@ -907,9 +907,7 @@ got_soa:
/*
* AXFR over UDP is not possible.
*/
if (reqtype == dns_rdatatype_axfr &&
(client->inner.attributes & NS_CLIENTATTR_TCP) == 0)
{
if (reqtype == dns_rdatatype_axfr && !client->inner.tcp) {
FAILC(DNS_R_FORMERR, "attempted AXFR over UDP");
}
@ -972,7 +970,7 @@ got_soa:
* IXFR over UDP (currently, we always do).
*/
if (DNS_SERIAL_GE(begin_serial, current_serial) ||
(client->inner.attributes & NS_CLIENTATTR_TCP) == 0)
!client->inner.tcp)
{
CHECK(soa_rrstream_create(mctx, db, ver, &stream));
is_poll = true;
@ -983,7 +981,7 @@ got_soa:
* Outgoing IXFR may have been disabled for this peer
* or globally.
*/
if ((client->inner.attributes & NS_CLIENTATTR_TCP) != 0) {
if (client->inner.tcp) {
bool provide_ixfr;
provide_ixfr = client->inner.view->provideixfr;
@ -1116,8 +1114,7 @@ have_stream:
if (zone != NULL) {
dns_zone_getraw(zone, &raw);
mayberaw = (raw != NULL) ? raw : zone;
if ((client->inner.attributes & NS_CLIENTATTR_WANTEXPIRE) !=
0 &&
if (client->inner.wantexpire &&
(dns_zone_gettype(mayberaw) == dns_zone_secondary ||
dns_zone_gettype(mayberaw) == dns_zone_mirror))
{
@ -1128,8 +1125,7 @@ have_stream:
if (secs >= client->inner.now &&
result == ISC_R_SUCCESS)
{
client->inner.attributes |=
NS_CLIENTATTR_HAVEEXPIRE;
client->inner.haveexpire = true;
client->inner.expire = secs - client->inner.now;
}
}
@ -1279,8 +1275,7 @@ xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client, unsigned int id,
static void
xfrout_send(xfrout_ctx_t *xfr) {
const bool is_tcp =
((xfr->client->inner.attributes & NS_CLIENTATTR_TCP) != 0);
const bool is_tcp = xfr->client->inner.tcp;
if (is_tcp) {
isc_region_t used;
@ -1371,7 +1366,7 @@ sendstream(xfrout_ctx_t *xfr) {
isc_buffer_clear(&xfr->buf);
isc_buffer_clear(&xfr->txbuf);
is_tcp = ((xfr->client->inner.attributes & NS_CLIENTATTR_TCP) != 0);
is_tcp = xfr->client->inner.tcp;
if (!is_tcp) {
/*
* In the UDP case, we put the response data directly into
@ -1395,7 +1390,7 @@ sendstream(xfrout_ctx_t *xfr) {
msg->id = xfr->id;
msg->rcode = dns_rcode_noerror;
msg->flags = DNS_MESSAGEFLAG_QR | DNS_MESSAGEFLAG_AA;
if ((xfr->client->inner.attributes & NS_CLIENTATTR_RA) != 0) {
if (xfr->client->inner.ra) {
msg->flags |= DNS_MESSAGEFLAG_RA;
}
CHECK(dns_message_settsigkey(msg, xfr->tsigkey));
@ -1408,17 +1403,13 @@ sendstream(xfrout_ctx_t *xfr) {
/*
* Add a EDNS option to the message?
*/
if ((xfr->client->inner.attributes & NS_CLIENTATTR_WANTOPT) !=
0)
{
if (xfr->client->inner.wantopt) {
CHECK(ns_client_addopt(xfr->client, msg));
/*
* Add to first message only.
*/
xfr->client->inner.attributes &=
~NS_CLIENTATTR_WANTNSID;
xfr->client->inner.attributes &=
~NS_CLIENTATTR_HAVEEXPIRE;
xfr->client->inner.wantnsid = false;
xfr->client->inner.haveexpire = false;
}
/*
@ -1671,7 +1662,7 @@ static void
xfrout_senddone(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
xfrout_ctx_t *xfr = (xfrout_ctx_t *)arg;
REQUIRE((xfr->client->inner.attributes & NS_CLIENTATTR_TCP) != 0);
REQUIRE(xfr->client->inner.tcp);
INSIST(handle == xfr->client->inner.handle);

View file

@ -438,11 +438,11 @@ ns_test_qctx_create(const ns_test_qctx_create_params_t *params,
}
/*
* Allow recursion for the client. As NS_CLIENTATTR_RA normally gets
* set in ns_client_request(), i.e. earlier than the unit tests hook
* Allow recursion for the client. As inner.ra normally gets set
* in ns_client_request(), i.e. earlier than the unit tests hook
* into the call chain, just set it manually.
*/
client->inner.attributes |= NS_CLIENTATTR_RA;
client->inner.ra = true;
/*
* Create a query context for a client sending the previously