Compare commits

...
Author SHA1 Message Date
Ondřej SurýandArtem Boldariev b6889fbf10 WIP: Add preliminary DoH client support to dig 2021-02-02 20:20:10 +02:00
Ondřej SurýandArtem Boldariev 81340a9ee0 Unit-test fixes and manual page updates for DoH configuration
This commit contains fixes to unit tests to make them work well on
various platforms (in particular ones shipping old versions of
OpenSSL) and fo different configurations.

It also updates the generated manpage to include DoH configuration
options.
2021-02-02 20:20:10 +02:00
Artem Boldariev bc1b832603 Initial support for DNS-over-HTTP(S)
This commit completes the support for DNS-over-HTTP(S) built on top of
nghttp2 and plugs it into the BIND. Support for both GET and POST
requests is present, as required by RFC8484.

Both encrypted (via TLS) and unencrypted HTTP/2 connections are
supported. The latter are mostly there for debugging/troubleshooting
purposes and for the means of encryption offloading to third-party
software (as might be desirable in some environments to simplify TLS
certificates management).
2021-02-02 20:20:01 +02:00
Witold KręcickiandArtem Boldariev 16966e5174 nghttp2-based HTTP layer in netmgr
This commit includes work-in-progress implementation of
DNS-over-HTTP(S).

Server-side code remains mostly untested, and there is only support
for POST requests.
2021-02-02 20:02:13 +02:00
Witold KręcickiandArtem Boldariev ba72d6f015 Add isc_mem_strndup() function
This commit adds an implementation of strndup() function which
allocates memory from the supplied isc_mem_t memory context.
2021-02-02 19:53:34 +02:00
Evan HuntandArtem Boldariev 37f81ca5fb Add parser support for DoH configuration options
This commit adds stub parser support and tests for:
- an "https-server" global option for HTTP/2 configuration.
- an "https-endpoint" view option for DoH configuration.
- add specific -p options to set dns, tls, or https port numbers by
  specifying -p dns-PORT, -p tls=PORT, or -p https=PORT.  NOTE: this
  change only affects syntax; specifying the TLS port on the command
  line DOES NOT CURRENTLY HAVE ANY EFFECT.
- change option names to tls-port and https-port for consistency.
- change variable names in system tests to TLSPORT and HTTPSPORT,
  and report them when running tests.

Documentation for these options has also been added to the ARM, but
needs further work.
2021-02-02 19:44:52 +02:00
Artem Boldariev fcb0b6a781 Resurrect old TLS code
This commit resurrects the old TLS code from
8f73c70d23.

It also includes numerous stability fixes and support for
isc_nm_cancelread() for the TLS layer.

The code was resurrected to be used for DoH.
2021-02-02 19:29:56 +02:00
Ondřej Surý 48a89e5fbe Merge branch '2444-call-freeaddrinfo-in-test_client' into 'main'
Fix addrinfo leak in test_client.c

Closes #2444

See merge request isc-projects/bind9!4629
2021-01-29 14:54:42 +00:00
Ondřej Surý 6aa4d59526 Fix addrinfo leak in test_client.c
The addrinfo we got from getaddrinfo() was never freed.
2021-01-29 13:26:28 +01:00
Ondřej Surý b42137c453 Merge branch '2392-xot-xfrin' into 'main'
Add support for incoming tranfers via XoT

Closes #2392

See merge request isc-projects/bind9!4571
2021-01-29 11:55:16 +00:00
Evan HuntandOndřej Surý 220bca9ebf CHANGES and release notes 2021-01-29 12:07:38 +01:00
Ondřej Surý e488309da7 implement xfrin via XoT
Add support for a "tls" key/value pair for zone primaries, referencing
either a "tls" configuration statement or "ephemeral". If set to use
TLS, zones will send SOA and AXFR/IXFR queries over a TLS channel.
2021-01-29 12:07:38 +01:00
Matthijs Mekking 778d0c03a9 Merge branch '2442-tsan-error-lib-dns-rbtdb-c' into 'main'
Resolve "TSAN error: lib/dns/rbtdb.c"

Closes #2442

See merge request isc-projects/bind9!4609
2021-01-29 10:45:40 +00:00
Diego FronzaandMatthijs Mekking c75575e350 Fix race condition on check_stale_header
This commit fix a race that could happen when two or more threads have
failed to refresh the same RRset, the threads could simultaneously
attempt to update the header->last_refresh_fail_ts field in
check_stale_header, a field used to implement stale-refresh-time.

By making this field atomic we avoid such race.
2021-01-29 10:29:51 +01:00
Matthijs Mekking 0fab6cf88e Merge branch '2434-fetch-limit-serve-stale' into 'main'
Resolve "Serve stale when fetch limits are hit"

Closes #2434

See merge request isc-projects/bind9!4607
2021-01-28 16:57:20 +00:00
Matthijs Mekking ed8421693c Add notes and change entry for [#2434]
This concludes the serve-stale improvements.
2021-01-28 17:02:56 +01:00
Matthijs Mekking 11b74fc176 Add test for serve-stale /w fetch-limits
Add a test case when fetch-limits are reached and we have stale data
in cache.

This test starts with a positive answer for 'data.example/TXT' in
cache.

1. Reload named.conf to set fetch limits.
2. Disable responses from the authoritative server.
3. Now send a batch of queries to the resolver, until hitting the
   fetch limits. We can detect this by looking at the response RCODE,
   at some point we will see SERVFAIL responses.
4. At that point we will turn on serve-stale.
5. Clients should see stale answers now.
6. An incoming query should not set the stale-refresh-time window,
   so a following query should still get a stale answer because of a
   resolver failure (and not because it was in the stale-refresh-time
   window).
2021-01-28 16:39:30 +01:00
Matthijs Mekking aabdedeae3 Only start stale refresh window when resuming
If we did not attempt a fetch due to fetch-limits, we should not start
the stale-refresh-time window.

Introduce a new flag DNS_DBFIND_STALESTART to differentiate between
a resolver failure and unexpected error. If we are resuming, this
indicates a resolver failure, then start the stale-refresh-time window,
otherwise don't start the stale-refresh-time window, but still fall
back to using stale data.

(This commit also wraps some docstrings to 80 characters width)
2021-01-28 16:38:34 +01:00
Matthijs Mekking c6fd02aed5 Use stale data also if we are not resuming
Before this change, BIND will only fallback to using stale data if
there was an actual attempt to resolve the query. Then on a timeout,
the stale data from cache becomes eligible.

This commit changes this so that on any unexpected error stale data
becomes eligble (you would still have to have 'stale-answer-enable'
enabled of course).

If there is no stale data, this may return in an error again, so don't
loop on stale data lookup attempts. If the DNS_DBFIND_STALEOK flag is
set, this means we already tried to lookup stale data, so if that is
the case, don't use stale again.
2021-01-28 16:36:46 +01:00
Mark Andrews c1c7e1ac5c Merge branch '2420-xmlfreetextwriter-could-be-called-twice' into 'main'
Resolve "CID 316510: Memory - corruptions (USE_AFTER_FREE)"

Closes #2420

See merge request isc-projects/bind9!4613
2021-01-28 05:19:53 +00:00
Mark Andrews 95114f7d60 Add CHANGES entry for [GL #2420] 2021-01-28 04:15:06 +00:00
Mark Andrews b5cf54252a Stop xmlFreeTextWriter being called twice
xmlFreeTextWriter could be called twice if xmlDocDumpFormatMemoryEnc
failed.
2021-01-28 04:15:06 +00:00
Mark Andrews 838d3673a8 Merge branch 'marka-changes-line-length' into 'main'
Detect overly long CHANGES lines

See merge request isc-projects/bind9!4603
2021-01-28 04:06:14 +00:00
Mark Andrews 28449acded fix overly long line 2021-01-28 14:12:40 +11:00
Mark Andrews b1ecab6383 Detect overly long CHANGES lines 2021-01-28 13:49:02 +11:00
Mark Andrews 12c5b2a1b8 Merge branch '2413-after-upgrade-to-bind9-9-16-11-named-is-killed-with-status-11-segv' into 'main'
Resolve "after upgrade to bind9 9.16.11 named is killed with status=11/SEGV"

Closes #2413

See merge request isc-projects/bind9!4592
2021-01-28 02:34:43 +00:00
Mark Andrews 79fad620a2 Add release note for [GL #2413] 2021-01-28 01:54:59 +00:00
Mark Andrews 5ec9999b28 Add CHANGES for [GL #2413] 2021-01-28 01:54:59 +00:00
Mark Andrews 3dee62cfa5 Add a named acl example 2021-01-28 01:54:59 +00:00
Mark Andrews a8b55992a8 Require 'ctx' to be non-NULL in cfg_acl_fromconfig{,2} 2021-01-28 01:54:59 +00:00
Mark Andrews 2b3fcd7156 Pass an afg_aclconfctx_t structure to cfg_acl_fromconfig
in named_zone_inlinesigning.  A NULL pointer does not work.
2021-01-28 01:54:59 +00:00
Mark Andrews b111592dca Merge branch '2391-check-nsupdate-y-for-all-hmac-algorithms' into 'main'
Resolve "Check 'nsupdate -y' for all hmac algorithms."

Closes #2391

See merge request isc-projects/bind9!4569
2021-01-28 01:54:30 +00:00
Mark Andrews 4b01ba44ea Check that 'nsupdate -y' works for all HMAC algorithms 2021-01-28 01:21:27 +00:00
Mark Andrews 5921af4c7f Merge branch '2073-dnssec-verify-tries-all-keys-which-results-in-poor-performance' into 'main'
Resolve "dnssec-verify tries all keys which results in poor performance"

Closes #2073

See merge request isc-projects/bind9!4411
2021-01-28 01:06:47 +00:00
Mark Andrews 3f0859d223 Add CHANGES note 2021-01-28 11:07:52 +11:00
Mark Andrews c75b325832 Optimise dnssec-verify
dns_dnssec_keyfromrdata() only needs to be called once per DNSKEY
rather than once per verification attempt.
2021-01-28 11:07:03 +11:00
Mark Andrews d7f41c3dce Merge branch '2342-rndc-retransfer-issues-misleading-diagnostic-on-primary-zone' into 'main'
Resolve "rndc retransfer issues misleading diagnostic on primary zone"

Closes #2342

See merge request isc-projects/bind9!4482
2021-01-27 22:42:05 +00:00
Mark Andrews 1f55f49f21 Add CHANGES 2021-01-28 08:43:50 +11:00
Mark Andrews 8f36b8567a Check 'rndc retransfer' of primary error message 2021-01-28 08:43:03 +11:00
Mark Andrews dd3520ae41 Improve the diagnostic 'rndc retransfer' error message 2021-01-28 08:43:03 +11:00
Matthijs Mekking 1fcc6132c4 Merge branch '2178-dnssec-fromlabel-ec_crash' into 'main'
Resolve "dnssec-keyfromlabel  ECDSAP256SHA256 error on AEP Keypers HSM"

Closes #2178

See merge request isc-projects/bind9!4495
2021-01-26 14:02:49 +00:00
Matthijs Mekking 57ac70ad46 Make opensslecdsa_parse use fromlabel
When 'opensslecdsa_parse()' encounters a label tag in the private key
file, load the private key with 'opensslecdsa_fromlabel()'. Otherwise
load it from the private structure.

This was attempted before with 'load_privkey()' and 'uses_engine()',
but had the same flaw as 'opensslecdsa_fromlabel()' had previously,
that is getting the private and public key separately, juggling with
pointers between EC_KEY and EVP_PKEY, did not create a valid
cryptographic key that could be used for signing.
2021-01-26 15:01:26 +01:00
Matthijs Mekking 393052d6ff Simplify opensslecdsa_fromlabel
The 'opensslecdsa_fromlabel()' function does not need to get the
OpenSSL engine twice to load the private and public key. Also no need
to call 'dst_key_to_eckey()' as the EC_KEY can be derived from the
loaded EVP_PKEY's.

Add some extra checks to ensure the key has the same base id and curve
(group nid) as the dst key.

Since we already have the EVP_PKEY, no need to call 'finalize_eckey()',
instead just set the right values in the key structure.
2021-01-26 15:01:26 +01:00
Matthijs Mekking 1fcd0ef8bd Replace EVP_DigestFinal with EVP_DigestFinal_ex
The openssl docs claim that EVP_DigestFinal() is obsolete and that
one should use EVP_DigestFinal_ex() instead.
2021-01-26 15:01:26 +01:00
Matthijs Mekking 37d11f5be0 Add notes and changes for [#2178] 2021-01-26 15:01:24 +01:00
Matthijs Mekking 06b9724152 Don't set pubkey if eckey already has public key
The 'ecdsa_check()' function tries to correctly set the public key
on the eckey, but this should be skipped if the public key is
retrieved via the private key.
2021-01-26 15:01:04 +01:00
Matthijs Mekking 46afeca8bf ECDSA code should not use RSA label
The 'opensslecdsa_tofile()' function tags the label as an RSA label,
that is a copy paste error and should be of course an ECDSA label.
2021-01-26 15:01:04 +01:00
Matthijs Mekking 01239691a1 Correctly update pointers to pubkey and privkey
The functions 'load_pubkey_from_engine()' and
'load_privkey_from_engine()' did not correctly store the pointers.

Update both functions to add 'EC_KEY_set_public_key()' and
'EC_KEY_set_private_key()' respectively, so that the pointers to
the public and private keys survive the "load from engine" functions.
2021-01-26 15:01:04 +01:00
Matthijs Mekking 370285a62d load_pubkey_from_engine() should load public key
The 'function load_pubkey_from_engine()' made a call to the libssl
function 'ENGINE_load_private_key'.  This is a copy paste error and
should be 'ENGINE_load_public_key'.
2021-01-26 15:01:04 +01:00
Ondřej Surý 61ba7b9cba Merge branch '2403-dig-has-a-fit-with-option-multi-typo-on-multi' into 'main'
Report unknown dash option during the pre-parse phase

Closes #2403

See merge request isc-projects/bind9!4590
2021-01-26 13:17:02 +00:00
Mark AndrewsandOndřej Surý 0b6da18f31 Add CHANGES note for [GL #2403] 2021-01-26 13:26:29 +01:00
Mark AndrewsandOndřej Surý 3361c0d6f8 Report unknown dash option during the pre-parse phase 2021-01-26 13:26:10 +01:00
Michal Nowak 1869846858 Merge branch 'mnowak/add-rsabigexponent-README' into 'main'
Add README.md file to rsabigexponent system test

See merge request isc-projects/bind9!4579
2021-01-26 10:44:10 +00:00
Michal Nowak a247f24dfa Add README.md file to rsabigexponent system test
This README.md describes why is bigkey needed.
2021-01-26 11:40:42 +01:00
118 changed files with 10259 additions and 859 deletions
+3
View File
@@ -285,6 +285,7 @@ stages:
"with-openssl=C:/OpenSSL"
"with-libxml2=C:/libxml2"
"with-libuv=C:/libuv"
"with-nghttp2=C:/nghttp2"
"without-python"
"with-system-tests"
x64'
@@ -455,9 +456,11 @@ misc:
- sh util/tabify-changes < CHANGES > CHANGES.tmp
- diff -urNap CHANGES CHANGES.tmp
- perl util/check-changes CHANGES
- sh util/check-line-length.sh CHANGES
- test ! -f CHANGES.SE || sh util/tabify-changes < CHANGES.SE > CHANGES.tmp
- test ! -f CHANGES.SE || diff -urNap CHANGES.SE CHANGES.tmp
- test ! -f CHANGES.SE || perl util/check-changes master=0 CHANGES.SE
- test ! -f CHANGES.SE || sh util/check-line-length.sh CHANGES.SE
- rm CHANGES.tmp
- perl -w util/merge_copyrights
- diff -urNap util/copyrights util/newcopyrights
+39 -2
View File
@@ -1,7 +1,44 @@
5575. [func] Initial support for DNS-over-HTTP(S). BIND now
includes DNS-over-HTTP(S) layer built on top of nghttp2.
Both encrypted (via TLS) and unencrypted HTTP/2 connections
are supported.
5574. [func] Incoming zone transfers can now use TLS.
Addresses in a "primaries" list take an optional
"tls" argument, specifying either a previously
configured "tls" block or "ephemeral"; SOA queries
and zone transfer requests will then be sent via
TLS. [GL #2392]
5573. [func] Also return stale data if an error occurred and we are
not resuming. Only start the stale-refresh-time window
if we timed out. [GL #2434]
5572. [bug] Address potential double free in generatexml.
[GL #2420]
5571. [bug] If a zone had a non-builtin named allow-update acl
named failed to start. [GL #2413]
5570. [bug] Improve the performance of dnssec-verify by reducing
the number of repeated calls to dns_dnssec_keyfromrdata.
[GL #2073]
5569. [bug] Emit useful error message when 'rndc retransfer' is
applied to a zone of inappropriate type. [GL #2342]
5568. [bug] Fixed a crash in "dnssec-keyfromlabel" when using ECDSA
keys. [GL #2178]
5567. [bug] Dig now reports unknown dash options while pre-parsing
the options. This prevents '-multi' instead of
'+multi' reporting memory usage before ending option
parsing on 'Invalid option: -lti'. [GL #2403]
5566. [func] Add "stale-answer-client-timeout" option, which
is the amount of time a recursive resolver waits before
attempting to answer the query using stale data from cache.
[GL #2247]
attempting to answer the query using stale data from
cache. [GL #2247]
5565. [func] The SONAMEs for BIND 9 libraries now include the current
BIND 9 version number, in an effort to tightly couple
+22
View File
@@ -367,3 +367,25 @@ distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-----------------------------------------------------------------------------
Copyright Joyent, Inc. and other Node contributors. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
+47 -6
View File
@@ -228,6 +228,10 @@ help(void) {
"SERVFAIL)\n"
" +[no]header-only (Send query without a "
"question section)\n"
" +[no]https[=###] (DNS over HTTPS mode) "
"[/]\n"
" +[no]https-get (Use GET instead of "
"default POST method\n"
" +[no]identify (ID responders in short "
"answers)\n"
#ifdef HAVE_LIBIDN2
@@ -348,6 +352,8 @@ received(unsigned int bytes, isc_sockaddr_t *from, dig_query_t *query) {
}
if (query->lookup->tls_mode) {
proto = "TLS";
} else if (query->lookup->https_mode) {
proto = "HTTPS";
} else if (query->lookup->tcp_mode) {
proto = "TCP";
} else {
@@ -1412,8 +1418,39 @@ plus_option(char *option, bool is_batchfile, bool *need_clone,
lookup->servfail_stops = state;
break;
case 'h':
FULLCHECK("header-only");
lookup->header_only = state;
switch (cmd[1]) {
case 'e': /* header-only */
FULLCHECK("header-only");
lookup->header_only = state;
break;
case 't':
FULLCHECK2("https", "https-get");
switch (cmd[5]) {
case '\0':
FULLCHECK("https");
lookup->https_mode = state;
if (!lookup->tcp_mode_set) {
lookup->tcp_mode = state;
}
if (value == NULL) {
lookup->https_path = isc_mem_strdup(
mctx, DEFAULT_HTTPS_PATH);
break;
}
lookup->https_path = isc_mem_strdup(mctx,
value);
break;
case '-':
FULLCHECK("https-get");
lookup->https_get = true;
break;
default:
goto invalid_option;
}
break;
default:
goto invalid_option;
}
break;
case 'i':
switch (cmd[1]) {
@@ -2341,16 +2378,20 @@ preparse_args(int argc, char **argv) {
continue;
}
/* Look for dash value option. */
if (strpbrk(option, dash_opts) != &option[0] ||
strlen(option) > 1U) {
/* Error or value in option. */
if (strpbrk(option, dash_opts) != &option[0]) {
goto invalid_option;
}
if (strlen(option) > 1U) {
/* value in option. */
continue;
}
/* Dash value is next argument so we need to skip it. */
rc--, rv++;
/* Handle missing argument */
if (rc == 0) {
break;
invalid_option:
fprintf(stderr, "Invalid option: -%s\n", option);
usage();
}
}
}
+75 -92
View File
@@ -608,97 +608,35 @@ make_empty_lookup(void) {
INSIST(!free_now);
looknew = isc_mem_allocate(mctx, sizeof(struct dig_lookup));
looknew->pending = true;
looknew->textname[0] = 0;
looknew->cmdline[0] = 0;
looknew->rdtype = dns_rdatatype_a;
looknew->qrdtype = dns_rdatatype_a;
looknew->rdclass = dns_rdataclass_in;
looknew->rdtypeset = false;
looknew->rdclassset = false;
looknew->sendspace = NULL;
looknew->sendmsg = NULL;
looknew->name = NULL;
looknew->oname = NULL;
looknew->xfr_q = NULL;
looknew->current_query = NULL;
looknew->doing_xfr = false;
looknew->ixfr_serial = 0;
looknew->trace = false;
looknew->trace_root = false;
looknew->identify = false;
looknew->identify_previous_line = false;
looknew->ignore = false;
looknew->servfail_stops = true;
looknew->besteffort = true;
looknew->dns64prefix = false;
looknew->dnssec = false;
looknew->ednsflags = 0;
looknew->opcode = dns_opcode_query;
looknew->expire = false;
looknew->nsid = false;
looknew->tcp_keepalive = false;
looknew->padding = 0;
looknew->header_only = false;
looknew->sendcookie = false;
looknew->seenbadcookie = false;
looknew->badcookie = true;
looknew->multiline = false;
looknew->nottl = false;
looknew->noclass = false;
looknew->onesoa = false;
looknew->use_usec = false;
looknew->nocrypto = false;
looknew->ttlunits = false;
looknew->expandaaaa = false;
looknew->qr = false;
looknew = isc_mem_allocate(mctx, sizeof(*looknew));
*looknew = (dig_lookup_t){
.pending = true,
.rdtype = dns_rdatatype_a,
.qrdtype = dns_rdatatype_a,
.rdclass = dns_rdataclass_in,
.servfail_stops = true,
.besteffort = true,
.opcode = dns_opcode_query,
.badcookie = true,
#ifdef HAVE_LIBIDN2
looknew->idnin = isatty(1) ? (getenv("IDN_DISABLE") == NULL) : false;
looknew->idnout = looknew->idnin;
#else /* ifdef HAVE_LIBIDN2 */
looknew->idnin = false;
looknew->idnout = false;
.idnin = isatty(1) ? (getenv("IDN_DISABLE") == NULL) : false,
.idnout = looknew->idnin,
#endif /* HAVE_LIBIDN2 */
looknew->udpsize = -1;
looknew->edns = -1;
looknew->recurse = true;
looknew->aaonly = false;
looknew->adflag = false;
looknew->cdflag = false;
looknew->raflag = false;
looknew->tcflag = false;
looknew->print_unknown_format = false;
looknew->zflag = false;
looknew->setqid = false;
looknew->qid = 0;
looknew->ns_search_only = false;
looknew->origin = NULL;
looknew->tsigctx = NULL;
looknew->querysig = NULL;
looknew->retries = tries;
looknew->nsfound = 0;
looknew->tcp_mode = false;
looknew->tcp_mode_set = false;
looknew->tls_mode = false;
looknew->comments = true;
looknew->stats = true;
looknew->section_question = true;
looknew->section_answer = true;
looknew->section_authority = true;
looknew->section_additional = true;
looknew->new_search = false;
looknew->done_as_is = false;
looknew->need_search = false;
looknew->ecs_addr = NULL;
looknew->cookie = NULL;
looknew->ednsopts = NULL;
looknew->ednsoptscnt = 0;
looknew->ednsneg = true;
looknew->mapped = true;
looknew->dscp = -1;
looknew->rrcomments = 0;
looknew->eoferr = 0;
.udpsize = -1,
.edns = -1,
.recurse = true,
.retries = tries,
.comments = true,
.stats = true,
.section_question = true,
.section_answer = true,
.section_authority = true,
.section_additional = true,
.ednsneg = true,
.mapped = true,
.dscp = -1,
};
dns_fixedname_init(&looknew->fdomain);
ISC_LINK_INIT(looknew, link);
ISC_LIST_INIT(looknew->q);
@@ -787,6 +725,11 @@ clone_lookup(dig_lookup_t *lookold, bool servers) {
looknew->nsid = lookold->nsid;
looknew->tcp_keepalive = lookold->tcp_keepalive;
looknew->header_only = lookold->header_only;
looknew->https_mode = lookold->https_mode;
if (lookold->https_path != NULL) {
looknew->https_path = isc_mem_strdup(mctx, lookold->https_path);
}
looknew->https_get = lookold->https_get;
looknew->sendcookie = lookold->sendcookie;
looknew->seenbadcookie = lookold->seenbadcookie;
looknew->badcookie = lookold->badcookie;
@@ -1638,6 +1581,10 @@ _destroy_lookup(dig_lookup_t *lookup) {
isc_mem_free(mctx, lookup->ednsopts);
}
if (lookup->https_path) {
isc_mem_free(mctx, lookup->https_path);
}
isc_mem_free(mctx, lookup);
}
@@ -2760,7 +2707,17 @@ start_tcp(dig_query_t *query) {
* For TLS connections, we want to override the default
* port number.
*/
port = port_set ? port : (query->lookup->tls_mode ? 853 : 53);
if (!port_set) {
if (query->lookup->tls_mode) {
port = 853;
} else if (query->lookup->https_mode) {
port = 443;
} else {
port = 53;
}
}
fprintf(stderr, "query->servname = %s\n", query->servname);
result = get_address(query->servname, port, &query->sockaddr);
if (result != ISC_R_SUCCESS) {
@@ -2835,7 +2792,27 @@ start_tcp(dig_query_t *query) {
(isc_nmiface_t *)&query->sockaddr,
tcp_connected, query, local_timeout, 0,
query->tlsctx);
check_result(result, "isc_nm_tcpdnsconnect");
check_result(result, "isc_nm_tlsdnsconnect");
} else if (query->lookup->https_mode) {
char portbuf[12];
char uri[4096] = { 0 };
snprintf(portbuf, sizeof(portbuf), "%u",
(uint16_t)port);
strlcpy(uri, "https://", sizeof(uri));
strlcat(uri, query->servname, sizeof(uri));
strlcat(uri, ":", sizeof(uri));
strlcat(uri, portbuf, sizeof(uri));
strlcat(uri, query->lookup->https_path, sizeof(uri));
result = isc_tlsctx_createclient(&query->tlsctx);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
result = isc_nm_httpconnect(
netmgr, (isc_nmiface_t *)&localaddr,
(isc_nmiface_t *)&query->sockaddr, uri,
!query->lookup->https_get, tcp_connected, query,
query->tlsctx, local_timeout, 0);
check_result(result, "isc_nm_httpconnect");
} else {
result = isc_nm_tcpdnsconnect(
netmgr, (isc_nmiface_t *)&localaddr,
@@ -3183,7 +3160,12 @@ launch_next_query(dig_query_t *query) {
isc_nmhandle_settimeout(query->handle, local_timeout);
query_attach(query, &readquery);
isc_nm_read(query->handle, recv_done, readquery);
if (query->lookup->https_mode) {
isc_nm_httprequest(query->handle, &r, recv_done, readquery);
goto cleanup;
} else {
isc_nm_read(query->handle, recv_done, readquery);
}
if (!query->first_soa_rcvd) {
dig_query_t *sendquery = NULL;
@@ -3211,6 +3193,7 @@ launch_next_query(dig_query_t *query) {
}
}
}
cleanup:
lookup_detach(&l);
return;
}
+8
View File
@@ -76,6 +76,9 @@
#define DEFAULT_EDNS_VERSION 0
#define DEFAULT_EDNS_BUFSIZE 1232
#define DEFAULT_HTTPS_PATH "/dns-query"
#define DEFAULT_HTTPS_QUERY "?dns="
/*%
* Lookup_limit is just a limiter, keeping too many lookups from being
* created. It's job is mainly to prevent the program from running away
@@ -168,6 +171,11 @@ struct dig_lookup {
int rrcomments;
unsigned int eoferr;
uint16_t qid;
struct {
bool https_mode;
bool https_get;
char *https_path;
};
};
/*% The dig_query structure */
+2
View File
@@ -59,6 +59,7 @@ named_SOURCES = \
server.c \
statschannel.c \
tkeyconf.c \
transportconf.c \
tsigconf.c \
zoneconf.c \
unix/dlz_dlopen_driver.c \
@@ -77,6 +78,7 @@ named_SOURCES = \
include/named/smf_globals.h \
include/named/statschannel.h \
include/named/tkeyconf.h \
include/named/transportconf.h \
include/named/tsigconf.h \
include/named/types.h \
include/named/zoneconf.h \
+138 -134
View File
@@ -94,6 +94,8 @@ options {\n\
# pid-file \"" NAMED_LOCALSTATEDIR "/run/named/named.pid\"; \n\
port 53;\n\
tls-port 853;\n\
http-port 80;\n\
https-port 443;\n\
prefetch 2 9;\n\
recursing-file \"named.recursing\";\n\
recursive-clients 1000;\n\
@@ -608,10 +610,76 @@ named_config_getprimariesdef(const cfg_obj_t *cctx, const char *name,
return (result);
}
static isc_result_t
named_config_getname(isc_mem_t *mctx, const cfg_obj_t *obj,
dns_name_t **namep) {
REQUIRE(namep != NULL && *namep == NULL);
const char *objstr;
isc_result_t result;
isc_buffer_t b;
dns_fixedname_t fname;
if (!cfg_obj_isstring(obj)) {
*namep = NULL;
return (ISC_R_SUCCESS);
}
*namep = isc_mem_get(mctx, sizeof(**namep));
dns_name_init(*namep, NULL);
objstr = cfg_obj_asstring(obj);
isc_buffer_constinit(&b, objstr, strlen(objstr));
isc_buffer_add(&b, strlen(objstr));
dns_fixedname_init(&fname);
result = dns_name_fromtext(dns_fixedname_name(&fname), &b, dns_rootname,
0, NULL);
if (result != ISC_R_SUCCESS) {
isc_mem_put(mctx, *namep, sizeof(*namep));
*namep = NULL;
return (result);
}
dns_name_dup(dns_fixedname_name(&fname), mctx, *namep);
return (ISC_R_SUCCESS);
}
#define grow_array(mctx, array, newlen, oldlen) \
if (newlen >= oldlen) { \
size_t newsize = (newlen + 16) * sizeof(array[0]); \
size_t oldsize = oldlen * sizeof(array[0]); \
void *tmp = isc_mem_get(mctx, newsize); \
memset(tmp, 0, newsize); \
if (oldlen != 0) { \
memmove(tmp, array, oldsize); \
isc_mem_put(mctx, array, oldsize); \
} \
array = tmp; \
oldlen = newlen + 16; \
}
#define shrink_array(mctx, array, newlen, oldlen) \
if (newlen < oldlen) { \
void *tmp = NULL; \
size_t newsize = newlen * sizeof(array[0]); \
size_t oldsize = oldlen * sizeof(array[0]); \
if (newlen != 0) { \
tmp = isc_mem_get(mctx, newsize); \
memset(tmp, 0, newsize); \
memmove(tmp, array, newsize); \
} else { \
tmp = NULL; \
} \
isc_mem_put(mctx, array, oldsize); \
array = tmp; \
oldlen = newlen; \
}
isc_result_t
named_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list,
isc_mem_t *mctx, dns_ipkeylist_t *ipkl) {
uint32_t addrcount = 0, dscpcount = 0, keycount = 0, i = 0;
uint32_t addrcount = 0, dscpcount = 0, keycount = 0, tlscount = 0,
i = 0;
uint32_t listcount = 0, l = 0, j;
uint32_t stackcount = 0, pushed = 0;
isc_result_t result;
@@ -619,12 +687,14 @@ named_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list,
const cfg_obj_t *addrlist;
const cfg_obj_t *portobj;
const cfg_obj_t *dscpobj;
in_port_t port;
in_port_t port = (in_port_t)0;
in_port_t def_port;
in_port_t def_tlsport;
isc_dscp_t dscp = -1;
dns_fixedname_t fname;
isc_sockaddr_t *addrs = NULL;
isc_dscp_t *dscps = NULL;
dns_name_t **keys = NULL;
dns_name_t **tlss = NULL;
struct {
const char *name;
} *lists = NULL;
@@ -638,6 +708,7 @@ named_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list,
REQUIRE(ipkl->count == 0);
REQUIRE(ipkl->addrs == NULL);
REQUIRE(ipkl->keys == NULL);
REQUIRE(ipkl->tlss == NULL);
REQUIRE(ipkl->dscps == NULL);
REQUIRE(ipkl->labels == NULL);
REQUIRE(ipkl->allocated == 0);
@@ -645,7 +716,12 @@ named_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list,
/*
* Get system defaults.
*/
result = named_config_getport(config, "port", &port);
result = named_config_getport(config, "port", &def_port);
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
result = named_config_getport(config, "tls-port", &def_tlsport);
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
@@ -689,33 +765,20 @@ resume:
for (; element != NULL; element = cfg_list_next(element)) {
const cfg_obj_t *addr;
const cfg_obj_t *key;
const char *keystr;
isc_buffer_t b;
const cfg_obj_t *tls;
addr = cfg_tuple_get(cfg_listelt_value(element),
"primarieselement");
key = cfg_tuple_get(cfg_listelt_value(element), "key");
tls = cfg_tuple_get(cfg_listelt_value(element), "tls");
if (!cfg_obj_issockaddr(addr)) {
const char *listname = cfg_obj_asstring(addr);
isc_result_t tresult;
/* Grow lists? */
if (listcount == l) {
void *tmp;
uint32_t newlen = listcount + 16;
size_t newsize, oldsize;
grow_array(mctx, lists, l, listcount);
newsize = newlen * sizeof(*lists);
oldsize = listcount * sizeof(*lists);
tmp = isc_mem_get(mctx, newsize);
if (listcount != 0) {
memmove(tmp, lists, oldsize);
isc_mem_put(mctx, lists, oldsize);
}
lists = tmp;
listcount = newlen;
}
/* Seen? */
for (j = 0; j < l; j++) {
if (strcasecmp(lists[j].name, listname) == 0) {
@@ -741,21 +804,7 @@ resume:
}
lists[l++].name = listname;
/* Grow stack? */
if (stackcount == pushed) {
void *tmp;
uint32_t newlen = stackcount + 16;
size_t newsize, oldsize;
newsize = newlen * sizeof(*stack);
oldsize = stackcount * sizeof(*stack);
tmp = isc_mem_get(mctx, newsize);
if (stackcount != 0) {
memmove(tmp, stack, oldsize);
isc_mem_put(mctx, stack, oldsize);
}
stack = tmp;
stackcount = newlen;
}
grow_array(mctx, stack, pushed, stackcount);
/*
* We want to resume processing this list on the
* next element.
@@ -767,68 +816,44 @@ resume:
goto newlist;
}
if (i == addrcount) {
void *tmp;
uint32_t newlen = addrcount + 16;
size_t newsize, oldsize;
newsize = newlen * sizeof(isc_sockaddr_t);
oldsize = addrcount * sizeof(isc_sockaddr_t);
tmp = isc_mem_get(mctx, newsize);
if (addrcount != 0) {
memmove(tmp, addrs, oldsize);
isc_mem_put(mctx, addrs, oldsize);
}
addrs = tmp;
addrcount = newlen;
newsize = newlen * sizeof(isc_dscp_t);
oldsize = dscpcount * sizeof(isc_dscp_t);
tmp = isc_mem_get(mctx, newsize);
if (dscpcount != 0) {
memmove(tmp, dscps, oldsize);
isc_mem_put(mctx, dscps, oldsize);
}
dscps = tmp;
dscpcount = newlen;
newsize = newlen * sizeof(dns_name_t *);
oldsize = keycount * sizeof(dns_name_t *);
tmp = isc_mem_get(mctx, newsize);
if (keycount != 0) {
memmove(tmp, keys, oldsize);
isc_mem_put(mctx, keys, oldsize);
}
keys = tmp;
keycount = newlen;
}
grow_array(mctx, addrs, i, addrcount);
grow_array(mctx, dscps, i, dscpcount);
grow_array(mctx, keys, i, keycount);
grow_array(mctx, tlss, i, tlscount);
addrs[i] = *cfg_obj_assockaddr(addr);
if (isc_sockaddr_getport(&addrs[i]) == 0) {
isc_sockaddr_setport(&addrs[i], port);
}
dscps[i] = cfg_obj_getdscp(addr);
if (dscps[i] == -1) {
dscps[i] = dscp;
}
keys[i] = NULL;
i++; /* Increment here so that cleanup on error works. */
if (!cfg_obj_isstring(key)) {
continue;
}
keys[i - 1] = isc_mem_get(mctx, sizeof(dns_name_t));
dns_name_init(keys[i - 1], NULL);
keystr = cfg_obj_asstring(key);
isc_buffer_constinit(&b, keystr, strlen(keystr));
isc_buffer_add(&b, strlen(keystr));
dns_fixedname_init(&fname);
result = dns_name_fromtext(dns_fixedname_name(&fname), &b,
dns_rootname, 0, NULL);
result = named_config_getname(mctx, key, &keys[i]);
if (result != ISC_R_SUCCESS) {
i++; /* Increment here so that cleanup on error works.
*/
goto cleanup;
}
dns_name_dup(dns_fixedname_name(&fname), mctx, keys[i - 1]);
result = named_config_getname(mctx, tls, &tlss[i]);
if (result != ISC_R_SUCCESS) {
i++; /* Increment here so that cleanup on error works.
*/
goto cleanup;
}
/* Set the default port or tls-port */
if (port == 0) {
if (tlss[i] != NULL) {
port = def_tlsport;
} else {
port = def_port;
}
}
if (isc_sockaddr_getport(&addrs[i]) == 0) {
isc_sockaddr_setport(&addrs[i], port);
}
i++;
}
if (pushed != 0) {
pushed--;
@@ -837,61 +862,28 @@ resume:
dscp = stack[pushed].dscp;
goto resume;
}
if (i < addrcount) {
void *tmp;
size_t newsize, oldsize;
newsize = i * sizeof(isc_sockaddr_t);
oldsize = addrcount * sizeof(isc_sockaddr_t);
if (i != 0) {
tmp = isc_mem_get(mctx, newsize);
memmove(tmp, addrs, newsize);
} else {
tmp = NULL;
}
isc_mem_put(mctx, addrs, oldsize);
addrs = tmp;
addrcount = i;
newsize = i * sizeof(isc_dscp_t);
oldsize = dscpcount * sizeof(isc_dscp_t);
if (i != 0) {
tmp = isc_mem_get(mctx, newsize);
memmove(tmp, dscps, newsize);
} else {
tmp = NULL;
}
isc_mem_put(mctx, dscps, oldsize);
dscps = tmp;
dscpcount = i;
newsize = i * sizeof(dns_name_t *);
oldsize = keycount * sizeof(dns_name_t *);
if (i != 0) {
tmp = isc_mem_get(mctx, newsize);
memmove(tmp, keys, newsize);
} else {
tmp = NULL;
}
isc_mem_put(mctx, keys, oldsize);
keys = tmp;
keycount = i;
}
shrink_array(mctx, addrs, i, addrcount);
shrink_array(mctx, dscps, i, dscpcount);
shrink_array(mctx, keys, i, keycount);
shrink_array(mctx, tlss, i, tlscount);
if (lists != NULL) {
isc_mem_put(mctx, lists, listcount * sizeof(*lists));
isc_mem_put(mctx, lists, listcount * sizeof(lists[0]));
}
if (stack != NULL) {
isc_mem_put(mctx, stack, stackcount * sizeof(*stack));
isc_mem_put(mctx, stack, stackcount * sizeof(stack[0]));
}
INSIST(dscpcount == addrcount);
INSIST(keycount == addrcount);
INSIST(tlscount == addrcount);
INSIST(keycount == dscpcount);
ipkl->addrs = addrs;
ipkl->dscps = dscps;
ipkl->keys = keys;
ipkl->tlss = tlss;
ipkl->count = addrcount;
ipkl->allocated = addrcount;
@@ -899,10 +891,10 @@ resume:
cleanup:
if (addrs != NULL) {
isc_mem_put(mctx, addrs, addrcount * sizeof(isc_sockaddr_t));
isc_mem_put(mctx, addrs, addrcount * sizeof(addrs[0]));
}
if (dscps != NULL) {
isc_mem_put(mctx, dscps, dscpcount * sizeof(isc_dscp_t));
isc_mem_put(mctx, dscps, dscpcount * sizeof(dscps[0]));
}
if (keys != NULL) {
for (j = 0; j < i; j++) {
@@ -912,15 +904,27 @@ cleanup:
if (dns_name_dynamic(keys[j])) {
dns_name_free(keys[j], mctx);
}
isc_mem_put(mctx, keys[j], sizeof(dns_name_t));
isc_mem_put(mctx, keys[j], sizeof(*keys[j]));
}
isc_mem_put(mctx, keys, keycount * sizeof(dns_name_t *));
isc_mem_put(mctx, keys, keycount * sizeof(keys[0]));
}
if (tlss != NULL) {
for (j = 0; j < i; j++) {
if (tlss[j] == NULL) {
continue;
}
if (dns_name_dynamic(tlss[j])) {
dns_name_free(tlss[j], mctx);
}
isc_mem_put(mctx, tlss[j], sizeof(*tlss[j]));
}
isc_mem_put(mctx, tlss, tlscount * sizeof(tlss[0]));
}
if (lists != NULL) {
isc_mem_put(mctx, lists, listcount * sizeof(*lists));
isc_mem_put(mctx, lists, listcount * sizeof(lists[0]));
}
if (stack != NULL) {
isc_mem_put(mctx, stack, stackcount * sizeof(*stack));
isc_mem_put(mctx, stack, stackcount * sizeof(stack[0]));
}
return (result);
}
+12 -10
View File
@@ -64,16 +64,18 @@ EXTERN isc_timermgr_t *named_g_timermgr INIT(NULL);
EXTERN isc_socketmgr_t *named_g_socketmgr INIT(NULL);
EXTERN isc_nm_t *named_g_nm INIT(NULL);
EXTERN cfg_parser_t *named_g_parser INIT(NULL);
EXTERN cfg_parser_t *named_g_addparser INIT(NULL);
EXTERN const char *named_g_version INIT(PACKAGE_VERSION);
EXTERN const char *named_g_product INIT(PACKAGE_NAME);
EXTERN const char *named_g_description INIT(PACKAGE_DESCRIPTION);
EXTERN const char *named_g_srcid INIT(PACKAGE_SRCID);
EXTERN const char *named_g_configargs INIT(PACKAGE_CONFIGARGS);
EXTERN const char *named_g_builder INIT(PACKAGE_BUILDER);
EXTERN in_port_t named_g_port INIT(0);
EXTERN in_port_t named_g_tlsport INIT(0);
EXTERN isc_dscp_t named_g_dscp INIT(-1);
EXTERN cfg_parser_t *named_g_addparser INIT(NULL);
EXTERN const char *named_g_version INIT(PACKAGE_VERSION);
EXTERN const char *named_g_product INIT(PACKAGE_NAME);
EXTERN const char *named_g_description INIT(PACKAGE_DESCRIPTION);
EXTERN const char *named_g_srcid INIT(PACKAGE_SRCID);
EXTERN const char *named_g_configargs INIT(PACKAGE_CONFIGARGS);
EXTERN const char *named_g_builder INIT(PACKAGE_BUILDER);
EXTERN in_port_t named_g_port INIT(0);
EXTERN in_port_t named_g_tlsport INIT(0);
EXTERN in_port_t named_g_http_secure_port INIT(0);
EXTERN in_port_t named_g_http_port INIT(0);
EXTERN isc_dscp_t named_g_dscp INIT(-1);
EXTERN named_server_t *named_g_server INIT(NULL);
+41
View File
@@ -0,0 +1,41 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* 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/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
#pragma once
/*! \file */
#include <isc/lang.h>
#include <isc/types.h>
#include <dns/transport.h>
#include <isccfg/cfg.h>
ISC_LANG_BEGINDECLS
isc_result_t
named_transports_fromconfig(const cfg_obj_t *config, const cfg_obj_t *vconfig,
isc_mem_t *mctx, dns_transport_list_t **listp);
/*%<
* Create a list of transport objects (DoT or DoH) and configure them
* according to 'key-file', 'cert-file', 'ca-file' or 'hostname'
* statements.
*
* Requires:
* \li 'config' is not NULL.
* \li 'vconfig' is not NULL.
* \li 'mctx' is not NULL
* \li 'listp' is not NULL, and '*listp' is NULL
*
*/
ISC_LANG_ENDDECLS
+4 -2
View File
@@ -44,7 +44,8 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
bool
named_zone_reusable(dns_zone_t *zone, const cfg_obj_t *zconfig,
const cfg_obj_t *vconfig, const cfg_obj_t *config);
const cfg_obj_t *vconfig, const cfg_obj_t *config,
cfg_aclconfctx_t *actx);
/*%<
* If 'zone' can be safely reconfigured according to the configuration
* data in 'zconfig', return true. If the configuration data is so
@@ -54,7 +55,8 @@ named_zone_reusable(dns_zone_t *zone, const cfg_obj_t *zconfig,
bool
named_zone_inlinesigning(dns_zone_t *zone, const cfg_obj_t *zconfig,
const cfg_obj_t *vconfig, const cfg_obj_t *config);
const cfg_obj_t *vconfig, const cfg_obj_t *config,
cfg_aclconfctx_t *actx);
/*%<
* Determine if zone uses inline-signing. This is true if inline-signing
* is set to yes, or if there is a dnssec-policy on a non-dynamic zone.
+13 -1
View File
@@ -705,7 +705,7 @@ parse_T_opt(char *option) {
static void
parse_port(char *arg) {
enum { DNSPORT, TLSPORT } ptype = DNSPORT;
enum { DNSPORT, TLSPORT, HTTP_SECURE_PORT, HTTP_PORT } ptype = DNSPORT;
char *value = arg;
int port;
@@ -714,6 +714,12 @@ parse_port(char *arg) {
} else if (strncmp(arg, "tls=", 4) == 0) {
value = arg + 4;
ptype = TLSPORT;
} else if (strncmp(arg, "https=", 6) == 0) {
value = arg + 6;
ptype = HTTP_SECURE_PORT;
} else if (strncmp(arg, "http=", 5) == 0) {
value = arg + 6;
ptype = HTTP_PORT;
}
port = parse_int(value, "port");
@@ -728,6 +734,12 @@ parse_port(char *arg) {
case TLSPORT:
named_g_tlsport = port;
break;
case HTTP_SECURE_PORT:
named_g_http_secure_port = port;
break;
case HTTP_PORT:
named_g_http_port = port;
break;
default:
INSIST(0);
ISC_UNREACHABLE();
+38 -19
View File
@@ -86,6 +86,15 @@ DYNDB
dyndb string quoted_string {
unspecified-text };
HTTP
^^^^
::
http string {
endpoints { quoted_string; ... }; // experimental
};
KEY
^^^
@@ -137,7 +146,8 @@ MASTERS
masters string [ port integer ] [ dscp
integer ] { ( primaries | ipv4_address
[ port integer ] | ipv6_address [ port
integer ] ) [ key string ]; ... };
integer ] ) [ key string ] [ tls
string ]; ... };
OPTIONS
^^^^^^^
@@ -158,7 +168,7 @@ OPTIONS
allow-update-forwarding { address_match_element; ... };
also-notify [ port integer ] [ dscp integer ] { ( primaries |
ipv4_address [ port integer ] | ipv6_address [ port
integer ] ) [ key string ]; ... };
integer ] ) [ key string ] [ tls string ]; ... };
alt-transfer-source ( ipv4_address | * ) [ port ( integer | * )
] [ dscp integer ];
alt-transfer-source-v6 ( ipv6_address | * ) [ port ( integer |
@@ -176,8 +186,9 @@ OPTIONS
catalog-zones { zone string [ default-masters [ port integer ]
[ dscp integer ] { ( primaries | ipv4_address [ port
integer ] | ipv6_address [ port integer ] ) [ key
string ]; ... } ] [ zone-directory quoted_string ] [
in-memory boolean ] [ min-update-interval duration ]; ... };
string ] [ tls string ]; ... } ] [ zone-directory
quoted_string ] [ in-memory boolean ] [ min-update-interval
duration ]; ... };
check-dup-records ( fail | warn | ignore );
check-integrity boolean;
check-mx ( fail | warn | ignore );
@@ -262,6 +273,8 @@ OPTIONS
glue-cache boolean;// deprecated
heartbeat-interval integer;
hostname ( quoted_string | none );
http-port integer;
https-port integer;
inline-signing boolean;
interface-interval duration;
ipv4only-contact string;
@@ -273,10 +286,12 @@ OPTIONS
key-directory quoted_string;
lame-ttl duration;
listen-on [ port integer ] [ dscp
integer ] [ tls string ] {
integer ] [ tls string ] [ http
string ] {
address_match_element; ... };
listen-on-v6 [ port integer ] [ dscp
integer ] [ tls string ] {
integer ] [ tls string ] [ http
string ] {
address_match_element; ... };
lmdb-mapsize sizeval;
lock-file ( quoted_string | none );
@@ -461,7 +476,8 @@ PRIMARIES
primaries string [ port integer ] [ dscp
integer ] { ( primaries | ipv4_address
[ port integer ] | ipv6_address [ port
integer ] ) [ key string ]; ... };
integer ] ) [ key string ] [ tls
string ]; ... };
SERVER
^^^^^^
@@ -519,9 +535,11 @@ TLS
::
tls string {
ca-file quoted_string;
cert-file quoted_string;
ciphers string; // experimental
dh-param quoted_string; // experimental
hostname quoted_string;
key-file quoted_string;
protocols sslprotos; // experimental
};
@@ -566,7 +584,7 @@ VIEW
allow-update-forwarding { address_match_element; ... };
also-notify [ port integer ] [ dscp integer ] { ( primaries |
ipv4_address [ port integer ] | ipv6_address [ port
integer ] ) [ key string ]; ... };
integer ] ) [ key string ] [ tls string ]; ... };
alt-transfer-source ( ipv4_address | * ) [ port ( integer | * )
] [ dscp integer ];
alt-transfer-source-v6 ( ipv6_address | * ) [ port ( integer |
@@ -578,8 +596,9 @@ VIEW
catalog-zones { zone string [ default-masters [ port integer ]
[ dscp integer ] { ( primaries | ipv4_address [ port
integer ] | ipv6_address [ port integer ] ) [ key
string ]; ... } ] [ zone-directory quoted_string ] [
in-memory boolean ] [ min-update-interval duration ]; ... };
string ] [ tls string ]; ... } ] [ zone-directory
quoted_string ] [ in-memory boolean ] [ min-update-interval
duration ]; ... };
check-dup-records ( fail | warn | ignore );
check-integrity boolean;
check-mx ( fail | warn | ignore );
@@ -843,8 +862,8 @@ VIEW
allow-update-forwarding { address_match_element; ... };
also-notify [ port integer ] [ dscp integer ] { (
primaries | ipv4_address [ port integer ] |
ipv6_address [ port integer ] ) [ key string ];
... };
ipv6_address [ port integer ] ) [ key string ] [
tls string ]; ... };
alt-transfer-source ( ipv4_address | * ) [ port (
integer | * ) ] [ dscp integer ];
alt-transfer-source-v6 ( ipv6_address | * ) [ port (
@@ -884,8 +903,8 @@ VIEW
masterfile-style ( full | relative );
masters [ port integer ] [ dscp integer ] { (
primaries | ipv4_address [ port integer ] |
ipv6_address [ port integer ] ) [ key string ];
... };
ipv6_address [ port integer ] ) [ key string ] [
tls string ]; ... };
max-ixfr-ratio ( unlimited | percentage );
max-journal-size ( default | unlimited | sizeval );
max-records integer;
@@ -908,8 +927,8 @@ VIEW
notify-to-soa boolean;
primaries [ port integer ] [ dscp integer ] { (
primaries | ipv4_address [ port integer ] |
ipv6_address [ port integer ] ) [ key string ];
... };
ipv6_address [ port integer ] ) [ key string ] [
tls string ]; ... };
request-expire boolean;
request-ixfr boolean;
serial-update-method ( date | increment | unixtime );
@@ -954,7 +973,7 @@ ZONE
allow-update-forwarding { address_match_element; ... };
also-notify [ port integer ] [ dscp integer ] { ( primaries |
ipv4_address [ port integer ] | ipv6_address [ port
integer ] ) [ key string ]; ... };
integer ] ) [ key string ] [ tls string ]; ... };
alt-transfer-source ( ipv4_address | * ) [ port ( integer | * )
] [ dscp integer ];
alt-transfer-source-v6 ( ipv6_address | * ) [ port ( integer |
@@ -992,7 +1011,7 @@ ZONE
masterfile-style ( full | relative );
masters [ port integer ] [ dscp integer ] { ( primaries |
ipv4_address [ port integer ] | ipv6_address [ port
integer ] ) [ key string ]; ... };
integer ] ) [ key string ] [ tls string ]; ... };
max-ixfr-ratio ( unlimited | percentage );
max-journal-size ( default | unlimited | sizeval );
max-records integer;
@@ -1015,7 +1034,7 @@ ZONE
notify-to-soa boolean;
primaries [ port integer ] [ dscp integer ] { ( primaries |
ipv4_address [ port integer ] | ipv6_address [ port
integer ] ) [ key string ]; ... };
integer ] ) [ key string ] [ tls string ]; ... };
request-expire boolean;
request-ixfr boolean;
serial-update-method ( date | increment | unixtime );
+5 -1
View File
@@ -115,7 +115,11 @@ Options
``portnum``; if not not specified, the default is port 53. If
``value`` is of the form ``tls=<portnum>``, the server will
listen for TLS queries on ``portnum``; the default is 853.
If ``value`` is of the form ``https=<portnum>``, the server will
listen for HTTPS queries on ``portnum``; the default is 443.
If ``value`` is of the form ``http=<portnum>``, the server will
listen for HTTP queries on ``portnum``; the default is 80.
``-s``
This option writes memory usage statistics to ``stdout`` on exit.
+193 -99
View File
@@ -101,8 +101,10 @@
#include <dst/result.h>
#include <isccfg/grammar.h>
#include <isccfg/httpconf.h>
#include <isccfg/kaspconf.h>
#include <isccfg/namedconf.h>
#include <isccfg/tlsconf.h>
#include <ns/client.h>
#include <ns/hooks.h>
@@ -123,6 +125,7 @@
#include <named/server.h>
#include <named/statschannel.h>
#include <named/tkeyconf.h>
#include <named/transportconf.h>
#include <named/tsigconf.h>
#include <named/zoneconf.h>
#ifdef HAVE_LIBSCF
@@ -396,14 +399,24 @@ fatal(named_server_t *server, const char *msg, isc_result_t result);
static void
named_server_reload(isc_task_t *task, isc_event_t *event);
static isc_result_t
ns_listenelt_from_http(isc_cfg_http_obj_t *http, isc_cfg_tls_obj_t *tls,
in_port_t port, isc_mem_t *mctx,
ns_listenelt_t **target);
static isc_result_t
ns_listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config,
cfg_aclconfctx_t *actx, isc_mem_t *mctx,
uint16_t family, ns_listenelt_t **target);
uint16_t family, isc_cfg_http_storage_t *http_servers,
isc_cfg_tls_data_storage_t *tls_storage,
ns_listenelt_t **target);
static isc_result_t
ns_listenlist_fromconfig(const cfg_obj_t *listenlist, const cfg_obj_t *config,
cfg_aclconfctx_t *actx, isc_mem_t *mctx,
uint16_t family, ns_listenlist_t **target);
uint16_t family, isc_cfg_http_storage_t *http_servers,
isc_cfg_tls_data_storage_t *tls_storage,
ns_listenlist_t **target);
static isc_result_t
configure_forward(const cfg_obj_t *config, dns_view_t *view,
@@ -3988,6 +4001,7 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
uint32_t max_stale_ttl = 0;
uint32_t stale_refresh_time = 0;
dns_tsig_keyring_t *ring = NULL;
dns_transport_list_t *transports = NULL;
dns_view_t *pview = NULL; /* Production view */
isc_mem_t *cmctx = NULL, *hmctx = NULL;
dns_dispatch_t *dispatch4 = NULL;
@@ -4973,6 +4987,14 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
}
}
/*
* Configure the view's transports (DoT/DoH)
*/
CHECK(named_transports_fromconfig(config, vconfig, view->mctx,
&transports));
dns_view_settransports(view, transports);
dns_transport_list_detach(&transports);
/*
* Configure the view's TSIG keys.
*/
@@ -6578,7 +6600,8 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
}
if (zone != NULL &&
!named_zone_reusable(zone, zconfig, vconfig, config)) {
!named_zone_reusable(zone, zconfig, vconfig, config, aclconf))
{
dns_zone_detach(&zone);
}
@@ -6658,8 +6681,8 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
strcasecmp(ztypestr, "slave") == 0));
if (zone_maybe_inline) {
inline_signing = named_zone_inlinesigning(zone, zconfig,
vconfig, config);
inline_signing = named_zone_inlinesigning(
zone, zconfig, vconfig, config, aclconf);
}
if (inline_signing) {
dns_zone_getraw(zone, &raw);
@@ -7493,36 +7516,12 @@ portset_fromconf(isc_portset_t *portset, const cfg_obj_t *ports,
static isc_result_t
removed(dns_zone_t *zone, void *uap) {
const char *type;
if (dns_zone_getview(zone) != uap) {
return (ISC_R_SUCCESS);
}
switch (dns_zone_gettype(zone)) {
case dns_zone_master:
type = "primary";
break;
case dns_zone_slave:
type = "secondary";
break;
case dns_zone_mirror:
type = "mirror";
break;
case dns_zone_stub:
type = "stub";
break;
case dns_zone_staticstub:
type = "static-stub";
break;
case dns_zone_redirect:
type = "redirect";
break;
default:
type = "other";
break;
}
dns_zone_log(zone, ISC_LOG_INFO, "(%s) removed", type);
dns_zone_log(zone, ISC_LOG_INFO, "(%s) removed",
dns_zonetype_name(dns_zone_gettype(zone)));
return (ISC_R_SUCCESS);
}
@@ -8518,6 +8517,8 @@ load_configuration(const char *filename, named_server_t *server,
unsigned int initial, idle, keepalive, advertised;
dns_aclenv_t *env =
ns_interfacemgr_getaclenv(named_g_server->interfacemgr);
isc_cfg_tls_data_storage_t tls_storage;
isc_cfg_http_storage_t http_storage;
ISC_LIST_INIT(kasplist);
ISC_LIST_INIT(viewlist);
@@ -8525,6 +8526,9 @@ load_configuration(const char *filename, named_server_t *server,
ISC_LIST_INIT(cachelist);
ISC_LIST_INIT(altsecrets);
cfg_tls_storage_init(named_g_mctx, &tls_storage);
cfg_http_storage_init(named_g_mctx, &http_storage);
/* Create the ACL configuration context */
if (named_g_aclconfctx != NULL) {
cfg_aclconfctx_detach(&named_g_aclconfctx);
@@ -8586,6 +8590,19 @@ load_configuration(const char *filename, named_server_t *server,
maps[i++] = named_g_defaults;
maps[i] = NULL;
obj = NULL;
result = named_config_get(maps, "http-port", &obj);
INSIST(result == ISC_R_SUCCESS);
named_g_http_port = (in_port_t)cfg_obj_asuint32(obj);
obj = NULL;
result = named_config_get(maps, "https-port", &obj);
INSIST(result == ISC_R_SUCCESS);
named_g_http_secure_port = (in_port_t)cfg_obj_asuint32(obj);
CHECK(cfg_tls_storage_load(config, &tls_storage));
CHECK(cfg_http_storage_load(config, &http_storage));
/*
* If bind.keys exists, load it. If "dnssec-validation auto"
* is turned on, the root key found there will be used as a
@@ -9004,7 +9021,8 @@ load_configuration(const char *filename, named_server_t *server,
/* check return code? */
(void)ns_listenlist_fromconfig(
clistenon, config, named_g_aclconfctx,
named_g_mctx, AF_INET, &listenon);
named_g_mctx, AF_INET, &http_storage,
&tls_storage, &listenon);
} else {
/*
* Not specified, use default.
@@ -9032,7 +9050,8 @@ load_configuration(const char *filename, named_server_t *server,
/* check return code? */
(void)ns_listenlist_fromconfig(
clistenon, config, named_g_aclconfctx,
named_g_mctx, AF_INET6, &listenon);
named_g_mctx, AF_INET6, &http_storage,
&tls_storage, &listenon);
} else {
/*
* Not specified, use default.
@@ -9793,6 +9812,9 @@ cleanup:
isc_task_endexclusive(server->task);
}
cfg_http_storage_uninit(&http_storage);
cfg_tls_storage_uninit(&tls_storage);
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER, ISC_LOG_DEBUG(1),
"load_configuration: %s", isc_result_totext(result));
@@ -10792,7 +10814,16 @@ named_server_retransfercommand(named_server_t *server, isc_lex_t *lex,
{
dns_zone_forcereload(zone);
} else {
result = ISC_R_NOTFOUND;
(void)putstr(text, "retransfer: inappropriate zone type: ");
(void)putstr(text, dns_zonetype_name(type));
if (type == dns_zone_redirect) {
type = dns_zone_getredirecttype(zone);
(void)putstr(text, "(");
(void)putstr(text, dns_zonetype_name(type));
(void)putstr(text, ")");
}
(void)putnull(text);
result = ISC_R_FAILURE;
}
dns_zone_detach(&zone);
return (result);
@@ -10991,7 +11022,9 @@ named_server_togglequerylog(named_server_t *server, isc_lex_t *lex) {
static isc_result_t
ns_listenlist_fromconfig(const cfg_obj_t *listenlist, const cfg_obj_t *config,
cfg_aclconfctx_t *actx, isc_mem_t *mctx,
uint16_t family, ns_listenlist_t **target) {
uint16_t family, isc_cfg_http_storage_t *http_servers,
isc_cfg_tls_data_storage_t *tls_storage,
ns_listenlist_t **target) {
isc_result_t result;
const cfg_listelt_t *element;
ns_listenlist_t *dlist = NULL;
@@ -11009,7 +11042,8 @@ ns_listenlist_fromconfig(const cfg_obj_t *listenlist, const cfg_obj_t *config,
ns_listenelt_t *delt = NULL;
const cfg_obj_t *listener = cfg_listelt_value(element);
result = ns_listenelt_fromconfig(listener, config, actx, mctx,
family, &delt);
family, http_servers,
tls_storage, &delt);
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
@@ -11030,14 +11064,18 @@ cleanup:
static isc_result_t
ns_listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config,
cfg_aclconfctx_t *actx, isc_mem_t *mctx,
uint16_t family, ns_listenelt_t **target) {
uint16_t family, isc_cfg_http_storage_t *http_servers,
isc_cfg_tls_data_storage_t *tls_storage,
ns_listenelt_t **target) {
isc_result_t result;
const cfg_obj_t *tlsobj, *portobj, *dscpobj;
in_port_t port;
const cfg_obj_t *tlsobj, *portobj, *dscpobj, *httpobj;
in_port_t port = 0;
isc_dscp_t dscp = -1;
const char *key = NULL, *cert = NULL;
bool tls = false;
bool tls = false, http = false;
ns_listenelt_t *delt = NULL;
isc_cfg_http_obj_t *http_server = NULL;
isc_cfg_tls_obj_t *tls_cert = NULL;
REQUIRE(target != NULL && *target == NULL);
/* XXXWPK TODO be more verbose on failures. */
@@ -11046,43 +11084,60 @@ ns_listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config,
if (!strcmp(cfg_obj_asstring(tlsobj), "ephemeral")) {
tls = true;
} else {
const cfg_obj_t *tlsconfigs = NULL;
const cfg_listelt_t *element;
(void)cfg_map_get(config, "tls", &tlsconfigs);
for (element = cfg_list_first(tlsconfigs);
element != NULL; element = cfg_list_next(element))
{
cfg_obj_t *tconfig = cfg_listelt_value(element);
const cfg_obj_t *name =
cfg_map_getname(tconfig);
if (!strcmp(cfg_obj_asstring(name),
cfg_obj_asstring(tlsobj))) {
tls = true;
const cfg_obj_t *keyo = NULL,
*certo = NULL;
(void)cfg_map_get(tconfig, "key-file",
&keyo);
if (keyo == NULL) {
return (ISC_R_FAILURE);
}
(void)cfg_map_get(tconfig, "cert-file",
&certo);
if (certo == NULL) {
return (ISC_R_FAILURE);
}
key = cfg_obj_asstring(keyo);
cert = cfg_obj_asstring(certo);
break;
}
tls_cert = cfg_tls_storage_find(
cfg_obj_asstring(tlsobj), tls_storage);
if (tls_cert != NULL) {
tls = true;
key = tls_cert->key_file;
cert = tls_cert->cert_file;
INSIST(key != NULL);
INSIST(cert != NULL);
}
}
if (!tls) {
return (ISC_R_FAILURE);
}
}
httpobj = cfg_tuple_get(listener, "http");
if (httpobj != NULL && cfg_obj_isstring(httpobj)) {
if (tls && tls_cert == NULL) {
return (ISC_R_FAILURE);
}
http = true;
http_server = cfg_http_find(cfg_obj_asstring(httpobj),
http_servers);
if (http_server == NULL) {
isc_log_write(
named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER, ISC_LOG_WARNING,
"HTTP(S) server \"%s\" is nowhere to be found",
cfg_obj_asstring(httpobj));
return (ISC_R_FAILURE);
}
}
portobj = cfg_tuple_get(listener, "port");
if (!cfg_obj_isuint32(portobj)) {
if (tls) {
if (http && tls) {
if (named_g_http_secure_port != 0) {
port = named_g_http_secure_port;
} else {
result = named_config_getport(
config, "https-port", &port);
if (result != ISC_R_SUCCESS) {
return (result);
}
}
} else if (http && !tls) {
if (named_g_http_port != 0) {
port = named_g_port;
} else {
result = named_config_getport(
config, "http-port", &port);
if (result != ISC_R_SUCCESS) {
return (result);
}
}
} else if (tls) {
if (named_g_tlsport != 0) {
port = named_g_tlsport;
} else {
@@ -11126,8 +11181,14 @@ ns_listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config,
dscp = (isc_dscp_t)cfg_obj_asuint32(dscpobj);
}
result = ns_listenelt_create(mctx, port, dscp, NULL, tls, key, cert,
&delt);
if (http) {
INSIST(http_server != NULL);
result = ns_listenelt_from_http(http_server, tls_cert, port,
mctx, &delt);
} else {
result = ns_listenelt_create(mctx, port, dscp, NULL, tls, key,
cert, &delt);
}
if (result != ISC_R_SUCCESS) {
return (result);
}
@@ -11143,6 +11204,66 @@ ns_listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config,
return (ISC_R_SUCCESS);
}
/*
* Create a listen list for HTTP/HTTPS
*/
static isc_result_t
ns_listenelt_from_http(isc_cfg_http_obj_t *http, isc_cfg_tls_obj_t *tls,
in_port_t port, isc_mem_t *mctx,
ns_listenelt_t **target) {
isc_result_t result = ISC_R_SUCCESS;
ns_listenelt_t *delt = NULL;
const char *key = NULL, *cert = NULL;
char **http_endpoints = NULL;
size_t http_endpoints_number;
isc_cfg_http_endpoint_t *ep;
size_t i = 0;
REQUIRE(target != NULL && *target == NULL);
if (tls) {
INSIST(tls->key_file != NULL);
INSIST(tls->cert_file != NULL);
key = tls->key_file;
cert = tls->cert_file;
}
if (port == 0) {
port = tls != NULL ? named_g_http_secure_port
: named_g_http_port;
}
for (ep = ISC_LIST_HEAD(http->endpoints), i = 0; ep != NULL;
ep = ISC_LIST_NEXT(ep, link), i++)
;
INSIST(i > 0);
http_endpoints_number = i;
http_endpoints = isc_mem_allocate(mctx, sizeof(http_endpoints[0]) *
http_endpoints_number);
for (ep = ISC_LIST_HEAD(http->endpoints), i = 0; ep != NULL;
ep = ISC_LIST_NEXT(ep, link), i++)
{
http_endpoints[i] = isc_mem_strdup(mctx, ep->path);
}
INSIST(i == http_endpoints_number);
result = ns_listenelt_create_http(mctx, port, named_g_dscp, NULL, key,
cert, http_endpoints,
http_endpoints_number, &delt);
if (result != ISC_R_SUCCESS) {
if (delt != NULL) {
ns_listenelt_destroy(delt);
}
return result;
}
*target = delt;
return (result);
}
isc_result_t
named_server_dumpstats(named_server_t *server) {
isc_result_t result;
@@ -15161,34 +15282,7 @@ named_server_zonestatus(named_server_t *server, isc_lex_t *lex,
zonetype = dns_zone_gettype(zone);
}
switch (zonetype) {
case dns_zone_master:
type = "primary";
break;
case dns_zone_slave:
type = "secondary";
break;
case dns_zone_mirror:
type = "mirror";
break;
case dns_zone_stub:
type = "stub";
break;
case dns_zone_staticstub:
type = "staticstub";
break;
case dns_zone_redirect:
type = "redirect";
break;
case dns_zone_key:
type = "key";
break;
case dns_zone_dlz:
type = "dlz";
break;
default:
type = "unknown";
}
type = dns_zonetype_name(zonetype);
/* Serial number */
result = dns_zone_getserial(mayberaw, &serial);
+2 -2
View File
@@ -2336,12 +2336,12 @@ generatexml(named_server_t *server, uint32_t flags, int *buflen,
TRY0(xmlTextWriterEndElement(writer)); /* /statistics */
TRY0(xmlTextWriterEndDocument(writer));
xmlFreeTextWriter(writer);
xmlDocDumpFormatMemoryEnc(doc, buf, buflen, "UTF-8", 0);
if (*buf == NULL) {
goto cleanup;
}
xmlFreeTextWriter(writer);
xmlFreeDoc(doc);
return (ISC_R_SUCCESS);
+201
View File
@@ -0,0 +1,201 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* 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/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
/*! \file */
#include <inttypes.h>
#include <isc/buffer.h>
#include <isc/string.h>
#include <isc/util.h>
#include <dns/name.h>
#include <dns/transport.h>
#include <isccfg/cfg.h>
#include <named/log.h>
#include <named/transportconf.h>
#define create_name(id, name) \
isc_buffer_t namesrc, namebuf; \
char namedata[DNS_NAME_FORMATSIZE + 1]; \
dns_name_init(name, NULL); \
isc_buffer_constinit(&namesrc, id, strlen(id)); \
isc_buffer_add(&namesrc, strlen(id)); \
isc_buffer_init(&namebuf, namedata, sizeof(namedata)); \
result = (dns_name_fromtext(name, &namesrc, dns_rootname, \
DNS_NAME_DOWNCASE, &namebuf)); \
if (result != ISC_R_SUCCESS) { \
goto failure; \
}
#define parse_transport_option(map, transport, name, setter) \
{ \
const cfg_obj_t *obj = NULL; \
cfg_map_get(map, name, &obj); \
if (obj != NULL) { \
setter(transport, cfg_obj_asstring(obj)); \
} \
}
static isc_result_t
add_doh_transports(const cfg_obj_t *transportlist, dns_transport_list_t *list) {
const cfg_obj_t *doh = NULL;
const char *dohid = NULL;
isc_result_t result;
for (const cfg_listelt_t *element = cfg_list_first(transportlist);
element != NULL; element = cfg_list_next(element))
{
dns_name_t dohname;
dns_transport_t *transport;
doh = cfg_listelt_value(element);
dohid = cfg_obj_asstring(cfg_map_getname(doh));
create_name(dohid, &dohname);
transport = dns_transport_new(&dohname, DNS_TRANSPORT_DOH,
list);
parse_transport_option(doh, transport, "key-file",
dns_transport_set_keyfile);
parse_transport_option(doh, transport, "cert-file",
dns_transport_set_certfile);
parse_transport_option(doh, transport, "ca-file",
dns_transport_set_cafile);
parse_transport_option(doh, transport, "hostname",
dns_transport_set_hostname);
}
return (ISC_R_SUCCESS);
failure:
cfg_obj_log(doh, named_g_lctx, ISC_LOG_ERROR,
"configuring DoH '%s': %s", dohid,
isc_result_totext(result));
return (result);
}
static isc_result_t
add_tls_transports(const cfg_obj_t *transportlist, dns_transport_list_t *list) {
const cfg_obj_t *tls = NULL;
const char *tlsid = NULL;
isc_result_t result;
for (const cfg_listelt_t *element = cfg_list_first(transportlist);
element != NULL; element = cfg_list_next(element))
{
dns_name_t tlsname;
dns_transport_t *transport;
tls = cfg_listelt_value(element);
tlsid = cfg_obj_asstring(cfg_map_getname(tls));
if (!strcmp(tlsid, "ephemeral")) {
result = ISC_R_UNEXPECTEDTOKEN;
goto failure;
}
create_name(tlsid, &tlsname);
transport = dns_transport_new(&tlsname, DNS_TRANSPORT_TLS,
list);
parse_transport_option(tls, transport, "key-file",
dns_transport_set_keyfile);
parse_transport_option(tls, transport, "cert-file",
dns_transport_set_certfile);
parse_transport_option(tls, transport, "ca-file",
dns_transport_set_cafile);
parse_transport_option(tls, transport, "hostname",
dns_transport_set_hostname);
}
return (ISC_R_SUCCESS);
failure:
cfg_obj_log(tls, named_g_lctx, ISC_LOG_ERROR,
"configuring tls '%s': %s", tlsid,
isc_result_totext(result));
return (result);
}
#define CHECK(f) \
if ((result = f) != ISC_R_SUCCESS) { \
goto failure; \
}
static isc_result_t
transport_list_fromconfig(const cfg_obj_t *config, dns_transport_list_t *list) {
const cfg_obj_t *obj = NULL;
isc_result_t result = ISC_R_SUCCESS;
if (result == ISC_R_SUCCESS &&
cfg_map_get(config, "tls", &obj) == ISC_R_SUCCESS)
{
result = add_tls_transports(obj, list);
obj = NULL;
}
if (result == ISC_R_SUCCESS &&
cfg_map_get(config, "doh", &obj) == ISC_R_SUCCESS)
{
result = add_doh_transports(obj, list);
obj = NULL;
}
return (result);
}
static void
transport_list_add_ephemeral(dns_transport_list_t *list) {
isc_result_t result;
dns_name_t tlsname;
create_name("ephemeral", &tlsname);
(void)dns_transport_new(&tlsname, DNS_TRANSPORT_TLS, list);
return;
failure:
RUNTIME_CHECK(result == ISC_R_SUCCESS);
}
isc_result_t
named_transports_fromconfig(const cfg_obj_t *config, const cfg_obj_t *vconfig,
isc_mem_t *mctx, dns_transport_list_t **listp) {
isc_result_t result;
dns_transport_list_t *list = dns_transport_list_new(mctx);
REQUIRE(listp != NULL && *listp == NULL);
transport_list_add_ephemeral(list);
if (config != NULL) {
result = transport_list_fromconfig(config, list);
if (result != ISC_R_SUCCESS) {
goto failure;
}
}
if (vconfig != NULL) {
config = cfg_tuple_get(vconfig, "options");
transport_list_fromconfig(config, list);
}
*listp = list;
return (ISC_R_SUCCESS);
failure:
dns_transport_list_detach(&list);
return (result);
}
+6
View File
@@ -59,6 +59,9 @@
<ClCompile Include="..\tkeyconf.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\transportconf.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\tsigconf.c">
<Filter>Source Files</Filter>
</ClCompile>
@@ -111,6 +114,9 @@
<ClInclude Include="..\include\named\tkeyconf.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\named\transportconf.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\named\tsigconf.h">
<Filter>Header Files</Filter>
</ClInclude>
+2
View File
@@ -138,6 +138,7 @@ perl -e "print \";\";" &gt;&gt; xsl.c
<ClCompile Include="..\server.c" />
<ClCompile Include="..\statschannel.c" />
<ClCompile Include="..\tkeyconf.c" />
<ClCompile Include="..\transportconf.c" />
<ClCompile Include="..\tsigconf.c" />
<ClCompile Include="..\xsl.c" />
<ClCompile Include="..\zoneconf.c" />
@@ -159,6 +160,7 @@ perl -e "print \";\";" &gt;&gt; xsl.c
<ClInclude Include="..\include\named\server.h" />
<ClInclude Include="..\include\named\statschannel.h" />
<ClInclude Include="..\include\named\tkeyconf.h" />
<ClInclude Include="..\include\named\transportconf.h" />
<ClInclude Include="..\include\named\tsigconf.h" />
<ClInclude Include="..\include\named\types.h" />
<ClInclude Include="..\xsl_p.h" />
+16 -12
View File
@@ -176,7 +176,7 @@ configure_zone_acl(const cfg_obj_t *zconfig, const cfg_obj_t *vconfig,
parse_acl:
result = cfg_acl_fromconfig(aclobj, config, named_g_lctx, actx,
dns_zone_getmctx(zone), 0, &acl);
named_g_mctx, 0, &acl);
if (result != ISC_R_SUCCESS) {
return (result);
}
@@ -1302,13 +1302,14 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
RETERR(named_config_getipandkeylist(config, obj, mctx,
&ipkl));
result = dns_zone_setalsonotifydscpkeys(
zone, ipkl.addrs, ipkl.dscps, ipkl.keys,
ipkl.count);
result = dns_zone_setalsonotify(zone, ipkl.addrs,
ipkl.dscps, ipkl.keys,
ipkl.tlss, ipkl.count);
dns_ipkeylist_clear(mctx, &ipkl);
RETERR(result);
} else {
RETERR(dns_zone_setalsonotify(zone, NULL, 0));
RETERR(dns_zone_setalsonotify(zone, NULL, NULL, NULL,
NULL, 0));
}
obj = NULL;
@@ -1910,13 +1911,15 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
RETERR(named_config_getipandkeylist(config, obj, mctx,
&ipkl));
result = dns_zone_setprimarieswithkeys(
mayberaw, ipkl.addrs, ipkl.keys, ipkl.count);
result = dns_zone_setprimaries(mayberaw, ipkl.addrs,
ipkl.keys, ipkl.tlss,
ipkl.count);
count = ipkl.count;
dns_ipkeylist_clear(mctx, &ipkl);
RETERR(result);
} else {
result = dns_zone_setprimaries(mayberaw, NULL, 0);
result = dns_zone_setprimaries(mayberaw, NULL, NULL,
NULL, 0);
}
RETERR(result);
@@ -2068,7 +2071,8 @@ named_zone_configure_writeable_dlz(dns_dlzdb_t *dlzdatabase, dns_zone_t *zone,
bool
named_zone_reusable(dns_zone_t *zone, const cfg_obj_t *zconfig,
const cfg_obj_t *vconfig, const cfg_obj_t *config) {
const cfg_obj_t *vconfig, const cfg_obj_t *config,
cfg_aclconfctx_t *actx) {
const cfg_obj_t *zoptions = NULL;
const cfg_obj_t *obj = NULL;
const char *cfilename;
@@ -2103,7 +2107,7 @@ named_zone_reusable(dns_zone_t *zone, const cfg_obj_t *zconfig,
}
inline_signing = named_zone_inlinesigning(zone, zconfig, vconfig,
config);
config, actx);
if (!inline_signing && has_raw) {
dns_zone_log(zone, ISC_LOG_DEBUG(1),
"not reusable: old zone was inline-signing");
@@ -2141,7 +2145,8 @@ named_zone_reusable(dns_zone_t *zone, const cfg_obj_t *zconfig,
bool
named_zone_inlinesigning(dns_zone_t *zone, const cfg_obj_t *zconfig,
const cfg_obj_t *vconfig, const cfg_obj_t *config) {
const cfg_obj_t *vconfig, const cfg_obj_t *config,
cfg_aclconfctx_t *actx) {
isc_result_t res;
const cfg_obj_t *zoptions = NULL;
const cfg_obj_t *voptions = NULL;
@@ -2181,7 +2186,6 @@ named_zone_inlinesigning(dns_zone_t *zone, const cfg_obj_t *zconfig,
}
if (res == ISC_R_SUCCESS) {
dns_acl_t *acl = NULL;
cfg_aclconfctx_t *actx = NULL;
res = cfg_acl_fromconfig(
allowupdate, config, named_g_lctx, actx,
dns_zone_getmctx(zone), 0, &acl);
+1
View File
@@ -151,6 +151,7 @@ TESTS += \
views \
wildcard \
xferquota \
xot \
zonechecks
# eddsa test is broken
@@ -0,0 +1,27 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* 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 http://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
tls local-tls {
key-file "key.pem";
cert-file "cert.pem";
};
http local-http-server {
endpoints { "/dns-query"; };
};
options {
listen-on { 10.53.0.1; };
http-port 80;
https-port 443;
listen-on port 443 tls local-tls http local-http-server { 10.53.0.1; };
listen-on port 8080 http local-http-server { 10.53.0.1; };
};
@@ -0,0 +1,19 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* 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 http://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
tls local-tls {
key-file "key.pem";
cert-file "cert.pem";
};
options {
listen-on port 853 tls local-tls { 10.53.0.1; };
};
+2
View File
@@ -668,6 +668,8 @@ copy_setports() {
atsign="@"
sed -e "s/${atsign}PORT${atsign}/${PORT}/g" \
-e "s/${atsign}TLSPORT${atsign}/${TLSPORT}/g" \
-e "s/${atsign}HTTPPORT${atsign}/${HTTPSPORT}/g" \
-e "s/${atsign}HTTPSPORT${atsign}/${HTTPSPORT}/g" \
-e "s/${atsign}EXTRAPORT1${atsign}/${EXTRAPORT1}/g" \
-e "s/${atsign}EXTRAPORT2${atsign}/${EXTRAPORT2}/g" \
-e "s/${atsign}EXTRAPORT3${atsign}/${EXTRAPORT3}/g" \
+2
View File
@@ -82,6 +82,8 @@ done
echo "export PORT=$(get_port "$baseport")"
echo "export TLSPORT=$(get_port)"
echo "export HTTPPORT=$(get_port)"
echo "export HTTPSPORT=$(get_port)"
echo "export EXTRAPORT1=$(get_port)"
echo "export EXTRAPORT2=$(get_port)"
echo "export EXTRAPORT3=$(get_port)"
+5 -1
View File
@@ -23,6 +23,10 @@ options {
minimal-responses no;
};
acl named-acl {
any;
};
key rndc_key {
secret "1234abcd8765";
algorithm hmac-sha256;
@@ -67,7 +71,7 @@ zone "max-ttl.nil" {
file "max-ttl.db";
max-zone-ttl 300;
check-integrity no;
allow-update { any; };
allow-update { named-acl; };
allow-transfer { any; };
};
+21 -1
View File
@@ -795,7 +795,7 @@ fi
n=`expr $n + 1`
ret=0
echo_i "check TSIG key algorithms ($n)"
echo_i "check TSIG key algorithms (nsupdate -k) ($n)"
for alg in md5 sha1 sha224 sha256 sha384 sha512; do
$NSUPDATE -k ns1/${alg}.key <<END > /dev/null || ret=1
server 10.53.0.1 ${PORT}
@@ -812,6 +812,26 @@ if [ $ret -ne 0 ]; then
status=1
fi
n=`expr $n + 1`
ret=0
echo_i "check TSIG key algorithms (nsupdate -y) ($n)"
for alg in md5 sha1 sha224 sha256 sha384 sha512; do
secret=$(sed -n 's/.*secret "\(.*\)";.*/\1/p' ns1/${alg}.key)
$NSUPDATE -y "hmac-${alg}:${alg}-key:$secret" <<END > /dev/null || ret=1
server 10.53.0.1 ${PORT}
update add ${alg}.keytests.nil. 600 A 10.10.10.50
send
END
done
sleep 2
for alg in md5 sha1 sha224 sha256 sha384 sha512; do
$DIG $DIGOPTS +short @10.53.0.1 ${alg}.keytests.nil | grep 10.10.10.50 > /dev/null 2>&1 || ret=1
done
if [ $ret -ne 0 ]; then
echo_i "failed"
status=1
fi
n=`expr $n + 1`
ret=0
echo_i "check that ttl is capped by max-ttl ($n)"
+11
View File
@@ -677,5 +677,16 @@ lines=`cat rndc.out.test$n | wc -l`
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
echo_i "check 'rndc retransfer' of primary error message ($n)"
ret=0
$RNDCCMD 10.53.0.2 retransfer nil > rndc.out.test$n 2>&1 && ret=1
grep "rndc: 'retransfer' failed: failure" rndc.out.test$n > /dev/null || ret=1
grep "retransfer: inappropriate zone type: primary" rndc.out.test$n > /dev/null || ret=1
lines=`cat rndc.out.test$n | wc -l`
[ ${lines:-0} -eq 2 ] || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
echo_i "exit status: $status"
[ $status -eq 0 ] || exit 1
+24
View File
@@ -0,0 +1,24 @@
Copyright (C) Internet Systems Consortium, Inc. ("ISC")
See COPYRIGHT in the source root or https://isc.org/copyright.html for terms.
The `rsabigexponent` test is used to `check max-rsa-exponent-size`.
We only run this test on builds without PKCS#11, as we have control over
the RSA exponent size with plain OpenSSL. We have not explored how to do
this with PKCS#11, which would require generating such a key and then
signing a zone with it. Additionally, even with control of the exponent
size with PKCS#11, generating a DNSKEY with this property and signing
such a zone would be slow and undesirable for each test run; instead, we
use a pregenerated DNSKEY and a saved signed zone. These are located in
`rsabigexponent/ns2` and currently use RSASHA1 for the `DNSKEY`
algorithm; however, that may need to be changed in the future.
To generate the `DNSKEY` used in this test, we used `bigkey.c`, as
dnssec-keygen is not capable of generating such keys.
Do **not** remove `bigkey.c` as it may be needed to generate a new
`DNSKEY` for testing purposes.
`bigkey` is used to both test that we are not running under PKCS#11 and
generate a `DNSKEY` key with a large RSA exponent.
+1 -1
View File
@@ -149,7 +149,7 @@ stop_servers() {
echostart "S:$systest:$(date_with_args)"
echoinfo "T:$systest:1:A"
echoinfo "A:$systest:System test $systest"
echoinfo "I:$systest:PORTS:${PORT},${TLSPORT},${EXTRAPORT1},${EXTRAPORT2},${EXTRAPORT3},${EXTRAPORT4},${EXTRAPORT5},${EXTRAPORT6},${EXTRAPORT7},${EXTRAPORT8},${CONTROLPORT}"
echoinfo "I:$systest:PORTS:${PORT},${TLSPORT},${HTTPPORT},${HTTPSPORT},${EXTRAPORT1},${EXTRAPORT2},${EXTRAPORT3},${EXTRAPORT4},${EXTRAPORT5},${EXTRAPORT6},${EXTRAPORT7},${EXTRAPORT8},${CONTROLPORT}"
$PERL ${srcdir}/testsock.pl -p "$PORT" || {
echowarn "I:$systest:Network interface aliases not set up. Skipping test."
+1 -1
View File
@@ -145,7 +145,7 @@ sub reply_handler {
$rcode = "NXDOMAIN";
}
# mark the answer as authoritative (by setting the 'aa' flag
# mark the answer as authoritative (by setting the 'aa' flag)
return ($rcode, \@ans, \@auth, \@add, { aa => 1 });
}
@@ -0,0 +1,50 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* 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 http://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
/*
* Test stale-answer-client-timeout 0.
*/
key rndc_key {
secret "1234abcd8765";
algorithm hmac-sha256;
};
controls {
inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
};
options {
query-source address 10.53.0.3;
notify-source 10.53.0.3;
transfer-source 10.53.0.3;
port @PORT@;
pid-file "named.pid";
listen-on { 10.53.0.3; };
listen-on-v6 { none; };
dnssec-validation no;
recursion yes;
stale-answer-enable no;
stale-cache-enable yes;
stale-answer-ttl 3;
stale-answer-client-timeout disabled;
stale-refresh-time 4;
resolver-query-timeout 10;
fetches-per-zone 1 fail;
fetches-per-server 1 fail;
max-stale-ttl 3600;
};
zone "." {
type hint;
file "root.db";
};
+99
View File
@@ -2010,5 +2010,104 @@ grep "data\.example\..*[12].*IN.*TXT.*A text record with a 2 second ttl" dig.out
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status+ret))
####################################################################
# Test if fetch-limits quota is reached, stale data is served. #
####################################################################
echo_i "test stale data with fetch-limits"
n=$((n+1))
echo_i "updating ns3/named.conf ($n)"
ret=0
copy_setports ns3/named6.conf.in ns3/named.conf
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status+ret))
n=$((n+1))
echo_i "running 'rndc reload' ($n)"
ret=0
rndc_reload ns3 10.53.0.3
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status+ret))
# Disable responses from authoritative server.
n=$((n+1))
echo_i "disable responses from authoritative server ($n)"
ret=0
$DIG -p ${PORT} @10.53.0.2 txt disable > dig.out.test$n
grep "ANSWER: 1," dig.out.test$n > /dev/null || ret=1
grep "TXT.\"0\"" dig.out.test$n > /dev/null || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status+ret))
# Hit the fetch-limits.
burst() {
num=${1}
rm -f burst.input.$$
while [ $num -gt 0 ]; do
num=`expr $num - 1`
echo "${num}.data.example A" >> burst.input.$$
done
$PERL ../ditch.pl -p ${PORT} -s 10.53.0.3 burst.input.$$
rm -f burst.input.$$
}
wait_for_fetchlimits() {
burst 20
$DIG -p ${PORT} @10.53.0.3 data.example A > dig.out.test$n
grep "status: SERVFAIL" dig.out.test$n > /dev/null || return 1
}
n=$((n+1))
echo_i "hit fetch limits ($n)"
ret=0
retry_quiet 10 wait_for_fetchlimits || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status+ret))
# Allow RRset to become stale.
sleep 2
# Turn on serve-stale.
n=$((n+1))
echo_i "running 'rndc serve-stale on' ($n)"
ret=0
$RNDCCMD 10.53.0.3 serve-stale on || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status+ret))
n=$((n+1))
echo_i "check 'rndc serve-stale status' ($n)"
ret=0
$RNDCCMD 10.53.0.3 serve-stale status > rndc.out.test$n 2>&1 || ret=1
grep '_default: on (rndc) (stale-answer-ttl=3 max-stale-ttl=3600 stale-refresh-time=4)' rndc.out.test$n > /dev/null || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status+ret))
# Expect stale data now.
n=$((n+1))
ret=0
echo_i "check stale data.example comes from cache (fetch-limits) ($n)"
nextpart ns3/named.run > /dev/null
$DIG -p ${PORT} @10.53.0.3 data.example TXT > dig.out.test$n
wait_for_log 5 "data.example resolver failure, stale answer used" ns3/named.run || ret=1
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
grep "ANSWER: 1," dig.out.test$n > /dev/null || ret=1
grep "data\.example\..*3.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n > /dev/null || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status+ret))
# The previous query should not have started the stale-refresh-time window.
n=$((n+1))
ret=0
echo_i "check stale data.example comes from cache again (fetch-limits) ($n)"
nextpart ns3/named.run > /dev/null
$DIG -p ${PORT} @10.53.0.3 data.example TXT > dig.out.test$n
wait_for_log 5 "data.example resolver failure, stale answer used" ns3/named.run || ret=1
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
grep "ANSWER: 1," dig.out.test$n > /dev/null || ret=1
grep "data\.example\..*3.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n > /dev/null || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status+ret))
echo_i "exit status: $status"
[ $status -eq 0 ] || exit 1
+21
View File
@@ -0,0 +1,21 @@
#!/bin/sh
#
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# 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/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
#
# Clean up after zone transfer tests.
#
rm -f ./*/named.conf
rm -f ./*/named.memstats
rm -f ./*/named.run
rm -f ./*/named.run.prev
rm -f ./dig.out.*
rm -f ./*/*.db
+171
View File
@@ -0,0 +1,171 @@
example. 86400 IN SOA ns2.example. hostmaster.example. 1397051952 5 5 1814400 3600
example. 3600 IN NS ns2.example.
a01.example. 3600 IN A 0.0.0.0
a02.example. 3600 IN A 255.255.255.255
a601.example. 3600 IN A6 0 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
a601.example. 3600 IN A6 64 ::ffff:ffff:ffff:ffff foo.
a601.example. 3600 IN A6 127 ::1 foo.
a601.example. 3600 IN A6 128 .
aaaa01.example. 3600 IN AAAA ::1
aaaa02.example. 3600 IN AAAA fd92:7065:b8e:ffff::5
afsdb01.example. 3600 IN AFSDB 0 hostname.example.
afsdb02.example. 3600 IN AFSDB 65535 .
amtrelay01.example. 3600 IN AMTRELAY 0 0 0
amtrelay02.example. 3600 IN AMTRELAY 0 1 0
amtrelay03.example. 3600 IN AMTRELAY 0 0 1 0.0.0.0
amtrelay04.example. 3600 IN AMTRELAY 0 0 2 ::
amtrelay05.example. 3600 IN AMTRELAY 0 0 3 example.net.
amtrelay06.example. 3600 IN AMTRELAY \# 2 0004
apl01.example. 3600 IN APL !1:10.0.0.1/32 1:10.0.0.0/24
apl02.example. 3600 IN APL
atma01.example. 3600 IN ATMA +61200000000
atma02.example. 3600 IN ATMA +61200000000
atma03.example. 3600 IN ATMA 1234567890abcdef
atma04.example. 3600 IN ATMA fedcba0987654321
avc.example. 3600 IN AVC "foo:bar"
caa01.example. 3600 IN CAA 0 issue "ca.example.net; policy=ev"
caa02.example. 3600 IN CAA 128 tbs "Unknown"
caa03.example. 3600 IN CAA 128 tbs ""
cdnskey01.example. 3600 IN CDNSKEY 512 255 1 AQMFD5raczCJHViKtLYhWGz8hMY9UGRuniJDBzC7w0aRyzWZriO6i2od GWWQVucZqKVsENW91IOW4vqudngPZsY3GvQ/xVA8/7pyFj6b7Esga60z yGW6LFe9r8n6paHrlG5ojqf0BaqHT+8=
cds01.example. 3600 IN CDS 30795 1 1 310D27F4D82C1FC2400704EA9939FE6E1CEAA3B9
cert01.example. 3600 IN CERT 65534 65535 PRIVATEOID MxFcby9k/yvedMfQgKzhH5er0Mu/vILz45IkskceFGgiWCn/GxHhai6V AuHAoNUz4YoU1tVfSCSqQYn6//11U6Nld80jEeC8aTrO+KKmCaY=
cname01.example. 3600 IN CNAME cname-target.
cname02.example. 3600 IN CNAME cname-target.example.
cname03.example. 3600 IN CNAME .
csync01.example. 3600 IN CSYNC 0 0 A NS AAAA
csync02.example. 3600 IN CSYNC 0 0
dhcid01.example. 3600 IN DHCID AAIBY2/AuCccgoJbsaxcQc9TUapptP69lOjxfNuVAA2kjEA=
dhcid02.example. 3600 IN DHCID AAEBOSD+XR3Os/0LozeXVqcNc7FwCfQdWL3b/NaiUDlW2No=
dhcid03.example. 3600 IN DHCID AAABxLmlskllE0MVjd57zHcWmEH3pCQ6VytcKD//7es/deY=
dlv.example. 3600 IN DLV 30795 1 1 310D27F4D82C1FC2400704EA9939FE6E1CEAA3B9
dname01.example. 3600 IN DNAME dname-target.
dname02.example. 3600 IN DNAME dname-target.example.
dname03.example. 3600 IN DNAME .
dnskey01.example. 3600 IN DNSKEY 512 255 1 AQMFD5raczCJHViKtLYhWGz8hMY9UGRuniJDBzC7w0aRyzWZriO6i2od GWWQVucZqKVsENW91IOW4vqudngPZsY3GvQ/xVA8/7pyFj6b7Esga60z yGW6LFe9r8n6paHrlG5ojqf0BaqHT+8=
doa01.example. 3600 IN DOA 1234567890 1234567890 1 "image/gif" R0lGODlhKAAZAOMCAGZmZgBmmf///zOZzMz//5nM/zNmmWbM/5nMzMzMzACZ/////////////////////yH5BAEKAA8ALAAAAAAoABkAAATH8IFJK5U2a4337F5ogRkpnoCJrly7PrCKyh8c3HgAhzT35MDbbtO7/IJIHbGiOiaTxVTpSVWWLqNq1UVyapNS1wd3OAxug0LhnCubcVhsxysQnOt4ATpvvzHlFzl1AwODhWeFAgRpen5/UhheAYMFdUB4SFcpGEGGdQeCAqBBLTuSk30EeXd9pEsAbKGxjHqDSE0Sp6ixN4N1BJmbc7lIhmsBich1awPAjkY1SZR8bJWrz382SGqIBQQFQd4IsUTaX+ceuudPEQA7
doa02.example. 3600 IN DOA 0 1 2 "" aHR0cHM6Ly93d3cuaXNjLm9yZy8=
ds01.example. 3600 IN DS 12892 5 2 26584835CA80C81C91999F31CFAF2A0E89D4FF1C8FAFD0DDB31A85C7 19277C13
ds01.example. 3600 IN NS ns42.example.
ds02.example. 3600 IN DS 12892 5 1 7AA4A3F416C2F2391FB7AB0D434F762CD62D1390
ds02.example. 3600 IN NS ns43.example.
eid01.example. 3600 IN EID 1289AB
eui48.example. 3600 IN EUI48 01-23-45-67-89-ab
eui64.example. 3600 IN EUI64 01-23-45-67-89-ab-cd-ef
gid01.example. 3600 IN GID \# 1 03
gpos01.example. 3600 IN GPOS "-22.6882" "116.8652" "250.0"
gpos02.example. 3600 IN GPOS "" "" ""
hinfo01.example. 3600 IN HINFO "Generic PC clone" "NetBSD-1.4"
hinfo02.example. 3600 IN HINFO "PC" "NetBSD"
hip1.example. 3600 IN HIP 2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D
hip2.example. 3600 IN HIP 2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D rvs.example.com.
ipseckey01.example. 3600 IN IPSECKEY 10 1 2 192.0.2.38 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
ipseckey02.example. 3600 IN IPSECKEY 10 0 2 . AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
ipseckey03.example. 3600 IN IPSECKEY 10 1 2 192.0.2.3 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
ipseckey04.example. 3600 IN IPSECKEY 10 3 2 mygateway.example.com. AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
ipseckey05.example. 3600 IN IPSECKEY 10 2 2 2001:db8:0:8002::2000:1 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
isdn01.example. 3600 IN ISDN "isdn-address"
isdn02.example. 3600 IN ISDN "isdn-address" "subaddress"
isdn03.example. 3600 IN ISDN "isdn-address"
isdn04.example. 3600 IN ISDN "isdn-address" "subaddress"
keydata.example. 3600 IN TYPE65533 \# 0
keydata.example. 3600 IN TYPE65533 \# 6 010203040506
keydata.example. 3600 IN TYPE65533 \# 18 010203040506010203040506010203040506
kx01.example. 3600 IN KX 10 kdc.example.
kx02.example. 3600 IN KX 10 .
l32.example. 3600 IN L32 10 1.2.3.4
l64.example. 3600 IN L64 10 14:4fff:ff20:ee64
loc01.example. 3600 IN LOC 60 9 0.000 N 24 39 0.000 E 10.00m 20m 2000m 20m
loc02.example. 3600 IN LOC 60 9 0.000 N 24 39 0.000 E 10.00m 20m 2000m 20m
lp.example. 3600 IN LP 10 example.net.
mb01.example. 3600 IN MG madname.example.
mb02.example. 3600 IN MG .
mg01.example. 3600 IN MG mgmname.example.
mg02.example. 3600 IN MG .
minfo01.example. 3600 IN MINFO rmailbx.example. emailbx.example.
minfo02.example. 3600 IN MINFO . .
mr01.example. 3600 IN MR mrname.example.
mr02.example. 3600 IN MR .
mx01.example. 3600 IN MX 10 mail.example.
mx02.example. 3600 IN MX 10 .
naptr01.example. 3600 IN NAPTR 0 0 "" "" "" .
naptr02.example. 3600 IN NAPTR 65535 65535 "blurgh" "blorf" "blllbb" foo.
nid.example. 3600 IN NID 10 14:4fff:ff20:ee64
nimloc01.example. 3600 IN NIMLOC 1289AB
ninfo01.example. 3600 IN NINFO "foo"
ninfo02.example. 3600 IN NINFO "foo" "bar"
ninfo03.example. 3600 IN NINFO "foo"
ninfo04.example. 3600 IN NINFO "foo" "bar"
ninfo05.example. 3600 IN NINFO "foo bar"
ninfo06.example. 3600 IN NINFO "foo bar"
ninfo07.example. 3600 IN NINFO "foo bar"
ninfo08.example. 3600 IN NINFO "foo\010bar"
ninfo09.example. 3600 IN NINFO "foo\010bar"
ninfo10.example. 3600 IN NINFO "foo bar"
ninfo11.example. 3600 IN NINFO "\"foo\""
ninfo12.example. 3600 IN NINFO "\"foo\""
ninfo13.example. 3600 IN NINFO "foo;"
ninfo14.example. 3600 IN NINFO "foo;"
ninfo15.example. 3600 IN NINFO "bar\\;"
ns2.example. 3600 IN A 10.53.0.2
nsap-ptr01.example. 3600 IN NSAP-PTR foo.
nsap-ptr01.example. 3600 IN NSAP-PTR .
nsap01.example. 3600 IN NSAP 0x47000580005a0000000001e133ffffff00016100
nsap02.example. 3600 IN NSAP 0x47000580005a0000000001e133ffffff00016100
nsec01.example. 3600 IN NSEC a.secure.nil. NS SOA MX LOC RRSIG NSEC DNSKEY
nsec02.example. 3600 IN NSEC . NSAP-PTR NSEC
nsec03.example. 3600 IN NSEC . A
nsec04.example. 3600 IN NSEC . TYPE127
openpgpkey.example. 3600 IN OPENPGPKEY AQMFD5raczCJHViKtLYhWGz8hMY9UGRuniJDBzC7w0aRyzWZriO6i2od GWWQVucZqKVsENW91IOW4vqudngPZsY3GvQ/xVA8/7pyFj6b7Esga60z yGW6LFe9r8n6paHrlG5ojqf0BaqHT+8=
ptr01.example. 3600 IN PTR example.
px01.example. 3600 IN PX 65535 foo. bar.
px02.example. 3600 IN PX 65535 . .
rkey01.example. 3600 IN RKEY 0 255 1 AQMFD5raczCJHViKtLYhWGz8hMY9UGRuniJDBzC7w0aRyzWZriO6i2od GWWQVucZqKVsENW91IOW4vqudngPZsY3GvQ/xVA8/7pyFj6b7Esga60z yGW6LFe9r8n6paHrlG5ojqf0BaqHT+8=
rp01.example. 3600 IN RP mbox-dname.example. txt-dname.example.
rp02.example. 3600 IN RP . .
rrsig01.example. 3600 IN RRSIG NSEC 1 3 3600 20000102030405 19961211100908 2143 foo.nil. MxFcby9k/yvedMfQgKzhH5er0Mu/vILz45IkskceFGgiWCn/GxHhai6V AuHAoNUz4YoU1tVfSCSqQYn6//11U6Nld80jEeC8aTrO+KKmCaY=
rt01.example. 3600 IN RT 0 intermediate-host.example.
rt02.example. 3600 IN RT 65535 .
sink01.example. 3600 IN SINK 1 0 0
sink02.example. 3600 IN SINK 8 0 2 l4ik
smimea.example. 3600 IN SMIMEA 1 1 2 92003BA34942DC74152E2F2C408D29ECA5A520E7F2E06BB944F4DCA3 46BAF63C1B177615D466F6C4B71C216A50292BD58C9EBDD2F74E38FE 51FFD48C43326CBC
spf01.example. 3600 IN SPF "v=spf1 -all"
spf02.example. 3600 IN SPF "v=spf1" " -all"
srv01.example. 3600 IN SRV 0 0 0 .
srv02.example. 3600 IN SRV 65535 65535 65535 old-slow-box.example.
sshfp01.example. 3600 IN SSHFP 4 2 C76D8329954DA2835751E371544E963EFDA099080D6C58DD2BFD9A31 6E162C83
sshfp02.example. 3600 IN SSHFP 1 2 BF29468C83AC58CCF8C85AB7B3BEB054ECF1E38512B8353AB36471FA 88961DCC
ta.example. 3600 IN TA 30795 1 1 310D27F4D82C1FC2400704EA9939FE6E1CEAA3B9
talink0.example. 3600 IN TALINK . talink1.example.
talink1.example. 3600 IN TALINK talink0.example. talink2.example.
talink2.example. 3600 IN TALINK talink2.example. .
tlsa.example. 3600 IN TLSA 1 1 2 92003BA34942DC74152E2F2C408D29ECA5A520E7F2E06BB944F4DCA3 46BAF63C1B177615D466F6C4B71C216A50292BD58C9EBDD2F74E38FE 51FFD48C43326CBC
txt01.example. 3600 IN TXT "foo"
txt02.example. 3600 IN TXT "foo" "bar"
txt03.example. 3600 IN TXT "foo"
txt04.example. 3600 IN TXT "foo" "bar"
txt05.example. 3600 IN TXT "foo bar"
txt06.example. 3600 IN TXT "foo bar"
txt07.example. 3600 IN TXT "foo bar"
txt08.example. 3600 IN TXT "foo\010bar"
txt09.example. 3600 IN TXT "foo\010bar"
txt10.example. 3600 IN TXT "foo bar"
txt11.example. 3600 IN TXT "\"foo\""
txt12.example. 3600 IN TXT "\"foo\""
txt13.example. 3600 IN TXT "foo;"
txt14.example. 3600 IN TXT "foo;"
txt15.example. 3600 IN TXT "bar\\;"
uid01.example. 3600 IN UID \# 1 02
uinfo01.example. 3600 IN UINFO \# 1 01
unspec01.example. 3600 IN UNSPEC \# 1 04
uri01.example. 3600 IN URI 10 20 "https://www.isc.org/"
uri02.example. 3600 IN URI 30 40 "https://www.isc.org/HolyCowThisSureIsAVeryLongURIRecordIDontEvenKnowWhatSomeoneWouldEverWantWithSuchAThingButTheSpecificationRequiresThatWesupportItSoHereWeGoTestingItLaLaLaLaLaLaLaSeriouslyThoughWhyWouldYouEvenConsiderUsingAURIThisLongItSeemsLikeASillyIdeaButEnhWhatAreYouGonnaDo/"
uri03.example. 3600 IN URI 30 40 ""
wks01.example. 3600 IN WKS 10.0.0.1 6 0 1 2 21 23
wks02.example. 3600 IN WKS 10.0.0.1 17 0 1 2 53
wks03.example. 3600 IN WKS 10.0.0.2 6 65535
x2501.example. 3600 IN X25 "123456789"
zonemd01.example. 3600 IN ZONEMD 2019020700 1 0 C220B8A6ED5728A971902F7E3D4FD93ADEEA88B0453C2E8E8C863D46 5AB06CF34EB95B266398C98B59124FA239CB7EEB
8f1tmio9avcom2k0frp92lgcumak0cad.example. 3600 IN NSEC3 1 0 10 D2CF0294C020CE6C 8FPNS2UCT7FBS643THP2B77PEQ77K6IU A NS SOA MX AAAA RRSIG DNSKEY NSEC3PARAM
kcd3juae64f9c5csl1kif1htaui7un0g.example. 3600 IN NSEC3 1 0 10 D2CF0294C020CE6C KD5MN2M20340DGO0BL7NTSB8JP4BSC7E
mr5ukvsk1l37btu4q7b1dfevft4hkqdk.example. 3600 IN NSEC3 1 0 10 D2CF0294C020CE6C MT38J6VG7S0SN5G17MCUF6IQIKFUAJ05 A AAAA RRSIG
example. 86400 IN SOA ns2.example. hostmaster.example. 1397051952 5 5 1814400 3600
+41
View File
@@ -0,0 +1,41 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* 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 http://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
include "../../common/rndc.key";
controls {
inet 10.53.0.1 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
};
options {
port @PORT@;
tls-port @TLSPORT@;
pid-file "named.pid";
listen-on { 10.53.0.1; };
listen-on-v6 { none; };
listen-on tls ephemeral { 10.53.0.1; };
recursion no;
notify explicit;
also-notify { 10.53.0.2 port @PORT@; };
statistics-file "named.stats";
dnssec-validation yes;
};
zone "." {
type hint;
file "../../common/root.hint";
};
zone "example" {
type primary;
file "example.db";
allow-transfer { any; };
};
+46
View File
@@ -0,0 +1,46 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* 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 http://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
include "../../common/rndc.key";
controls {
inet 10.53.0.2 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
};
options {
query-source address 10.53.0.2;
notify-source 10.53.0.2;
transfer-source 10.53.0.2;
port @PORT@;
tls-port @TLSPORT@;
pid-file "named.pid";
listen-on { 10.53.0.2; };
listen-on tls ephemeral { 10.53.0.2; };
listen-on-v6 { none; };
listen-on tls ephemeral { 10.53.0.2; };
recursion no;
notify no;
ixfr-from-differences yes;
check-integrity no;
dnssec-validation yes;
};
zone "." {
type hint;
file "../../common/root.hint";
};
zone "example" {
type secondary;
primaries { 10.53.0.1 tls ephemeral; };
file "example.db";
allow-transfer { any; };
};
+17
View File
@@ -0,0 +1,17 @@
#!/bin/sh
#
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# 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/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
. ../conf.sh
$SHELL ${TOP_SRCDIR}/bin/tests/system/genzone.sh 2 >ns1/example.db
copy_setports ns1/named.conf.in ns1/named.conf
copy_setports ns2/named.conf.in ns2/named.conf
+50
View File
@@ -0,0 +1,50 @@
#!/bin/sh
#
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# 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/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
. ../conf.sh
dig_with_opts() {
"$DIG" +tls +noadd +nosea +nostat +noquest +nocomm +nocmd -p "${TLSPORT}" "$@"
}
wait_for_xfer() (
dig_with_opts -b 10.53.0.3 @10.53.0.2 example. AXFR > "dig.out.ns2.test$n" || return 1
grep "^;" "dig.out.ns2.test$n" > /dev/null && return 1
return 0
)
status=0
n=0
n=$((n+1))
echo_i "testing XoT server functionality (using dig) ($n)"
ret=0
dig_with_opts example. -b 10.53.0.3 @10.53.0.1 axfr > dig.out.ns1.test$n || ret=1
grep "^;" dig.out.ns1.test$n | cat_i
digcomp dig1.good dig.out.ns1.test$n || ret=1
if test $ret != 0 ; then echo_i "failed"; fi
status=$((status+ret))
n=$((n+1))
echo_i "testing basic incoming XoT functionality (from secondary) ($n)"
ret=0
if retry_quiet 10 wait_for_xfer; then
grep "^;" "dig.out.ns2.test$n" | cat_i
digcomp dig1.good "dig.out.ns2.test$n" || ret=1
else
echo_i "timed out waiting for zone transfer"
ret=1
fi
if test $ret != 0 ; then echo_i "failed"; fi
status=$((status+ret))
echo_i "exit status: $status"
[ $status -eq 0 ] || exit 1
+2
View File
@@ -237,6 +237,7 @@ parse_options(int argc, char **argv) {
rp->ai_addr) ==
ISC_R_SUCCESS);
}
freeaddrinfo(result);
}
{
@@ -255,6 +256,7 @@ parse_options(int argc, char **argv) {
&sockaddr_remote, rp->ai_addr) ==
ISC_R_SUCCESS);
}
freeaddrinfo(result);
}
isc_sockaddr_format(&sockaddr_local, buf, sizeof(buf));
+2 -1
View File
@@ -138,7 +138,8 @@ const FileData installFiles[] =
{"libdns.dll", FileData::BinDir, FileData::Critical, FALSE, TRUE},
{"libirs.dll", FileData::BinDir, FileData::Critical, FALSE, TRUE},
{"libeay32.dll", FileData::BinDir, FileData::Critical, FALSE, TRUE},
{"libuv.dll", FileData::BinDir, FileData::Critical, FALSE, TRUE},
{"nghttp2.dll", FileData::BinDir, FileData::Critical, FALSE, TRUE},
{"uv.dll", FileData::BinDir, FileData::Critical, FALSE, TRUE},
#ifdef HAVE_LIBXML2
{"libxml2.dll", FileData::BinDir, FileData::Critical, FALSE, TRUE},
#endif
+10 -1
View File
@@ -124,7 +124,7 @@ AS_IF([test "$enable_static" != "no" && test "$enable_developer" != "yes"],
#
# Set the default CFLAGS and CPPFLAGS
#
STD_CFLAGS="-Wall -Wextra -Wwrite-strings -Wcast-qual -Wpointer-arith -Wno-missing-field-initializers -Wformat -Wshadow"
STD_CFLAGS="-Wall -Wextra -Wwrite-strings -Wpointer-arith -Wno-missing-field-initializers -Wformat -Wshadow"
# These should be always errors
STD_CFLAGS="$STD_CFLAGS -Werror=implicit-function-declaration -Werror=missing-prototypes -Werror=format-security -Werror=parentheses -Werror=implicit -Werror=strict-prototypes"
@@ -574,6 +574,15 @@ LIBS="$LIBS $LIBUV_LIBS"
AC_CHECK_FUNCS([uv_handle_get_data uv_handle_set_data uv_import uv_udp_connect uv_translate_sys_error])
AX_RESTORE_FLAGS([libuv])
# libnghttp2
AC_MSG_CHECKING([for libnghttp2])
PKG_CHECK_MODULES([LIBNGHTTP2], [libnghttp2 >= 1.6.0], [],
[AC_MSG_ERROR([libnghttp2 not found])])
AX_SAVE_FLAGS([libnghttp2])
CFLAGS="$CFLAGS $LIBNGHTTP2_CFLAGS"
LIBS="$LIBS $LIBNGHTTP2_LIBS"
#
# flockfile is usually provided by pthreads
#
+69 -5
View File
@@ -30,7 +30,7 @@ file documentation:
A list of one or more ``ip_addr``, ``ip_prefix``, ``key_id``, or ``acl_name`` elements; see :ref:`address_match_lists`.
``primaries_list``
A named list of one or more ``ip_addr`` with optional ``key_id`` and/or ``ip_port``. A ``primaries_list`` may include other ``primaries_list``.
A named list of one or more ``ip_addr`` with optional ``tls_id``, ``key_id`` and/or ``ip_port``. A ``primaries_list`` may include other ``primaries_list``.
``domain_name``
A quoted string which is used as a DNS name; for example. ``my.test.domain``.
@@ -66,6 +66,9 @@ file documentation:
``key_list``
A list of one or more ``key_id``, separated by semicolons and ending with a semicolon.
``tls_id``
A string representing a TLS configuration object, including a key and certificate.
``number``
A non-negative 32-bit integer (i.e., a number between 0 and 4294967295, inclusive). Its acceptable value might be further limited by the context in which it is used.
@@ -286,6 +289,9 @@ The following statements are supported:
``statistics-channels``
Declares communication channels to get access to ``named`` statistics.
``tls``
Specifies configuration information for a TLS connection, including a ``key-file``, ``cert-file``, ``ca-file`` and ``hostname``.
``trust-anchors``
Defines DNSSEC trust anchors: if used with the ``initial-key`` or ``initial-ds`` keyword, trust anchors are kept up-to-date using :rfc:`5011` trust anchor maintenance; if used with ``static-key`` or ``static-ds``, keys are permanent.
@@ -1072,6 +1078,14 @@ default is used.
the default is the ``named`` working directory. See :ref:`acl`
for details about ``geoip`` ACLs.
.. _https_endpoint:
``https-endpoint``
This configures an DNS-over-HTTPS service endpoint. It takes a string
which specifies the endpoint URL path, and an ``https-server``
parameter specifying the server name of an HTTPS listener. (See
:ref:`Link title <https_server>`.)
``key-directory``
This is the directory where the public and private DNSSEC key files should be
found when performing a dynamic update of secure zones, if different
@@ -2430,6 +2444,8 @@ Interfaces
The interfaces and ports that the server answers queries from may be
specified using the ``listen-on`` and ``listen-on-v6`` options.
specified using the ``listen-on`` and ``listen-on-v6`` options, as
well as the ``https-server`` option for HTTPS queries.
``listen-on`` takes an optional port, an optional TLS configuration
identifier, and an ``address_match_list`` of IPv4 addresses. (IPv6
@@ -2446,12 +2462,13 @@ Multiple ``listen-on`` statements are allowed. For example:
listen-on { 5.6.7.8; };
listen-on port 1234 { !1.2.3.4; 1.2/16; };
listen-on port 8853 tls example-tls { 4.3.2.1; };
listen-on port 8853 tls ephemeral { 4.3.2.1; };
enables the name server to listen for standard DNS queries on port 53 of the
IP address 5.6.7.8 and on port 1234 of an address on the machine in net 1.2
that is not 1.2.3.4, and to listen for DNS-over-TLS connections on port
8853 of the IP address 4.3.2.1.
8853 of the IP address 4.3.2.1, using an ephemeral TLS key and certificate
created for the currently running ``named`` process.
If no ``listen-on`` is specified, the server listens for standard DNS
on port 53 of all IPv4 interfaces.
@@ -2472,14 +2489,24 @@ Multiple ``listen-on-v6`` options can be used. For example:
enables the name server to listen for standard DNS queries on port 53 of
any IPv6 addresses and on port 1234 of IPv6 addresses that are not in the
prefix 2001:db8::/32, and for DNS-over-TLS connections on port 8853 of
the address 2001:db8::100.
the address 2001:db8::100, using a TLS key and certificate specified in
the a ``tls`` statement with the name ``example-tls``.
To instruct the server not to listen on any IPv6 address, use:
To instruct the server not to listen on any IPv6 addresses, use:
::
listen-on-v6 { none; };
.. _https_server:
``https-server`` takes a server name, an optional port, a TLS
configuration identifier, and an ``address_match_list`` of both IPv4 and
IPv6 addresses. This sets up an HTTPS responder using the key and
certificate specified in the referenced ``tls`` statement. The endpoint
for incoming HTTPS queries must be specified using the ``https-endpoint``
option (see :ref:`Link title <https_endpoint>`).
.. _query_address:
Query Address
@@ -4579,6 +4606,43 @@ socket statistics), http://127.0.0.1:8888/json/v1/mem (memory manager
statistics), http://127.0.0.1:8888/json/v1/tasks (task manager
statistics), and http://127.0.0.1:8888/json/v1/traffic (traffic sizes).
.. _tls:
``tls`` Statement Grammar
~~~~~~~~~~~~~~~~~~~~~~~~~
.. include:: ../misc/tls.grammar.rst
``tls`` Statement Definition and Usage
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The ``tls`` statement is used to configure a TLS connection; this
configuration can then be referenced by a ``listen-on`` or ``listen-on-v6``
statement to cause ``named`` to listen for incoming requests via TLS,
or in the ``primaries`` statement for a zone of type ``secondary`` to
cause zone transfer requests to be sent via TLS.
``tls`` can only be set at the top level of ``named.conf``.
The following options can be specified in a ``tls`` statement:
``key-file``
Path to a file containing the private TLS key to be used for
the connection.
``cert-file``
Path to a file containing the TLS certificate to be used for
the connection.
``ca-file``
Path to a file containing trusted TLS certificates.
``hostname``
The hostname associated with the certificate.
The built-in ``ephemeral`` TLS connection object represents a temporary
key and certificate created for the current ``named`` session only.
.. _trust_anchors:
``trust-anchors`` Statement Grammar
+4
View File
@@ -115,6 +115,10 @@ for queries. If \fBvalue\fP is of the form \fB<portnum>\fP or
\fBportnum\fP; if not not specified, the default is port 53. If
\fBvalue\fP is of the form \fBtls=<portnum>\fP, the server will
listen for TLS queries on \fBportnum\fP; the default is 853.
If \fBvalue\fP is of the form \fBhttps=<portnum>\fP, the server will
listen for HTTPS queries on \fBportnum\fP; the default is 443.
If \fBvalue\fP is of the form \fBhttp=<portnum>\fP, the server will
listen for HTTP queries on \fBportnum\fP; the default is 80.
.TP
.B \fB\-s\fP
This option writes memory usage statistics to \fBstdout\fP on exit.
+42 -19
View File
@@ -132,6 +132,19 @@ dyndb string quoted_string {
.fi
.UNINDENT
.UNINDENT
.SS HTTP
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
http string {
endpoints { quoted_string; ... }; // experimental
};
.ft P
.fi
.UNINDENT
.UNINDENT
.SS KEY
.INDENT 0.0
.INDENT 3.5
@@ -196,7 +209,8 @@ managed\-keys { string ( static\-key
masters string [ port integer ] [ dscp
integer ] { ( primaries | ipv4_address
[ port integer ] | ipv6_address [ port
integer ] ) [ key string ]; ... };
integer ] ) [ key string ] [ tls
string ]; ... };
.ft P
.fi
.UNINDENT
@@ -221,7 +235,7 @@ options {
allow\-update\-forwarding { address_match_element; ... };
also\-notify [ port integer ] [ dscp integer ] { ( primaries |
ipv4_address [ port integer ] | ipv6_address [ port
integer ] ) [ key string ]; ... };
integer ] ) [ key string ] [ tls string ]; ... };
alt\-transfer\-source ( ipv4_address | * ) [ port ( integer | * )
] [ dscp integer ];
alt\-transfer\-source\-v6 ( ipv6_address | * ) [ port ( integer |
@@ -239,8 +253,9 @@ options {
catalog\-zones { zone string [ default\-masters [ port integer ]
[ dscp integer ] { ( primaries | ipv4_address [ port
integer ] | ipv6_address [ port integer ] ) [ key
string ]; ... } ] [ zone\-directory quoted_string ] [
in\-memory boolean ] [ min\-update\-interval duration ]; ... };
string ] [ tls string ]; ... } ] [ zone\-directory
quoted_string ] [ in\-memory boolean ] [ min\-update\-interval
duration ]; ... };
check\-dup\-records ( fail | warn | ignore );
check\-integrity boolean;
check\-mx ( fail | warn | ignore );
@@ -325,6 +340,8 @@ options {
glue\-cache boolean;// deprecated
heartbeat\-interval integer;
hostname ( quoted_string | none );
http\-port integer;
https\-port integer;
inline\-signing boolean;
interface\-interval duration;
ipv4only\-contact string;
@@ -336,10 +353,12 @@ options {
key\-directory quoted_string;
lame\-ttl duration;
listen\-on [ port integer ] [ dscp
integer ] [ tls string ] {
integer ] [ tls string ] [ http
string ] {
address_match_element; ... };
listen\-on\-v6 [ port integer ] [ dscp
integer ] [ tls string ] {
integer ] [ tls string ] [ http
string ] {
address_match_element; ... };
lmdb\-mapsize sizeval;
lock\-file ( quoted_string | none );
@@ -532,7 +551,8 @@ plugin ( query ) string [ { unspecified\-text
primaries string [ port integer ] [ dscp
integer ] { ( primaries | ipv4_address
[ port integer ] | ipv6_address [ port
integer ] ) [ key string ]; ... };
integer ] ) [ key string ] [ tls
string ]; ... };
.ft P
.fi
.UNINDENT
@@ -602,9 +622,11 @@ statistics\-channels {
.nf
.ft C
tls string {
ca\-file quoted_string;
cert\-file quoted_string;
ciphers string; // experimental
dh\-param quoted_string; // experimental
hostname quoted_string;
key\-file quoted_string;
protocols sslprotos; // experimental
};
@@ -661,7 +683,7 @@ view string [ class ] {
allow\-update\-forwarding { address_match_element; ... };
also\-notify [ port integer ] [ dscp integer ] { ( primaries |
ipv4_address [ port integer ] | ipv6_address [ port
integer ] ) [ key string ]; ... };
integer ] ) [ key string ] [ tls string ]; ... };
alt\-transfer\-source ( ipv4_address | * ) [ port ( integer | * )
] [ dscp integer ];
alt\-transfer\-source\-v6 ( ipv6_address | * ) [ port ( integer |
@@ -673,8 +695,9 @@ view string [ class ] {
catalog\-zones { zone string [ default\-masters [ port integer ]
[ dscp integer ] { ( primaries | ipv4_address [ port
integer ] | ipv6_address [ port integer ] ) [ key
string ]; ... } ] [ zone\-directory quoted_string ] [
in\-memory boolean ] [ min\-update\-interval duration ]; ... };
string ] [ tls string ]; ... } ] [ zone\-directory
quoted_string ] [ in\-memory boolean ] [ min\-update\-interval
duration ]; ... };
check\-dup\-records ( fail | warn | ignore );
check\-integrity boolean;
check\-mx ( fail | warn | ignore );
@@ -938,8 +961,8 @@ view string [ class ] {
allow\-update\-forwarding { address_match_element; ... };
also\-notify [ port integer ] [ dscp integer ] { (
primaries | ipv4_address [ port integer ] |
ipv6_address [ port integer ] ) [ key string ];
... };
ipv6_address [ port integer ] ) [ key string ] [
tls string ]; ... };
alt\-transfer\-source ( ipv4_address | * ) [ port (
integer | * ) ] [ dscp integer ];
alt\-transfer\-source\-v6 ( ipv6_address | * ) [ port (
@@ -979,8 +1002,8 @@ view string [ class ] {
masterfile\-style ( full | relative );
masters [ port integer ] [ dscp integer ] { (
primaries | ipv4_address [ port integer ] |
ipv6_address [ port integer ] ) [ key string ];
... };
ipv6_address [ port integer ] ) [ key string ] [
tls string ]; ... };
max\-ixfr\-ratio ( unlimited | percentage );
max\-journal\-size ( default | unlimited | sizeval );
max\-records integer;
@@ -1003,8 +1026,8 @@ view string [ class ] {
notify\-to\-soa boolean;
primaries [ port integer ] [ dscp integer ] { (
primaries | ipv4_address [ port integer ] |
ipv6_address [ port integer ] ) [ key string ];
... };
ipv6_address [ port integer ] ) [ key string ] [
tls string ]; ... };
request\-expire boolean;
request\-ixfr boolean;
serial\-update\-method ( date | increment | unixtime );
@@ -1053,7 +1076,7 @@ zone string [ class ] {
allow\-update\-forwarding { address_match_element; ... };
also\-notify [ port integer ] [ dscp integer ] { ( primaries |
ipv4_address [ port integer ] | ipv6_address [ port
integer ] ) [ key string ]; ... };
integer ] ) [ key string ] [ tls string ]; ... };
alt\-transfer\-source ( ipv4_address | * ) [ port ( integer | * )
] [ dscp integer ];
alt\-transfer\-source\-v6 ( ipv6_address | * ) [ port ( integer |
@@ -1091,7 +1114,7 @@ zone string [ class ] {
masterfile\-style ( full | relative );
masters [ port integer ] [ dscp integer ] { ( primaries |
ipv4_address [ port integer ] | ipv6_address [ port
integer ] ) [ key string ]; ... };
integer ] ) [ key string ] [ tls string ]; ... };
max\-ixfr\-ratio ( unlimited | percentage );
max\-journal\-size ( default | unlimited | sizeval );
max\-records integer;
@@ -1114,7 +1137,7 @@ zone string [ class ] {
notify\-to\-soa boolean;
primaries [ port integer ] [ dscp integer ] { ( primaries |
ipv4_address [ port integer ] | ipv6_address [ port
integer ] ) [ key string ]; ... };
integer ] ) [ key string ] [ tls string ]; ... };
request\-expire boolean;
request\-ixfr boolean;
serial\-update\-method ( date | increment | unixtime );
+4
View File
@@ -34,6 +34,7 @@ OPTIONS_FILES = \
options.grammar.rst \
server.grammar.rst \
statistics-channels.grammar.rst \
tls.grammar.rst \
trust-anchors.grammar.rst \
managed-keys.grammar.rst \
trusted-keys.grammar.rst
@@ -162,6 +163,9 @@ server.grammar.rst: options.active
statistics-channels.grammar.rst: options.active
$(AM_V_RST_GRAMMARS)$(PERL) $(srcdir)/rst-grammars.pl options.active statistics-channels > $@
tls.grammar.rst: options.active
$(AM_V_RST_GRAMMARS)$(PERL) $(srcdir)/rst-grammars.pl options.active tls > $@
trust-anchors.grammar.rst: options.active
$(AM_V_RST_GRAMMARS)$(PERL) $(srcdir)/rst-grammars.pl options.active trust-anchors > $@
+1 -1
View File
@@ -4,7 +4,7 @@ zone <string> [ <class> ] {
allow-query-on { <address_match_element>; ... };
allow-transfer { <address_match_element>; ... };
allow-update { <address_match_element>; ... };
also-notify [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
also-notify [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
alt-transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
alt-transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
auto-dnssec ( allow | maintain | off );
+1 -1
View File
@@ -6,7 +6,7 @@
allow-query-on { <address_match_element>; ... };
allow-transfer { <address_match_element>; ... };
allow-update { <address_match_element>; ... };
also-notify [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
also-notify [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
alt-transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
alt-transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
auto-dnssec ( allow | maintain | off );
+3 -3
View File
@@ -5,7 +5,7 @@ zone <string> [ <class> ] {
allow-query-on { <address_match_element>; ... };
allow-transfer { <address_match_element>; ... };
allow-update-forwarding { <address_match_element>; ... };
also-notify [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
also-notify [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
alt-transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
alt-transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
check-names ( fail | warn | ignore );
@@ -15,7 +15,7 @@ zone <string> [ <class> ] {
journal <quoted_string>;
masterfile-format ( map | raw | text );
masterfile-style ( full | relative );
masters [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
masters [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
max-ixfr-ratio ( unlimited | <percentage> );
max-journal-size ( default | unlimited | <sizeval> );
max-records <integer>;
@@ -32,7 +32,7 @@ zone <string> [ <class> ] {
notify-delay <integer>;
notify-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
notify-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
primaries [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
primaries [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
request-expire <boolean>;
request-ixfr <boolean>;
transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
+3 -3
View File
@@ -7,7 +7,7 @@
allow-query-on { <address_match_element>; ... };
allow-transfer { <address_match_element>; ... };
allow-update-forwarding { <address_match_element>; ... };
also-notify [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
also-notify [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
alt-transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
alt-transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
check-names ( fail | warn | ignore );
@@ -17,7 +17,7 @@
journal <quoted_string>;
masterfile-format ( map | raw | text );
masterfile-style ( full | relative );
masters [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
masters [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
max-ixfr-ratio ( unlimited | <percentage> );
max-journal-size ( default | unlimited | <sizeval> );
max-records <integer>;
@@ -34,7 +34,7 @@
notify-delay <integer>;
notify-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
notify-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
primaries [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
primaries [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
request-expire <boolean>;
request-ixfr <boolean>;
transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
+33 -19
View File
@@ -42,6 +42,10 @@ dnssec-policy <string> {
dyndb <string> <quoted_string> {
<unspecified-text> }; // may occur multiple times
http <string> {
endpoints { <quoted_string>; ... }; // experimental
}; // may occur multiple times
key <string> {
algorithm <string>;
secret <string>;
@@ -71,7 +75,8 @@ managed-keys { <string> ( static-key
masters <string> [ port <integer> ] [ dscp
<integer> ] { ( <primaries> | <ipv4_address>
[ port <integer> ] | <ipv6_address> [ port
<integer> ] ) [ key <string> ]; ... }; // may occur multiple times
<integer> ] ) [ key <string> ] [ tls
<string> ]; ... }; // may occur multiple times
options {
allow-new-zones <boolean>;
@@ -87,7 +92,7 @@ options {
allow-update-forwarding { <address_match_element>; ... };
also-notify [ port <integer> ] [ dscp <integer> ] { ( <primaries> |
<ipv4_address> [ port <integer> ] | <ipv6_address> [ port
<integer> ] ) [ key <string> ]; ... };
<integer> ] ) [ key <string> ] [ tls <string> ]; ... };
alt-transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * )
] [ dscp <integer> ];
alt-transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> |
@@ -105,8 +110,9 @@ options {
catalog-zones { zone <string> [ default-masters [ port <integer> ]
[ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port
<integer> ] | <ipv6_address> [ port <integer> ] ) [ key
<string> ]; ... } ] [ zone-directory <quoted_string> ] [
in-memory <boolean> ] [ min-update-interval <duration> ]; ... };
<string> ] [ tls <string> ]; ... } ] [ zone-directory
<quoted_string> ] [ in-memory <boolean> ] [ min-update-interval
<duration> ]; ... };
check-dup-records ( fail | warn | ignore );
check-integrity <boolean>;
check-mx ( fail | warn | ignore );
@@ -191,6 +197,8 @@ options {
glue-cache <boolean>; // deprecated
heartbeat-interval <integer>;
hostname ( <quoted_string> | none );
http-port <integer>;
https-port <integer>;
inline-signing <boolean>;
interface-interval <duration>;
ipv4only-contact <string>;
@@ -202,10 +210,12 @@ options {
key-directory <quoted_string>;
lame-ttl <duration>;
listen-on [ port <integer> ] [ dscp
<integer> ] [ tls <string> ] {
<integer> ] [ tls <string> ] [ http
<string> ] {
<address_match_element>; ... }; // may occur multiple times
listen-on-v6 [ port <integer> ] [ dscp
<integer> ] [ tls <string> ] {
<integer> ] [ tls <string> ] [ http
<string> ] {
<address_match_element>; ... }; // may occur multiple times
lmdb-mapsize <sizeval>;
lock-file ( <quoted_string> | none );
@@ -382,7 +392,8 @@ plugin ( query ) <string> [ { <unspecified-text>
primaries <string> [ port <integer> ] [ dscp
<integer> ] { ( <primaries> | <ipv4_address>
[ port <integer> ] | <ipv6_address> [ port
<integer> ] ) [ key <string> ]; ... }; // may occur multiple times
<integer> ] ) [ key <string> ] [ tls
<string> ]; ... }; // may occur multiple times
server <netprefix> {
bogus <boolean>;
@@ -425,9 +436,11 @@ statistics-channels {
}; // may occur multiple times
tls <string> {
ca-file <quoted_string>;
cert-file <quoted_string>;
ciphers <string>; // experimental
dh-param <quoted_string>; // experimental
hostname <quoted_string>;
key-file <quoted_string>;
protocols <sslprotos>; // experimental
}; // may occur multiple times
@@ -455,7 +468,7 @@ view <string> [ <class> ] {
allow-update-forwarding { <address_match_element>; ... };
also-notify [ port <integer> ] [ dscp <integer> ] { ( <primaries> |
<ipv4_address> [ port <integer> ] | <ipv6_address> [ port
<integer> ] ) [ key <string> ]; ... };
<integer> ] ) [ key <string> ] [ tls <string> ]; ... };
alt-transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * )
] [ dscp <integer> ];
alt-transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> |
@@ -467,8 +480,9 @@ view <string> [ <class> ] {
catalog-zones { zone <string> [ default-masters [ port <integer> ]
[ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port
<integer> ] | <ipv6_address> [ port <integer> ] ) [ key
<string> ]; ... } ] [ zone-directory <quoted_string> ] [
in-memory <boolean> ] [ min-update-interval <duration> ]; ... };
<string> ] [ tls <string> ]; ... } ] [ zone-directory
<quoted_string> ] [ in-memory <boolean> ] [ min-update-interval
<duration> ]; ... };
check-dup-records ( fail | warn | ignore );
check-integrity <boolean>;
check-mx ( fail | warn | ignore );
@@ -734,8 +748,8 @@ view <string> [ <class> ] {
allow-update-forwarding { <address_match_element>; ... };
also-notify [ port <integer> ] [ dscp <integer> ] { (
<primaries> | <ipv4_address> [ port <integer> ] |
<ipv6_address> [ port <integer> ] ) [ key <string> ];
... };
<ipv6_address> [ port <integer> ] ) [ key <string> ] [
tls <string> ]; ... };
alt-transfer-source ( <ipv4_address> | * ) [ port (
<integer> | * ) ] [ dscp <integer> ];
alt-transfer-source-v6 ( <ipv6_address> | * ) [ port (
@@ -775,8 +789,8 @@ view <string> [ <class> ] {
masterfile-style ( full | relative );
masters [ port <integer> ] [ dscp <integer> ] { (
<primaries> | <ipv4_address> [ port <integer> ] |
<ipv6_address> [ port <integer> ] ) [ key <string> ];
... };
<ipv6_address> [ port <integer> ] ) [ key <string> ] [
tls <string> ]; ... };
max-ixfr-ratio ( unlimited | <percentage> );
max-journal-size ( default | unlimited | <sizeval> );
max-records <integer>;
@@ -800,8 +814,8 @@ view <string> [ <class> ] {
nsec3-test-zone <boolean>; // test only
primaries [ port <integer> ] [ dscp <integer> ] { (
<primaries> | <ipv4_address> [ port <integer> ] |
<ipv6_address> [ port <integer> ] ) [ key <string> ];
... };
<ipv6_address> [ port <integer> ] ) [ key <string> ] [
tls <string> ]; ... };
request-expire <boolean>;
request-ixfr <boolean>;
serial-update-method ( date | increment | unixtime );
@@ -841,7 +855,7 @@ zone <string> [ <class> ] {
allow-update-forwarding { <address_match_element>; ... };
also-notify [ port <integer> ] [ dscp <integer> ] { ( <primaries> |
<ipv4_address> [ port <integer> ] | <ipv6_address> [ port
<integer> ] ) [ key <string> ]; ... };
<integer> ] ) [ key <string> ] [ tls <string> ]; ... };
alt-transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * )
] [ dscp <integer> ];
alt-transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> |
@@ -879,7 +893,7 @@ zone <string> [ <class> ] {
masterfile-style ( full | relative );
masters [ port <integer> ] [ dscp <integer> ] { ( <primaries> |
<ipv4_address> [ port <integer> ] | <ipv6_address> [ port
<integer> ] ) [ key <string> ]; ... };
<integer> ] ) [ key <string> ] [ tls <string> ]; ... };
max-ixfr-ratio ( unlimited | <percentage> );
max-journal-size ( default | unlimited | <sizeval> );
max-records <integer>;
@@ -903,7 +917,7 @@ zone <string> [ <class> ] {
nsec3-test-zone <boolean>; // test only
primaries [ port <integer> ] [ dscp <integer> ] { ( <primaries> |
<ipv4_address> [ port <integer> ] | <ipv6_address> [ port
<integer> ] ) [ key <string> ]; ... };
<integer> ] ) [ key <string> ] [ tls <string> ]; ... };
request-expire <boolean>;
request-ixfr <boolean>;
serial-update-method ( date | increment | unixtime );
+33 -19
View File
@@ -41,6 +41,10 @@ dnssec-policy <string> {
dyndb <string> <quoted_string> {
<unspecified-text> }; // may occur multiple times
http <string> {
endpoints { <quoted_string>; ... }; // experimental
}; // may occur multiple times
key <string> {
algorithm <string>;
secret <string>;
@@ -70,7 +74,8 @@ managed-keys { <string> ( static-key
masters <string> [ port <integer> ] [ dscp
<integer> ] { ( <primaries> | <ipv4_address>
[ port <integer> ] | <ipv6_address> [ port
<integer> ] ) [ key <string> ]; ... }; // may occur multiple times
<integer> ] ) [ key <string> ] [ tls
<string> ]; ... }; // may occur multiple times
options {
allow-new-zones <boolean>;
@@ -86,7 +91,7 @@ options {
allow-update-forwarding { <address_match_element>; ... };
also-notify [ port <integer> ] [ dscp <integer> ] { ( <primaries> |
<ipv4_address> [ port <integer> ] | <ipv6_address> [ port
<integer> ] ) [ key <string> ]; ... };
<integer> ] ) [ key <string> ] [ tls <string> ]; ... };
alt-transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * )
] [ dscp <integer> ];
alt-transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> |
@@ -104,8 +109,9 @@ options {
catalog-zones { zone <string> [ default-masters [ port <integer> ]
[ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port
<integer> ] | <ipv6_address> [ port <integer> ] ) [ key
<string> ]; ... } ] [ zone-directory <quoted_string> ] [
in-memory <boolean> ] [ min-update-interval <duration> ]; ... };
<string> ] [ tls <string> ]; ... } ] [ zone-directory
<quoted_string> ] [ in-memory <boolean> ] [ min-update-interval
<duration> ]; ... };
check-dup-records ( fail | warn | ignore );
check-integrity <boolean>;
check-mx ( fail | warn | ignore );
@@ -190,6 +196,8 @@ options {
glue-cache <boolean>; // deprecated
heartbeat-interval <integer>;
hostname ( <quoted_string> | none );
http-port <integer>;
https-port <integer>;
inline-signing <boolean>;
interface-interval <duration>;
ipv4only-contact <string>;
@@ -201,10 +209,12 @@ options {
key-directory <quoted_string>;
lame-ttl <duration>;
listen-on [ port <integer> ] [ dscp
<integer> ] [ tls <string> ] {
<integer> ] [ tls <string> ] [ http
<string> ] {
<address_match_element>; ... }; // may occur multiple times
listen-on-v6 [ port <integer> ] [ dscp
<integer> ] [ tls <string> ] {
<integer> ] [ tls <string> ] [ http
<string> ] {
<address_match_element>; ... }; // may occur multiple times
lmdb-mapsize <sizeval>;
lock-file ( <quoted_string> | none );
@@ -379,7 +389,8 @@ plugin ( query ) <string> [ { <unspecified-text>
primaries <string> [ port <integer> ] [ dscp
<integer> ] { ( <primaries> | <ipv4_address>
[ port <integer> ] | <ipv6_address> [ port
<integer> ] ) [ key <string> ]; ... }; // may occur multiple times
<integer> ] ) [ key <string> ] [ tls
<string> ]; ... }; // may occur multiple times
server <netprefix> {
bogus <boolean>;
@@ -422,9 +433,11 @@ statistics-channels {
}; // may occur multiple times
tls <string> {
ca-file <quoted_string>;
cert-file <quoted_string>;
ciphers <string>; // experimental
dh-param <quoted_string>; // experimental
hostname <quoted_string>;
key-file <quoted_string>;
protocols <sslprotos>; // experimental
}; // may occur multiple times
@@ -452,7 +465,7 @@ view <string> [ <class> ] {
allow-update-forwarding { <address_match_element>; ... };
also-notify [ port <integer> ] [ dscp <integer> ] { ( <primaries> |
<ipv4_address> [ port <integer> ] | <ipv6_address> [ port
<integer> ] ) [ key <string> ]; ... };
<integer> ] ) [ key <string> ] [ tls <string> ]; ... };
alt-transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * )
] [ dscp <integer> ];
alt-transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> |
@@ -464,8 +477,9 @@ view <string> [ <class> ] {
catalog-zones { zone <string> [ default-masters [ port <integer> ]
[ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port
<integer> ] | <ipv6_address> [ port <integer> ] ) [ key
<string> ]; ... } ] [ zone-directory <quoted_string> ] [
in-memory <boolean> ] [ min-update-interval <duration> ]; ... };
<string> ] [ tls <string> ]; ... } ] [ zone-directory
<quoted_string> ] [ in-memory <boolean> ] [ min-update-interval
<duration> ]; ... };
check-dup-records ( fail | warn | ignore );
check-integrity <boolean>;
check-mx ( fail | warn | ignore );
@@ -729,8 +743,8 @@ view <string> [ <class> ] {
allow-update-forwarding { <address_match_element>; ... };
also-notify [ port <integer> ] [ dscp <integer> ] { (
<primaries> | <ipv4_address> [ port <integer> ] |
<ipv6_address> [ port <integer> ] ) [ key <string> ];
... };
<ipv6_address> [ port <integer> ] ) [ key <string> ] [
tls <string> ]; ... };
alt-transfer-source ( <ipv4_address> | * ) [ port (
<integer> | * ) ] [ dscp <integer> ];
alt-transfer-source-v6 ( <ipv6_address> | * ) [ port (
@@ -770,8 +784,8 @@ view <string> [ <class> ] {
masterfile-style ( full | relative );
masters [ port <integer> ] [ dscp <integer> ] { (
<primaries> | <ipv4_address> [ port <integer> ] |
<ipv6_address> [ port <integer> ] ) [ key <string> ];
... };
<ipv6_address> [ port <integer> ] ) [ key <string> ] [
tls <string> ]; ... };
max-ixfr-ratio ( unlimited | <percentage> );
max-journal-size ( default | unlimited | <sizeval> );
max-records <integer>;
@@ -794,8 +808,8 @@ view <string> [ <class> ] {
notify-to-soa <boolean>;
primaries [ port <integer> ] [ dscp <integer> ] { (
<primaries> | <ipv4_address> [ port <integer> ] |
<ipv6_address> [ port <integer> ] ) [ key <string> ];
... };
<ipv6_address> [ port <integer> ] ) [ key <string> ] [
tls <string> ]; ... };
request-expire <boolean>;
request-ixfr <boolean>;
serial-update-method ( date | increment | unixtime );
@@ -835,7 +849,7 @@ zone <string> [ <class> ] {
allow-update-forwarding { <address_match_element>; ... };
also-notify [ port <integer> ] [ dscp <integer> ] { ( <primaries> |
<ipv4_address> [ port <integer> ] | <ipv6_address> [ port
<integer> ] ) [ key <string> ]; ... };
<integer> ] ) [ key <string> ] [ tls <string> ]; ... };
alt-transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * )
] [ dscp <integer> ];
alt-transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> |
@@ -873,7 +887,7 @@ zone <string> [ <class> ] {
masterfile-style ( full | relative );
masters [ port <integer> ] [ dscp <integer> ] { ( <primaries> |
<ipv4_address> [ port <integer> ] | <ipv6_address> [ port
<integer> ] ) [ key <string> ]; ... };
<integer> ] ) [ key <string> ] [ tls <string> ]; ... };
max-ixfr-ratio ( unlimited | <percentage> );
max-journal-size ( default | unlimited | <sizeval> );
max-records <integer>;
@@ -896,7 +910,7 @@ zone <string> [ <class> ] {
notify-to-soa <boolean>;
primaries [ port <integer> ] [ dscp <integer> ] { ( <primaries> |
<ipv4_address> [ port <integer> ] | <ipv6_address> [ port
<integer> ] ) [ key <string> ]; ... };
<integer> ] ) [ key <string> ] [ tls <string> ]; ... };
request-expire <boolean>;
request-ixfr <boolean>;
serial-update-method ( date | increment | unixtime );
+10 -5
View File
@@ -14,7 +14,7 @@
allow-update-forwarding { <address_match_element>; ... };
also-notify [ port <integer> ] [ dscp <integer> ] { ( <primaries> |
<ipv4_address> [ port <integer> ] | <ipv6_address> [ port
<integer> ] ) [ key <string> ]; ... };
<integer> ] ) [ key <string> ] [ tls <string> ]; ... };
alt-transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * )
] [ dscp <integer> ];
alt-transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> |
@@ -32,8 +32,9 @@
catalog-zones { zone <string> [ default-masters [ port <integer> ]
[ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port
<integer> ] | <ipv6_address> [ port <integer> ] ) [ key
<string> ]; ... } ] [ zone-directory <quoted_string> ] [
in-memory <boolean> ] [ min-update-interval <duration> ]; ... };
<string> ] [ tls <string> ]; ... } ] [ zone-directory
<quoted_string> ] [ in-memory <boolean> ] [ min-update-interval
<duration> ]; ... };
check-dup-records ( fail | warn | ignore );
check-integrity <boolean>;
check-mx ( fail | warn | ignore );
@@ -118,6 +119,8 @@
glue-cache <boolean>; // deprecated
heartbeat-interval <integer>;
hostname ( <quoted_string> | none );
http-port <integer>;
https-port <integer>;
inline-signing <boolean>;
interface-interval <duration>;
ipv4only-contact <string>;
@@ -129,10 +132,12 @@
key-directory <quoted_string>;
lame-ttl <duration>;
listen-on [ port <integer> ] [ dscp
<integer> ] [ tls <string> ] {
<integer> ] [ tls <string> ] [ http
<string> ] {
<address_match_element>; ... };
listen-on-v6 [ port <integer> ] [ dscp
<integer> ] [ tls <string> ] {
<integer> ] [ tls <string> ] [ http
<string> ] {
<address_match_element>; ... };
lmdb-mapsize <sizeval>;
lock-file ( <quoted_string> | none );
+2 -1
View File
@@ -3,4 +3,5 @@
primaries <string> [ port <integer> ] [ dscp
<integer> ] { ( <primaries> | <ipv4_address>
[ port <integer> ] | <ipv6_address> [ port
<integer> ] ) [ key <string> ]; ... };
<integer> ] ) [ key <string> ] [ tls
<string> ]; ... };
+2 -2
View File
@@ -6,9 +6,9 @@ zone <string> [ <class> ] {
file <quoted_string>;
masterfile-format ( map | raw | text );
masterfile-style ( full | relative );
masters [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
masters [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
max-records <integer>;
max-zone-ttl ( unlimited | <duration> );
primaries [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
primaries [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
zone-statistics ( full | terse | none | <boolean> );
};
+2 -2
View File
@@ -8,9 +8,9 @@
file <quoted_string>;
masterfile-format ( map | raw | text );
masterfile-style ( full | relative );
masters [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
masters [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
max-records <integer>;
max-zone-ttl ( unlimited | <duration> );
primaries [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
primaries [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
zone-statistics ( full | terse | none | <boolean> );
};
+3 -3
View File
@@ -5,7 +5,7 @@ zone <string> [ <class> ] {
allow-query-on { <address_match_element>; ... };
allow-transfer { <address_match_element>; ... };
allow-update-forwarding { <address_match_element>; ... };
also-notify [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
also-notify [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
alt-transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
alt-transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
auto-dnssec ( allow | maintain | off );
@@ -27,7 +27,7 @@ zone <string> [ <class> ] {
key-directory <quoted_string>;
masterfile-format ( map | raw | text );
masterfile-style ( full | relative );
masters [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
masters [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
max-ixfr-ratio ( unlimited | <percentage> );
max-journal-size ( default | unlimited | <sizeval> );
max-records <integer>;
@@ -45,7 +45,7 @@ zone <string> [ <class> ] {
notify-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
notify-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
notify-to-soa <boolean>;
primaries [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
primaries [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
request-expire <boolean>;
request-ixfr <boolean>;
sig-signing-nodes <integer>;
+3 -3
View File
@@ -7,7 +7,7 @@
allow-query-on { <address_match_element>; ... };
allow-transfer { <address_match_element>; ... };
allow-update-forwarding { <address_match_element>; ... };
also-notify [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
also-notify [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
alt-transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
alt-transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
auto-dnssec ( allow | maintain | off );
@@ -29,7 +29,7 @@
key-directory <quoted_string>;
masterfile-format ( map | raw | text );
masterfile-style ( full | relative );
masters [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
masters [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
max-ixfr-ratio ( unlimited | <percentage> );
max-journal-size ( default | unlimited | <sizeval> );
max-records <integer>;
@@ -47,7 +47,7 @@
notify-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
notify-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
notify-to-soa <boolean>;
primaries [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
primaries [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
request-expire <boolean>;
request-ixfr <boolean>;
sig-signing-nodes <integer>;
+2 -2
View File
@@ -11,7 +11,7 @@ zone <string> [ <class> ] {
forwarders [ port <integer> ] [ dscp <integer> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ] [ dscp <integer> ]; ... };
masterfile-format ( map | raw | text );
masterfile-style ( full | relative );
masters [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
masters [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
max-records <integer>;
max-refresh-time <integer>;
max-retry-time <integer>;
@@ -20,7 +20,7 @@ zone <string> [ <class> ] {
min-refresh-time <integer>;
min-retry-time <integer>;
multi-master <boolean>;
primaries [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
primaries [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
use-alt-transfer-source <boolean>;
+2 -2
View File
@@ -13,7 +13,7 @@
forwarders [ port <integer> ] [ dscp <integer> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ] [ dscp <integer> ]; ... };
masterfile-format ( map | raw | text );
masterfile-style ( full | relative );
masters [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
masters [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
max-records <integer>;
max-refresh-time <integer>;
max-retry-time <integer>;
@@ -22,7 +22,7 @@
min-refresh-time <integer>;
min-retry-time <integer>;
multi-master <boolean>;
primaries [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
primaries [ port <integer> ] [ dscp <integer> ] { ( <primaries> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
use-alt-transfer-source <boolean>;
+11
View File
@@ -0,0 +1,11 @@
::
tls <string> {
ca-file <quoted_string>;
cert-file <quoted_string>;
ciphers <string>; // experimental
dh-param <quoted_string>; // experimental
hostname <quoted_string>;
key-file <quoted_string>;
protocols <sslprotos>; // experimental
};
+26 -4
View File
@@ -24,9 +24,7 @@ Known Issues
New Features
~~~~~~~~~~~~
- None.
- A new option, ```stale-answer-client-timeout``, has been added to
- A new option, ``stale-answer-client-timeout``, has been added to
improve ``named``'s behavior with respect to serving stale data. The option
defines the amount of time ``named`` waits before attempting
to answer the query with a stale RRset from cache. If a stale answer
@@ -41,7 +39,25 @@ New Features
The option can be disabled by setting the value to ``off`` or
``disabled``. It also has no effect if ``stale-answer-enable`` is
disabled.
disabled. [GL #2247]
- Also return stale data if an error occurred and we are not resuming a
query (and serve-stale is enabled). This may happen for example if
``fetches-per-server`` or ``fetches-per-zone` limits are reached. In this
case, we will try to answer DNS requests with stale data, but not start
the ``stale-refresh-time`` window. [GL #2434]
- ``named`` now supports XFR-over-TLS (XoT) for incoming as well as
outgoing zone transfers. Addresses in a ``primaries`` list can take
an optional ``tls`` option which specifies either a previously configured
``tls`` statement or ``ephemeral``. [GL #2392]
- ``named`` now has initial support for DNS-over-HTTP(S). Both
encrypted (via TLS) and unencrypted HTTP/2 connections are supported.
The latter are mostly there for debugging/troubleshooting
purposes and for the means of encryption offloading to third-party
software (as might be desirable in some environments to aid in TLS
certificates management).
Removed Features
~~~~~~~~~~~~~~~~
@@ -77,3 +93,9 @@ Bug Fixes
- KASP incorrectly set signature validity to the value of the DNSKEY signature
validity. This is now fixed. [GL #2383]
- Previously, ``dnssec-keyfromlabel`` crashed when operating on an ECDSA key.
This has been fixed. [GL #2178]
- Named ``allow-update`` acls where broken in BIND 9.17.9 and BIND 9.16.11
preventing ``named`` starting. [GL #2413]
+2
View File
@@ -129,6 +129,7 @@ libdns_la_HEADERS = \
include/dns/tcpmsg.h \
include/dns/time.h \
include/dns/timer.h \
include/dns/transport.h \
include/dns/tkey.h \
include/dns/tsec.h \
include/dns/tsig.h \
@@ -232,6 +233,7 @@ libdns_la_SOURCES = \
tcpmsg.c \
time.c \
timer.c \
transport.c \
tkey.c \
tsec.c \
tsig.c \
+20 -17
View File
@@ -241,33 +241,36 @@ struct dns_dbonupdatelistener {
#define DNS_DBFIND_NOZONECUT 0x0200
/*
* DNS_DBFIND_STALEOK: This flag is set when BIND fails to refresh a
* RRset due to timeout (resolver-query-timeout), its intent is to
* try to look for stale data in cache as a fallback, but only if
* stale answers are enabled in configuration.
*
* This flag is also used to activate stale-refresh-time window, since it
* is the only way the database knows that a resolution has failed.
* DNS_DBFIND_STALEOK: This flag is set when BIND fails to refresh a RRset due
* to timeout (resolver-query-timeout). Its intent is to try to look for stale
* data in cache as a fallback, but only if stale answers are enabled in
* configuration.
*/
#define DNS_DBFIND_STALEOK 0x0400
/*
* DNS_DBFIND_STALEENABLED: This flag is used as a hint to the database
* that it may use stale data. It is always set during query lookup if
* stale answers are enabled, but only effectively used during
* stale-refresh-time window. Also during this window, the resolver will
* not try to resolve the query, in other words no attempt to refresh the
* data in cache is made when the stale-refresh-time window is active.
* DNS_DBFIND_STALEENABLED: This flag is used as a hint to the database that
* it may use stale data. It is always set during query lookup if stale
* answers are enabled, but only effectively used during stale-refresh-time
* window. Also during this window, the resolver will not try to resolve the
* query, in other words no attempt to refresh the data in cache is made when
* the stale-refresh-time window is active.
*/
#define DNS_DBFIND_STALEENABLED 0x0800
/*
* DNS_DBFIND_STALEONLY: This new introduced flag is used when we want
* stale data from the database, but not due to a failure in resolution,
* it also doesn't require stale-refresh-time window timer to be active.
* As long as there is a stale RRset available, it should be returned.
* DNS_DBFIND_STALEONLY: This flag is used when we want stale data from the
* database, but not due to a failure in resolution, it also doesn't require
* stale-refresh-time window timer to be active. As long as there is a stale
* RRset available, it should be returned.
*/
#define DNS_DBFIND_STALEONLY 0x1000
/*
* DNS_DBFIND_STALESTART: This flag is used to activate stale-refresh-time
* window.
*/
#define DNS_DBFIND_STALESTART 0x2000
/*@}*/
/*@{*/
+1
View File
@@ -26,6 +26,7 @@ struct dns_ipkeylist {
isc_sockaddr_t *addrs;
isc_dscp_t * dscps;
dns_name_t ** keys;
dns_name_t ** tlss;
dns_name_t ** labels;
uint32_t count;
uint32_t allocated;
+141
View File
@@ -0,0 +1,141 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* 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/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
#pragma once
#include <dns/name.h>
typedef enum {
DNS_TRANSPORT_NONE = 0,
DNS_TRANSPORT_UDP = 1,
DNS_TRANSPORT_TCP = 2,
DNS_TRANSPORT_TLS = 3,
DNS_TRANSPORT_DOH = 4,
DNS_TRANSPORT_COUNT = 5,
} dns_transport_type_t;
typedef enum {
DNS_DOH_GET = 0,
DNS_DOH_POST = 1,
} dns_doh_mode_t;
typedef struct dns_transport dns_transport_t;
typedef struct dns_transport_list dns_transport_list_t;
dns_transport_t *
dns_transport_new(const dns_name_t *name, dns_transport_type_t type,
dns_transport_list_t *list);
/*%<
* Create a new transport object with name 'name' and type 'type',
* and append it to 'list'.
*/
dns_transport_type_t
dns_transport_get_type(dns_transport_t *transport);
char *
dns_transport_get_certfile(dns_transport_t *transport);
char *
dns_transport_get_keyfile(dns_transport_t *transport);
char *
dns_transport_get_cafile(dns_transport_t *transport);
char *
dns_transport_get_hostname(dns_transport_t *transport);
char *
dns_transport_get_endpoint(dns_transport_t *transport);
dns_doh_mode_t
dns_transport_get_mode(dns_transport_t *transport);
/*%<
* Getter functions: return the type, cert file, key file, CA file,
* hostname, DoH endpoint, or DoH mode (GET or POST) for 'transport'.
*/
void
dns_transport_set_certfile(dns_transport_t *transport, const char *certfile);
void
dns_transport_set_keyfile(dns_transport_t *transport, const char *keyfile);
void
dns_transport_set_cafile(dns_transport_t *transport, const char *cafile);
void
dns_transport_set_hostname(dns_transport_t *transport, const char *hostname);
void
dns_transport_set_endpoint(dns_transport_t *transport, const char *endpoint);
void
dns_transport_set_mode(dns_transport_t *transport, dns_doh_mode_t mode);
/*%<
* Setter functions: set the type, cert file, key file, CA file,
* hostname, DoH endpoint, or DoH mode (GET or POST) for 'transport'.
*
* Requires:
*\li 'transport' is valid.
*\li 'transport' is of type DNS_TRANSPORT_TLS or DNS_TRANSPORT_DOH
* (for certfile, keyfile, cafile, or hostname).
*\li 'transport' is of type DNS_TRANSPORT_DOH (for endpoint or mode).
*/
void
dns_transport_attach(dns_transport_t *source, dns_transport_t **targetp);
/*%<
* Attach to a transport object.
*
* Requires:
*\li 'source' is a valid transport.
*\li 'targetp' is not NULL and '*targetp' is NULL.
*/
void
dns_transport_detach(dns_transport_t **transportp);
/*%<
* Detach a transport object; destroy it if there are no remaining
* references.
*
* Requires:
*\li 'transportp' is not NULL.
*\li '*transportp' is a valid transport.
*/
dns_transport_t *
dns_transport_find(const dns_transport_type_t type, const dns_name_t *name,
dns_transport_list_t *list);
/*%<
* Find a transport matching type 'type' and name `name` in 'list'.
*
* Requires:
*\li 'list' is valid.
*\li 'list' contains a table of type 'type' transports.
*/
dns_transport_list_t *
dns_transport_list_new(isc_mem_t *mctx);
/*%<
* Create a new transport list.
*/
void
dns_transport_list_attach(dns_transport_list_t * source,
dns_transport_list_t **targetp);
/*%<
* Attach to a transport list.
*
* Requires:
*\li 'source' is a valid transport list.
*\li 'targetp' is not NULL and '*targetp' is NULL.
*/
void
dns_transport_list_detach(dns_transport_list_t **listp);
/*%<
* Detach a transport list; destroy it if there are no remaining
* references.
*
* Requires:
*\li 'listp' is not NULL.
*\li '*listp' is a valid transport list.
*/
+9
View File
@@ -73,6 +73,7 @@
#include <dns/rdatastruct.h>
#include <dns/rpz.h>
#include <dns/rrl.h>
#include <dns/transport.h>
#include <dns/types.h>
#include <dns/zt.h>
@@ -111,6 +112,7 @@ struct dns_view {
bool cacheshared;
/* Configurable data. */
dns_transport_list_t *transports;
dns_tsig_keyring_t * statickeys;
dns_tsig_keyring_t * dynamickeys;
dns_peerlist_t * peers;
@@ -454,6 +456,9 @@ dns_view_sethints(dns_view_t *view, dns_db_t *hints);
* \li The hints database of 'view' is 'hints'.
*/
void
dns_view_settransports(dns_view_t *view, dns_transport_list_t *list);
void
dns_view_setkeyring(dns_view_t *view, dns_tsig_keyring_t *ring);
void
@@ -817,6 +822,10 @@ dns_view_asyncload(dns_view_t *view, bool newonly, dns_zt_allloaded_t callback,
*\li 'view' is valid.
*/
isc_result_t
dns_view_gettransport(dns_view_t *view, const dns_transport_type_t type,
const dns_name_t *name, dns_transport_t **transportp);
isc_result_t
dns_view_gettsig(dns_view_t *view, const dns_name_t *keyname,
dns_tsigkey_t **keyp);
+4 -2
View File
@@ -27,6 +27,7 @@
#include <isc/lang.h>
#include <dns/transport.h>
#include <dns/types.h>
/***
@@ -48,8 +49,9 @@ isc_result_t
dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype,
const isc_sockaddr_t *masteraddr,
const isc_sockaddr_t *sourceaddr, isc_dscp_t dscp,
dns_tsigkey_t *tsigkey, isc_mem_t *mctx, isc_nm_t *netmgr,
dns_xfrindone_t done, dns_xfrin_ctx_t **xfrp);
dns_tsigkey_t *tsigkey, dns_transport_t *transport,
isc_mem_t *mctx, isc_nm_t *netmgr, dns_xfrindone_t done,
dns_xfrin_ctx_t **xfrp);
/*%<
* Attempt to start an incoming zone transfer of 'zone'
* from 'masteraddr', creating a dns_xfrin_ctx_t object to
+9 -11
View File
@@ -625,10 +625,8 @@ dns_zone_maintenance(dns_zone_t *zone);
isc_result_t
dns_zone_setprimaries(dns_zone_t *zone, const isc_sockaddr_t *primaries,
dns_name_t **keynames, dns_name_t **tlsnames,
uint32_t count);
isc_result_t
dns_zone_setprimarieswithkeys(dns_zone_t *zone, const isc_sockaddr_t *primaries,
dns_name_t **keynames, uint32_t count);
/*%<
* Set the list of master servers for the zone.
*
@@ -651,14 +649,8 @@ dns_zone_setprimarieswithkeys(dns_zone_t *zone, const isc_sockaddr_t *primaries,
isc_result_t
dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify,
uint32_t count);
isc_result_t
dns_zone_setalsonotifywithkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
dns_name_t **keynames, uint32_t count);
isc_result_t
dns_zone_setalsonotifydscpkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
const isc_dscp_t *dscps, dns_name_t **keynames,
uint32_t count);
const isc_dscp_t *dscps, dns_name_t **keynames,
dns_name_t **tlsnames, uint32_t count);
/*%<
* Set the list of additional servers to be notified when
* a zone changes. To clear the list use 'count = 0'.
@@ -2585,4 +2577,10 @@ dns_zone_verifydb(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver);
* \li #DNS_R_VERIFYFAILURE any other case
*/
const char *
dns_zonetype_name(dns_zonetype_t type);
/*%<
* Return the name of the zone type 'type'.
*/
#endif /* DNS_ZONE_H */
+41
View File
@@ -26,6 +26,7 @@ dns_ipkeylist_init(dns_ipkeylist_t *ipkl) {
ipkl->addrs = NULL;
ipkl->dscps = NULL;
ipkl->keys = NULL;
ipkl->tlss = NULL;
ipkl->labels = NULL;
}
@@ -63,6 +64,20 @@ dns_ipkeylist_clear(isc_mem_t *mctx, dns_ipkeylist_t *ipkl) {
ipkl->allocated * sizeof(dns_name_t *));
}
if (ipkl->tlss != NULL) {
for (i = 0; i < ipkl->allocated; i++) {
if (ipkl->tlss[i] == NULL) {
continue;
}
if (dns_name_dynamic(ipkl->tlss[i])) {
dns_name_free(ipkl->tlss[i], mctx);
}
isc_mem_put(mctx, ipkl->tlss[i], sizeof(dns_name_t));
}
isc_mem_put(mctx, ipkl->tlss,
ipkl->allocated * sizeof(dns_name_t *));
}
if (ipkl->labels != NULL) {
for (i = 0; i < ipkl->allocated; i++) {
if (ipkl->labels[i] == NULL) {
@@ -119,6 +134,19 @@ dns_ipkeylist_copy(isc_mem_t *mctx, const dns_ipkeylist_t *src,
}
}
if (src->tlss != NULL) {
for (i = 0; i < src->count; i++) {
if (src->tlss[i] != NULL) {
dst->tlss[i] = isc_mem_get(mctx,
sizeof(dns_name_t));
dns_name_init(dst->tlss[i], NULL);
dns_name_dup(src->tlss[i], mctx, dst->tlss[i]);
} else {
dst->tlss[i] = NULL;
}
}
}
if (src->labels != NULL) {
for (i = 0; i < src->count; i++) {
if (src->labels[i] != NULL) {
@@ -141,6 +169,7 @@ dns_ipkeylist_resize(isc_mem_t *mctx, dns_ipkeylist_t *ipkl, unsigned int n) {
isc_sockaddr_t *addrs = NULL;
isc_dscp_t *dscps = NULL;
dns_name_t **keys = NULL;
dns_name_t **tlss = NULL;
dns_name_t **labels = NULL;
REQUIRE(ipkl != NULL);
@@ -153,6 +182,7 @@ dns_ipkeylist_resize(isc_mem_t *mctx, dns_ipkeylist_t *ipkl, unsigned int n) {
addrs = isc_mem_get(mctx, n * sizeof(isc_sockaddr_t));
dscps = isc_mem_get(mctx, n * sizeof(isc_dscp_t));
keys = isc_mem_get(mctx, n * sizeof(dns_name_t *));
tlss = isc_mem_get(mctx, n * sizeof(dns_name_t *));
labels = isc_mem_get(mctx, n * sizeof(dns_name_t *));
if (ipkl->addrs != NULL) {
@@ -185,6 +215,16 @@ dns_ipkeylist_resize(isc_mem_t *mctx, dns_ipkeylist_t *ipkl, unsigned int n) {
memset(&ipkl->keys[ipkl->allocated], 0,
(n - ipkl->allocated) * sizeof(dns_name_t *));
if (ipkl->tlss) {
memmove(tlss, ipkl->tlss,
ipkl->allocated * sizeof(dns_name_t *));
isc_mem_put(mctx, ipkl->tlss,
ipkl->allocated * sizeof(dns_name_t *));
}
ipkl->tlss = tlss;
memset(&ipkl->tlss[ipkl->allocated], 0,
(n - ipkl->allocated) * sizeof(dns_name_t *));
if (ipkl->labels != NULL) {
memmove(labels, ipkl->labels,
ipkl->allocated * sizeof(dns_name_t *));
@@ -200,6 +240,7 @@ dns_ipkeylist_resize(isc_mem_t *mctx, dns_ipkeylist_t *ipkl, unsigned int n) {
isc_mem_put(mctx, addrs, n * sizeof(isc_sockaddr_t));
isc_mem_put(mctx, dscps, n * sizeof(isc_dscp_t));
isc_mem_put(mctx, tlss, n * sizeof(dns_name_t *));
isc_mem_put(mctx, keys, n * sizeof(dns_name_t *));
isc_mem_put(mctx, labels, n * sizeof(dns_name_t *));
+130 -146
View File
@@ -174,9 +174,9 @@ opensslecdsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
DST_RET(ISC_R_NOSPACE);
}
if (!EVP_DigestFinal(evp_md_ctx, digest, &dgstlen)) {
if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &dgstlen)) {
DST_RET(dst__openssl_toresult3(
dctx->category, "EVP_DigestFinal", ISC_R_FAILURE));
dctx->category, "EVP_DigestFinal_ex", ISC_R_FAILURE));
}
ecdsasig = ECDSA_do_sign(digest, dgstlen, eckey);
@@ -539,7 +539,7 @@ opensslecdsa_tofile(const dst_key_t *key, const char *directory) {
}
if (key->label != NULL) {
priv.elements[i].tag = TAG_RSA_LABEL;
priv.elements[i].tag = TAG_ECDSA_LABEL;
priv.elements[i].length = (unsigned short)strlen(key->label) +
1;
priv.elements[i].data = (unsigned char *)key->label;
@@ -561,42 +561,24 @@ static isc_result_t
ecdsa_check(EC_KEY *eckey, EC_KEY *pubeckey) {
const EC_POINT *pubkey;
pubkey = EC_KEY_get0_public_key(pubeckey);
if (pubkey == NULL) {
return (ISC_R_SUCCESS);
}
if (EC_KEY_set_public_key(eckey, pubkey) != 1) {
pubkey = EC_KEY_get0_public_key(eckey);
if (pubkey != NULL) {
return (ISC_R_SUCCESS);
} else if (pubeckey != NULL) {
pubkey = EC_KEY_get0_public_key(pubeckey);
if (pubkey == NULL) {
return (ISC_R_SUCCESS);
}
if (EC_KEY_set_public_key(eckey, pubkey) != 1) {
return (ISC_R_SUCCESS);
}
}
if (EC_KEY_check_key(eckey) == 1) {
return (ISC_R_SUCCESS);
}
return (ISC_R_FAILURE);
}
static bool
uses_engine(const dst_private_t *priv, const char **engine,
const char **label) {
for (unsigned short i = 0; i < priv->nelements; i++) {
switch (priv->elements[i].tag) {
case TAG_ECDSA_ENGINE:
*engine = (char *)priv->elements[i].data;
break;
case TAG_ECDSA_LABEL:
*label = (char *)priv->elements[i].data;
break;
default:
break;
}
}
if (*label != NULL) {
return (true);
}
return (false);
}
static isc_result_t
load_privkey_from_privstruct(EC_KEY *eckey, dst_private_t *priv) {
BIGNUM *privkey = BN_bin2bn(priv->elements[0].data,
@@ -615,92 +597,6 @@ load_privkey_from_privstruct(EC_KEY *eckey, dst_private_t *priv) {
return (result);
}
#if !defined(OPENSSL_NO_ENGINE)
static isc_result_t
load_pubkey_from_engine(EC_KEY *eckey, const char *engine, const char *label) {
if (engine == NULL || label == NULL) {
return (DST_R_NOENGINE);
}
ENGINE *ep = dst__openssl_getengine(engine);
;
if (ep == NULL) {
return (DST_R_NOENGINE);
}
EVP_PKEY *pubkey = ENGINE_load_private_key(ep, label, NULL, NULL);
if (pubkey == NULL) {
return (dst__openssl_toresult2("ENGINE_load_public_key",
ISC_R_NOTFOUND));
}
eckey = EVP_PKEY_get1_EC_KEY(pubkey);
EVP_PKEY_free(pubkey);
if (eckey == NULL) {
return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
}
return (ISC_R_SUCCESS);
}
static isc_result_t
load_privkey_from_engine(EC_KEY *eckey, const char *engine, const char *label) {
if (engine == NULL || label == NULL) {
return (DST_R_NOENGINE);
}
ENGINE *ep = dst__openssl_getengine(engine);
;
if (ep == NULL) {
return (DST_R_NOENGINE);
}
EVP_PKEY *privkey = ENGINE_load_private_key(ep, label, NULL, NULL);
if (privkey == NULL) {
return (dst__openssl_toresult2("ENGINE_load_private_key",
ISC_R_NOTFOUND));
}
eckey = EVP_PKEY_get1_EC_KEY(privkey);
EVP_PKEY_free(privkey);
if (eckey == NULL) {
return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
}
return (ISC_R_SUCCESS);
}
#else
static isc_result_t
load_pubkey_from_engine(EC_KEY *eckey, const char *engine, const char *label) {
UNUSED(eckey);
UNUSED(engine);
UNUSED(label);
return (DST_R_NOENGINE);
}
static isc_result_t
load_privkey_from_engine(EC_KEY *eckey, const char *engine, const char *label) {
UNUSED(eckey);
UNUSED(engine);
UNUSED(label);
return (DST_R_NOENGINE);
}
#endif
static isc_result_t
load_privkey(EC_KEY *eckey, dst_private_t *priv, const char **engine,
const char **label) {
if (uses_engine(priv, engine, label)) {
return (load_privkey_from_engine(eckey, *engine, *label));
} else {
return (load_privkey_from_privstruct(eckey, priv));
}
}
static isc_result_t
eckey_to_pkey(EC_KEY *eckey, EVP_PKEY **pkey) {
REQUIRE(pkey != NULL && *pkey == NULL);
@@ -767,6 +663,10 @@ dst__key_to_eckey(dst_key_t *key, EC_KEY **eckey) {
return (ISC_R_SUCCESS);
}
static isc_result_t
opensslecdsa_fromlabel(dst_key_t *key, const char *engine, const char *label,
const char *pin);
static isc_result_t
opensslecdsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
dst_private_t priv;
@@ -775,6 +675,8 @@ opensslecdsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
EC_KEY *pubeckey = NULL;
const char *engine = NULL;
const char *label = NULL;
int i, privkey_index = -1;
bool finalize_key = false;
/* read private key file */
result = dst__privstruct_parse(key, DST_ALG_ECDSA256, lexer, key->mctx,
@@ -793,26 +695,65 @@ opensslecdsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
goto end;
}
for (i = 0; i < priv.nelements; i++) {
switch (priv.elements[i].tag) {
case TAG_ECDSA_ENGINE:
engine = (char *)priv.elements[i].data;
break;
case TAG_ECDSA_LABEL:
label = (char *)priv.elements[i].data;
break;
case TAG_ECDSA_PRIVATEKEY:
privkey_index = i;
break;
default:
break;
}
}
if (privkey_index < 0) {
result = DST_R_INVALIDPRIVATEKEY;
goto end;
}
if (label != NULL) {
result = opensslecdsa_fromlabel(key, engine, label, NULL);
if (result != ISC_R_SUCCESS) {
goto end;
}
eckey = EVP_PKEY_get1_EC_KEY(key->keydata.pkey);
if (eckey == NULL) {
result = dst__openssl_toresult(DST_R_OPENSSLFAILURE);
goto end;
}
} else {
result = dst__key_to_eckey(key, &eckey);
if (result != ISC_R_SUCCESS) {
goto end;
}
result = load_privkey_from_privstruct(eckey, &priv);
if (result != ISC_R_SUCCESS) {
goto end;
}
finalize_key = true;
}
if (pub != NULL && pub->keydata.pkey != NULL) {
pubeckey = EVP_PKEY_get1_EC_KEY(pub->keydata.pkey);
}
result = dst__key_to_eckey(key, &eckey);
if (result != ISC_R_SUCCESS) {
goto end;
}
result = load_privkey(eckey, &priv, &engine, &label);
if (result != ISC_R_SUCCESS) {
goto end;
}
if (ecdsa_check(eckey, pubeckey) != ISC_R_SUCCESS) {
result = DST_R_INVALIDPRIVATEKEY;
goto end;
}
result = finalize_eckey(key, eckey, engine, label);
if (finalize_key) {
result = finalize_eckey(key, eckey, engine, label);
}
end:
if (pubeckey != NULL) {
@@ -830,40 +771,83 @@ static isc_result_t
opensslecdsa_fromlabel(dst_key_t *key, const char *engine, const char *label,
const char *pin) {
#if !defined(OPENSSL_NO_ENGINE)
isc_result_t result = ISC_R_SUCCESS;
isc_result_t ret = ISC_R_SUCCESS;
ENGINE *e;
EC_KEY *eckey = NULL;
EC_KEY *pubeckey = NULL;
EVP_PKEY *pkey = NULL;
EVP_PKEY *pubkey = NULL;
int group_nid = 0;
UNUSED(pin);
result = dst__key_to_eckey(key, &eckey);
if (result != ISC_R_SUCCESS) {
goto end;
if (engine == NULL || label == NULL) {
return (DST_R_NOENGINE);
}
e = dst__openssl_getengine(engine);
if (e == NULL) {
return (DST_R_NOENGINE);
}
result = dst__key_to_eckey(key, &pubeckey);
if (result != ISC_R_SUCCESS) {
goto end;
if (key->key_alg == DST_ALG_ECDSA256) {
group_nid = NID_X9_62_prime256v1;
} else {
group_nid = NID_secp384r1;
}
result = load_pubkey_from_engine(pubeckey, engine, label);
if (result != ISC_R_SUCCESS) {
goto end;
/* Load private key. */
pkey = ENGINE_load_private_key(e, label, NULL, NULL);
if (pkey == NULL) {
return (dst__openssl_toresult2("ENGINE_load_private_key",
DST_R_OPENSSLFAILURE));
}
/* Check base id, group nid */
if (EVP_PKEY_base_id(pkey) != EVP_PKEY_EC) {
DST_RET(DST_R_INVALIDPRIVATEKEY);
}
eckey = EVP_PKEY_get1_EC_KEY(pkey);
if (eckey == NULL) {
DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE));
}
if (EC_GROUP_get_curve_name(EC_KEY_get0_group(eckey)) != group_nid) {
DST_RET(DST_R_INVALIDPRIVATEKEY);
}
result = load_privkey_from_engine(eckey, engine, label);
if (result != ISC_R_SUCCESS) {
return (result);
/* Load public key. */
pubkey = ENGINE_load_public_key(e, label, NULL, NULL);
if (pubkey == NULL) {
DST_RET(dst__openssl_toresult2("ENGINE_load_public_key",
DST_R_OPENSSLFAILURE));
}
/* Check base id, group nid */
if (EVP_PKEY_base_id(pubkey) != EVP_PKEY_EC) {
DST_RET(DST_R_INVALIDPUBLICKEY);
}
pubeckey = EVP_PKEY_get1_EC_KEY(pubkey);
if (pubeckey == NULL) {
DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE));
}
if (EC_GROUP_get_curve_name(EC_KEY_get0_group(pubeckey)) != group_nid) {
DST_RET(DST_R_INVALIDPUBLICKEY);
}
if (ecdsa_check(eckey, pubeckey) != ISC_R_SUCCESS) {
result = DST_R_INVALIDPRIVATEKEY;
goto end;
DST_RET(DST_R_INVALIDPRIVATEKEY);
}
result = finalize_eckey(key, eckey, engine, label);
key->label = isc_mem_strdup(key->mctx, label);
key->engine = isc_mem_strdup(key->mctx, engine);
key->key_size = EVP_PKEY_bits(pkey);
key->keydata.pkey = pkey;
pkey = NULL;
end:
err:
if (pubkey != NULL) {
EVP_PKEY_free(pubkey);
}
if (pkey != NULL) {
EVP_PKEY_free(pkey);
}
if (pubeckey != NULL) {
EC_KEY_free(pubeckey);
}
@@ -871,7 +855,7 @@ end:
EC_KEY_free(eckey);
}
return (result);
return (ret);
#else
UNUSED(key);
UNUSED(engine);
+12 -7
View File
@@ -205,7 +205,7 @@ typedef struct rdatasetheader {
rbtdb_rdatatype_t type;
atomic_uint_least16_t attributes;
dns_trust_t trust;
isc_stdtime_t last_refresh_fail_ts;
atomic_uint_fast32_t last_refresh_fail_ts;
struct noqname *noqname;
struct noqname *closest;
unsigned int is_mmapped : 1;
@@ -1487,6 +1487,7 @@ init_rdataset(dns_rbtdb_t *rbtdb, rdatasetheader_t *h) {
h->next_is_relative = 0;
h->node_is_relative = 0;
atomic_init(&h->attributes, 0);
atomic_init(&h->last_refresh_fail_ts, 0);
#ifndef ISC_MUTEX_ATOMICS
STATIC_ASSERT((sizeof(h->attributes) == 2),
@@ -4565,16 +4566,20 @@ check_stale_header(dns_rbtnode_t *node, rdatasetheader_t *header,
mark_header_stale(search->rbtdb, header);
*header_prev = header;
/*
* If DNS_DBFIND_STALEOK is set then it means we failed
* to resolve the name during recursion, in this case we
* mark the time in which the refresh failed.
* If DNS_DBFIND_STALESTART is set then it means we
* failed to resolve the name during recursion, in
* this case we mark the time in which the refresh
* failed.
*/
if ((search->options & DNS_DBFIND_STALEOK) != 0) {
header->last_refresh_fail_ts = search->now;
if ((search->options & DNS_DBFIND_STALESTART) != 0) {
atomic_store_release(
&header->last_refresh_fail_ts,
search->now);
} else if ((search->options &
DNS_DBFIND_STALEENABLED) != 0 &&
search->now <
(header->last_refresh_fail_ts +
(atomic_load_acquire(
&header->last_refresh_fail_ts) +
search->rbtdb->serve_stale_refresh))
{
/*
+347
View File
@@ -0,0 +1,347 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* 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/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
#include <inttypes.h>
#include <isc/list.h>
#include <isc/mem.h>
#include <isc/refcount.h>
#include <isc/result.h>
#include <isc/rwlock.h>
#include <isc/util.h>
#include <dns/name.h>
#include <dns/rbt.h>
#include <dns/result.h>
#include <dns/transport.h>
#define TRANSPORT_MAGIC ISC_MAGIC('T', 'r', 'n', 's')
#define VALID_TRANSPORT(ptr) ISC_MAGIC_VALID(ptr, TRANSPORT_MAGIC)
#define TRANSPORT_LIST_MAGIC ISC_MAGIC('T', 'r', 'L', 's')
#define VALID_TRANSPORT_LIST(ptr) ISC_MAGIC_VALID(ptr, TRANSPORT_LIST_MAGIC)
struct dns_transport_list {
unsigned int magic;
isc_refcount_t references;
isc_mem_t *mctx;
isc_rwlock_t lock;
dns_rbt_t *transports[DNS_TRANSPORT_COUNT];
};
struct dns_transport {
unsigned int magic;
isc_refcount_t references;
isc_mem_t *mctx;
dns_transport_type_t type;
struct {
char *certfile;
char *keyfile;
char *cafile;
char *hostname;
} tls;
struct {
char *endpoint;
dns_doh_mode_t mode;
} doh;
};
static void
free_dns_transport(void *node, void *arg) {
dns_transport_t *transport = node;
REQUIRE(node != NULL);
UNUSED(arg);
dns_transport_detach(&transport);
}
static isc_result_t
list_add(dns_transport_list_t *list, const dns_name_t *name,
const dns_transport_type_t type, dns_transport_t *transport) {
isc_result_t result;
dns_rbt_t *rbt = NULL;
RWLOCK(&list->lock, isc_rwlocktype_write);
rbt = list->transports[type];
INSIST(rbt != NULL);
result = dns_rbt_addname(rbt, name, transport);
RWUNLOCK(&list->lock, isc_rwlocktype_write);
return (result);
}
dns_transport_type_t
dns_transport_get_type(dns_transport_t *transport) {
REQUIRE(VALID_TRANSPORT(transport));
return (transport->type);
}
char *
dns_transport_get_certfile(dns_transport_t *transport) {
REQUIRE(VALID_TRANSPORT(transport));
return (transport->tls.certfile);
}
char *
dns_transport_get_keyfile(dns_transport_t *transport) {
REQUIRE(VALID_TRANSPORT(transport));
return (transport->tls.keyfile);
}
char *
dns_transport_get_cafile(dns_transport_t *transport) {
REQUIRE(VALID_TRANSPORT(transport));
return (transport->tls.cafile);
}
char *
dns_transport_get_hostname(dns_transport_t *transport) {
REQUIRE(VALID_TRANSPORT(transport));
return (transport->tls.hostname);
}
char *
dns_transport_get_endpoint(dns_transport_t *transport) {
REQUIRE(VALID_TRANSPORT(transport));
return (transport->doh.endpoint);
}
dns_doh_mode_t
dns_transport_get_mode(dns_transport_t *transport) {
REQUIRE(VALID_TRANSPORT(transport));
return (transport->doh.mode);
}
dns_transport_t *
dns_transport_new(const dns_name_t *name, dns_transport_type_t type,
dns_transport_list_t *list) {
dns_transport_t *transport = isc_mem_get(list->mctx,
sizeof(*transport));
*transport = (dns_transport_t){ .type = type };
isc_refcount_init(&transport->references, 1);
isc_mem_attach(list->mctx, &transport->mctx);
transport->magic = TRANSPORT_MAGIC;
list_add(list, name, type, transport);
return (transport);
}
void
dns_transport_set_certfile(dns_transport_t *transport, const char *certfile) {
REQUIRE(VALID_TRANSPORT(transport));
REQUIRE(transport->type == DNS_TRANSPORT_TLS ||
transport->type == DNS_TRANSPORT_DOH);
if (certfile != NULL) {
transport->tls.certfile = isc_mem_strdup(transport->mctx,
certfile);
}
}
void
dns_transport_set_keyfile(dns_transport_t *transport, const char *keyfile) {
REQUIRE(VALID_TRANSPORT(transport));
REQUIRE(transport->type == DNS_TRANSPORT_TLS ||
transport->type == DNS_TRANSPORT_DOH);
if (keyfile != NULL) {
transport->tls.keyfile = isc_mem_strdup(transport->mctx,
keyfile);
}
}
void
dns_transport_set_cafile(dns_transport_t *transport, const char *cafile) {
REQUIRE(VALID_TRANSPORT(transport));
REQUIRE(transport->type == DNS_TRANSPORT_TLS ||
transport->type == DNS_TRANSPORT_DOH);
if (cafile != NULL) {
transport->tls.cafile = isc_mem_strdup(transport->mctx, cafile);
}
}
void
dns_transport_set_hostname(dns_transport_t *transport, const char *hostname) {
REQUIRE(VALID_TRANSPORT(transport));
REQUIRE(transport->type == DNS_TRANSPORT_TLS ||
transport->type == DNS_TRANSPORT_DOH);
if (hostname != NULL) {
transport->tls.hostname = isc_mem_strdup(transport->mctx,
hostname);
}
}
void
dns_transport_set_endpoint(dns_transport_t *transport, const char *endpoint) {
REQUIRE(VALID_TRANSPORT(transport));
REQUIRE(transport->type == DNS_TRANSPORT_DOH);
if (endpoint != NULL) {
transport->doh.endpoint = isc_mem_strdup(transport->mctx,
endpoint);
}
}
void
dns_transport_set_mode(dns_transport_t *transport, dns_doh_mode_t mode) {
REQUIRE(VALID_TRANSPORT(transport));
REQUIRE(transport->type == DNS_TRANSPORT_DOH);
transport->doh.mode = mode;
}
static void
transport_destroy(dns_transport_t *transport) {
isc_refcount_destroy(&transport->references);
transport->magic = 0;
if (transport->doh.endpoint != NULL) {
isc_mem_free(transport->mctx, transport->doh.endpoint);
}
if (transport->tls.hostname != NULL) {
isc_mem_free(transport->mctx, transport->tls.hostname);
}
if (transport->tls.cafile != NULL) {
isc_mem_free(transport->mctx, transport->tls.cafile);
}
if (transport->tls.keyfile != NULL) {
isc_mem_free(transport->mctx, transport->tls.keyfile);
}
if (transport->tls.certfile != NULL) {
isc_mem_free(transport->mctx, transport->tls.certfile);
}
isc_mem_putanddetach(&transport->mctx, transport, sizeof(*transport));
}
void
dns_transport_attach(dns_transport_t *source, dns_transport_t **targetp) {
REQUIRE(source != NULL);
REQUIRE(targetp != NULL && *targetp == NULL);
isc_refcount_increment(&source->references);
*targetp = source;
}
void
dns_transport_detach(dns_transport_t **transportp) {
dns_transport_t *transport = NULL;
REQUIRE(transportp != NULL);
REQUIRE(VALID_TRANSPORT(*transportp));
transport = *transportp;
*transportp = NULL;
if (isc_refcount_decrement(&transport->references) == 1) {
transport_destroy(transport);
}
}
dns_transport_t *
dns_transport_find(const dns_transport_type_t type, const dns_name_t *name,
dns_transport_list_t *list) {
isc_result_t result;
dns_transport_t *transport = NULL;
dns_rbt_t *rbt = NULL;
REQUIRE(VALID_TRANSPORT_LIST(list));
REQUIRE(list->transports[type] != NULL);
rbt = list->transports[type];
RWLOCK(&list->lock, isc_rwlocktype_read);
result = dns_rbt_findname(rbt, name, 0, NULL, (void *)&transport);
if (result == ISC_R_SUCCESS) {
isc_refcount_increment(&transport->references);
}
RWUNLOCK(&list->lock, isc_rwlocktype_read);
return (transport);
}
dns_transport_list_t *
dns_transport_list_new(isc_mem_t *mctx) {
dns_transport_list_t *list = isc_mem_get(mctx, sizeof(*list));
*list = (dns_transport_list_t){ 0 };
isc_rwlock_init(&list->lock, 0, 0);
isc_mem_attach(mctx, &list->mctx);
isc_refcount_init(&list->references, 1);
list->magic = TRANSPORT_LIST_MAGIC;
for (size_t type = 0; type < DNS_TRANSPORT_COUNT; type++) {
isc_result_t result;
result = dns_rbt_create(list->mctx, free_dns_transport, NULL,
&list->transports[type]);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
}
return (list);
}
void
dns_transport_list_attach(dns_transport_list_t *source,
dns_transport_list_t **targetp) {
REQUIRE(VALID_TRANSPORT_LIST(source));
REQUIRE(targetp != NULL && *targetp == NULL);
isc_refcount_increment(&source->references);
*targetp = source;
}
static void
transport_list_destroy(dns_transport_list_t *list) {
isc_refcount_destroy(&list->references);
list->magic = 0;
for (size_t type = 0; type < DNS_TRANSPORT_COUNT; type++) {
if (list->transports[type] != NULL) {
dns_rbt_destroy(&list->transports[type]);
}
}
isc_rwlock_destroy(&list->lock);
isc_mem_putanddetach(&list->mctx, list, sizeof(*list));
}
void
dns_transport_list_detach(dns_transport_list_t **listp) {
dns_transport_list_t *list = NULL;
REQUIRE(listp != NULL);
REQUIRE(VALID_TRANSPORT_LIST(*listp));
list = *listp;
*listp = NULL;
if (isc_refcount_decrement(&list->references) == 1) {
transport_list_destroy(list);
}
}
+31
View File
@@ -56,6 +56,7 @@
#include <dns/rrl.h>
#include <dns/stats.h>
#include <dns/time.h>
#include <dns/transport.h>
#include <dns/tsig.h>
#include <dns/zone.h>
#include <dns/zt.h>
@@ -152,6 +153,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, const char *name,
atomic_init(&view->attributes,
(DNS_VIEWATTR_RESSHUTDOWN | DNS_VIEWATTR_ADBSHUTDOWN |
DNS_VIEWATTR_REQSHUTDOWN));
view->transports = NULL;
view->statickeys = NULL;
view->dynamickeys = NULL;
view->matchclients = NULL;
@@ -397,6 +399,9 @@ destroy(dns_view_t *view) {
}
}
}
if (view->transports != NULL) {
dns_transport_list_detach(&view->transports);
}
if (view->statickeys != NULL) {
dns_tsigkeyring_detach(&view->statickeys);
}
@@ -884,6 +889,16 @@ dns_view_sethints(dns_view_t *view, dns_db_t *hints) {
dns_db_attach(hints, &view->hints);
}
void
dns_view_settransports(dns_view_t *view, dns_transport_list_t *list) {
REQUIRE(DNS_VIEW_VALID(view));
REQUIRE(list != NULL);
if (view->transports != NULL) {
dns_transport_list_detach(&view->transports);
}
dns_transport_list_attach(list, &view->transports);
}
void
dns_view_setkeyring(dns_view_t *view, dns_tsig_keyring_t *ring) {
REQUIRE(DNS_VIEW_VALID(view));
@@ -1589,6 +1604,22 @@ dns_view_gettsig(dns_view_t *view, const dns_name_t *keyname,
return (result);
}
isc_result_t
dns_view_gettransport(dns_view_t *view, const dns_transport_type_t type,
const dns_name_t *name, dns_transport_t **transportp) {
REQUIRE(DNS_VIEW_VALID(view));
REQUIRE(transportp != NULL && *transportp == NULL);
dns_transport_t *transport = dns_transport_find(type, name,
view->transports);
if (transport == NULL) {
return (ISC_R_NOTFOUND);
}
*transportp = transport;
return (ISC_R_SUCCESS);
}
isc_result_t
dns_view_getpeertsig(dns_view_t *view, const isc_netaddr_t *peeraddr,
dns_tsigkey_t **keyp) {
+23 -3
View File
@@ -1059,6 +1059,26 @@ dns_tkey_processgssresponse
dns_tkey_processquery
dns_tkeyctx_create
dns_tkeyctx_destroy
dns_transport_attach
dns_transport_detach
dns_transport_find
dns_transport_get_cafile
dns_transport_get_certfile
dns_transport_get_endpoint
dns_transport_get_hostname
dns_transport_get_keyfile
dns_transport_get_mode
dns_transport_get_type
dns_transport_list_attach
dns_transport_list_detach
dns_transport_list_new
dns_transport_new
dns_transport_set_cafile
dns_transport_set_certfile
dns_transport_set_endpoint
dns_transport_set_hostname
dns_transport_set_keyfile
dns_transport_set_mode
dns_trust_totext
dns_tsec_create
dns_tsec_destroy
@@ -1120,6 +1140,7 @@ dns_view_getresquerystats
dns_view_getresstats
dns_view_getrootdelonly
dns_view_getsecroots
dns_view_gettransport
dns_view_gettsig
dns_view_initntatable
dns_view_initsecroots
@@ -1144,6 +1165,7 @@ dns_view_setnewzones
dns_view_setresquerystats
dns_view_setresstats
dns_view_setrootdelonly
dns_view_settransports
dns_view_setviewcommit
dns_view_setviewrevert
dns_view_simplefind
@@ -1283,8 +1305,6 @@ dns_zone_secure_to_insecure
dns_zone_set_parentcatz
dns_zone_setadded
dns_zone_setalsonotify
dns_zone_setalsonotifydscpkeys
dns_zone_setalsonotifywithkeys
dns_zone_setaltxfrsource4
dns_zone_setaltxfrsource4dscp
dns_zone_setaltxfrsource6
@@ -1332,7 +1352,6 @@ dns_zone_setnsec3param
dns_zone_setoption
dns_zone_setorigin
dns_zone_setprimaries
dns_zone_setprimarieswithkeys
dns_zone_setprivatetype
dns_zone_setqueryacl
dns_zone_setqueryonacl
@@ -1397,6 +1416,7 @@ dns_zonemgr_shutdown
dns_zonemgr_unreachable
dns_zonemgr_unreachableadd
dns_zonemgr_unreachabledel
dns_zonetype_name
dns_zoneverify_dnssec
dns_zt_apply
dns_zt_asyncload
+6
View File
@@ -236,6 +236,9 @@
<ClCompile Include="..\tkey.c">
<Filter>Library Source Files</Filter>
</ClCompile>
<ClCompile Include="..\transport.c">
<Filter>Library Source Files</Filter>
</ClCompile>
<ClCompile Include="..\tsec.c">
<Filter>Library Source Files</Filter>
</ClCompile>
@@ -583,6 +586,9 @@
<ClInclude Include="..\include\dns\tkey.h">
<Filter>Library Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\dns\transport.h">
<Filter>Library Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\dns\tsec.h">
<Filter>Library Header Files</Filter>
</ClInclude>
+2
View File
@@ -209,6 +209,7 @@
<ClCompile Include="..\time.c" />
<ClCompile Include="..\timer.c" />
<ClCompile Include="..\tkey.c" />
<ClCompile Include="..\transport.c" />
<ClCompile Include="..\tsec.c" />
<ClCompile Include="..\tsig.c" />
<ClCompile Include="..\ttl.c" />
@@ -315,6 +316,7 @@
<ClInclude Include="..\include\dns\time.h" />
<ClInclude Include="..\include\dns\timer.h" />
<ClInclude Include="..\include\dns\tkey.h" />
<ClInclude Include="..\include\dns\transport.h" />
<ClInclude Include="..\include\dns\tsec.h" />
<ClInclude Include="..\include\dns\tsig.h" />
<ClInclude Include="..\include\dns\ttl.h" />
+60 -13
View File
@@ -35,6 +35,7 @@
#include <dns/result.h>
#include <dns/soa.h>
#include <dns/tcpmsg.h>
#include <dns/transport.h>
#include <dns/tsig.h>
#include <dns/view.h>
#include <dns/xfrin.h>
@@ -160,6 +161,10 @@ struct dns_xfrin_ctx {
isc_buffer_t *lasttsig; /*%< The last TSIG */
dst_context_t *tsigctx; /*%< TSIG verification context */
unsigned int sincetsig; /*%< recvd since the last TSIG */
dns_transport_t *transport;
isc_tlsctx_t *tlsctx;
dns_xfrindone_t done;
/*%
@@ -190,7 +195,8 @@ xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db, isc_nm_t *netmgr,
dns_name_t *zonename, dns_rdataclass_t rdclass,
dns_rdatatype_t reqtype, const isc_sockaddr_t *masteraddr,
const isc_sockaddr_t *sourceaddr, isc_dscp_t dscp,
dns_tsigkey_t *tsigkey, dns_xfrin_ctx_t **xfrp);
dns_tsigkey_t *tsigkey, dns_transport_t *transport,
dns_xfrin_ctx_t **xfrp);
static isc_result_t
axfr_init(dns_xfrin_ctx_t *xfr);
@@ -652,8 +658,9 @@ isc_result_t
dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype,
const isc_sockaddr_t *masteraddr,
const isc_sockaddr_t *sourceaddr, isc_dscp_t dscp,
dns_tsigkey_t *tsigkey, isc_mem_t *mctx, isc_nm_t *netmgr,
dns_xfrindone_t done, dns_xfrin_ctx_t **xfrp) {
dns_tsigkey_t *tsigkey, dns_transport_t *transport,
isc_mem_t *mctx, isc_nm_t *netmgr, dns_xfrindone_t done,
dns_xfrin_ctx_t **xfrp) {
dns_name_t *zonename = dns_zone_getorigin(zone);
dns_xfrin_ctx_t *xfr = NULL;
isc_result_t result;
@@ -661,6 +668,7 @@ dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype,
REQUIRE(xfrp != NULL && *xfrp == NULL);
REQUIRE(done != NULL);
REQUIRE(isc_sockaddr_getport(masteraddr) != 0);
(void)dns_zone_getdb(zone, &db);
@@ -669,7 +677,8 @@ dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype,
}
xfrin_create(mctx, zone, db, netmgr, zonename, dns_zone_getclass(zone),
xfrtype, masteraddr, sourceaddr, dscp, tsigkey, &xfr);
xfrtype, masteraddr, sourceaddr, dscp, tsigkey, transport,
&xfr);
if (db != NULL) {
xfr->zone_had_db = true;
@@ -809,7 +818,8 @@ xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db, isc_nm_t *netmgr,
dns_name_t *zonename, dns_rdataclass_t rdclass,
dns_rdatatype_t reqtype, const isc_sockaddr_t *masteraddr,
const isc_sockaddr_t *sourceaddr, isc_dscp_t dscp,
dns_tsigkey_t *tsigkey, dns_xfrin_ctx_t **xfrp) {
dns_tsigkey_t *tsigkey, dns_transport_t *transport,
dns_xfrin_ctx_t **xfrp) {
dns_xfrin_ctx_t *xfr = NULL;
xfr = isc_mem_get(mctx, sizeof(*xfr));
@@ -845,6 +855,10 @@ xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db, isc_nm_t *netmgr,
dns_tsigkey_attach(tsigkey, &xfr->tsigkey);
}
if (transport != NULL) {
dns_transport_attach(transport, &xfr->transport);
}
dns_name_dup(zonename, mctx, &xfr->name);
INSIST(isc_sockaddr_pf(masteraddr) == isc_sockaddr_pf(sourceaddr));
@@ -865,20 +879,45 @@ static isc_result_t
xfrin_start(dns_xfrin_ctx_t *xfr) {
isc_result_t result;
dns_xfrin_ctx_t *connect_xfr = NULL;
/*
* XXX: timeout hard-coded to 30 seconds; this needs to be
* configurable.
*/
dns_transport_type_t transport_type = DNS_TRANSPORT_TCP;
(void)isc_refcount_increment0(&xfr->connects);
dns_xfrin_attach(xfr, &connect_xfr);
CHECK(isc_nm_tcpdnsconnect(xfr->netmgr,
(isc_nmiface_t *)&xfr->sourceaddr,
(isc_nmiface_t *)&xfr->masteraddr,
xfrin_connect_done, connect_xfr, 30000, 0));
if (xfr->transport != NULL) {
transport_type = dns_transport_get_type(xfr->transport);
}
/*
* XXX: timeouts are hard-coded to 30 seconds; this needs to be
* configurable.
*/
switch (transport_type) {
case DNS_TRANSPORT_TCP:
CHECK(isc_nm_tcpdnsconnect(
xfr->netmgr, (isc_nmiface_t *)&xfr->sourceaddr,
(isc_nmiface_t *)&xfr->masteraddr, xfrin_connect_done,
connect_xfr, 30000, 0));
break;
case DNS_TRANSPORT_TLS:
CHECK(isc_tlsctx_createclient(&xfr->tlsctx));
CHECK(isc_nm_tlsdnsconnect(
xfr->netmgr, (isc_nmiface_t *)&xfr->sourceaddr,
(isc_nmiface_t *)&xfr->masteraddr, xfrin_connect_done,
connect_xfr, 30000, 0, xfr->tlsctx));
break;
default:
INSIST(0);
ISC_UNREACHABLE();
}
/* TODO isc_socket_dscp(xfr->socket, xfr->dscp); */
return (ISC_R_SUCCESS);
failure:
if (xfr->tlsctx != NULL) {
isc_tlsctx_free(&xfr->tlsctx);
}
isc_refcount_decrement0(&xfr->connects);
dns_xfrin_detach(&connect_xfr);
return (result);
@@ -925,6 +964,10 @@ xfrin_connect_done(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
isc_refcount_decrement0(&xfr->connects);
if (xfr->tlsctx != NULL) {
isc_tlsctx_free(&xfr->tlsctx);
}
if (xfr->shuttingdown) {
result = ISC_R_SHUTTINGDOWN;
}
@@ -1499,6 +1542,10 @@ xfrin_destroy(dns_xfrin_ctx_t *xfr) {
isc_nmhandle_detach(&xfr->sendhandle);
}
if (xfr->transport != NULL) {
dns_transport_detach(&xfr->transport);
}
if (xfr->tsigkey != NULL) {
dns_tsigkey_detach(&xfr->tsigkey);
}
+240 -92
View File
@@ -259,6 +259,7 @@ struct dns_zone {
isc_sockaddr_t *masters;
isc_dscp_t *masterdscps;
dns_name_t **masterkeynames;
dns_name_t **mastertlsnames;
bool *mastersok;
unsigned int masterscnt;
unsigned int curmaster;
@@ -266,6 +267,7 @@ struct dns_zone {
dns_notifytype_t notifytype;
isc_sockaddr_t *notify;
dns_name_t **notifykeynames;
dns_name_t **notifytlsnames;
isc_dscp_t *notifydscp;
unsigned int notifycnt;
isc_sockaddr_t notifyfrom;
@@ -284,8 +286,9 @@ struct dns_zone {
isc_dscp_t xfrsource6dscp;
isc_dscp_t altxfrsource4dscp;
isc_dscp_t altxfrsource6dscp;
dns_xfrin_ctx_t *xfr; /* task locked */
dns_tsigkey_t *tsigkey; /* key used for xfr */
dns_xfrin_ctx_t *xfr; /* task locked */
dns_tsigkey_t *tsigkey; /* key used for xfr */
dns_transport_t *transport; /* transport used for xfr */
/* Access Control Lists */
dns_acl_t *update_acl;
dns_acl_t *forward_acl;
@@ -595,6 +598,7 @@ struct dns_notify {
dns_name_t ns;
isc_sockaddr_t dst;
dns_tsigkey_t *key;
dns_transport_t *transport;
isc_dscp_t dscp;
ISC_LINK(dns_notify_t) link;
isc_event_t *event;
@@ -1047,12 +1051,14 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
zone->masters = NULL;
zone->masterdscps = NULL;
zone->masterkeynames = NULL;
zone->mastertlsnames = NULL;
zone->mastersok = NULL;
zone->masterscnt = 0;
zone->curmaster = 0;
zone->maxttl = 0;
zone->notify = NULL;
zone->notifykeynames = NULL;
zone->notifytlsnames = NULL;
zone->notifydscp = NULL;
zone->notifytype = dns_notifytype_yes;
zone->notifycnt = 0;
@@ -1091,6 +1097,7 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
zone->altxfrsource6dscp = -1;
zone->xfr = NULL;
zone->tsigkey = NULL;
zone->transport = NULL;
zone->maxxfrin = MAX_XFER_TIME;
zone->maxxfrout = MAX_XFER_TIME;
zone->ssutable = NULL;
@@ -1301,9 +1308,10 @@ zone_free(dns_zone_t *zone) {
dns_catz_catzs_detach(&zone->catzs);
}
zone_freedbargs(zone);
RUNTIME_CHECK(dns_zone_setprimarieswithkeys(zone, NULL, NULL, 0) ==
RUNTIME_CHECK(dns_zone_setprimaries(zone, NULL, NULL, NULL, 0) ==
ISC_R_SUCCESS);
RUNTIME_CHECK(dns_zone_setalsonotify(zone, NULL, NULL, NULL, NULL, 0) ==
ISC_R_SUCCESS);
RUNTIME_CHECK(dns_zone_setalsonotify(zone, NULL, 0) == ISC_R_SUCCESS);
zone->check_names = dns_severity_ignore;
if (zone->update_acl != NULL) {
dns_acl_detach(&zone->update_acl);
@@ -6148,8 +6156,8 @@ same_addrs(isc_sockaddr_t const *oldlist, isc_sockaddr_t const *newlist,
}
static bool
same_keynames(dns_name_t *const *oldlist, dns_name_t *const *newlist,
uint32_t count) {
same_names(dns_name_t *const *oldlist, dns_name_t *const *newlist,
uint32_t count) {
unsigned int i;
if (oldlist == NULL && newlist == NULL) {
@@ -6173,16 +6181,20 @@ same_keynames(dns_name_t *const *oldlist, dns_name_t *const *newlist,
}
static void
clear_addresskeylist(isc_sockaddr_t **addrsp, isc_dscp_t **dscpsp,
dns_name_t ***keynamesp, unsigned int *countp,
isc_mem_t *mctx) {
clear_primarieslist(isc_sockaddr_t **addrsp, isc_dscp_t **dscpsp,
dns_name_t ***keynamesp, dns_name_t ***tlsnamesp,
unsigned int *countp, isc_mem_t *mctx) {
unsigned int count;
isc_sockaddr_t *addrs;
isc_dscp_t *dscps;
dns_name_t **keynames;
dns_name_t **tlsnames;
REQUIRE(countp != NULL && addrsp != NULL && dscpsp != NULL &&
keynamesp != NULL);
REQUIRE(countp != NULL);
REQUIRE(addrsp != NULL);
REQUIRE(dscpsp != NULL);
REQUIRE(keynamesp != NULL);
REQUIRE(tlsnamesp != NULL);
count = *countp;
*countp = 0;
@@ -6192,6 +6204,8 @@ clear_addresskeylist(isc_sockaddr_t **addrsp, isc_dscp_t **dscpsp,
*dscpsp = NULL;
keynames = *keynamesp;
*keynamesp = NULL;
tlsnames = *tlsnamesp;
*tlsnamesp = NULL;
if (addrs != NULL) {
isc_mem_put(mctx, addrs, count * sizeof(isc_sockaddr_t));
@@ -6213,21 +6227,37 @@ clear_addresskeylist(isc_sockaddr_t **addrsp, isc_dscp_t **dscpsp,
}
isc_mem_put(mctx, keynames, count * sizeof(dns_name_t *));
}
if (tlsnames != NULL) {
unsigned int i;
for (i = 0; i < count; i++) {
if (tlsnames[i] != NULL) {
dns_name_free(tlsnames[i], mctx);
isc_mem_put(mctx, tlsnames[i],
sizeof(dns_name_t));
tlsnames[i] = NULL;
}
}
isc_mem_put(mctx, tlsnames, count * sizeof(dns_name_t *));
}
}
static isc_result_t
set_addrkeylist(unsigned int count, const isc_sockaddr_t *addrs,
isc_sockaddr_t **newaddrsp, const isc_dscp_t *dscp,
isc_dscp_t **newdscpp, dns_name_t **names,
dns_name_t ***newnamesp, isc_mem_t *mctx) {
set_primarieslist(unsigned int count, const isc_sockaddr_t *addrs,
isc_sockaddr_t **newaddrsp, const isc_dscp_t *dscp,
isc_dscp_t **newdscpp, dns_name_t **keynames,
dns_name_t ***newkeynamesp, dns_name_t **tlsnames,
dns_name_t ***newtlsnamesp, isc_mem_t *mctx) {
isc_sockaddr_t *newaddrs = NULL;
isc_dscp_t *newdscp = NULL;
dns_name_t **newnames = NULL;
dns_name_t **newkeynames = NULL;
dns_name_t **newtlsnames = NULL;
unsigned int i;
REQUIRE(newaddrsp != NULL && *newaddrsp == NULL);
REQUIRE(newdscpp != NULL && *newdscpp == NULL);
REQUIRE(newnamesp != NULL && *newnamesp == NULL);
REQUIRE(newkeynamesp != NULL && *newkeynamesp == NULL);
REQUIRE(newtlsnamesp != NULL && *newtlsnamesp == NULL);
newaddrs = isc_mem_get(mctx, count * sizeof(*newaddrs));
memmove(newaddrs, addrs, count * sizeof(*newaddrs));
@@ -6239,26 +6269,40 @@ set_addrkeylist(unsigned int count, const isc_sockaddr_t *addrs,
newdscp = NULL;
}
if (names != NULL) {
newnames = isc_mem_get(mctx, count * sizeof(*newnames));
if (keynames != NULL) {
newkeynames = isc_mem_get(mctx, count * sizeof(*newkeynames));
for (i = 0; i < count; i++) {
newnames[i] = NULL;
newkeynames[i] = NULL;
}
for (i = 0; i < count; i++) {
if (names[i] != NULL) {
newnames[i] = isc_mem_get(mctx,
sizeof(dns_name_t));
dns_name_init(newnames[i], NULL);
dns_name_dup(names[i], mctx, newnames[i]);
if (keynames[i] != NULL) {
newkeynames[i] =
isc_mem_get(mctx, sizeof(dns_name_t));
dns_name_init(newkeynames[i], NULL);
dns_name_dup(keynames[i], mctx, newkeynames[i]);
}
}
}
if (tlsnames != NULL) {
newtlsnames = isc_mem_get(mctx, count * sizeof(*newtlsnames));
for (i = 0; i < count; i++) {
newtlsnames[i] = NULL;
}
for (i = 0; i < count; i++) {
if (tlsnames[i] != NULL) {
newtlsnames[i] =
isc_mem_get(mctx, sizeof(dns_name_t));
dns_name_init(newtlsnames[i], NULL);
dns_name_dup(tlsnames[i], mctx, newtlsnames[i]);
}
}
} else {
newnames = NULL;
}
*newdscpp = newdscp;
*newaddrsp = newaddrs;
*newnamesp = newnames;
*newkeynamesp = newkeynames;
*newtlsnamesp = newtlsnames;
return (ISC_R_SUCCESS);
}
@@ -6281,26 +6325,13 @@ dns_zone_getnotifysrc6dscp(dns_zone_t *zone) {
isc_result_t
dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify,
uint32_t count) {
return (dns_zone_setalsonotifydscpkeys(zone, notify, NULL, NULL,
count));
}
isc_result_t
dns_zone_setalsonotifywithkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
dns_name_t **keynames, uint32_t count) {
return (dns_zone_setalsonotifydscpkeys(zone, notify, NULL, keynames,
count));
}
isc_result_t
dns_zone_setalsonotifydscpkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
const isc_dscp_t *dscps, dns_name_t **keynames,
uint32_t count) {
const isc_dscp_t *dscps, dns_name_t **keynames,
dns_name_t **tlsnames, uint32_t count) {
isc_result_t result;
isc_sockaddr_t *newaddrs = NULL;
isc_dscp_t *newdscps = NULL;
dns_name_t **newnames = NULL;
dns_name_t **newkeynames = NULL;
dns_name_t **newtlsnames = NULL;
REQUIRE(DNS_ZONE_VALID(zone));
REQUIRE(count == 0 || notify != NULL);
@@ -6312,14 +6343,15 @@ dns_zone_setalsonotifydscpkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
if (count == zone->notifycnt &&
same_addrs(zone->notify, notify, count) &&
same_keynames(zone->notifykeynames, keynames, count))
same_names(zone->notifykeynames, keynames, count) &&
same_names(zone->notifytlsnames, tlsnames, count))
{
goto unlock;
}
clear_addresskeylist(&zone->notify, &zone->notifydscp,
&zone->notifykeynames, &zone->notifycnt,
zone->mctx);
clear_primarieslist(&zone->notify, &zone->notifydscp,
&zone->notifykeynames, &zone->notifytlsnames,
&zone->notifycnt, zone->mctx);
if (count == 0) {
goto unlock;
@@ -6328,8 +6360,9 @@ dns_zone_setalsonotifydscpkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
/*
* Set up the notify and notifykey lists
*/
result = set_addrkeylist(count, notify, &newaddrs, dscps, &newdscps,
keynames, &newnames, zone->mctx);
result = set_primarieslist(count, notify, &newaddrs, dscps, &newdscps,
keynames, &newkeynames, tlsnames,
&newtlsnames, zone->mctx);
if (result != ISC_R_SUCCESS) {
goto unlock;
}
@@ -6339,7 +6372,8 @@ dns_zone_setalsonotifydscpkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
*/
zone->notify = newaddrs;
zone->notifydscp = newdscps;
zone->notifykeynames = newnames;
zone->notifykeynames = newkeynames;
zone->notifytlsnames = newtlsnames;
zone->notifycnt = count;
unlock:
UNLOCK_ZONE(zone);
@@ -6348,26 +6382,19 @@ unlock:
isc_result_t
dns_zone_setprimaries(dns_zone_t *zone, const isc_sockaddr_t *masters,
dns_name_t **keynames, dns_name_t **tlsnames,
uint32_t count) {
isc_result_t result;
result = dns_zone_setprimarieswithkeys(zone, masters, NULL, count);
return (result);
}
isc_result_t
dns_zone_setprimarieswithkeys(dns_zone_t *zone, const isc_sockaddr_t *masters,
dns_name_t **keynames, uint32_t count) {
isc_result_t result = ISC_R_SUCCESS;
isc_sockaddr_t *newaddrs = NULL;
isc_dscp_t *newdscps = NULL;
dns_name_t **newnames = NULL;
dns_name_t **newkeynames = NULL;
dns_name_t **newtlsnames = NULL;
bool *newok;
unsigned int i;
REQUIRE(DNS_ZONE_VALID(zone));
REQUIRE(count == 0 || masters != NULL);
if (keynames != NULL) {
if (keynames != NULL || tlsnames != NULL) {
REQUIRE(count != 0);
}
@@ -6380,7 +6407,8 @@ dns_zone_setprimarieswithkeys(dns_zone_t *zone, const isc_sockaddr_t *masters,
*/
if (count != zone->masterscnt ||
!same_addrs(zone->masters, masters, count) ||
!same_keynames(zone->masterkeynames, keynames, count))
!same_names(zone->masterkeynames, keynames, count) ||
!same_names(zone->mastertlsnames, tlsnames, count))
{
if (zone->request != NULL) {
dns_request_cancel(zone->request);
@@ -6398,9 +6426,9 @@ dns_zone_setprimarieswithkeys(dns_zone_t *zone, const isc_sockaddr_t *masters,
zone->masterscnt * sizeof(bool));
zone->mastersok = NULL;
}
clear_addresskeylist(&zone->masters, &zone->masterdscps,
&zone->masterkeynames, &zone->masterscnt,
zone->mctx);
clear_primarieslist(&zone->masters, &zone->masterdscps,
&zone->masterkeynames, &zone->mastertlsnames,
&zone->masterscnt, zone->mctx);
/*
* If count == 0, don't allocate any space for masters, mastersok or
* keynames so internally, those pointers are NULL if count == 0
@@ -6420,8 +6448,9 @@ dns_zone_setprimarieswithkeys(dns_zone_t *zone, const isc_sockaddr_t *masters,
/*
* Now set up the primaries and primary key lists
*/
result = set_addrkeylist(count, masters, &newaddrs, NULL, &newdscps,
keynames, &newnames, zone->mctx);
result = set_primarieslist(count, masters, &newaddrs, NULL, &newdscps,
keynames, &newkeynames, tlsnames,
&newtlsnames, zone->mctx);
INSIST(newdscps == NULL);
if (result != ISC_R_SUCCESS) {
isc_mem_put(zone->mctx, newok, count * sizeof(*newok));
@@ -6435,7 +6464,8 @@ dns_zone_setprimarieswithkeys(dns_zone_t *zone, const isc_sockaddr_t *masters,
zone->mastersok = newok;
zone->masters = newaddrs;
zone->masterdscps = newdscps;
zone->masterkeynames = newnames;
zone->masterkeynames = newkeynames;
zone->mastertlsnames = newtlsnames;
zone->masterscnt = count;
DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOMASTERS);
@@ -11897,7 +11927,8 @@ dns_zone_setmaxrecords(dns_zone_t *zone, uint32_t val) {
static bool
notify_isqueued(dns_zone_t *zone, unsigned int flags, dns_name_t *name,
isc_sockaddr_t *addr, dns_tsigkey_t *key) {
isc_sockaddr_t *addr, dns_tsigkey_t *key,
dns_transport_t *transport) {
dns_notify_t *notify;
dns_zonemgr_t *zmgr;
isc_result_t result;
@@ -11914,7 +11945,7 @@ notify_isqueued(dns_zone_t *zone, unsigned int flags, dns_name_t *name,
goto requeue;
}
if (addr != NULL && isc_sockaddr_equal(addr, &notify->dst) &&
notify->key == key)
notify->key == key && notify->transport == transport)
{
goto requeue;
}
@@ -12032,6 +12063,9 @@ notify_destroy(dns_notify_t *notify, bool locked) {
if (notify->key != NULL) {
dns_tsigkey_detach(&notify->key);
}
if (notify->transport != NULL) {
dns_transport_detach(&notify->transport);
}
mctx = notify->mctx;
isc_mem_put(notify->mctx, notify, sizeof(*notify));
isc_mem_detach(&mctx);
@@ -12044,15 +12078,11 @@ notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) {
REQUIRE(notifyp != NULL && *notifyp == NULL);
notify = isc_mem_get(mctx, sizeof(*notify));
*notify = (dns_notify_t){
.flags = flags,
};
notify->mctx = NULL;
isc_mem_attach(mctx, &notify->mctx);
notify->flags = flags;
notify->zone = NULL;
notify->find = NULL;
notify->request = NULL;
notify->key = NULL;
notify->event = NULL;
isc_sockaddr_any(&notify->dst);
dns_name_init(&notify->ns, NULL);
ISC_LINK_INIT(notify, link);
@@ -12332,7 +12362,7 @@ notify_send(dns_notify_t *notify) {
{
dst = ai->sockaddr;
if (notify_isqueued(notify->zone, notify->flags, NULL, &dst,
NULL)) {
NULL, NULL)) {
continue;
}
if (notify_isself(notify->zone, &dst)) {
@@ -12485,20 +12515,37 @@ zone_notify(dns_zone_t *zone, isc_time_t *now) {
LOCK_ZONE(zone);
for (i = 0; i < zone->notifycnt; i++) {
dns_tsigkey_t *key = NULL;
dns_transport_t *transport = NULL;
dns_notify_t *notify = NULL;
dns_view_t *view = dns_zone_getview(zone);
if ((zone->notifykeynames != NULL) &&
(zone->notifykeynames[i] != NULL)) {
dns_view_t *view = dns_zone_getview(zone);
dns_name_t *keyname = zone->notifykeynames[i];
(void)dns_view_gettsig(view, keyname, &key);
}
if ((zone->notifytlsnames != NULL) &&
(zone->notifytlsnames[i] != NULL)) {
dns_name_t *tlsname = zone->notifytlsnames[i];
(void)dns_view_gettransport(view, DNS_TRANSPORT_TLS,
tlsname, &transport);
dns_zone_logc(
zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR,
"got TLS configuration for zone transfer");
}
/* TODO: glue the transport to the notify */
dst = zone->notify[i];
if (notify_isqueued(zone, flags, NULL, &dst, key)) {
if (notify_isqueued(zone, flags, NULL, &dst, key, transport)) {
if (key != NULL) {
dns_tsigkey_detach(&key);
}
if (transport != NULL) {
dns_transport_detach(&transport);
}
continue;
}
@@ -12507,6 +12554,9 @@ zone_notify(dns_zone_t *zone, isc_time_t *now) {
if (key != NULL) {
dns_tsigkey_detach(&key);
}
if (transport != NULL) {
dns_transport_detach(&transport);
}
continue;
}
@@ -12520,6 +12570,12 @@ zone_notify(dns_zone_t *zone, isc_time_t *now) {
key = NULL;
}
INSIST(notify->transport == NULL);
if (transport != NULL) {
notify->transport = transport;
transport = NULL;
}
ISC_LIST_APPEND(zone->notifies, notify, link);
result = notify_send_queue(notify, startup);
if (result != ISC_R_SUCCESS) {
@@ -12574,7 +12630,8 @@ zone_notify(dns_zone_t *zone, isc_time_t *now) {
}
LOCK_ZONE(zone);
isqueued = notify_isqueued(zone, flags, &ns.name, NULL, NULL);
isqueued = notify_isqueued(zone, flags, &ns.name, NULL, NULL,
NULL);
UNLOCK_ZONE(zone);
if (isqueued) {
result = dns_rdataset_next(&nsrdset);
@@ -13973,12 +14030,14 @@ soa_query(isc_task_t *task, isc_event_t *event) {
dns_zone_t *dummy = NULL;
isc_netaddr_t masterip;
dns_tsigkey_t *key = NULL;
dns_transport_t *transport = NULL;
uint32_t options;
bool cancel = true;
int timeout;
bool have_xfrsource, have_xfrdscp, reqnsid, reqexpire;
uint16_t udpsize = SEND_BUFFER_SIZE;
isc_dscp_t dscp = -1;
bool do_queue_xfrin = false;
REQUIRE(DNS_ZONE_VALID(zone));
@@ -13998,11 +14057,6 @@ soa_query(isc_task_t *task, isc_event_t *event) {
}
again:
result = create_query(zone, dns_rdatatype_soa, &zone->origin, &message);
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
INSIST(zone->masterscnt > 0);
INSIST(zone->curmaster < zone->masterscnt);
@@ -14038,6 +14092,23 @@ again:
}
}
if ((zone->mastertlsnames != NULL) &&
(zone->mastertlsnames[zone->curmaster] != NULL))
{
dns_view_t *view = dns_zone_getview(zone);
dns_name_t *tlsname = zone->mastertlsnames[zone->curmaster];
result = dns_view_gettransport(view, DNS_TRANSPORT_TLS, tlsname,
&transport);
if (result != ISC_R_SUCCESS) {
char namebuf[DNS_NAME_FORMATSIZE];
dns_name_format(tlsname, namebuf, sizeof(namebuf));
dns_zone_log(zone, ISC_LOG_ERROR,
"unable to find TLS configuration: %s",
namebuf);
goto skip_master;
}
}
options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ? DNS_REQUESTOPT_TCP
: 0;
have_xfrsource = have_xfrdscp = false;
@@ -14116,6 +14187,24 @@ again:
goto cleanup;
}
/*
* FIXME(OS): This is a bit hackish, but it enforces the SOA query to go
* through the XFR channel instead of doing dns_request that doesn't
* have DoT support yet.
*/
if (transport != NULL) {
DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
do_queue_xfrin = true;
cancel = false;
result = ISC_R_SUCCESS;
goto cleanup;
}
result = create_query(zone, dns_rdatatype_soa, &zone->origin, &message);
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
result = add_opt(message, udpsize, reqnsid, reqexpire);
if (result != ISC_R_SUCCESS) {
@@ -14148,8 +14237,10 @@ again:
}
}
cancel = false;
cleanup:
if (transport != NULL) {
dns_transport_detach(&transport);
}
if (key != NULL) {
dns_tsigkey_detach(&key);
}
@@ -14164,6 +14255,9 @@ cleanup:
}
isc_event_free(&event);
UNLOCK_ZONE(zone);
if (do_queue_xfrin) {
queue_xfrin(zone);
}
dns_zone_idetach(&zone);
return;
@@ -14171,7 +14265,9 @@ skip_master:
if (key != NULL) {
dns_tsigkey_detach(&key);
}
dns_message_detach(&message);
if (message != NULL) {
dns_message_detach(&message);
}
/*
* Skip to next failed / untried master.
*/
@@ -14316,6 +14412,8 @@ ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
(void)dns_view_getpeertsig(zone->view, &masterip, &key);
}
/* FIXME(OS): Do we need the transport here too? Most probably yes */
reqnsid = zone->view->requestnsid;
if (zone->view->peers != NULL) {
dns_peer_t *peer = NULL;
@@ -15629,6 +15727,32 @@ dns_zone_gettype(dns_zone_t *zone) {
return (zone->type);
}
const char *
dns_zonetype_name(dns_zonetype_t type) {
switch (type) {
case dns_zone_none:
return ("none");
case dns_zone_master:
return ("primary");
case dns_zone_slave:
return ("secondary");
case dns_zone_mirror:
return ("mirror");
case dns_zone_stub:
return ("stub");
case dns_zone_staticstub:
return ("static-stub");
case dns_zone_key:
return ("key");
case dns_zone_dlz:
return ("dlz");
case dns_zone_redirect:
return ("redirect");
default:
return ("unknown");
}
}
dns_zonetype_t
dns_zone_getredirecttype(dns_zone_t *zone) {
REQUIRE(DNS_ZONE_VALID(zone));
@@ -17204,6 +17328,10 @@ again:
dns_tsigkey_detach(&zone->tsigkey);
}
if (zone->transport != NULL) {
dns_transport_detach(&zone->transport);
}
/*
* Handle any deferred journal compaction.
*/
@@ -17561,6 +17689,26 @@ got_transfer_quota(isc_task_t *task, isc_event_t *event) {
isc_result_totext(result));
}
if ((zone->mastertlsnames != NULL) &&
(zone->mastertlsnames[zone->curmaster] != NULL))
{
dns_view_t *view = dns_zone_getview(zone);
dns_name_t *tlsname = zone->mastertlsnames[zone->curmaster];
result = dns_view_gettransport(view, DNS_TRANSPORT_TLS, tlsname,
&zone->transport);
dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR,
"got TLS configuration for zone transfer: %s",
isc_result_totext(result));
}
if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
dns_zone_logc(
zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR,
"could not get TLS configuration for zone transfer: %s",
isc_result_totext(result));
}
if (zone->masterdscps != NULL) {
dscp = zone->masterdscps[zone->curmaster];
}
@@ -17591,8 +17739,8 @@ got_transfer_quota(isc_task_t *task, isc_event_t *event) {
}
CHECK(dns_xfrin_create(zone, xfrtype, &masteraddr, &sourceaddr, dscp,
zone->tsigkey, zone->mctx, zone->zmgr->netmgr,
zone_xfrdone, &zone->xfr));
zone->tsigkey, zone->transport, zone->mctx,
zone->zmgr->netmgr, zone_xfrdone, &zone->xfr));
LOCK_ZONE(zone);
if (xfrtype == dns_rdatatype_axfr) {
if (isc_sockaddr_pf(&masteraddr) == PF_INET) {
+41 -32
View File
@@ -161,37 +161,22 @@ has_dname(const vctx_t *vctx, dns_dbnode_t *node) {
static bool
goodsig(const vctx_t *vctx, dns_rdata_t *sigrdata, const dns_name_t *name,
dns_rdataset_t *keyrdataset, dns_rdataset_t *rdataset) {
dns_rdata_dnskey_t key;
dst_key_t **dstkeys, size_t nkeys, dns_rdataset_t *rdataset) {
dns_rdata_rrsig_t sig;
dst_key_t *dstkey = NULL;
isc_result_t result;
result = dns_rdata_tostruct(sigrdata, &sig, NULL);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
for (result = dns_rdataset_first(keyrdataset); result == ISC_R_SUCCESS;
result = dns_rdataset_next(keyrdataset))
{
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdataset_current(keyrdataset, &rdata);
result = dns_rdata_tostruct(&rdata, &key, NULL);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
result = dns_dnssec_keyfromrdata(vctx->origin, &rdata,
vctx->mctx, &dstkey);
if (result != ISC_R_SUCCESS) {
return (false);
}
if (sig.algorithm != key.algorithm ||
sig.keyid != dst_key_id(dstkey) ||
for (size_t key = 0; key < nkeys; key++) {
if (sig.algorithm != dst_key_alg(dstkeys[key]) ||
sig.keyid != dst_key_id(dstkeys[key]) ||
!dns_name_equal(&sig.signer, vctx->origin))
{
dst_key_free(&dstkey);
continue;
}
result = dns_dnssec_verify(name, rdataset, dstkey, false, 0,
vctx->mctx, sigrdata, NULL);
dst_key_free(&dstkey);
result = dns_dnssec_verify(name, rdataset, dstkeys[key], false,
0, vctx->mctx, sigrdata, NULL);
if (result == ISC_R_SUCCESS || result == DNS_R_FROMWILDCARD) {
return (true);
}
@@ -816,7 +801,7 @@ verifynsec3s(const vctx_t *vctx, const dns_name_t *name,
static isc_result_t
verifyset(vctx_t *vctx, dns_rdataset_t *rdataset, const dns_name_t *name,
dns_dbnode_t *node, dns_rdataset_t *keyrdataset) {
dns_dbnode_t *node, dst_key_t **dstkeys, size_t nkeys) {
unsigned char set_algorithms[256];
char namebuf[DNS_NAME_FORMATSIZE];
char algbuf[DNS_SECALG_FORMATSIZE];
@@ -883,7 +868,7 @@ verifyset(vctx_t *vctx, dns_rdataset_t *rdataset, const dns_name_t *name,
{
continue;
}
if (goodsig(vctx, &rdata, name, keyrdataset, rdataset)) {
if (goodsig(vctx, &rdata, name, dstkeys, nkeys, rdataset)) {
dns_rdataset_settrust(rdataset, dns_trust_secure);
dns_rdataset_settrust(&sigrdataset, dns_trust_secure);
set_algorithms[sig.algorithm] = 1;
@@ -919,7 +904,7 @@ done:
static isc_result_t
verifynode(vctx_t *vctx, const dns_name_t *name, dns_dbnode_t *node,
bool delegation, dns_rdataset_t *keyrdataset,
bool delegation, dst_key_t **dstkeys, size_t nkeys,
dns_rdataset_t *nsecset, dns_rdataset_t *nsec3paramset,
const dns_name_t *nextname, isc_result_t *vresult) {
unsigned char types[8192];
@@ -953,8 +938,8 @@ verifynode(vctx_t *vctx, const dns_name_t *name, dns_dbnode_t *node,
(!delegation || rdataset.type == dns_rdatatype_ds ||
rdataset.type == dns_rdatatype_nsec))
{
result = verifyset(vctx, &rdataset, name, node,
keyrdataset);
result = verifyset(vctx, &rdataset, name, node, dstkeys,
nkeys);
if (result != ISC_R_SUCCESS) {
dns_rdataset_disassociate(&rdataset);
dns_rdatasetiter_destroy(&rdsiter);
@@ -1724,6 +1709,8 @@ verify_nodes(vctx_t *vctx, isc_result_t *vresult) {
dns_name_t *name, *nextname, *prevname, *zonecut;
dns_dbnode_t *node = NULL, *nextnode;
dns_dbiterator_t *dbiter = NULL;
dst_key_t **dstkeys;
size_t count, nkeys = 0;
bool done = false;
isc_result_t tvresult = ISC_R_UNSET;
isc_result_t result;
@@ -1735,11 +1722,27 @@ verify_nodes(vctx_t *vctx, isc_result_t *vresult) {
dns_fixedname_init(&fzonecut);
zonecut = NULL;
count = dns_rdataset_count(&vctx->keyset);
dstkeys = isc_mem_get(vctx->mctx, sizeof(*dstkeys) * count);
for (result = dns_rdataset_first(&vctx->keyset);
result == ISC_R_SUCCESS; result = dns_rdataset_next(&vctx->keyset))
{
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdataset_current(&vctx->keyset, &rdata);
dstkeys[nkeys] = NULL;
result = dns_dnssec_keyfromrdata(vctx->origin, &rdata,
vctx->mctx, &dstkeys[nkeys]);
if (result == ISC_R_SUCCESS) {
nkeys++;
}
}
result = dns_db_createiterator(vctx->db, DNS_DB_NONSEC3, &dbiter);
if (result != ISC_R_SUCCESS) {
zoneverify_log_error(vctx, "dns_db_createiterator(): %s",
isc_result_totext(result));
return (result);
goto done;
}
result = dns_dbiterator_first(dbiter);
@@ -1839,9 +1842,9 @@ verify_nodes(vctx_t *vctx, isc_result_t *vresult) {
dns_db_detachnode(vctx->db, &node);
goto done;
}
result = verifynode(vctx, name, node, isdelegation,
&vctx->keyset, &vctx->nsecset,
&vctx->nsec3paramset, nextname, &tvresult);
result = verifynode(vctx, name, node, isdelegation, dstkeys,
nkeys, &vctx->nsecset, &vctx->nsec3paramset,
nextname, &tvresult);
if (result != ISC_R_SUCCESS) {
dns_db_detachnode(vctx->db, &node);
goto done;
@@ -1889,7 +1892,7 @@ verify_nodes(vctx_t *vctx, isc_result_t *vresult) {
isc_result_totext(result));
goto done;
}
result = verifynode(vctx, name, node, false, &vctx->keyset,
result = verifynode(vctx, name, node, false, dstkeys, nkeys,
NULL, NULL, NULL, NULL);
if (result != ISC_R_SUCCESS) {
zoneverify_log_error(vctx, "verifynode: %s",
@@ -1907,7 +1910,13 @@ verify_nodes(vctx_t *vctx, isc_result_t *vresult) {
result = ISC_R_SUCCESS;
done:
dns_dbiterator_destroy(&dbiter);
while (nkeys-- > 0U) {
dst_key_free(&dstkeys[nkeys]);
}
isc_mem_put(vctx->mctx, dstkeys, sizeof(*dstkeys) * count);
if (dbiter != NULL) {
dns_dbiterator_destroy(&dbiter);
}
return (result);
}
+4
View File
@@ -90,6 +90,7 @@ libisc_la_HEADERS = \
include/isc/tls.h \
include/isc/tm.h \
include/isc/types.h \
include/isc/url.h \
include/isc/utf8.h \
include/isc/util.h \
pthreads/include/isc/condition.h\
@@ -124,11 +125,13 @@ libisc_la_SOURCES = \
$(libisc_la_HEADERS) \
$(pk11_HEADERS) \
$(pkcs11_HEADERS) \
netmgr/http.c \
netmgr/netmgr-int.h \
netmgr/netmgr.c \
netmgr/tcp.c \
netmgr/tcpdns.c \
netmgr/tlsdns.c \
netmgr/tlsstream.c \
netmgr/udp.c \
netmgr/uv-compat.c \
netmgr/uv-compat.h \
@@ -149,6 +152,7 @@ libisc_la_SOURCES = \
unix/stdtime.c \
unix/syslog.c \
unix/time.c \
url.c \
pk11.c \
pk11_result.c \
aes.c \
+6 -1
View File
@@ -172,6 +172,8 @@ typedef struct isc_memmethods {
void *(*memreallocate)(isc_mem_t *mctx, void *ptr,
size_t size _ISC_MEM_FLARG);
char *(*memstrdup)(isc_mem_t *mctx, const char *s _ISC_MEM_FLARG);
char *(*memstrndup)(isc_mem_t *mctx, const char *s,
size_t size _ISC_MEM_FLARG);
void (*memfree)(isc_mem_t *mctx, void *ptr _ISC_MEM_FLARG);
} isc_memmethods_t;
@@ -226,7 +228,9 @@ struct isc_mempool {
#define isc_mem_reallocate(c, p, s) \
ISCMEMFUNC(reallocate)((c), (p), (s)_ISC_MEM_FILELINE)
#define isc_mem_strdup(c, p) ISCMEMFUNC(strdup)((c), (p)_ISC_MEM_FILELINE)
#define isc_mempool_get(c) ISCMEMPOOLFUNC(get)((c)_ISC_MEM_FILELINE)
#define isc_mem_strndup(c, p, l) \
ISCMEMFUNC(strndup)((c), (p), (l)_ISC_MEM_FILELINE)
#define isc_mempool_get(c) ISCMEMPOOLFUNC(get)((c)_ISC_MEM_FILELINE)
#define isc_mem_put(c, p, s) \
do { \
@@ -596,6 +600,7 @@ void *ISCMEMFUNC(allocate)(isc_mem_t *, size_t _ISC_MEM_FLARG);
void *ISCMEMFUNC(reallocate)(isc_mem_t *, void *, size_t _ISC_MEM_FLARG);
void ISCMEMFUNC(free)(isc_mem_t *, void *_ISC_MEM_FLARG);
char *ISCMEMFUNC(strdup)(isc_mem_t *, const char *_ISC_MEM_FLARG);
char *ISCMEMFUNC(strndup)(isc_mem_t *, const char *, size_t _ISC_MEM_FLARG);
void *ISCMEMPOOLFUNC(get)(isc_mempool_t *_ISC_MEM_FLARG);
void ISCMEMPOOLFUNC(put)(isc_mempool_t *, void *_ISC_MEM_FLARG);
+54
View File
@@ -473,6 +473,17 @@ isc_nm_setstats(isc_nm_t *mgr, isc_stats_t *stats);
* full range of socket-related stats counter numbers.
*/
isc_result_t
isc_nm_listentls(isc_nm_t *mgr, isc_nmiface_t *iface,
isc_nm_accept_cb_t accept_cb, void *accept_cbarg,
size_t extrahandlesize, int backlog, isc_quota_t *quota,
isc_tlsctx_t *sslctx, isc_nmsocket_t **sockp);
isc_result_t
isc_nm_tlsconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
isc_nm_cb_t cb, void *cbarg, isc_tlsctx_t *ctx,
unsigned int timeout, size_t extrahandlesize);
isc_result_t
isc_nm_tcpdnsconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
isc_nm_cb_t cb, void *cbarg, unsigned int timeout,
@@ -494,3 +505,46 @@ isc_nm_tlsdnsconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
* The connected socket can only be accessed via the handle passed to
* 'cb'.
*/
typedef void (*isc_nm_http_cb_t)(isc_nmhandle_t *handle, isc_result_t eresult,
isc_region_t *data, void *cbarg);
/*%<
* Callback function to be used when receiving an HTTP request.
*
* 'handle' the handle that can be used to send back the answer.
* 'eresult' the result of the event.
* 'data' contains the received data, if any. It will be freed
* after return by caller.
* 'cbarg' the callback argument passed to listen function.
*/
isc_result_t
isc_nm_http_connect_send_request(isc_nm_t *mgr, const char *uri, bool POST,
isc_region_t *message, isc_nm_recv_cb_t cb,
void *cbarg, isc_tlsctx_t *ctx,
unsigned int timeout);
isc_result_t
isc_nm_httpconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
const char *uri, bool POST, isc_nm_cb_t cb, void *cbarg,
isc_tlsctx_t *ctx, unsigned int timeout,
size_t extrahandlesize);
isc_result_t
isc_nm_httprequest(isc_nmhandle_t *handle, isc_region_t *region,
isc_nm_recv_cb_t reply_cb, void *cbarg);
isc_result_t
isc_nm_listenhttp(isc_nm_t *mgr, isc_nmiface_t *iface, int backlog,
isc_quota_t *quota, isc_tlsctx_t *ctx,
isc_nmsocket_t **sockp);
isc_result_t
isc_nm_http_add_endpoint(isc_nmsocket_t *sock, const char *uri,
isc_nm_http_cb_t cb, void *cbarg,
size_t extrahandlesize);
isc_result_t
isc_nm_http_add_doh_endpoint(isc_nmsocket_t *sock, const char *uri,
isc_nm_recv_cb_t cb, void *cbarg,
size_t extrahandlesize);
+80
View File
@@ -0,0 +1,80 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* 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/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
/*
* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include <stdbool.h>
#include <stdint.h>
#include <isc/result.h>
/*
* Compile with -DHTTP_PARSER_STRICT=0 to make less checks, but run
* faster
*/
#ifndef HTTP_PARSER_STRICT
#define HTTP_PARSER_STRICT 1
#endif
typedef enum {
ISC_UF_SCHEMA = 0,
ISC_UF_HOST = 1,
ISC_UF_PORT = 2,
ISC_UF_PATH = 3,
ISC_UF_QUERY = 4,
ISC_UF_FRAGMENT = 5,
ISC_UF_USERINFO = 6,
ISC_UF_MAX = 7
} isc_url_field_t;
/* Result structure for isc_url_parse().
*
* Callers should index into field_data[] with UF_* values iff field_set
* has the relevant (1 << UF_*) bit set. As a courtesy to clients (and
* because we probably have padding left over), we convert any port to
* a uint16_t.
*/
typedef struct {
uint16_t field_set; /* Bitmask of (1 << UF_*) values */
uint16_t port; /* Converted UF_PORT string */
struct {
uint16_t off; /* Offset into buffer in which field starts */
uint16_t len; /* Length of run in buffer */
} field_data[ISC_UF_MAX];
} isc_url_parser_t;
isc_result_t
isc_url_parse(const char *buf, size_t buflen, bool is_connect,
isc_url_parser_t *up);
/*%<
* Parse a URL; return nonzero on failure
*/
+33 -1
View File
@@ -244,13 +244,15 @@ static void *
isc___mem_reallocate(isc_mem_t *ctx, void *ptr, size_t size FLARG);
static char *
isc___mem_strdup(isc_mem_t *mctx, const char *s FLARG);
static char *
isc___mem_strndup(isc_mem_t *mctx, const char *s, size_t size FLARG);
static void
isc___mem_free(isc_mem_t *ctx, void *ptr FLARG);
static isc_memmethods_t memmethods = {
isc___mem_get, isc___mem_put, isc___mem_putanddetach,
isc___mem_allocate, isc___mem_reallocate, isc___mem_strdup,
isc___mem_free,
isc___mem_strndup, isc___mem_free,
};
#if ISC_MEM_TRACKLINES
@@ -1439,6 +1441,29 @@ isc___mem_strdup(isc_mem_t *mctx0, const char *s FLARG) {
return (ns);
}
char *
isc___mem_strndup(isc_mem_t *mctx0, const char *s, size_t size FLARG) {
REQUIRE(VALID_CONTEXT(mctx0));
REQUIRE(s != NULL);
isc__mem_t *mctx = (isc__mem_t *)mctx0;
size_t len;
char *ns;
len = strlen(s) + 1;
if (len > size) {
len = size;
}
ns = isc__mem_allocate((isc_mem_t *)mctx, len FLARG_PASS);
if (ns != NULL) {
strlcpy(ns, s, len);
}
return (ns);
}
void
isc_mem_setdestroycheck(isc_mem_t *ctx0, bool flag) {
REQUIRE(VALID_CONTEXT(ctx0));
@@ -2467,6 +2492,13 @@ isc__mem_strdup(isc_mem_t *mctx, const char *s FLARG) {
return (mctx->methods->memstrdup(mctx, s FLARG_PASS));
}
char *
isc__mem_strndup(isc_mem_t *mctx, const char *s, size_t size FLARG) {
REQUIRE(ISCAPI_MCTX_VALID(mctx));
return (mctx->methods->memstrndup(mctx, s, size FLARG_PASS));
}
void
isc__mem_free(isc_mem_t *mctx, void *ptr FLARG) {
REQUIRE(ISCAPI_MCTX_VALID(mctx));
File diff suppressed because it is too large Load Diff
+237 -5
View File
@@ -30,6 +30,7 @@
#include <isc/refcount.h>
#include <isc/region.h>
#include <isc/result.h>
#include <isc/rwlock.h>
#include <isc/sockaddr.h>
#include <isc/stats.h>
#include <isc/thread.h>
@@ -155,6 +156,8 @@ isc__nm_dump_active(isc_nm_t *nm);
#define isc__nmsocket_prep_destroy(sock) isc___nmsocket_prep_destroy(sock)
#endif
typedef struct isc_nm_http2_session isc_nm_http2_session_t;
/*
* Single network event loop worker.
*/
@@ -207,6 +210,8 @@ struct isc_nmhandle {
isc_nmsocket_t *sock;
size_t ah_pos; /* Position in the socket's 'active handles' array */
isc_nm_http2_session_t *httpsession;
isc_sockaddr_t peer;
isc_sockaddr_t local;
isc_nm_opaquecb_t doreset; /* reset extra callback, external */
@@ -252,6 +257,13 @@ typedef enum isc__netievent_type {
netievent_tcpdnsclose,
netievent_tcpdnsstop,
netievent_tlsclose,
netievent_tlssend,
netievent_tlsstartread,
netievent_tlsconnect,
netievent_tlsdobio,
netievent_tlscancel,
netievent_tlsdnsaccept,
netievent_tlsdnsconnect,
netievent_tlsdnssend,
@@ -262,6 +274,10 @@ typedef enum isc__netievent_type {
netievent_tlsdnscycle,
netievent_tlsdnsshutdown,
netievent_httpstop,
netievent_httpsend,
netievent_httpclose,
netievent_close,
netievent_shutdown,
netievent_stop,
@@ -286,11 +302,22 @@ typedef enum isc__netievent_type {
typedef union {
isc_nm_recv_cb_t recv;
isc_nm_http_cb_t http;
isc_nm_cb_t send;
isc_nm_cb_t connect;
isc_nm_accept_cb_t accept;
} isc__nm_cb_t;
typedef struct isc_nm_http2_server_handler isc_nm_http2_server_handler_t;
struct isc_nm_http2_server_handler {
char *path;
isc_nm_http_cb_t cb;
void *cbarg;
size_t extrahandlesize;
LINK(isc_nm_http2_server_handler_t) link;
};
/*
* Wrapper around uv_req_t with 'our' fields in it. req->data should
* always point to its parent. Note that we always allocate more than
@@ -642,8 +669,12 @@ typedef enum isc_nmsocket_type {
isc_nm_tcplistener,
isc_nm_tcpdnslistener,
isc_nm_tcpdnssocket,
isc_nm_tlslistener,
isc_nm_tlssocket,
isc_nm_tlsdnslistener,
isc_nm_tlsdnssocket
isc_nm_tlsdnssocket,
isc_nm_httplistener,
isc_nm_httpstream
} isc_nmsocket_type;
/*%
@@ -670,12 +701,74 @@ enum {
STATID_ACTIVE = 10
};
typedef struct isc_nmsocket_tls_send_req {
isc_nmsocket_t *tlssock;
isc_region_t data;
} isc_nmsocket_tls_send_req_t;
typedef enum isc_doh_request_type {
ISC_HTTP_REQ_GET,
ISC_HTTP_REQ_POST,
ISC_HTTP_REQ_UNSUPPORTED
} isc_http2_request_type_t;
typedef enum isc_http2_scheme_type {
ISC_HTTP_SCHEME_HTTP,
ISC_HTTP_SCHEME_HTTP_SECURE,
ISC_HTTP_SCHEME_UNSUPPORTED
} isc_http2_scheme_type_t;
typedef struct isc_nm_http_doh_cbarg {
isc_nm_recv_cb_t cb;
void *cbarg;
LINK(struct isc_nm_http_doh_cbarg) link;
} isc_nm_http_doh_cbarg_t;
typedef struct isc_nmsocket_h2 {
isc_nmsocket_t *psock; /* owner of the structure */
char *request_path;
char *query_data;
size_t query_data_len;
bool query_too_large;
isc_nm_http2_server_handler_t *handler;
uint8_t *buf;
size_t bufsize;
size_t bufpos;
int32_t stream_id;
isc_nm_http2_session_t *session;
isc_nmsocket_t *httpserver;
isc_http2_request_type_t request_type;
isc_http2_scheme_type_t request_scheme;
size_t content_length;
bool content_type_verified;
bool accept_type_verified;
isc_nm_http_cb_t handler_cb;
void *handler_cbarg;
LINK(struct isc_nmsocket_h2) link;
ISC_LIST(isc_nm_http2_server_handler_t) handlers;
ISC_LIST(isc_nm_http_doh_cbarg_t) handlers_cbargs;
isc_rwlock_t handlers_lock;
char response_content_length_str[128];
struct isc_nmsocket_h2_connect_data {
char *uri;
bool post;
} connect;
} isc_nmsocket_h2_t;
struct isc_nmsocket {
/*% Unlocked, RO */
int magic;
int tid;
isc_nmsocket_type type;
isc_nm_t *mgr;
/*% Parent socket for multithreaded listeners */
isc_nmsocket_t *parent;
/*% Listener socket this connection was accepted on */
@@ -705,6 +798,28 @@ struct isc_nmsocket {
isc__nm_uvreq_t *pending_req;
} tls;
/*% TLS stuff */
struct tlsstream {
bool server;
BIO *app_bio;
SSL *ssl;
SSL_CTX *ctx;
BIO *ssl_bio;
isc_nmsocket_t *tlslistener;
enum {
TLS_INIT,
TLS_HANDSHAKE,
TLS_IO,
TLS_ERROR,
TLS_CLOSING,
TLS_CLOSED
} state;
size_t nsending;
/* List of active send requests. */
ISC_LIST(isc__nm_uvreq_t) sends;
} tlsstream;
isc_nmsocket_h2_t h2;
/*%
* quota is the TCP client, attached when a TCP connection
* is established. pquota is a non-attached pointer to the
@@ -906,6 +1021,7 @@ struct isc_nmsocket {
void *accept_cbarg;
atomic_int_fast32_t active_child_connections;
#ifdef NETMGR_TRACE
void *backtrace[TRACE_SIZE];
int backtrace_size;
@@ -1070,8 +1186,8 @@ isc__nm_async_shutdown(isc__networker_t *worker, isc__netievent_t *ev0);
*/
void
isc__nm_udp_send(isc_nmhandle_t *handle, isc_region_t *region, isc_nm_cb_t cb,
void *cbarg);
isc__nm_udp_send(isc_nmhandle_t *handle, const isc_region_t *region,
isc_nm_cb_t cb, void *cbarg);
/*%<
* Back-end implementation of isc_nm_send() for UDP handles.
*/
@@ -1132,8 +1248,8 @@ isc__nm_async_udpclose(isc__networker_t *worker, isc__netievent_t *ev0);
*/
void
isc__nm_tcp_send(isc_nmhandle_t *handle, isc_region_t *region, isc_nm_cb_t cb,
void *cbarg);
isc__nm_tcp_send(isc_nmhandle_t *handle, const isc_region_t *region,
isc_nm_cb_t cb, void *cbarg);
/*%<
* Back-end implementation of isc_nm_send() for TCP handles.
*/
@@ -1220,6 +1336,28 @@ isc__nm_async_tcpclose(isc__networker_t *worker, isc__netievent_t *ev0);
* stoplisten, send, read, pause, close).
*/
void
isc__nm_async_tlsclose(isc__networker_t *worker, isc__netievent_t *ev0);
void
isc__nm_async_tlssend(isc__networker_t *worker, isc__netievent_t *ev0);
void
isc__nm_async_tlsconnect(isc__networker_t *worker, isc__netievent_t *ev0);
void
isc__nm_async_tlsstartread(isc__networker_t *worker, isc__netievent_t *ev0);
void
isc__nm_async_tlsdobio(isc__networker_t *worker, isc__netievent_t *ev0);
void
isc__nm_async_tlscancel(isc__networker_t *worker, isc__netievent_t *ev0);
/*%<
* Callback handlers for asynchronouse TLS events.
*/
void
isc__nm_async_tcpdnsaccept(isc__networker_t *worker, isc__netievent_t *ev0);
void
@@ -1291,6 +1429,14 @@ isc__nm_async_tlsdnslisten(isc__networker_t *worker, isc__netievent_t *ev0);
void
isc__nm_tlsdns_send(isc_nmhandle_t *handle, isc_region_t *region,
isc_nm_cb_t cb, void *cbarg);
void
isc__nm_tls_send(isc_nmhandle_t *handle, const isc_region_t *region,
isc_nm_cb_t cb, void *cbarg);
void
isc__nm_tls_cancelread(isc_nmhandle_t *handle);
/*%<
* Back-end implementation of isc_nm_send() for TLSDNS handles.
*/
@@ -1344,6 +1490,71 @@ isc__nm_tlsdns_cancelread(isc_nmhandle_t *handle);
* Stop reading on a connected TLSDNS handle.
*/
void
isc__nm_tls_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg);
void
isc__nm_tls_close(isc_nmsocket_t *sock);
/*%<
* Close a TLS socket.
*/
void
isc__nm_tls_pauseread(isc_nmhandle_t *handle);
/*%<
* Pause reading on this handle, while still remembering the callback.
*/
void
isc__nm_tls_resumeread(isc_nmhandle_t *handle);
/*%<
* Resume reading from the handle.
*
*/
void
isc__nm_tls_cleanup_data(isc_nmsocket_t *sock);
void
isc__nm_tls_stoplistening(isc_nmsocket_t *sock);
void
isc__nm_http_stoplistening(isc_nmsocket_t *sock);
void
isc__nm_http_clear_handlers(isc_nmsocket_t *sock);
void
isc__nm_http_clear_session(isc_nmsocket_t *sock);
void
isc__nm_http_send(isc_nmhandle_t *handle, const isc_region_t *region,
isc_nm_cb_t cb, void *cbarg);
void
isc__nm_http_close(isc_nmsocket_t *sock);
void
isc__nm_async_httpsend(isc__networker_t *worker, isc__netievent_t *ev0);
void
isc__nm_async_httpstop(isc__networker_t *worker, isc__netievent_t *ev0);
void
isc__nm_async_httpclose(isc__networker_t *worker, isc__netievent_t *ev0);
bool
isc__nm_parse_doh_query_string(const char *query_string, const char **start,
size_t *len);
char *
isc__nm_base64url_to_base64(isc_mem_t *mem, const char *base64url,
const size_t base64url_len, size_t *res_len);
char *
isc__nm_base64_to_base64url(isc_mem_t *mem, const char *base64,
const size_t base64_len, size_t *res_len);
#define isc__nm_uverr2result(x) \
isc___nm_uverr2result(x, true, __FILE__, __LINE__, __func__)
isc_result_t
@@ -1444,6 +1655,12 @@ NETIEVENT_SOCKET_TYPE(tcpclose);
NETIEVENT_SOCKET_TYPE(tcplisten);
NETIEVENT_SOCKET_TYPE(tcppauseread);
NETIEVENT_SOCKET_TYPE(tcpstop);
NETIEVENT_SOCKET_TYPE(tlsclose);
/* NETIEVENT_SOCKET_TYPE(tlsconnect); */ /* unique type, defined independently
*/
NETIEVENT_SOCKET_TYPE(tlsdobio);
NETIEVENT_SOCKET_TYPE(tlsstartread);
NETIEVENT_SOCKET_HANDLE_TYPE(tlscancel);
NETIEVENT_SOCKET_TYPE(udpclose);
NETIEVENT_SOCKET_TYPE(udplisten);
NETIEVENT_SOCKET_TYPE(udpread);
@@ -1470,9 +1687,14 @@ NETIEVENT_SOCKET_HANDLE_TYPE(tlsdnscancel);
NETIEVENT_SOCKET_QUOTA_TYPE(tlsdnsaccept);
NETIEVENT_SOCKET_TYPE(tlsdnscycle);
NETIEVENT_SOCKET_TYPE(httpstop);
NETIEVENT_SOCKET_REQ_TYPE(httpsend);
NETIEVENT_SOCKET_TYPE(httpclose);
NETIEVENT_SOCKET_REQ_TYPE(tcpconnect);
NETIEVENT_SOCKET_REQ_TYPE(tcpsend);
NETIEVENT_SOCKET_TYPE(tcpstartread);
NETIEVENT_SOCKET_REQ_TYPE(tlssend);
NETIEVENT_SOCKET_REQ_TYPE(udpconnect);
NETIEVENT_SOCKET_REQ_RESULT_TYPE(connectcb);
@@ -1498,6 +1720,11 @@ NETIEVENT_SOCKET_DECL(tcplisten);
NETIEVENT_SOCKET_DECL(tcppauseread);
NETIEVENT_SOCKET_DECL(tcpstartread);
NETIEVENT_SOCKET_DECL(tcpstop);
NETIEVENT_SOCKET_DECL(tlsclose);
NETIEVENT_SOCKET_DECL(tlsconnect);
NETIEVENT_SOCKET_DECL(tlsdobio);
NETIEVENT_SOCKET_DECL(tlsstartread);
NETIEVENT_SOCKET_HANDLE_DECL(tlscancel);
NETIEVENT_SOCKET_DECL(udpclose);
NETIEVENT_SOCKET_DECL(udplisten);
NETIEVENT_SOCKET_DECL(udpread);
@@ -1524,8 +1751,13 @@ NETIEVENT_SOCKET_HANDLE_DECL(tlsdnscancel);
NETIEVENT_SOCKET_QUOTA_DECL(tlsdnsaccept);
NETIEVENT_SOCKET_DECL(tlsdnscycle);
NETIEVENT_SOCKET_DECL(httpstop);
NETIEVENT_SOCKET_REQ_DECL(httpsend);
NETIEVENT_SOCKET_DECL(httpclose);
NETIEVENT_SOCKET_REQ_DECL(tcpconnect);
NETIEVENT_SOCKET_REQ_DECL(tcpsend);
NETIEVENT_SOCKET_REQ_DECL(tlssend);
NETIEVENT_SOCKET_REQ_DECL(udpconnect);
NETIEVENT_SOCKET_REQ_RESULT_DECL(connectcb);
+123 -2
View File
@@ -716,6 +716,13 @@ process_netievent(isc__networker_t *worker, isc__netievent_t *ievent) {
NETIEVENT_CASE(tcpdnsread);
NETIEVENT_CASE(tcpdnsstop);
NETIEVENT_CASE(tlsstartread);
NETIEVENT_CASE(tlssend);
NETIEVENT_CASE(tlsclose);
NETIEVENT_CASE(tlsconnect);
NETIEVENT_CASE(tlsdobio);
NETIEVENT_CASE(tlscancel);
NETIEVENT_CASE(tlsdnscycle);
NETIEVENT_CASE(tlsdnsaccept);
NETIEVENT_CASE(tlsdnslisten);
@@ -727,6 +734,10 @@ process_netievent(isc__networker_t *worker, isc__netievent_t *ievent) {
NETIEVENT_CASE(tlsdnsstop);
NETIEVENT_CASE(tlsdnsshutdown);
NETIEVENT_CASE(httpstop);
NETIEVENT_CASE(httpsend);
NETIEVENT_CASE(httpclose);
NETIEVENT_CASE(connectcb);
NETIEVENT_CASE(readcb);
NETIEVENT_CASE(sendcb);
@@ -776,6 +787,11 @@ NETIEVENT_SOCKET_DEF(tcplisten);
NETIEVENT_SOCKET_DEF(tcppauseread);
NETIEVENT_SOCKET_DEF(tcpstartread);
NETIEVENT_SOCKET_DEF(tcpstop);
NETIEVENT_SOCKET_DEF(tlsclose);
NETIEVENT_SOCKET_DEF(tlsconnect);
NETIEVENT_SOCKET_DEF(tlsdobio);
NETIEVENT_SOCKET_DEF(tlsstartread);
NETIEVENT_SOCKET_HANDLE_DEF(tlscancel);
NETIEVENT_SOCKET_DEF(udpclose);
NETIEVENT_SOCKET_DEF(udplisten);
NETIEVENT_SOCKET_DEF(udpread);
@@ -802,8 +818,13 @@ NETIEVENT_SOCKET_QUOTA_DEF(tlsdnsaccept);
NETIEVENT_SOCKET_DEF(tlsdnscycle);
NETIEVENT_SOCKET_DEF(tlsdnsshutdown);
NETIEVENT_SOCKET_DEF(httpstop);
NETIEVENT_SOCKET_REQ_DEF(httpsend);
NETIEVENT_SOCKET_DEF(httpclose);
NETIEVENT_SOCKET_REQ_DEF(tcpconnect);
NETIEVENT_SOCKET_REQ_DEF(tcpsend);
NETIEVENT_SOCKET_REQ_DEF(tlssend);
NETIEVENT_SOCKET_REQ_DEF(udpconnect);
NETIEVENT_SOCKET_REQ_RESULT_DEF(connectcb);
@@ -986,6 +1007,34 @@ nmsocket_cleanup(isc_nmsocket_t *sock, bool dofree FLARG) {
isc_mutex_destroy(&sock->lock);
isc_condition_destroy(&sock->cond);
isc_condition_destroy(&sock->scond);
isc__nm_tls_cleanup_data(sock);
if (sock->type == isc_nm_httplistener) {
isc__nm_http_clear_handlers(sock);
isc_rwlock_destroy(&sock->h2.handlers_lock);
}
if (sock->h2.request_path != NULL) {
isc_mem_free(sock->mgr->mctx, sock->h2.request_path);
sock->h2.request_path = NULL;
}
if (sock->h2.query_data != NULL) {
isc_mem_free(sock->mgr->mctx, sock->h2.query_data);
sock->h2.query_data = NULL;
}
if (sock->h2.connect.uri != NULL) {
isc_mem_free(sock->mgr->mctx, sock->h2.connect.uri);
sock->h2.query_data = NULL;
}
if (sock->h2.buf != NULL) {
isc_mem_free(sock->mgr->mctx, sock->h2.buf);
sock->h2.buf = NULL;
}
isc__nm_http_clear_session(sock);
#ifdef NETMGR_TRACE
LOCK(&sock->mgr->lock);
ISC_LIST_UNLINK(sock->mgr->active_sockets, sock, active_link);
@@ -1094,9 +1143,15 @@ isc___nmsocket_prep_destroy(isc_nmsocket_t *sock FLARG) {
case isc_nm_tcpdnssocket:
isc__nm_tcpdns_close(sock);
return;
case isc_nm_tlssocket:
isc__nm_tls_close(sock);
break;
case isc_nm_tlsdnssocket:
isc__nm_tlsdns_close(sock);
return;
case isc_nm_httpstream:
isc__nm_http_close(sock);
return;
default:
break;
}
@@ -1139,7 +1194,9 @@ isc_nmsocket_close(isc_nmsocket_t **sockp) {
REQUIRE((*sockp)->type == isc_nm_udplistener ||
(*sockp)->type == isc_nm_tcplistener ||
(*sockp)->type == isc_nm_tcpdnslistener ||
(*sockp)->type == isc_nm_tlsdnslistener);
(*sockp)->type == isc_nm_tlsdnslistener ||
(*sockp)->type == isc_nm_tlslistener ||
(*sockp)->type == isc_nm_httplistener);
isc__nmsocket_detach(sockp);
}
@@ -1202,6 +1259,8 @@ isc___nmsocket_init(isc_nmsocket_t *sock, isc_nm_t *mgr, isc_nmsocket_type type,
case isc_nm_tcpdnslistener:
case isc_nm_tlsdnssocket:
case isc_nm_tlsdnslistener:
case isc_nm_httpstream:
case isc_nm_httplistener:
if (family == AF_INET) {
sock->statsindex = tcp4statsindex;
} else {
@@ -1218,6 +1277,9 @@ isc___nmsocket_init(isc_nmsocket_t *sock, isc_nm_t *mgr, isc_nmsocket_type type,
isc_condition_init(&sock->scond);
isc_refcount_init(&sock->references, 1);
memset(&sock->tlsstream, 0, sizeof(sock->tlsstream));
ISC_LIST_INIT(sock->tlsstream.sends);
NETMGR_TRACE_LOG("isc__nmsocket_init():%p->references = %lu\n", sock,
isc_refcount_current(&sock->references));
@@ -1228,6 +1290,28 @@ isc___nmsocket_init(isc_nmsocket_t *sock, isc_nm_t *mgr, isc_nmsocket_type type,
atomic_store(&sock->active_child_connections, 0);
if (type == isc_nm_httplistener) {
ISC_LIST_INIT(sock->h2.handlers);
ISC_LIST_INIT(sock->h2.handlers_cbargs);
isc_rwlock_init(&sock->h2.handlers_lock, 0, 1);
}
sock->h2.session = NULL;
sock->h2.httpserver = NULL;
sock->h2.query_data = NULL;
sock->h2.query_data_len = 0;
sock->h2.query_too_large = false;
sock->h2.request_path = NULL;
sock->h2.request_type = ISC_HTTP_REQ_UNSUPPORTED;
sock->h2.request_scheme = ISC_HTTP_SCHEME_UNSUPPORTED;
sock->h2.content_length = 0;
sock->h2.content_type_verified = false;
sock->h2.accept_type_verified = false;
sock->h2.handler_cb = NULL;
sock->h2.handler_cbarg = NULL;
sock->h2.connect.uri = NULL;
sock->h2.buf = NULL;
sock->magic = NMSOCK_MAGIC;
}
@@ -1353,7 +1437,7 @@ isc___nmhandle_get(isc_nmsocket_t *sock, isc_sockaddr_t *peer,
#endif
UNLOCK(&sock->lock);
if (sock->type == isc_nm_tcpsocket ||
if (sock->type == isc_nm_tcpsocket || sock->type == isc_nm_tlssocket ||
(sock->type == isc_nm_udpsocket && atomic_load(&sock->client)) ||
(sock->type == isc_nm_tcpdnssocket && atomic_load(&sock->client)) ||
(sock->type == isc_nm_tlsdnssocket && atomic_load(&sock->client)))
@@ -1369,6 +1453,10 @@ isc___nmhandle_get(isc_nmsocket_t *sock, isc_sockaddr_t *peer,
sock->statichandle = handle;
}
if (sock->type == isc_nm_httpstream) {
handle->httpsession = sock->h2.session;
}
return (handle);
}
@@ -1390,6 +1478,7 @@ isc_nmhandle_is_stream(isc_nmhandle_t *handle) {
return (handle->sock->type == isc_nm_tcpsocket ||
handle->sock->type == isc_nm_tcpdnssocket ||
handle->sock->type == isc_nm_tlssocket ||
handle->sock->type == isc_nm_tlsdnssocket);
}
@@ -1667,9 +1756,15 @@ isc_nm_send(isc_nmhandle_t *handle, isc_region_t *region, isc_nm_cb_t cb,
case isc_nm_tcpdnssocket:
isc__nm_tcpdns_send(handle, region, cb, cbarg);
break;
case isc_nm_tlssocket:
isc__nm_tls_send(handle, region, cb, cbarg);
break;
case isc_nm_tlsdnssocket:
isc__nm_tlsdns_send(handle, region, cb, cbarg);
break;
case isc_nm_httpstream:
isc__nm_http_send(handle, region, cb, cbarg);
break;
default:
INSIST(0);
ISC_UNREACHABLE();
@@ -1697,6 +1792,9 @@ isc_nm_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg) {
case isc_nm_tcpdnssocket:
isc__nm_tcpdns_read(handle, cb, cbarg);
break;
case isc_nm_tlssocket:
isc__nm_tls_read(handle, cb, cbarg);
break;
case isc_nm_tlsdnssocket:
isc__nm_tlsdns_read(handle, cb, cbarg);
break;
@@ -1723,6 +1821,9 @@ isc_nm_cancelread(isc_nmhandle_t *handle) {
case isc_nm_tlsdnssocket:
isc__nm_tlsdns_cancelread(handle);
break;
case isc_nm_tlssocket:
isc__nm_tls_cancelread(handle);
break;
default:
INSIST(0);
ISC_UNREACHABLE();
@@ -1739,6 +1840,9 @@ isc_nm_pauseread(isc_nmhandle_t *handle) {
case isc_nm_tcpsocket:
isc__nm_tcp_pauseread(handle);
break;
case isc_nm_tlssocket:
isc__nm_tls_pauseread(handle);
break;
default:
INSIST(0);
ISC_UNREACHABLE();
@@ -1755,6 +1859,9 @@ isc_nm_resumeread(isc_nmhandle_t *handle) {
case isc_nm_tcpsocket:
isc__nm_tcp_resumeread(handle);
break;
case isc_nm_tlssocket:
isc__nm_tls_resumeread(handle);
break;
default:
INSIST(0);
ISC_UNREACHABLE();
@@ -1775,9 +1882,15 @@ isc_nm_stoplistening(isc_nmsocket_t *sock) {
case isc_nm_tcplistener:
isc__nm_tcp_stoplistening(sock);
break;
case isc_nm_tlslistener:
isc__nm_tls_stoplistening(sock);
break;
case isc_nm_tlsdnslistener:
isc__nm_tlsdns_stoplistening(sock);
break;
case isc_nm_httplistener:
isc__nm_http_stoplistening(sock);
break;
default:
INSIST(0);
ISC_UNREACHABLE();
@@ -2322,10 +2435,18 @@ nmsocket_type_totext(isc_nmsocket_type type) {
return ("isc_nm_tcpdnslistener");
case isc_nm_tcpdnssocket:
return ("isc_nm_tcpdnssocket");
case isc_nm_tlssocket:
return ("isc_nm_tlssocket");
case isc_nm_tlslistener:
return ("isc_nm_tlslistener");
case isc_nm_tlsdnslistener:
return ("isc_nm_tlsdnslistener");
case isc_nm_tlsdnssocket:
return ("isc_nm_tlsdnssocket");
case isc_nm_httplistener:
return ("isc_nm_httplistener");
case isc_nm_httpstream:
return ("isc_nm_httpstream");
default:
INSIST(0);
ISC_UNREACHABLE();
+28 -21
View File
@@ -167,6 +167,27 @@ tcp_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
REQUIRE(isc__nm_in_netthread());
REQUIRE(sock->tid == isc_nm_tid());
result = isc__nm_socket(req->peer.type.sa.sa_family, SOCK_STREAM, 0,
&sock->fd);
/*
* The socket() call can fail spuriously on FreeBSD 12, so we need to
* handle the failure early and gracefully.
*/
if (result != ISC_R_SUCCESS) {
atomic_store(&sock->closed, true);
isc__nm_uvreq_t *cbreq = NULL;
cbreq = isc__nm_uvreq_get(sock->mgr, sock);
cbreq->cb.connect = req->cb.connect;
cbreq->cbarg = req->cbarg;
isc_nmhandle_attach(req->handle, &cbreq->handle);
isc__nmsocket_clearcb(sock);
isc__nm_connectcb(sock, cbreq, result);
goto error;
}
result = isc__nm_socket_connectiontimeout(sock->fd,
sock->connect_timeout);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
worker = &sock->mgr->workers[sock->tid];
atomic_store(&sock->connecting, true);
@@ -210,7 +231,7 @@ tcp_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
done:
result = isc__nm_uverr2result(r);
error:
LOCK(&sock->lock);
sock->result = result;
SIGNAL(&sock->cond);
@@ -239,10 +260,13 @@ isc__nm_async_tcpconnect(isc__networker_t *worker, isc__netievent_t *ev0) {
REQUIRE(sock->parent == NULL);
REQUIRE(sock->tid == isc_nm_tid());
sock->fd = (uv_os_sock_t)(-1);
result = tcp_connect_direct(sock, req);
if (result != ISC_R_SUCCESS) {
atomic_store(&sock->active, false);
isc__nm_tcp_close(sock);
if (sock->fd != (uv_os_sock_t)(-1)) {
isc__nm_tcp_close(sock);
}
isc__nm_uvreq_put(&req, sock);
}
@@ -309,36 +333,19 @@ isc_nm_tcpconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
isc_nmsocket_t *sock = NULL;
isc__netievent_tcpconnect_t *ievent = NULL;
isc__nm_uvreq_t *req = NULL;
sa_family_t sa_family;
uv_os_sock_t fd;
REQUIRE(VALID_NM(mgr));
REQUIRE(local != NULL);
REQUIRE(peer != NULL);
sa_family = peer->addr.type.sa.sa_family;
/*
* The socket() call can fail spuriously on FreeBSD 12, so we need to
* handle the failure early and gracefully.
*/
result = isc__nm_socket(sa_family, SOCK_STREAM, 0, &fd);
if (result != ISC_R_SUCCESS) {
return (result);
}
sock = isc_mem_get(mgr->mctx, sizeof(*sock));
isc__nmsocket_init(sock, mgr, isc_nm_tcpsocket, local);
sock->extrahandlesize = extrahandlesize;
sock->connect_timeout = timeout;
sock->result = ISC_R_DEFAULT;
sock->fd = fd;
atomic_init(&sock->client, true);
result = isc__nm_socket_connectiontimeout(fd, timeout);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
req = isc__nm_uvreq_get(mgr, sock);
req->cb.connect = cb;
req->cbarg = cbarg;
@@ -1155,8 +1162,8 @@ failure:
}
void
isc__nm_tcp_send(isc_nmhandle_t *handle, isc_region_t *region, isc_nm_cb_t cb,
void *cbarg) {
isc__nm_tcp_send(isc_nmhandle_t *handle, const isc_region_t *region,
isc_nm_cb_t cb, void *cbarg) {
REQUIRE(VALID_NMHANDLE(handle));
REQUIRE(VALID_NMSOCK(handle->sock));
+936
View File
@@ -0,0 +1,936 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* 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/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
#include <libgen.h>
#include <unistd.h>
#include <uv.h>
#include <openssl/err.h>
#include <openssl/ssl.h>
#include <isc/atomic.h>
#include <isc/buffer.h>
#include <isc/condition.h>
#include <isc/log.h>
#include <isc/magic.h>
#include <isc/mem.h>
#include <isc/netmgr.h>
#include <isc/once.h>
#include <isc/quota.h>
#include <isc/random.h>
#include <isc/refcount.h>
#include <isc/region.h>
#include <isc/result.h>
#include <isc/sockaddr.h>
#include <isc/stdtime.h>
#include <isc/thread.h>
#include <isc/util.h>
#include "netmgr-int.h"
#include "uv-compat.h"
#define TLS_BUF_SIZE 65536
static isc_result_t
tls_error_to_result(int tls_err) {
switch (tls_err) {
case SSL_ERROR_ZERO_RETURN:
return (ISC_R_EOF);
default:
return (ISC_R_UNEXPECTED);
}
}
static void
tls_do_bio(isc_nmsocket_t *sock);
static void
tls_close_direct(isc_nmsocket_t *sock);
static void
async_tls_do_bio(isc_nmsocket_t *sock);
/*
* The socket is closing, outerhandle has been detached, listener is
* inactive, or the netmgr is closing: any operation on it should abort
* with ISC_R_CANCELED.
*/
static bool
inactive(isc_nmsocket_t *sock) {
return (!isc__nmsocket_active(sock) || atomic_load(&sock->closing) ||
sock->outerhandle == NULL ||
(sock->listener != NULL &&
!isc__nmsocket_active(sock->listener)) ||
atomic_load(&sock->mgr->closing));
}
static void
update_result(isc_nmsocket_t *sock, const isc_result_t result) {
LOCK(&sock->lock);
sock->result = result;
SIGNAL(&sock->cond);
if (!atomic_load(&sock->active)) {
WAIT(&sock->scond, &sock->lock);
}
UNLOCK(&sock->lock);
if (sock->parent) {
LOCK(&sock->parent->lock);
sock->parent->result = result;
UNLOCK(&sock->parent->lock);
}
}
static void
tls_senddone(isc_nmhandle_t *handle, isc_result_t eresult, void *cbarg) {
isc_nmsocket_tls_send_req_t *send_req =
(isc_nmsocket_tls_send_req_t *)cbarg;
isc_nmsocket_t *sock = send_req->tlssock;
REQUIRE(VALID_NMHANDLE(handle));
REQUIRE(VALID_NMSOCK(handle->sock));
REQUIRE(VALID_NMSOCK(sock));
/* XXXWPK TODO */
UNUSED(eresult);
isc_mem_put(handle->sock->mgr->mctx, send_req->data.base,
send_req->data.length);
isc_mem_put(handle->sock->mgr->mctx, send_req, sizeof(*send_req));
sock->tlsstream.nsending--;
async_tls_do_bio(sock);
isc__nmsocket_detach(&sock);
}
static void
tls_failed_read_cb(isc_nmsocket_t *sock, isc_nmhandle_t *handle,
const isc_result_t result, const bool close) {
REQUIRE(VALID_NMSOCK(sock));
if (!sock->tlsstream.server &&
(sock->tlsstream.state == TLS_INIT ||
sock->tlsstream.state == TLS_HANDSHAKE) &&
sock->connect_cb != NULL)
{
INSIST(handle == NULL);
handle = isc__nmhandle_get(sock, NULL, NULL);
sock->connect_cb(handle, result, sock->connect_cbarg);
update_result(sock, result);
isc__nmsocket_clearcb(sock);
isc_nmhandle_detach(&handle);
} else if (sock->recv_cb != NULL) {
isc__nm_uvreq_t *req = NULL;
req = isc__nm_uvreq_get(sock->mgr, sock);
req->cb.recv = sock->recv_cb;
req->cbarg = sock->recv_cbarg;
req->handle = NULL;
if (handle) {
REQUIRE(VALID_NMHANDLE(handle));
isc_nmhandle_attach(handle, &req->handle);
} else {
req->handle = isc__nmhandle_get(sock, NULL, NULL);
}
isc__nmsocket_clearcb(sock);
isc__nm_readcb(sock, req, result);
}
sock->tlsstream.state = TLS_ERROR;
if (close) {
isc__nmsocket_prep_destroy(sock);
}
}
static void
async_tls_do_bio(isc_nmsocket_t *sock) {
isc__netievent_tlsdobio_t *ievent =
isc__nm_get_netievent_tlsdobio(sock->mgr, sock);
isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid],
(isc__netievent_t *)ievent);
}
static void
tls_do_bio(isc_nmsocket_t *sock) {
isc_result_t result = ISC_R_SUCCESS;
int pending, tls_err = 0;
int rv;
isc__nm_uvreq_t *req;
REQUIRE(VALID_NMSOCK(sock));
REQUIRE(sock->tid == isc_nm_tid());
/* We will resume read if TLS layer wants us to */
if (sock->outerhandle != NULL) {
REQUIRE(VALID_NMHANDLE(sock->outerhandle));
isc_nm_pauseread(sock->outerhandle);
}
if (sock->tlsstream.state == TLS_INIT) {
(void)SSL_do_handshake(sock->tlsstream.ssl);
sock->tlsstream.state = TLS_HANDSHAKE;
} else if (sock->tlsstream.state == TLS_ERROR) {
result = ISC_R_FAILURE;
goto low_level_error;
} else if (sock->tlsstream.state == TLS_CLOSED) {
return;
}
/* Data from TLS to client */
char buf[1];
if (sock->tlsstream.state == TLS_IO && sock->recv_cb != NULL &&
!atomic_load(&sock->readpaused))
{
(void)SSL_peek(sock->tlsstream.ssl, buf, 1);
while ((pending = SSL_pending(sock->tlsstream.ssl)) > 0) {
if (pending > TLS_BUF_SIZE) {
pending = TLS_BUF_SIZE;
}
isc_region_t region = {
isc_mem_get(sock->mgr->mctx, pending), pending
};
isc_region_t dregion;
memset(region.base, 0, region.length);
rv = SSL_read(sock->tlsstream.ssl, region.base,
region.length);
/* Pending succeded, so should read */
RUNTIME_CHECK(rv == pending);
dregion = (isc_region_t){ region.base, rv };
sock->recv_cb(sock->statichandle, ISC_R_SUCCESS,
&dregion, sock->recv_cbarg);
isc_mem_put(sock->mgr->mctx, region.base,
region.length);
}
}
/* Peek to move the session forward */
(void)SSL_peek(sock->tlsstream.ssl, buf, 1);
/* Data from TLS to network */
pending = BIO_pending(sock->tlsstream.app_bio);
if (pending > 0) {
/*TODO Should we keep the track of these requests in a list? */
isc_nmsocket_tls_send_req_t *send_req = NULL;
if (pending > TLS_BUF_SIZE) {
pending = TLS_BUF_SIZE;
}
send_req = isc_mem_get(sock->mgr->mctx, sizeof(*send_req));
send_req->data.base = isc_mem_get(sock->mgr->mctx, pending);
send_req->data.length = pending;
send_req->tlssock = NULL;
isc__nmsocket_attach(sock, &send_req->tlssock);
rv = BIO_read(sock->tlsstream.app_bio, send_req->data.base,
pending);
/* There's something pending, read must succeed */
RUNTIME_CHECK(rv == pending);
INSIST(VALID_NMHANDLE(sock->outerhandle));
isc_nm_send(sock->outerhandle, &send_req->data, tls_senddone,
send_req);
/* We'll continue in tls_senddone */
return;
}
/* Get the potential error code */
rv = SSL_peek(sock->tlsstream.ssl, buf, 1);
if (rv < 0) {
tls_err = SSL_get_error(sock->tlsstream.ssl, rv);
}
/* Only after doing the IO we can check if SSL handshake is done */
if (sock->tlsstream.state == TLS_HANDSHAKE &&
SSL_is_init_finished(sock->tlsstream.ssl) == 1)
{
isc_nmhandle_t *tlshandle = isc__nmhandle_get(sock, NULL, NULL);
if (sock->tlsstream.server) {
sock->listener->accept_cb(sock->statichandle,
ISC_R_SUCCESS,
sock->listener->accept_cbarg);
} else {
sock->connect_cb(tlshandle, ISC_R_SUCCESS,
sock->connect_cbarg);
update_result(tlshandle->sock, ISC_R_SUCCESS);
}
isc_nmhandle_detach(&tlshandle);
sock->tlsstream.state = TLS_IO;
async_tls_do_bio(sock);
return;
}
switch (tls_err) {
case 0:
return;
case SSL_ERROR_WANT_WRITE:
if (sock->tlsstream.nsending == 0) {
/*
* Launch tls_do_bio asynchronously. If we're sending
* already the send callback will call it.
*/
async_tls_do_bio(sock);
} else {
return;
}
break;
case SSL_ERROR_WANT_READ:
INSIST(VALID_NMHANDLE(sock->outerhandle));
isc_nm_resumeread(sock->outerhandle);
break;
default:
result = tls_error_to_result(tls_err);
goto error;
}
while ((req = ISC_LIST_HEAD(sock->tlsstream.sends)) != NULL) {
INSIST(VALID_UVREQ(req));
rv = SSL_write(sock->tlsstream.ssl, req->uvbuf.base,
req->uvbuf.len);
if (rv < 0) {
if (sock->tlsstream.nsending == 0) {
async_tls_do_bio(sock);
}
return;
}
if (rv != (int)req->uvbuf.len) {
if (!sock->tlsstream.server &&
(sock->tlsstream.state == TLS_HANDSHAKE ||
TLS_INIT))
{
isc_nmhandle_t *tlshandle =
isc__nmhandle_get(sock, NULL, NULL);
sock->connect_cb(tlshandle, result,
sock->connect_cbarg);
update_result(tlshandle->sock, result);
isc_nmhandle_detach(&tlshandle);
}
sock->tlsstream.state = TLS_ERROR;
async_tls_do_bio(sock);
return;
}
ISC_LIST_UNLINK(sock->tlsstream.sends, req, link);
req->cb.send(sock->statichandle, ISC_R_SUCCESS, req->cbarg);
isc__nm_uvreq_put(&req, sock);
}
return;
error:
isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_NETMGR,
ISC_LOG_ERROR, "SSL error in BIO: %d %s", tls_err,
isc_result_totext(result));
low_level_error:
if (sock->tlsstream.state == TLS_HANDSHAKE) {
isc_nmhandle_t *tlshandle = isc__nmhandle_get(sock, NULL, NULL);
if (!sock->tlsstream.server) {
sock->connect_cb(tlshandle, result,
sock->connect_cbarg);
update_result(tlshandle->sock, result);
}
isc_nmhandle_detach(&tlshandle);
} else if (sock->tlsstream.state == TLS_IO) {
if (ISC_LIST_HEAD(sock->tlsstream.sends) != NULL) {
while ((req = ISC_LIST_HEAD(sock->tlsstream.sends)) !=
NULL) {
req->cb.send(sock->statichandle, result,
req->cbarg);
ISC_LIST_UNLINK(sock->tlsstream.sends, req,
link);
isc__nm_uvreq_put(&req, sock);
}
} else if (sock->recv_cb != NULL) {
tls_failed_read_cb(sock, sock->statichandle, result,
false);
} else {
tls_close_direct(sock);
}
}
sock->tlsstream.state = TLS_ERROR;
}
static void
tls_readcb(isc_nmhandle_t *handle, isc_result_t result, isc_region_t *region,
void *cbarg) {
isc_nmsocket_t *tlssock = (isc_nmsocket_t *)cbarg;
int rv;
REQUIRE(VALID_NMSOCK(tlssock));
REQUIRE(VALID_NMHANDLE(handle));
REQUIRE(tlssock->tid == isc_nm_tid());
if (result != ISC_R_SUCCESS) {
tls_failed_read_cb(tlssock, tlssock->statichandle, result,
true);
return;
}
rv = BIO_write(tlssock->tlsstream.app_bio, region->base,
region->length);
if (rv != (int)region->length) {
/* XXXWPK log it? */
tlssock->tlsstream.state = TLS_ERROR;
}
tls_do_bio(tlssock);
}
static isc_result_t
initialize_tls(isc_nmsocket_t *sock, bool server) {
REQUIRE(sock->tid == isc_nm_tid());
if (BIO_new_bio_pair(&(sock->tlsstream.ssl_bio), TLS_BUF_SIZE,
&(sock->tlsstream.app_bio), TLS_BUF_SIZE) != 1)
{
SSL_free(sock->tlsstream.ssl);
return (ISC_R_TLSERROR);
}
SSL_set_bio(sock->tlsstream.ssl, sock->tlsstream.ssl_bio,
sock->tlsstream.ssl_bio);
if (server) {
SSL_set_accept_state(sock->tlsstream.ssl);
} else {
SSL_set_connect_state(sock->tlsstream.ssl);
}
sock->tlsstream.nsending = 0;
isc_nm_read(sock->outerhandle, tls_readcb, sock);
tls_do_bio(sock);
return (ISC_R_SUCCESS);
}
static isc_result_t
tlslisten_acceptcb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
isc_nmsocket_t *tlslistensock = (isc_nmsocket_t *)cbarg;
isc_nmsocket_t *tlssock = NULL;
int r;
/* If accept() was unsuccessful we can't do anything */
if (result != ISC_R_SUCCESS) {
return (result);
}
REQUIRE(VALID_NMHANDLE(handle));
REQUIRE(VALID_NMSOCK(handle->sock));
REQUIRE(VALID_NMSOCK(tlslistensock));
REQUIRE(tlslistensock->type == isc_nm_tlslistener);
/*
* We need to create a 'wrapper' tlssocket for this connection.
*/
tlssock = isc_mem_get(handle->sock->mgr->mctx, sizeof(*tlssock));
isc__nmsocket_init(tlssock, handle->sock->mgr, isc_nm_tlssocket,
handle->sock->iface);
/* We need to initialize SSL now to reference SSL_CTX properly */
tlssock->tlsstream.ctx = tlslistensock->tlsstream.ctx;
tlssock->tlsstream.ssl = SSL_new(tlssock->tlsstream.ctx);
ISC_LIST_INIT(tlssock->tlsstream.sends);
if (tlssock->tlsstream.ssl == NULL) {
update_result(tlssock, ISC_R_TLSERROR);
atomic_store(&tlssock->closed, true);
isc__nmsocket_detach(&tlssock);
return (ISC_R_TLSERROR);
}
tlssock->extrahandlesize = tlslistensock->extrahandlesize;
isc__nmsocket_attach(tlslistensock, &tlssock->listener);
isc_nmhandle_attach(handle, &tlssock->outerhandle);
tlssock->peer = handle->sock->peer;
tlssock->read_timeout = atomic_load(&handle->sock->mgr->init);
tlssock->tid = isc_nm_tid();
tlssock->tlsstream.server = true;
tlssock->tlsstream.state = TLS_INIT;
r = uv_timer_init(&tlssock->mgr->workers[isc_nm_tid()].loop,
&tlssock->timer);
RUNTIME_CHECK(r == 0);
tlssock->timer.data = tlssock;
tlssock->timer_initialized = true;
tlssock->tlsstream.ctx = tlslistensock->tlsstream.ctx;
result = initialize_tls(tlssock, true);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
/* TODO: catch failure code, detach tlssock, and log the error */
return (result);
}
isc_result_t
isc_nm_listentls(isc_nm_t *mgr, isc_nmiface_t *iface,
isc_nm_accept_cb_t accept_cb, void *accept_cbarg,
size_t extrahandlesize, int backlog, isc_quota_t *quota,
SSL_CTX *sslctx, isc_nmsocket_t **sockp) {
isc_result_t result;
isc_nmsocket_t *tlssock = isc_mem_get(mgr->mctx, sizeof(*tlssock));
isc_nmsocket_t *tsock = NULL;
REQUIRE(VALID_NM(mgr));
isc__nmsocket_init(tlssock, mgr, isc_nm_tlslistener, iface);
tlssock->result = ISC_R_DEFAULT;
tlssock->accept_cb = accept_cb;
tlssock->accept_cbarg = accept_cbarg;
tlssock->extrahandlesize = extrahandlesize;
tlssock->tlsstream.ctx = sslctx;
tlssock->tlsstream.ssl = NULL;
/*
* tlssock will be a TLS 'wrapper' around an unencrypted stream.
* We set tlssock->outer to a socket listening for a TCP connection.
*/
result = isc_nm_listentcp(mgr, iface, tlslisten_acceptcb, tlssock,
extrahandlesize, backlog, quota,
&tlssock->outer);
if (result != ISC_R_SUCCESS) {
atomic_store(&tlssock->closed, true);
isc__nmsocket_detach(&tlssock);
return (result);
}
/* wait for listen result */
isc__nmsocket_attach(tlssock->outer, &tsock);
LOCK(&tlssock->outer->lock);
while (tlssock->outer->rchildren != tlssock->outer->nchildren) {
WAIT(&tlssock->outer->cond, &tlssock->outer->lock);
}
result = tlssock->outer->result;
tlssock->result = result;
atomic_store(&tlssock->active, true);
INSIST(tlssock->outer->tlsstream.tlslistener == NULL);
isc__nmsocket_attach(tlssock, &tlssock->outer->tlsstream.tlslistener);
BROADCAST(&tlssock->outer->scond);
UNLOCK(&tlssock->outer->lock);
isc__nmsocket_detach(&tsock);
INSIST(result != ISC_R_DEFAULT);
if (result == ISC_R_SUCCESS) {
atomic_store(&tlssock->listening, true);
*sockp = tlssock;
}
return result;
}
void
isc__nm_async_tlssend(isc__networker_t *worker, isc__netievent_t *ev0) {
int rv;
isc__netievent_tlssend_t *ievent = (isc__netievent_tlssend_t *)ev0;
isc_nmsocket_t *sock = ievent->sock;
isc__nm_uvreq_t *req = ievent->req;
ievent->req = NULL;
REQUIRE(VALID_UVREQ(req));
REQUIRE(sock->tid == isc_nm_tid());
UNUSED(worker);
if (inactive(sock)) {
req->cb.send(req->handle, ISC_R_CANCELED, req->cbarg);
isc__nm_uvreq_put(&req, sock);
return;
}
if (!ISC_LIST_EMPTY(sock->tlsstream.sends)) {
/* We're not the first */
ISC_LIST_APPEND(sock->tlsstream.sends, req, link);
tls_do_bio(sock);
return;
}
rv = SSL_write(sock->tlsstream.ssl, req->uvbuf.base, req->uvbuf.len);
if (rv < 0) {
/*
* We might need to read, we might need to write, or the
* TLS socket might be dead - in any case, we need to
* enqueue the uvreq and let the TLS BIO layer do the rest.
*/
ISC_LIST_APPEND(sock->tlsstream.sends, req, link);
tls_do_bio(sock);
return;
}
if (rv != (int)req->uvbuf.len) {
sock->tlsstream.state = TLS_ERROR;
async_tls_do_bio(sock);
return;
}
req->cb.send(sock->statichandle, ISC_R_SUCCESS, req->cbarg);
isc__nm_uvreq_put(&req, sock);
tls_do_bio(sock);
return;
}
void
isc__nm_tls_send(isc_nmhandle_t *handle, const isc_region_t *region,
isc_nm_cb_t cb, void *cbarg) {
isc__netievent_tlssend_t *ievent = NULL;
isc__nm_uvreq_t *uvreq = NULL;
isc_nmsocket_t *sock = NULL;
REQUIRE(VALID_NMHANDLE(handle));
REQUIRE(VALID_NMSOCK(handle->sock));
sock = handle->sock;
REQUIRE(sock->type == isc_nm_tlssocket);
if (inactive(sock)) {
cb(handle, ISC_R_CANCELED, cbarg);
return;
}
uvreq = isc__nm_uvreq_get(sock->mgr, sock);
isc_nmhandle_attach(handle, &uvreq->handle);
uvreq->cb.send = cb;
uvreq->cbarg = cbarg;
uvreq->uvbuf.base = (char *)region->base;
uvreq->uvbuf.len = region->length;
/*
* We need to create an event and pass it using async channel
*/
ievent = isc__nm_get_netievent_tlssend(sock->mgr, sock, uvreq);
isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid],
(isc__netievent_t *)ievent);
}
void
isc__nm_async_tlsstartread(isc__networker_t *worker, isc__netievent_t *ev0) {
isc__netievent_tlsstartread_t *ievent =
(isc__netievent_tlsstartread_t *)ev0;
isc_nmsocket_t *sock = ievent->sock;
REQUIRE(sock->tid == isc_nm_tid());
UNUSED(worker);
tls_do_bio(sock);
}
void
isc__nm_tls_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg) {
REQUIRE(VALID_NMHANDLE(handle));
REQUIRE(VALID_NMSOCK(handle->sock));
REQUIRE(handle->sock->statichandle == handle);
REQUIRE(handle->sock->tid == isc_nm_tid());
isc__netievent_tlsstartread_t *ievent = NULL;
isc_nmsocket_t *sock = handle->sock;
if (inactive(sock)) {
cb(handle, ISC_R_NOTCONNECTED, NULL, cbarg);
return;
}
sock->recv_cb = cb;
sock->recv_cbarg = cbarg;
ievent = isc__nm_get_netievent_tlsstartread(sock->mgr, sock);
isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid],
(isc__netievent_t *)ievent);
}
void
isc__nm_tls_pauseread(isc_nmhandle_t *handle) {
REQUIRE(VALID_NMHANDLE(handle));
REQUIRE(VALID_NMSOCK(handle->sock));
isc_nmsocket_t *sock = handle->sock;
atomic_store(&sock->readpaused, true);
}
void
isc__nm_tls_resumeread(isc_nmhandle_t *handle) {
REQUIRE(VALID_NMHANDLE(handle));
REQUIRE(VALID_NMSOCK(handle->sock));
isc_nmsocket_t *sock = handle->sock;
atomic_store(&sock->readpaused, false);
async_tls_do_bio(sock);
}
static void
timer_close_cb(uv_handle_t *handle) {
isc_nmsocket_t *sock = (isc_nmsocket_t *)uv_handle_get_data(handle);
tls_close_direct(sock);
}
static void
tls_close_direct(isc_nmsocket_t *sock) {
REQUIRE(VALID_NMSOCK(sock));
REQUIRE(sock->tid == isc_nm_tid());
/* if (!sock->tlsstream.server) { */
/* INSIST(sock->tlsstream.state != TLS_HANDSHAKE && */
/* sock->tlsstream.state != TLS_INIT); */
/* } */
sock->tlsstream.state = TLS_CLOSING;
if (sock->timer_running) {
uv_timer_stop(&sock->timer);
sock->timer_running = false;
}
/* We don't need atomics here, it's all in single network thread
*/
if (sock->timer_initialized) {
/*
* We need to fire the timer callback to clean it up,
* it will then call us again (via detach) so that we
* can finally close the socket.
*/
sock->timer_initialized = false;
uv_timer_stop(&sock->timer);
uv_close((uv_handle_t *)&sock->timer, timer_close_cb);
} else {
/*
* At this point we're certain that there are no
* external references, we can close everything.
*/
if (sock->outerhandle != NULL) {
isc_nm_pauseread(sock->outerhandle);
isc_nmhandle_detach(&sock->outerhandle);
}
if (sock->listener != NULL) {
isc__nmsocket_detach(&sock->listener);
}
if (sock->tlsstream.ssl != NULL) {
SSL_free(sock->tlsstream.ssl);
sock->tlsstream.ssl = NULL;
/* These are destroyed when we free SSL* */
sock->tlsstream.ctx = NULL;
sock->tlsstream.ssl_bio = NULL;
}
if (sock->tlsstream.app_bio != NULL) {
BIO_free(sock->tlsstream.app_bio);
sock->tlsstream.app_bio = NULL;
}
sock->tlsstream.state = TLS_CLOSED;
atomic_store(&sock->closed, true);
isc__nmsocket_detach(&sock);
}
}
void
isc__nm_tls_close(isc_nmsocket_t *sock) {
REQUIRE(VALID_NMSOCK(sock));
REQUIRE(sock->type == isc_nm_tlssocket);
if (!atomic_compare_exchange_strong(&sock->closing, &(bool){ false },
true)) {
return;
}
if (sock->tid == isc_nm_tid()) {
tls_close_direct(sock);
} else {
isc__netievent_tlsclose_t *ievent =
isc__nm_get_netievent_tlsclose(sock->mgr, sock);
isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid],
(isc__netievent_t *)ievent);
}
}
void
isc__nm_async_tlsclose(isc__networker_t *worker, isc__netievent_t *ev0) {
isc__netievent_tlsclose_t *ievent = (isc__netievent_tlsclose_t *)ev0;
REQUIRE(ievent->sock->tid == isc_nm_tid());
UNUSED(worker);
tls_close_direct(ievent->sock);
}
void
isc__nm_tls_stoplistening(isc_nmsocket_t *sock) {
REQUIRE(VALID_NMSOCK(sock));
REQUIRE(sock->type == isc_nm_tlslistener);
atomic_store(&sock->listening, false);
atomic_store(&sock->closed, true);
sock->recv_cb = NULL;
sock->recv_cbarg = NULL;
if (sock->tlsstream.ssl != NULL) {
SSL_free(sock->tlsstream.ssl);
sock->tlsstream.ssl = NULL;
sock->tlsstream.ctx = NULL;
}
if (sock->outer != NULL) {
isc_nm_stoplistening(sock->outer);
isc__nmsocket_detach(&sock->outer);
}
}
isc_result_t
isc_nm_tlsconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
isc_nm_cb_t cb, void *cbarg, SSL_CTX *ctx,
unsigned int timeout, size_t extrahandlesize) {
isc_nmsocket_t *nsock = NULL, *tsock = NULL;
isc__netievent_tlsconnect_t *ievent = NULL;
isc_result_t result = ISC_R_DEFAULT;
REQUIRE(VALID_NM(mgr));
nsock = isc_mem_get(mgr->mctx, sizeof(*nsock));
isc__nmsocket_init(nsock, mgr, isc_nm_tlssocket, local);
nsock->extrahandlesize = extrahandlesize;
nsock->result = ISC_R_DEFAULT;
nsock->connect_cb = cb;
nsock->connect_cbarg = cbarg;
nsock->connect_timeout = timeout;
nsock->tlsstream.ctx = ctx;
ievent = isc__nm_get_netievent_tlsconnect(mgr, nsock);
ievent->local = local->addr;
ievent->peer = peer->addr;
ievent->ctx = ctx;
isc__nmsocket_attach(nsock, &tsock);
if (isc__nm_in_netthread()) {
nsock->tid = isc_nm_tid();
isc__nm_async_tlsconnect(&mgr->workers[nsock->tid],
(isc__netievent_t *)ievent);
isc__nm_put_netievent_tlsconnect(mgr, ievent);
} else {
nsock->tid = isc_random_uniform(mgr->nworkers);
isc__nm_enqueue_ievent(&mgr->workers[nsock->tid],
(isc__netievent_t *)ievent);
}
LOCK(&nsock->lock);
result = nsock->result;
while (result == ISC_R_DEFAULT) {
WAIT(&nsock->cond, &nsock->lock);
result = nsock->result;
}
atomic_store(&nsock->active, true);
BROADCAST(&nsock->scond);
UNLOCK(&nsock->lock);
INSIST(VALID_NMSOCK(nsock));
isc__nmsocket_detach(&tsock);
INSIST(result != ISC_R_DEFAULT);
return (result);
}
static void
tls_connect_cb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
isc_nmsocket_t *tlssock = (isc_nmsocket_t *)cbarg;
REQUIRE(VALID_NMSOCK(tlssock));
if (result != ISC_R_SUCCESS) {
tlssock->connect_cb(handle, result, tlssock->connect_cbarg);
update_result(tlssock, result);
tls_close_direct(tlssock);
return;
}
INSIST(VALID_NMHANDLE(handle));
tlssock->peer = isc_nmhandle_peeraddr(handle);
isc_nmhandle_attach(handle, &tlssock->outerhandle);
result = initialize_tls(tlssock, false);
if (result != ISC_R_SUCCESS) {
tlssock->connect_cb(handle, result, tlssock->connect_cbarg);
update_result(tlssock, result);
tls_close_direct(tlssock);
return;
}
}
void
isc__nm_async_tlsconnect(isc__networker_t *worker, isc__netievent_t *ev0) {
isc__netievent_tlsconnect_t *ievent =
(isc__netievent_tlsconnect_t *)ev0;
isc_nmsocket_t *tlssock = ievent->sock;
isc_result_t result;
int r;
isc_nmhandle_t *tlshandle = NULL;
UNUSED(worker);
/*
* We need to initialize SSL now to reference SSL_CTX properly.
*/
tlssock->tlsstream.ssl = SSL_new(tlssock->tlsstream.ctx);
if (tlssock->tlsstream.ssl == NULL) {
result = ISC_R_TLSERROR;
goto error;
}
tlssock->tid = isc_nm_tid();
r = uv_timer_init(&tlssock->mgr->workers[isc_nm_tid()].loop,
&tlssock->timer);
RUNTIME_CHECK(r == 0);
tlssock->timer.data = tlssock;
tlssock->timer_initialized = true;
tlssock->tlsstream.state = TLS_INIT;
result = isc_nm_tcpconnect(worker->mgr, (isc_nmiface_t *)&ievent->local,
(isc_nmiface_t *)&ievent->peer,
tls_connect_cb, tlssock,
tlssock->connect_timeout, 0);
if (result != ISC_R_SUCCESS) {
goto error;
}
return;
error:
tlshandle = isc__nmhandle_get(tlssock, NULL, NULL);
atomic_store(&tlssock->closed, true);
tlssock->connect_cb(tlshandle, result, tlssock->connect_cbarg);
isc_nmhandle_detach(&tlshandle);
update_result(tlssock, result);
tls_close_direct(tlssock);
}
void
isc__nm_tls_cancelread(isc_nmhandle_t *handle) {
isc_nmsocket_t *sock = NULL;
isc__netievent_tlscancel_t *ievent = NULL;
REQUIRE(VALID_NMHANDLE(handle));
sock = handle->sock;
REQUIRE(sock->type == isc_nm_tlssocket);
ievent = isc__nm_get_netievent_tlscancel(sock->mgr, sock, handle);
isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid],
(isc__netievent_t *)ievent);
}
void
isc__nm_async_tlscancel(isc__networker_t *worker, isc__netievent_t *ev0) {
isc__netievent_tlscancel_t *ievent = (isc__netievent_tlscancel_t *)ev0;
isc_nmsocket_t *sock = ievent->sock;
isc_nmhandle_t *handle = ievent->handle;
REQUIRE(VALID_NMSOCK(sock));
REQUIRE(worker->id == sock->tid);
REQUIRE(sock->tid == isc_nm_tid());
UNUSED(worker);
tls_failed_read_cb(sock, handle, ISC_R_EOF, false);
if (sock->outerhandle) {
isc__nm_tcp_cancelread(sock->outerhandle);
}
}
void
isc__nm_async_tlsdobio(isc__networker_t *worker, isc__netievent_t *ev0) {
UNUSED(worker);
isc__netievent_tlsdobio_t *ievent = (isc__netievent_tlsdobio_t *)ev0;
tls_do_bio(ievent->sock);
}
void
isc__nm_tls_cleanup_data(isc_nmsocket_t *sock) {
if (sock->tlsstream.tlslistener) {
REQUIRE(VALID_NMSOCK(sock->tlsstream.tlslistener));
isc__nmsocket_detach(&sock->tlsstream.tlslistener);
}
}
+2 -2
View File
@@ -478,8 +478,8 @@ free:
* another thread.
*/
void
isc__nm_udp_send(isc_nmhandle_t *handle, isc_region_t *region, isc_nm_cb_t cb,
void *cbarg) {
isc__nm_udp_send(isc_nmhandle_t *handle, const isc_region_t *region,
isc_nm_cb_t cb, void *cbarg) {
isc_nmsocket_t *sock = handle->sock;
isc_nmsocket_t *psock = NULL, *rsock = sock;
isc_sockaddr_t *peer = &handle->peer;
+13 -2
View File
@@ -20,6 +20,7 @@ TESTS = \
buffer_test \
counter_test \
crc64_test \
doh_test \
errno_test \
file_test \
hash_test \
@@ -44,17 +45,27 @@ TESTS = \
symtab_test \
task_test \
taskpool_test \
tcp_test \
tcp_quota_test \
tcp_test \
tcpdns_test \
tlsdns_test \
time_test \
timer_test \
tlsdns_test \
udp_test
check_PROGRAMS = \
$(TESTS)
doh_test_CPPFLAGS = \
$(AM_CPPFLAGS) \
$(OPENSSL_CFLAGS) \
$(LIBUV_CFLAGS)
doh_test_LDADD = \
$(LDADD) \
$(OPENSSL_LIBS) \
$(LIBUV_LIBS)
hmac_test_CPPFLAGS = \
$(AM_CPPFLAGS) \
$(OPENSSL_CFLAGS)
File diff suppressed because it is too large Load Diff
+4 -2
View File
@@ -127,8 +127,10 @@ isc_tlsctx_createclient(isc_tlsctx_t **ctxp) {
#if HAVE_SSL_CTX_SET_MIN_PROTO_VERSION
SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION);
#else
SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |
SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1);
SSL_CTX_set_options(
ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 |
SSL_OP_NO_TLSv1_1 | SSL_OP_NO_COMPRESSION |
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
#endif
*ctxp = ctx;
+667
View File
@@ -0,0 +1,667 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* 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/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
/*
* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include <ctype.h>
#include <limits.h>
#include <stddef.h>
#include <string.h>
#include <isc/url.h>
#include <isc/util.h>
#ifndef BIT_AT
#define BIT_AT(a, i) \
(!!((unsigned int)(a)[(unsigned int)(i) >> 3] & \
(1 << ((unsigned int)(i)&7))))
#endif
#if HTTP_PARSER_STRICT
#define T(v) 0
#else
#define T(v) v
#endif
static const uint8_t normal_url_char[32] = {
/* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0,
/* 8 bs 9 ht 10 nl 11 vt 12 np 13 cr 14 so 15 si */
0 | T(2) | 0 | 0 | T(16) | 0 | 0 | 0,
/* 16 dle 17 dc1 18 dc2 19 dc3 20 dc4 21 nak 22 syn 23 etb */
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0,
/* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0,
/* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */
0 | 2 | 4 | 0 | 16 | 32 | 64 | 128,
/* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */
1 | 2 | 4 | 8 | 16 | 32 | 64 | 128,
/* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */
1 | 2 | 4 | 8 | 16 | 32 | 64 | 128,
/* 56 8 57 9 58 : 59 ; 60 < 61 = 62 > 63 ? */
1 | 2 | 4 | 8 | 16 | 32 | 64 | 0,
/* 64 @ 65 A 66 B 67 C 68 D 69 E 70 F 71 G */
1 | 2 | 4 | 8 | 16 | 32 | 64 | 128,
/* 72 H 73 I 74 J 75 K 76 L 77 M 78 N 79 O */
1 | 2 | 4 | 8 | 16 | 32 | 64 | 128,
/* 80 P 81 Q 82 R 83 S 84 T 85 U 86 V 87 W */
1 | 2 | 4 | 8 | 16 | 32 | 64 | 128,
/* 88 X 89 Y 90 Z 91 [ 92 \ 93 ] 94 ^ 95 _ */
1 | 2 | 4 | 8 | 16 | 32 | 64 | 128,
/* 96 ` 97 a 98 b 99 c 100 d 101 e 102 f 103 g */
1 | 2 | 4 | 8 | 16 | 32 | 64 | 128,
/* 104 h 105 i 106 j 107 k 108 l 109 m 110 n 111 o */
1 | 2 | 4 | 8 | 16 | 32 | 64 | 128,
/* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */
1 | 2 | 4 | 8 | 16 | 32 | 64 | 128,
/* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */
1 | 2 | 4 | 8 | 16 | 32 | 64 | 0,
};
#undef T
typedef enum {
s_dead = 1, /* important that this is > 0 */
s_start_req_or_res,
s_res_or_resp_H,
s_start_res,
s_res_H,
s_res_HT,
s_res_HTT,
s_res_HTTP,
s_res_http_major,
s_res_http_dot,
s_res_http_minor,
s_res_http_end,
s_res_first_status_code,
s_res_status_code,
s_res_status_start,
s_res_status,
s_res_line_almost_done,
s_start_req,
s_req_method,
s_req_spaces_before_url,
s_req_schema,
s_req_schema_slash,
s_req_schema_slash_slash,
s_req_server_start,
s_req_server,
s_req_server_with_at,
s_req_path,
s_req_query_string_start,
s_req_query_string,
s_req_fragment_start,
s_req_fragment,
s_req_http_start,
s_req_http_H,
s_req_http_HT,
s_req_http_HTT,
s_req_http_HTTP,
s_req_http_I,
s_req_http_IC,
s_req_http_major,
s_req_http_dot,
s_req_http_minor,
s_req_http_end,
s_req_line_almost_done,
s_header_field_start,
s_header_field,
s_header_value_discard_ws,
s_header_value_discard_ws_almost_done,
s_header_value_discard_lws,
s_header_value_start,
s_header_value,
s_header_value_lws,
s_header_almost_done,
s_chunk_size_start,
s_chunk_size,
s_chunk_parameters,
s_chunk_size_almost_done,
s_headers_almost_done,
s_headers_done,
/*
* Important: 's_headers_done' must be the last 'header' state. All
* states beyond this must be 'body' states. It is used for overflow
* checking. See the PARSING_HEADER() macro.
*/
s_chunk_data,
s_chunk_data_almost_done,
s_chunk_data_done,
s_body_identity,
s_body_identity_eof,
s_message_done
} state_t;
typedef enum {
s_http_host_dead = 1,
s_http_userinfo_start,
s_http_userinfo,
s_http_host_start,
s_http_host_v6_start,
s_http_host,
s_http_host_v6,
s_http_host_v6_end,
s_http_host_v6_zone_start,
s_http_host_v6_zone,
s_http_host_port_start,
s_http_host_port
} host_state_t;
/* Macros for character classes; depends on strict-mode */
#define IS_MARK(c) \
((c) == '-' || (c) == '_' || (c) == '.' || (c) == '!' || (c) == '~' || \
(c) == '*' || (c) == '\'' || (c) == '(' || (c) == ')')
#define IS_USERINFO_CHAR(c) \
(isalnum(c) || IS_MARK(c) || (c) == '%' || (c) == ';' || (c) == ':' || \
(c) == '&' || (c) == '=' || (c) == '+' || (c) == '$' || (c) == ',')
#if HTTP_PARSER_STRICT
#define IS_URL_CHAR(c) (BIT_AT(normal_url_char, (unsigned char)c))
#define IS_HOST_CHAR(c) (isalnum(c) || (c) == '.' || (c) == '-')
#else
#define IS_URL_CHAR(c) (BIT_AT(normal_url_char, (unsigned char)c) || ((c)&0x80))
#define IS_HOST_CHAR(c) (isalnum(c) || (c) == '.' || (c) == '-' || (c) == '_')
#endif
/*
* Our URL parser.
*
* This is designed to be shared by http_parser_execute() for URL validation,
* hence it has a state transition + byte-for-byte interface. In addition, it
* is meant to be embedded in http_parser_parse_url(), which does the dirty
* work of turning state transitions URL components for its API.
*
* This function should only be invoked with non-space characters. It is
* assumed that the caller cares about (and can detect) the transition between
* URL and non-URL states by looking for these.
*/
static state_t
parse_url_char(state_t s, const char ch) {
if (ch == ' ' || ch == '\r' || ch == '\n') {
return (s_dead);
}
#if HTTP_PARSER_STRICT
if (ch == '\t' || ch == '\f') {
return (s_dead);
}
#endif
switch (s) {
case s_req_spaces_before_url:
/* Proxied requests are followed by scheme of an absolute URI
* (alpha). All methods except CONNECT are followed by '/' or
* '*'.
*/
if (ch == '/' || ch == '*') {
return (s_req_path);
}
if (isalpha(ch)) {
return (s_req_schema);
}
break;
case s_req_schema:
if (isalpha(ch)) {
return (s);
}
if (ch == ':') {
return (s_req_schema_slash);
}
break;
case s_req_schema_slash:
if (ch == '/') {
return (s_req_schema_slash_slash);
}
break;
case s_req_schema_slash_slash:
if (ch == '/') {
return (s_req_server_start);
}
break;
case s_req_server_with_at:
if (ch == '@') {
return (s_dead);
}
/* FALLTHROUGH */
case s_req_server_start:
case s_req_server:
if (ch == '/') {
return (s_req_path);
}
if (ch == '?') {
return (s_req_query_string_start);
}
if (ch == '@') {
return (s_req_server_with_at);
}
if (IS_USERINFO_CHAR(ch) || ch == '[' || ch == ']') {
return (s_req_server);
}
break;
case s_req_path:
if (IS_URL_CHAR(ch)) {
return (s);
}
switch (ch) {
case '?':
return (s_req_query_string_start);
case '#':
return (s_req_fragment_start);
}
break;
case s_req_query_string_start:
case s_req_query_string:
if (IS_URL_CHAR(ch)) {
return (s_req_query_string);
}
switch (ch) {
case '?':
/* allow extra '?' in query string */
return (s_req_query_string);
case '#':
return (s_req_fragment_start);
}
break;
case s_req_fragment_start:
if (IS_URL_CHAR(ch)) {
return (s_req_fragment);
}
switch (ch) {
case '?':
return (s_req_fragment);
case '#':
return (s);
}
break;
case s_req_fragment:
if (IS_URL_CHAR(ch)) {
return (s);
}
switch (ch) {
case '?':
case '#':
return (s);
}
break;
default:
break;
}
/*
* We should never fall out of the switch above unless there's an
* error.
*/
return (s_dead);
}
static host_state_t
http_parse_host_char(host_state_t s, const char ch) {
switch (s) {
case s_http_userinfo:
case s_http_userinfo_start:
if (ch == '@') {
return (s_http_host_start);
}
if (IS_USERINFO_CHAR(ch)) {
return (s_http_userinfo);
}
break;
case s_http_host_start:
if (ch == '[') {
return (s_http_host_v6_start);
}
if (IS_HOST_CHAR(ch)) {
return (s_http_host);
}
break;
case s_http_host:
if (IS_HOST_CHAR(ch)) {
return (s_http_host);
}
/* FALLTHROUGH */
case s_http_host_v6_end:
if (ch == ':') {
return (s_http_host_port_start);
}
break;
case s_http_host_v6:
if (ch == ']') {
return (s_http_host_v6_end);
}
/* FALLTHROUGH */
case s_http_host_v6_start:
if (isxdigit(ch) || ch == ':' || ch == '.') {
return (s_http_host_v6);
}
if (s == s_http_host_v6 && ch == '%') {
return (s_http_host_v6_zone_start);
}
break;
case s_http_host_v6_zone:
if (ch == ']') {
return (s_http_host_v6_end);
}
/* FALLTHROUGH */
case s_http_host_v6_zone_start:
/* RFC 6874 Zone ID consists of 1*( unreserved / pct-encoded) */
if (isalnum(ch) || ch == '%' || ch == '.' || ch == '-' ||
ch == '_' || ch == '~')
{
return (s_http_host_v6_zone);
}
break;
case s_http_host_port:
case s_http_host_port_start:
if (isdigit(ch)) {
return (s_http_host_port);
}
break;
default:
break;
}
return (s_http_host_dead);
}
static isc_result_t
http_parse_host(const char *buf, isc_url_parser_t *up, int found_at) {
host_state_t s;
const char *p = NULL;
size_t buflen = up->field_data[ISC_UF_HOST].off +
up->field_data[ISC_UF_HOST].len;
REQUIRE((up->field_set & (1 << ISC_UF_HOST)) != 0);
up->field_data[ISC_UF_HOST].len = 0;
s = found_at ? s_http_userinfo_start : s_http_host_start;
for (p = buf + up->field_data[ISC_UF_HOST].off; p < buf + buflen; p++) {
host_state_t new_s = http_parse_host_char(s, *p);
if (new_s == s_http_host_dead) {
return (ISC_R_FAILURE);
}
switch (new_s) {
case s_http_host:
if (s != s_http_host) {
up->field_data[ISC_UF_HOST].off =
(uint16_t)(p - buf);
}
up->field_data[ISC_UF_HOST].len++;
break;
case s_http_host_v6:
if (s != s_http_host_v6) {
up->field_data[ISC_UF_HOST].off =
(uint16_t)(p - buf);
}
up->field_data[ISC_UF_HOST].len++;
break;
case s_http_host_v6_zone_start:
case s_http_host_v6_zone:
up->field_data[ISC_UF_HOST].len++;
break;
case s_http_host_port:
if (s != s_http_host_port) {
up->field_data[ISC_UF_PORT].off =
(uint16_t)(p - buf);
up->field_data[ISC_UF_PORT].len = 0;
up->field_set |= (1 << ISC_UF_PORT);
}
up->field_data[ISC_UF_PORT].len++;
break;
case s_http_userinfo:
if (s != s_http_userinfo) {
up->field_data[ISC_UF_USERINFO].off =
(uint16_t)(p - buf);
up->field_data[ISC_UF_USERINFO].len = 0;
up->field_set |= (1 << ISC_UF_USERINFO);
}
up->field_data[ISC_UF_USERINFO].len++;
break;
default:
break;
}
s = new_s;
}
/* Make sure we don't end somewhere unexpected */
switch (s) {
case s_http_host_start:
case s_http_host_v6_start:
case s_http_host_v6:
case s_http_host_v6_zone_start:
case s_http_host_v6_zone:
case s_http_host_port_start:
case s_http_userinfo:
case s_http_userinfo_start:
return (ISC_R_FAILURE);
default:
break;
}
return (ISC_R_SUCCESS);
}
isc_result_t
isc_url_parse(const char *buf, size_t buflen, bool is_connect,
isc_url_parser_t *up) {
state_t s;
isc_url_field_t uf, old_uf;
int found_at = 0;
const char *p = NULL;
if (buflen == 0) {
return (ISC_R_FAILURE);
}
up->port = up->field_set = 0;
s = is_connect ? s_req_server_start : s_req_spaces_before_url;
old_uf = ISC_UF_MAX;
for (p = buf; p < buf + buflen; p++) {
s = parse_url_char(s, *p);
/* Figure out the next field that we're operating on */
switch (s) {
case s_dead:
return (ISC_R_FAILURE);
/* Skip delimiters */
case s_req_schema_slash:
case s_req_schema_slash_slash:
case s_req_server_start:
case s_req_query_string_start:
case s_req_fragment_start:
continue;
case s_req_schema:
uf = ISC_UF_SCHEMA;
break;
case s_req_server_with_at:
found_at = 1;
/* FALLTHROUGH */
case s_req_server:
uf = ISC_UF_HOST;
break;
case s_req_path:
uf = ISC_UF_PATH;
break;
case s_req_query_string:
uf = ISC_UF_QUERY;
break;
case s_req_fragment:
uf = ISC_UF_FRAGMENT;
break;
default:
INSIST(0);
ISC_UNREACHABLE();
}
/* Nothing's changed; soldier on */
if (uf == old_uf) {
up->field_data[uf].len++;
continue;
}
up->field_data[uf].off = (uint16_t)(p - buf);
up->field_data[uf].len = 1;
up->field_set |= (1 << uf);
old_uf = uf;
}
/* host must be present if there is a schema */
/* parsing http:///toto will fail */
if ((up->field_set & (1 << ISC_UF_SCHEMA)) &&
(up->field_set & (1 << ISC_UF_HOST)) == 0)
{
return (ISC_R_FAILURE);
}
if (up->field_set & (1 << ISC_UF_HOST)) {
isc_result_t result;
result = http_parse_host(buf, up, found_at);
if (result != ISC_R_SUCCESS) {
return (result);
}
}
/* CONNECT requests can only contain "hostname:port" */
if (is_connect &&
up->field_set != ((1 << ISC_UF_HOST) | (1 << ISC_UF_PORT))) {
return (ISC_R_FAILURE);
}
if (up->field_set & (1 << ISC_UF_PORT)) {
uint16_t off;
uint16_t len;
const char *pp = NULL;
const char *end = NULL;
unsigned long v;
off = up->field_data[ISC_UF_PORT].off;
len = up->field_data[ISC_UF_PORT].len;
end = buf + off + len;
/*
* NOTE: The characters are already validated and are in the
* [0-9] range
*/
INSIST(off + len <= buflen);
v = 0;
for (pp = buf + off; pp < end; pp++) {
v *= 10;
v += *pp - '0';
/* Ports have a max value of 2^16 */
if (v > 0xffff) {
return (ISC_R_RANGE);
}
}
up->port = (uint16_t)v;
}
return (ISC_R_SUCCESS);
}
+9
View File
@@ -448,7 +448,14 @@ isc_nm_cancelread
isc_nm_closedown
isc_nm_destroy
isc_nm_detach
isc_nm_http_add_doh_endpoint
isc_nm_http_add_endpoint
isc_nm_http_connect_send_request
isc_nm_httpconnect
isc_nm_httprequest
isc_nm_listenhttp
isc_nm_listentcpdns
isc_nm_listentls
isc_nm_listentlsdns
isc_nm_listentcp
isc_nm_listenudp
@@ -467,6 +474,7 @@ isc_nm_settimeouts
isc_nm_tcpdns_keepalive
isc_nm_tcpdns_sequential
isc_nm_tid
isc_nm_tlsconnect
isc_nm_tlsdnsconnect
isc_nm_udpconnect
isc_nmsocket_close
@@ -706,6 +714,7 @@ isc_tlsctx_createserver
isc_tlsctx_free
isc_tm_timegm
isc_tm_strptime
isc_url_parse
isc_utf8_bom
isc_utf8_valid
isc_win32os_versioncheck
+7 -1
View File
@@ -260,6 +260,9 @@
<ClInclude Include="..\include\isc\types.h">
<Filter>Library Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\isc\url.h">
<Filter>Library Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\isc\utf8.h">
<Filter>Library Header Files</Filter>
</ClInclude>
@@ -608,12 +611,15 @@
<ClCompile Include="..\timer.c">
<Filter>Library Source Files</Filter>
</ClCompile>
<ClCompile Include="..\tls.c">
<ClCompile Include="..\tlsstream.c">
<Filter>Library Source Files</Filter>
</ClCompile>
<ClCompile Include="..\tm.c">
<Filter>Library Source Files</Filter>
</ClCompile>
<ClCompile Include="..\url.c">
<Filter>Library Source Files</Filter>
</ClCompile>
<ClCompile Include="..\utf8.c">
<Filter>Library Source Files</Filter>
</ClCompile>
+19 -9
View File
@@ -62,11 +62,11 @@
@IF PKCS11
<PreprocessorDefinitions>BIND9;@PK11_LIB_LOCATION@WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBISC_EXPORTS;%(PreprocessorDefinitions);%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ForcedIncludeFiles>..\..\..\config.h</ForcedIncludeFiles>
<AdditionalIncludeDirectories>.\;..\..\..\;@LIBXML2_INC@@LIBUV_INC@@OPENSSL_INC@@ZLIB_INC@include;..\include;..\;win32;..\..\isccfg\include;..\..\dns\win32\include;..\..\dns\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>.\;..\..\..\;@LIBXML2_INC@@LIBUV_INC@@NGHTTP2_INC@@OPENSSL_INC@@ZLIB_INC@include;..\include;..\;win32;..\..\isccfg\include;..\..\dns\win32\include;..\..\dns\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@ELSE PKCS11
<PreprocessorDefinitions>BIND9;WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBISC_EXPORTS;%(PreprocessorDefinitions);%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ForcedIncludeFiles>..\..\..\config.h</ForcedIncludeFiles>
<AdditionalIncludeDirectories>.\;..\..\..\;@LIBXML2_INC@@LIBUV_INC@@OPENSSL_INC@@ZLIB_INC@include;..\include;..\;win32;..\..\isccfg\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>.\;..\..\..\;@LIBXML2_INC@@LIBUV_INC@@NGHTTP2_INC@@OPENSSL_INC@@ZLIB_INC@include;..\include;..\;win32;..\..\isccfg\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@END PKCS11
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeaderOutputFile>.\$(Configuration)\$(TargetName).pch</PrecompiledHeaderOutputFile>
@@ -80,7 +80,7 @@
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<OutputFile>..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt)</OutputFile>
<AdditionalDependencies>@OPENSSL_LIBCRYPTO@@OPENSSL_LIBSSL@@LIBUV_LIB@@LIBXML2_LIB@@ZLIB_LIB@ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>@OPENSSL_LIBCRYPTO@@OPENSSL_LIBSSL@@LIBUV_LIB@@NGHTTP2_LIB@@LIBXML2_LIB@@ZLIB_LIB@ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>$(ProjectName).def</ModuleDefinitionFile>
<ImportLibrary>.\$(Configuration)\$(ProjectName).lib</ImportLibrary>
</Link>
@@ -116,6 +116,9 @@ echo Copying the libxml DLL.
copy @LIBXML2_DLL@ ..\Build\Debug\
@END LIBXML2
echo Copying nghttp2 DLL.
copy @NGHTTP2_DLL@ ..\Build\Debug\
@IF GSSAPI
echo Copying the GSSAPI and KRB5 DLLs.
@@ -163,11 +166,11 @@ copy InstallFiles ..\Build\Debug\
@IF PKCS11
<PreprocessorDefinitions>BIND9;@PK11_LIB_LOCATION@WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBISC_EXPORTS;%(PreprocessorDefinitions);%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ForcedIncludeFiles>..\..\..\config.h</ForcedIncludeFiles>
<AdditionalIncludeDirectories>.\;..\..\..\;@LIBXML2_INC@@LIBUV_INC@@OPENSSL_INC@@ZLIB_INC@include;..\include;..\;win32;..\..\isccfg\include;..\..\dns\win32\include;..\..\dns\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>.\;..\..\..\;@LIBXML2_INC@@LIBUV_INC@@NGHTTP2_INC@@OPENSSL_INC@@ZLIB_INC@include;..\include;..\;win32;..\..\isccfg\include;..\..\dns\win32\include;..\..\dns\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@ELSE PKCS11
<PreprocessorDefinitions>BIND9;WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBISC_EXPORTS;%(PreprocessorDefinitions);%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ForcedIncludeFiles>..\..\..\config.h</ForcedIncludeFiles>
<AdditionalIncludeDirectories>.\;..\..\..\;@LIBXML2_INC@@LIBUV_INC@@OPENSSL_INC@@ZLIB_INC@include;..\include;..\;win32;..\..\isccfg\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>.\;..\..\..\;@LIBXML2_INC@@LIBUV_INC@@NGHTTP2_INC@@OPENSSL_INC@@ZLIB_INC@include;..\include;..\;win32;..\..\isccfg\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@END PKCS11
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<WholeProgramOptimization>false</WholeProgramOptimization>
@@ -184,7 +187,7 @@ copy InstallFiles ..\Build\Debug\
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<OutputFile>..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt)</OutputFile>
<AdditionalDependencies>@OPENSSL_LIBCRYPTO@@OPENSSL_LIBSSL@@LIBUV_LIB@@LIBXML2_LIB@@ZLIB_LIB@ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>@OPENSSL_LIBCRYPTO@@OPENSSL_LIBSSL@@LIBUV_LIB@@NGHTTP2_LIB@@LIBXML2_LIB@@ZLIB_LIB@ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>$(ProjectName).def</ModuleDefinitionFile>
<ImportLibrary>.\$(Configuration)\$(ProjectName).lib</ImportLibrary>
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
@@ -211,6 +214,9 @@ copy @OPENSSL_PATH@\LICENSE ..\Build\Release\OpenSSL-LICENSE
echo Copying libuv DLL.
copy @LIBUV_DLL@ ..\Build\Release\
echo Copying nghttp2 DLL.
copy @NGHTTP2_DLL@ ..\Build\Release\
@IF LIBXML2
echo Copying the libxml DLL.
@@ -337,6 +343,7 @@ copy InstallFiles ..\Build\Release\
<ClInclude Include="..\include\isc\tls.h" />
<ClInclude Include="..\include\isc\tm.h" />
<ClInclude Include="..\include\isc\types.h" />
<ClInclude Include="..\include\isc\url.h" />
<ClInclude Include="..\include\isc\utf8.h" />
<ClInclude Include="..\include\isc\util.h" />
@IF PKCS11
@@ -408,13 +415,15 @@ copy InstallFiles ..\Build\Release\
<ClCompile Include="..\mem.c" />
<ClCompile Include="..\mutexblock.c" />
<ClCompile Include="..\netaddr.c" />
<ClCompile Include="..\netmgr\http.c" />
<ClCompile Include="..\netmgr\netmgr.c" />
<ClCompile Include="..\netmgr\tcp.c" />
<ClCompile Include="..\netmgr\udp.c" />
<ClCompile Include="..\netmgr\uverr2result.c" />
<ClCompile Include="..\netmgr\uv-compat.c" />
<ClCompile Include="..\netmgr\tcpdns.c" />
<ClCompile Include="..\netmgr\tlsstream.c" />
<ClCompile Include="..\netmgr\udp.c" />
<ClCompile Include="..\netmgr\tlsdns.c" />
<ClCompile Include="..\netmgr\uv-compat.c" />
<ClCompile Include="..\netmgr\uverr2result.c" />
<ClCompile Include="..\netscope.c" />
<ClCompile Include="..\nonce.c" />
<ClCompile Include="..\openssl_shim.c" />
@@ -442,6 +451,7 @@ copy InstallFiles ..\Build\Release\
<ClCompile Include="..\timer.c" />
<ClCompile Include="..\tls.c" />
<ClCompile Include="..\tm.c" />
<ClCompile Include="..\url.c" />
<ClCompile Include="..\utf8.c" />
@IF PKCS11
<ClCompile Include="..\pk11.c" />
+5 -1
View File
@@ -7,17 +7,21 @@ libisccfg_la_HEADERS = \
include/isccfg/aclconf.h \
include/isccfg/cfg.h \
include/isccfg/grammar.h \
include/isccfg/httpconf.h \
include/isccfg/kaspconf.h \
include/isccfg/log.h \
include/isccfg/namedconf.h
include/isccfg/namedconf.h \
include/isccfg/tlsconf.h
libisccfg_la_SOURCES = \
$(libisccfg_la_HEADERS) \
aclconf.c \
httpconf.c \
dnsconf.c \
kaspconf.c \
log.c \
namedconf.c \
tlsconf.c \
parser.c
libisccfg_la_CPPFLAGS = \
+1
View File
@@ -643,6 +643,7 @@ cfg_acl_fromconfig2(const cfg_obj_t *caml, const cfg_obj_t *cctx,
new_nest_level = nest_level - 1;
}
REQUIRE(ctx != NULL);
REQUIRE(target != NULL);
REQUIRE(*target == NULL || DNS_ACL_VALID(*target));

Some files were not shown because too many files have changed in this diff Show More