2017-09-08 13:39:09 -07:00
|
|
|
/*
|
|
|
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: MPL-2.0
|
2021-06-03 08:37:05 +02:00
|
|
|
*
|
2017-09-08 13:39:09 -07:00
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
2018-02-23 09:53:12 +01:00
|
|
|
*
|
2017-09-08 13:39:09 -07:00
|
|
|
* See the COPYRIGHT file distributed with this work for additional
|
|
|
|
* information regarding copyright ownership.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*! \file */
|
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
#include <stdbool.h>
|
|
|
|
|
2017-09-08 13:39:09 -07:00
|
|
|
#include <isc/mem.h>
|
|
|
|
#include <isc/stats.h>
|
2017-10-19 12:26:32 +11:00
|
|
|
#include <isc/util.h>
|
2017-09-08 13:39:09 -07:00
|
|
|
|
|
|
|
#include <dns/stats.h>
|
|
|
|
#include <dns/tkey.h>
|
|
|
|
|
2018-08-06 19:34:20 -07:00
|
|
|
#include <ns/query.h>
|
2017-09-08 13:39:09 -07:00
|
|
|
#include <ns/server.h>
|
|
|
|
#include <ns/stats.h>
|
|
|
|
|
|
|
|
#define SCTX_MAGIC ISC_MAGIC('S', 'c', 't', 'x')
|
|
|
|
#define SCTX_VALID(s) ISC_MAGIC_VALID(s, SCTX_MAGIC)
|
|
|
|
|
|
|
|
#define CHECKFATAL(op) \
|
|
|
|
do { \
|
|
|
|
result = (op); \
|
|
|
|
RUNTIME_CHECK(result == ISC_R_SUCCESS); \
|
|
|
|
} while (0)
|
|
|
|
|
2023-06-26 11:09:26 +02:00
|
|
|
void
|
2018-04-22 14:56:28 +02:00
|
|
|
ns_server_create(isc_mem_t *mctx, ns_matchview_t matchingview,
|
|
|
|
ns_server_t **sctxp) {
|
2024-06-25 14:30:20 -07:00
|
|
|
ns_server_t *sctx = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
|
|
|
|
REQUIRE(sctxp != NULL && *sctxp == NULL);
|
|
|
|
|
2022-08-26 11:58:51 +02:00
|
|
|
sctx = isc_mem_get(mctx, sizeof(*sctx));
|
|
|
|
*sctx = (ns_server_t){
|
|
|
|
.udpsize = 1232,
|
|
|
|
.transfer_tcp_message_size = 20480,
|
|
|
|
|
|
|
|
.fuzztype = isc_fuzz_none,
|
|
|
|
|
|
|
|
.matchingview = matchingview,
|
|
|
|
.answercookie = true,
|
|
|
|
};
|
2017-09-08 13:39:09 -07:00
|
|
|
|
|
|
|
isc_mem_attach(mctx, &sctx->mctx);
|
|
|
|
|
2023-08-10 23:08:25 +03:00
|
|
|
/*
|
|
|
|
* See here for more details:
|
|
|
|
* https://github.com/jemalloc/jemalloc/issues/2483
|
|
|
|
*/
|
|
|
|
|
2018-08-01 11:46:11 +02:00
|
|
|
isc_refcount_init(&sctx->references, 1);
|
2017-09-08 13:39:09 -07:00
|
|
|
|
2018-11-16 15:45:01 +01:00
|
|
|
isc_quota_init(&sctx->xfroutquota, 10);
|
|
|
|
isc_quota_init(&sctx->tcpquota, 10);
|
|
|
|
isc_quota_init(&sctx->recursionquota, 100);
|
2022-09-01 16:05:04 -07:00
|
|
|
isc_quota_init(&sctx->updquota, 100);
|
2024-03-25 11:07:47 +00:00
|
|
|
isc_quota_init(&sctx->sig0checksquota, 1);
|
Add (http-)listener-clients option (DoH quota mechanism)
This commit adds support for http-listener-clients global options as
well as ability to override the default in an HTTP server description,
like:
http local-http-server {
...
listener-clients 100;
...
};
This way we have ability to specify per-listener active connections
quota globally and then override it when required. This is exactly
what AT&T requested us: they wanted a functionality to specify quota
globally and then override it for specific IPs. This change
functionality makes such a configuration possible.
It makes sense: for example, one could have different quotas for
internal and external clients. Or, for example, one could use BIND's
internal ability to serve encrypted DoH with some sane quota value for
internal clients, while having un-encrypted DoH listener without quota
to put BIND behind a load balancer doing TLS offloading for external
clients.
Moreover, the code no more shares the quota with TCP, which makes
little sense anyway (see tcp-clients option), because of the nature of
interaction of DoH clients: they tend to keep idle opened connections
for longer periods of time, preventing the TCP and TLS client from
being served. Thus, the need to have a separate, generally larger,
quota for them.
Also, the change makes any option within "http <name> { ... };"
statement optional, making it easier to override only required default
options.
By default, the DoH connections are limited to 300 per listener. I
hope that it is a good initial guesstimate.
2021-05-14 14:18:57 +03:00
|
|
|
ISC_LIST_INIT(sctx->http_quotas);
|
2022-06-22 14:52:58 +03:00
|
|
|
isc_mutex_init(&sctx->http_quotas_lock);
|
2017-09-08 13:39:09 -07:00
|
|
|
|
2023-06-26 10:58:30 +02:00
|
|
|
ns_stats_create(mctx, ns_statscounter_max, &sctx->nsstats);
|
2017-09-08 13:39:09 -07:00
|
|
|
|
2023-06-26 10:58:30 +02:00
|
|
|
dns_rdatatypestats_create(mctx, &sctx->rcvquerystats);
|
2017-09-08 13:39:09 -07:00
|
|
|
|
2023-06-26 10:58:30 +02:00
|
|
|
dns_opcodestats_create(mctx, &sctx->opcodestats);
|
2017-09-08 13:39:09 -07:00
|
|
|
|
2023-06-26 10:58:30 +02:00
|
|
|
dns_rcodestats_create(mctx, &sctx->rcodestats);
|
2017-09-08 13:39:09 -07:00
|
|
|
|
2023-03-16 14:31:46 +00:00
|
|
|
isc_histomulti_create(mctx, DNS_SIZEHISTO_SIGBITSIN,
|
|
|
|
&sctx->udpinstats4);
|
2017-09-08 13:39:09 -07:00
|
|
|
|
2023-03-16 14:31:46 +00:00
|
|
|
isc_histomulti_create(mctx, DNS_SIZEHISTO_SIGBITSOUT,
|
|
|
|
&sctx->udpoutstats4);
|
2017-09-08 13:39:09 -07:00
|
|
|
|
2023-03-16 14:31:46 +00:00
|
|
|
isc_histomulti_create(mctx, DNS_SIZEHISTO_SIGBITSIN,
|
|
|
|
&sctx->udpinstats6);
|
2017-09-08 13:39:09 -07:00
|
|
|
|
2023-03-16 14:31:46 +00:00
|
|
|
isc_histomulti_create(mctx, DNS_SIZEHISTO_SIGBITSOUT,
|
|
|
|
&sctx->udpoutstats6);
|
2017-09-08 13:39:09 -07:00
|
|
|
|
2023-03-16 14:31:46 +00:00
|
|
|
isc_histomulti_create(mctx, DNS_SIZEHISTO_SIGBITSIN,
|
|
|
|
&sctx->tcpinstats4);
|
2017-09-08 13:39:09 -07:00
|
|
|
|
2023-03-16 14:31:46 +00:00
|
|
|
isc_histomulti_create(mctx, DNS_SIZEHISTO_SIGBITSOUT,
|
|
|
|
&sctx->tcpoutstats4);
|
2017-09-08 13:39:09 -07:00
|
|
|
|
2023-03-16 14:31:46 +00:00
|
|
|
isc_histomulti_create(mctx, DNS_SIZEHISTO_SIGBITSIN,
|
|
|
|
&sctx->tcpinstats6);
|
2017-09-08 13:39:09 -07:00
|
|
|
|
2023-03-16 14:31:46 +00:00
|
|
|
isc_histomulti_create(mctx, DNS_SIZEHISTO_SIGBITSOUT,
|
|
|
|
&sctx->tcpoutstats6);
|
2017-09-08 13:39:09 -07:00
|
|
|
|
|
|
|
ISC_LIST_INIT(sctx->altsecrets);
|
|
|
|
|
|
|
|
sctx->magic = SCTX_MAGIC;
|
|
|
|
*sctxp = sctx;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ns_server_attach(ns_server_t *src, ns_server_t **dest) {
|
|
|
|
REQUIRE(SCTX_VALID(src));
|
|
|
|
REQUIRE(dest != NULL && *dest == NULL);
|
|
|
|
|
2018-08-17 15:16:59 +02:00
|
|
|
isc_refcount_increment(&src->references);
|
2017-09-08 13:39:09 -07:00
|
|
|
|
|
|
|
*dest = src;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ns_server_detach(ns_server_t **sctxp) {
|
|
|
|
ns_server_t *sctx;
|
|
|
|
|
2018-08-28 10:18:59 +02:00
|
|
|
REQUIRE(sctxp != NULL && SCTX_VALID(*sctxp));
|
2017-09-08 13:39:09 -07:00
|
|
|
sctx = *sctxp;
|
2018-08-28 10:18:59 +02:00
|
|
|
*sctxp = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
|
2018-08-17 15:16:59 +02:00
|
|
|
if (isc_refcount_decrement(&sctx->references) == 1) {
|
2025-05-23 13:02:22 -07:00
|
|
|
ISC_LIST_FOREACH (sctx->altsecrets, altsecret, link) {
|
2017-09-08 13:39:09 -07:00
|
|
|
ISC_LIST_UNLINK(sctx->altsecrets, altsecret, link);
|
|
|
|
isc_mem_put(sctx->mctx, altsecret, sizeof(*altsecret));
|
|
|
|
}
|
|
|
|
|
2024-03-25 11:07:47 +00:00
|
|
|
if (sctx->sig0checksquota_exempt != NULL) {
|
|
|
|
dns_acl_detach(&sctx->sig0checksquota_exempt);
|
|
|
|
}
|
|
|
|
|
|
|
|
isc_quota_destroy(&sctx->sig0checksquota);
|
2022-09-01 16:05:04 -07:00
|
|
|
isc_quota_destroy(&sctx->updquota);
|
2017-09-08 13:39:09 -07:00
|
|
|
isc_quota_destroy(&sctx->recursionquota);
|
|
|
|
isc_quota_destroy(&sctx->tcpquota);
|
|
|
|
isc_quota_destroy(&sctx->xfroutquota);
|
|
|
|
|
2025-05-23 13:02:22 -07:00
|
|
|
ISC_LIST_FOREACH (sctx->http_quotas, http_quota, link) {
|
Add (http-)listener-clients option (DoH quota mechanism)
This commit adds support for http-listener-clients global options as
well as ability to override the default in an HTTP server description,
like:
http local-http-server {
...
listener-clients 100;
...
};
This way we have ability to specify per-listener active connections
quota globally and then override it when required. This is exactly
what AT&T requested us: they wanted a functionality to specify quota
globally and then override it for specific IPs. This change
functionality makes such a configuration possible.
It makes sense: for example, one could have different quotas for
internal and external clients. Or, for example, one could use BIND's
internal ability to serve encrypted DoH with some sane quota value for
internal clients, while having un-encrypted DoH listener without quota
to put BIND behind a load balancer doing TLS offloading for external
clients.
Moreover, the code no more shares the quota with TCP, which makes
little sense anyway (see tcp-clients option), because of the nature of
interaction of DoH clients: they tend to keep idle opened connections
for longer periods of time, preventing the TCP and TLS client from
being served. Thus, the need to have a separate, generally larger,
quota for them.
Also, the change makes any option within "http <name> { ... };"
statement optional, making it easier to override only required default
options.
By default, the DoH connections are limited to 300 per listener. I
hope that it is a good initial guesstimate.
2021-05-14 14:18:57 +03:00
|
|
|
ISC_LIST_DEQUEUE(sctx->http_quotas, http_quota, link);
|
|
|
|
isc_quota_destroy(http_quota);
|
|
|
|
isc_mem_put(sctx->mctx, http_quota,
|
|
|
|
sizeof(*http_quota));
|
|
|
|
}
|
2022-06-22 14:52:58 +03:00
|
|
|
isc_mutex_destroy(&sctx->http_quotas_lock);
|
Add (http-)listener-clients option (DoH quota mechanism)
This commit adds support for http-listener-clients global options as
well as ability to override the default in an HTTP server description,
like:
http local-http-server {
...
listener-clients 100;
...
};
This way we have ability to specify per-listener active connections
quota globally and then override it when required. This is exactly
what AT&T requested us: they wanted a functionality to specify quota
globally and then override it for specific IPs. This change
functionality makes such a configuration possible.
It makes sense: for example, one could have different quotas for
internal and external clients. Or, for example, one could use BIND's
internal ability to serve encrypted DoH with some sane quota value for
internal clients, while having un-encrypted DoH listener without quota
to put BIND behind a load balancer doing TLS offloading for external
clients.
Moreover, the code no more shares the quota with TCP, which makes
little sense anyway (see tcp-clients option), because of the nature of
interaction of DoH clients: they tend to keep idle opened connections
for longer periods of time, preventing the TCP and TLS client from
being served. Thus, the need to have a separate, generally larger,
quota for them.
Also, the change makes any option within "http <name> { ... };"
statement optional, making it easier to override only required default
options.
By default, the DoH connections are limited to 300 per listener. I
hope that it is a good initial guesstimate.
2021-05-14 14:18:57 +03:00
|
|
|
|
2019-07-04 15:45:06 +02:00
|
|
|
if (sctx->server_id != NULL) {
|
2017-09-08 13:39:09 -07:00
|
|
|
isc_mem_free(sctx->mctx, sctx->server_id);
|
2019-07-04 15:45:06 +02:00
|
|
|
}
|
2017-09-08 13:39:09 -07:00
|
|
|
|
2019-07-04 15:45:06 +02:00
|
|
|
if (sctx->blackholeacl != NULL) {
|
2017-09-08 13:39:09 -07:00
|
|
|
dns_acl_detach(&sctx->blackholeacl);
|
2019-07-04 15:45:06 +02:00
|
|
|
}
|
|
|
|
if (sctx->tkeyctx != NULL) {
|
2017-09-08 13:39:09 -07:00
|
|
|
dns_tkeyctx_destroy(&sctx->tkeyctx);
|
2019-07-04 15:45:06 +02:00
|
|
|
}
|
2017-09-08 13:39:09 -07:00
|
|
|
|
2019-07-04 15:45:06 +02:00
|
|
|
if (sctx->nsstats != NULL) {
|
2017-09-08 13:39:09 -07:00
|
|
|
ns_stats_detach(&sctx->nsstats);
|
2019-07-04 15:45:06 +02:00
|
|
|
}
|
2017-09-08 13:39:09 -07:00
|
|
|
|
2019-07-04 15:45:06 +02:00
|
|
|
if (sctx->rcvquerystats != NULL) {
|
2017-09-08 13:39:09 -07:00
|
|
|
dns_stats_detach(&sctx->rcvquerystats);
|
2019-07-04 15:45:06 +02:00
|
|
|
}
|
|
|
|
if (sctx->opcodestats != NULL) {
|
2017-09-08 13:39:09 -07:00
|
|
|
dns_stats_detach(&sctx->opcodestats);
|
2019-07-04 15:45:06 +02:00
|
|
|
}
|
|
|
|
if (sctx->rcodestats != NULL) {
|
2017-09-08 13:39:09 -07:00
|
|
|
dns_stats_detach(&sctx->rcodestats);
|
2019-07-04 15:45:06 +02:00
|
|
|
}
|
2017-09-08 13:39:09 -07:00
|
|
|
|
2019-07-04 15:45:06 +02:00
|
|
|
if (sctx->udpinstats4 != NULL) {
|
2023-03-16 14:31:46 +00:00
|
|
|
isc_histomulti_destroy(&sctx->udpinstats4);
|
2019-07-04 15:45:06 +02:00
|
|
|
}
|
|
|
|
if (sctx->tcpinstats4 != NULL) {
|
2023-03-16 14:31:46 +00:00
|
|
|
isc_histomulti_destroy(&sctx->tcpinstats4);
|
2019-07-04 15:45:06 +02:00
|
|
|
}
|
|
|
|
if (sctx->udpoutstats4 != NULL) {
|
2023-03-16 14:31:46 +00:00
|
|
|
isc_histomulti_destroy(&sctx->udpoutstats4);
|
2019-07-04 15:45:06 +02:00
|
|
|
}
|
|
|
|
if (sctx->tcpoutstats4 != NULL) {
|
2023-03-16 14:31:46 +00:00
|
|
|
isc_histomulti_destroy(&sctx->tcpoutstats4);
|
2019-07-04 15:45:06 +02:00
|
|
|
}
|
2017-09-08 13:39:09 -07:00
|
|
|
|
2019-07-04 15:45:06 +02:00
|
|
|
if (sctx->udpinstats6 != NULL) {
|
2023-03-16 14:31:46 +00:00
|
|
|
isc_histomulti_destroy(&sctx->udpinstats6);
|
2019-07-04 15:45:06 +02:00
|
|
|
}
|
|
|
|
if (sctx->tcpinstats6 != NULL) {
|
2023-03-16 14:31:46 +00:00
|
|
|
isc_histomulti_destroy(&sctx->tcpinstats6);
|
2019-07-04 15:45:06 +02:00
|
|
|
}
|
|
|
|
if (sctx->udpoutstats6 != NULL) {
|
2023-03-16 14:31:46 +00:00
|
|
|
isc_histomulti_destroy(&sctx->udpoutstats6);
|
2019-07-04 15:45:06 +02:00
|
|
|
}
|
|
|
|
if (sctx->tcpoutstats6 != NULL) {
|
2023-03-16 14:31:46 +00:00
|
|
|
isc_histomulti_destroy(&sctx->tcpoutstats6);
|
2019-07-04 15:45:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
sctx->magic = 0;
|
2017-09-08 13:39:09 -07:00
|
|
|
|
|
|
|
isc_mem_putanddetach(&sctx->mctx, sctx, sizeof(*sctx));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
isc_result_t
|
|
|
|
ns_server_setserverid(ns_server_t *sctx, const char *serverid) {
|
|
|
|
REQUIRE(SCTX_VALID(sctx));
|
|
|
|
|
|
|
|
if (sctx->server_id != NULL) {
|
|
|
|
isc_mem_free(sctx->mctx, sctx->server_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (serverid != NULL) {
|
|
|
|
sctx->server_id = isc_mem_strdup(sctx->mctx, serverid);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ISC_R_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ns_server_setoption(ns_server_t *sctx, unsigned int option, bool value) {
|
|
|
|
REQUIRE(SCTX_VALID(sctx));
|
|
|
|
if (value) {
|
|
|
|
sctx->options |= option;
|
|
|
|
} else {
|
|
|
|
sctx->options &= ~option;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
bool
|
2017-09-08 13:39:09 -07:00
|
|
|
ns_server_getoption(ns_server_t *sctx, unsigned int option) {
|
|
|
|
REQUIRE(SCTX_VALID(sctx));
|
|
|
|
|
2018-10-11 11:57:57 +02:00
|
|
|
return (sctx->options & option) != 0;
|
2017-09-08 13:39:09 -07:00
|
|
|
}
|
2022-06-22 14:52:58 +03:00
|
|
|
|
|
|
|
void
|
|
|
|
ns_server_append_http_quota(ns_server_t *sctx, isc_quota_t *http_quota) {
|
|
|
|
REQUIRE(SCTX_VALID(sctx));
|
|
|
|
REQUIRE(http_quota != NULL);
|
|
|
|
|
|
|
|
LOCK(&sctx->http_quotas_lock);
|
|
|
|
ISC_LINK_INIT(http_quota, link);
|
|
|
|
ISC_LIST_APPEND(sctx->http_quotas, http_quota, link);
|
|
|
|
UNLOCK(&sctx->http_quotas_lock);
|
|
|
|
}
|