Compare commits

...
Author SHA1 Message Date
Evan Hunt fb7846bf2e change ISC__BUFFER macros to inline functions
previously, when ISC_BUFFER_USEINLINE was defined, macros were
used to implement isc_buffer primitives (isc_buffer_init(),
isc_buffer_region(), etc). these macros were missing the DbC
assertions for those primitives, which made it possible for
coding errors to go undetected.

adding the assertions to the macros caused compiler warnings on
some platforms. therefore, this commit converts the ISC__BUFFER
macros to static inline functions instead, with assertions included,
and eliminates the non-inline implementation from buffer.c.

the --enable-buffer-useinline configure option has been removed.
2022-09-12 14:36:47 -07:00
Evan Hunt 00e3c8fe1a Merge branch '3520-rndc-shutdown-hang' into 'main'
prevent a possible shutdown hang in rndc

See merge request isc-projects/bind9!6734
2022-09-12 20:34:32 +00:00
Evan Hunt 9683439d73 prevent a possible shutdown hang in rndc
In rndc_recvdone(), if 'sends' was not 0, then 'recvs' was not
decremented, in which case isc_loopmgr_shutdown() was never reached,
which could cause a hang. (This has not been observed to happen, but
the code was incorrect on examination.)
2022-09-12 13:14:19 -07:00
Tony Finch b5b147864f Merge branch 'fanf-tolower' into 'main'
De-duplicate `tolower()`

See merge request isc-projects/bind9!6516
2022-09-12 12:08:06 +00:00
Tony Finch 022bb06264 CHANGES note for [GL !6516]
[cleanup]	Move the duplicated ASCII case conversion tables to
		isc_ascii where they can be shared, and replace the
		various hot-path tolower() loops with calls to new
		isc_ascii implementations.
2022-09-12 12:23:39 +01:00
Tony Finch 68029bfc9d Tests and benchmark for isc_ascii
The test is to verify basic functionality. The benchmark compares a
number of alternative tolower() implementations on large and small
strings.
2022-09-12 12:23:39 +01:00
Tony Finch 21a383a8fd General-purpose unrolled ASCII tolower() loops
When converting a string to lower case, the compiler is able to
autovectorize nicely, so a nice simple implementation is also very
fast, comparable to memcpy().

Comparisons are more difficult for the compiler, so we convert eight
bytes at a time using "SIMD within a register" tricks. Experiments
indicate it's best to stick to simple loops for shorter strings and
the remainder of long strings.
2022-09-12 12:18:57 +01:00
Tony Finch 27a561273e Consolidate some ASCII tables in isc/ascii and isc/hex
There were a number of places that had copies of various ASCII
tables (case conversion, hex and decimal conversion) that are intended
to be faster than the ctype.h macros, or avoid locale pollution.

Move them into libisc, and wrap the lookup tables with macros that
avoid the ctype.h gotchas.
2022-09-12 12:18:57 +01:00
Tony Finch db3590e0b7 Merge branch '3519-macos-tests' into 'main'
System test fixes for macOS

Closes #3519

See merge request isc-projects/bind9!6719
2022-09-12 11:14:27 +00:00
Tony Finch d8053785b0 Skip the xfer test when Net::DNS is too old
This allows the system tests to run to completion on macOS
without requiring extra modules from CPAN.
2022-09-12 12:13:04 +01:00
Tony Finch 258a896a0c The system tests are using another IP address
Reduce the number of places that know about the number of IP addresses
required by the system tests, by changing `testsock.pl` to read the
`max` from `ifconfig.sh.in`. This should make the test runner fail
early with a clear message when the interfaces have been set up by an
obsolete script.

Add comments to cross-reference `ifconfig.sh.in`, `testsock.pl`, and
`org.isc.bind.system` to make it easier to remember what needs
updating when an IP address is added.
2022-09-12 12:13:04 +01:00
Tony Finch eb68baffd9 Merge branch '3527-dig-idna-relaxed' into 'main'
More lenient IDNA processing in dig

Closes #3527

See merge request isc-projects/bind9!6738
2022-09-12 11:09:38 +00:00
Tony Finch ac487af09e CHANGES and release note for [GL #3527]
[func]		When an international domain name is not valid, DiG will
		now pass it through unchanged, instead of stopping with
		an error message. [GL #3527]
2022-09-12 11:42:02 +01:00
Tony Finch f820ef49bf More lenient IDNA processing in dig
If there are any problems with IDN processing, DiG will now quietly
handle the name as if IDN were disabled. This means that international
query names are rendered verbatim on the wire, and ACE names are
printed raw without conversion to UTF8.

If you want to check the syntax of international domain names,
use the `idn2` utility.
2022-09-12 11:40:08 +01:00
Tony Finch 8b9dba53dd Merge branch '3528-catz-test-faster' into 'main'
Speed up the `catz` system test

Closes #3528

See merge request isc-projects/bind9!6742
2022-09-12 10:31:10 +00:00
Tony Finch cdfe8f23c2 Speed up the catz system test
Do not delay sending NOFIFY messages, and allow catalog zones to
update every second instead of every 5 seconds.
2022-09-12 11:30:09 +01:00
Tony Finch 2ae81024df Merge branch '3531-initialize-struct-server' into 'main'
Ensure that named_server_t is properly initialized

Closes #3531

See merge request isc-projects/bind9!6755
2022-09-12 10:12:42 +00:00
Tony Finch 7b71b1020f Ensure that named_server_t is properly initialized
There was a ubsan error reporting an invalid value for interface_auto
(a boolean value cannot be 190) because it was not initialized. To
avoid this problem happening again, ensure the whole of the server
structure is initialized to zero before setting the (relatively few)
non-zero elements.
2022-09-12 10:35:39 +01:00
Michał Kępień 37cdd6b51d Merge branch '3534-fix-error-reporting-for-posix-threads-functions' into 'main'
Fix error reporting for POSIX Threads functions

See merge request isc-projects/bind9!6756
2022-09-09 18:28:07 +00:00
Michał Kępień 3b1c80fd0f Fix error reporting for POSIX Threads functions
Commit 3608abc8fa inadvertently carried
over a mistake in logging pthread_cond_init() errors to the
ERRNO_CHECK() preprocessor macro: instead of passing the value returned
by a given pthread_*() function to strerror_r(), ERRNO_CHECK() passes
the errno variable to strerror_r().  This causes bogus error reports
because POSIX Threads API functions do not set the errno variable.

Fix by passing the value returned by a given pthread_*() function
instead of the errno variable to strerror_r().  Since this change makes
the name of the affected macro (ERRNO_CHECK()) confusing, rename the
latter to PTHREADS_RUNTIME_CHECK().  Also log the integer error value
returned by a given pthread_*() function verbatim to rule out any
further confusion in runtime error reporting.
2022-09-09 20:25:47 +02:00
Michał Kępień a1ae24d9ae Merge branch 'michal/set-up-version-and-release-notes-for-bind-9.19.6' into 'main'
Set up version and release notes for BIND 9.19.6

See merge request isc-projects/bind9!6758
2022-09-09 18:23:08 +00:00
Michał Kępień 3239875a8a Set up release notes for BIND 9.19.6 2022-09-09 19:56:43 +02:00
Michał Kępień fa610c0d1b Update BIND version to 9.19.6-dev 2022-09-09 19:56:43 +02:00
51 changed files with 1636 additions and 1785 deletions
+6 -2
View File
@@ -599,7 +599,7 @@ gcc:oraclelinux8:amd64:
variables:
CC: gcc
CFLAGS: "${CFLAGS_COMMON}"
EXTRA_CONFIGURE: "--enable-buffer-useinline --with-libidn2"
EXTRA_CONFIGURE: "--with-libidn2"
<<: *oraclelinux_8_amd64_image
<<: *build_job
@@ -1464,9 +1464,13 @@ gcov:
# source files from lib/dns/rdata/*/, using an even nastier trick.
- find lib/dns/rdata/* -name "*.c" -execdir cp -f "{}" ../../ \;
# Help gcovr process inline functions in headers
- cp -f lib/isc/include/isc/*.h lib/dns/
- cp -f lib/isc/include/isc/*.h lib/isc/
- cp -f lib/dns/include/dns/*.h lib/dns/
- cp -f lib/dns/include/dns/*.h lib/ns/
- find bin lib -maxdepth 1 -mindepth 1 -type d -exec cp -f lib/isc/include/isc/buffer.h "{}" \;
- cp -f lib/isc/include/isc/buffer.h fuzz/
- cp -f lib/isc/include/isc/buffer.h lib/isc/netmgr/buffer.h
- cp -f lib/isc/include/isc/hash.h lib/dns/hash.h
# Generate XML file in the Cobertura XML format suitable for use by GitLab
# for the purpose of displaying code coverage information in the diff view
# of a given merge request.
+12
View File
@@ -1,3 +1,15 @@
5965. [cleanup] Move the duplicated ASCII case conversion tables to
isc_ascii where they can be shared, and replace the
various hot-path tolower() loops with calls to new
isc_ascii implementations. [GL !6516]
5964. [func] When an international domain name is not valid, DiG will
now pass it through unchanged, instead of stopping with
an error message. [GL #3527]
5963. [bug] Ensure struct named_server is properly initialized.
[GL #6531]
5962. [placeholder]
5961. [placeholder]
+19 -26
View File
@@ -235,10 +235,8 @@ help(void) {
" +[no]identify (ID responders in short "
"answers)\n"
#ifdef HAVE_LIBIDN2
" +[no]idnin (Parse IDN names "
"[default=on on tty])\n"
" +[no]idnout (Convert IDN response "
"[default=on on tty])\n"
" +[no]idn (convert international "
"domain names)\n"
#endif /* ifdef HAVE_LIBIDN2 */
" +[no]ignore (Don't revert to TCP for "
"TC responses.)\n"
@@ -1615,7 +1613,7 @@ plus_option(char *option, bool is_batchfile, bool *need_clone,
break;
case 'i':
switch (cmd[1]) {
case 'd': /* identify */
case 'd':
switch (cmd[2]) {
case 'e':
FULLCHECK("identify");
@@ -1623,33 +1621,28 @@ plus_option(char *option, bool is_batchfile, bool *need_clone,
break;
case 'n':
switch (cmd[3]) {
case 'i':
FULLCHECK("idnin");
#ifndef HAVE_LIBIDN2
if (state) {
fprintf(stderr,
";; IDN input support"
" not enabled\n");
}
#else /* ifndef HAVE_LIBIDN2 */
case '\0':
FULLCHECK("idn");
lookup->idnin = state;
#endif /* ifndef HAVE_LIBIDN2 */
break;
case 'o':
FULLCHECK("idnout");
#ifndef HAVE_LIBIDN2
if (state) {
fprintf(stderr,
";; IDN output support"
" not enabled\n");
}
#else /* ifndef HAVE_LIBIDN2 */
lookup->idnout = state;
#endif /* ifndef HAVE_LIBIDN2 */
break;
case 'i': /* (compat) */
FULLCHECK("idnin");
lookup->idnin = state;
break;
case 'o': /* (compat) */
FULLCHECK("idnout");
lookup->idnout = state;
break;
default:
goto invalid_option;
}
#ifndef HAVE_LIBIDN2
if (state) {
printf(";; IDN support "
"is not available\n");
}
#endif /* ifndef HAVE_LIBIDN2 */
break;
default:
goto invalid_option;
+8 -28
View File
@@ -432,28 +432,19 @@ abbreviation is unambiguous; for example, :option:`+cd` is equivalent to
form answers are requested, the default is not to show the source
address and port number of the server that provided the answer.
.. option:: +idnin, +noidnin
.. option:: +idn, +noidn
This option processes [or does not process] IDN domain names on input. This requires
``IDN SUPPORT`` to have been enabled at compile time.
Enable or disable IDN processing. By default IDN is enabled for
input query names, and for display when the output is a terminal.
The default is to process IDN input when standard output is a tty.
The IDN processing on input is disabled when :program:`dig` output is redirected
to files, pipes, and other non-tty file descriptors.
.. option:: +idnout, +noidnout
This option converts [or does not convert] puny code on output. This requires
``IDN SUPPORT`` to have been enabled at compile time.
The default is to process puny code on output when standard output is
a tty. The puny code processing on output is disabled when :program:`dig` output
is redirected to files, pipes, and other non-tty file descriptors.
You can also turn off :program:`dig`'s IDN processing by setting
the ``IDN_DISABLE`` environment variable.
.. option:: +ignore, +noignore
This option ignores [or does not ignore] truncation in UDP responses instead of retrying with TCP. By
default, TCP retries are performed.
This option ignores [or does not ignore] truncation in UDP
responses instead of retrying with TCP. By default, TCP retries are
performed.
.. option:: +keepalive, +nokeepalive
@@ -750,17 +741,6 @@ each lookup. The final query has a local query option of :option:`+qr` which
means that :program:`dig` does not print the initial query when it looks up the
NS records for ``isc.org``.
IDN Support
~~~~~~~~~~~
If :program:`dig` has been built with IDN (internationalized domain name)
support, it can accept and display non-ASCII domain names. :program:`dig`
appropriately converts character encoding of a domain name before sending
a request to a DNS server or displaying a reply from the server.
To turn off IDN support, use the parameters
:option:`+idnin` and :option:`+idnout`, or define the ``IDN_DISABLE`` environment
variable.
Return Codes
~~~~~~~~~~~~
+61 -156
View File
@@ -116,11 +116,7 @@ static char servercookie[256];
#ifdef HAVE_LIBIDN2
static void
idn_locale_to_ace(const char *src, char *dst, size_t dstlen);
static void
idn_ace_to_locale(const char *src, char **dst);
static isc_result_t
idn_output_filter(isc_buffer_t *buffer, unsigned int used_org);
idn_input(const char *src, char *dst, size_t dstlen);
#endif /* HAVE_LIBIDN2 */
isc_nmhandle_t *keep = NULL;
@@ -585,8 +581,13 @@ clone_server_list(dig_serverlist_t src, dig_serverlist_t *dest) {
dig_lookup_t *
make_empty_lookup(void) {
dig_lookup_t *looknew;
int idnin = false, idnout = false;
#ifdef HAVE_LIBIDN2
bool idn_allowed = isatty(1) ? (getenv("IDN_DISABLE") == NULL) : false;
if (getenv("IDN_DISABLE") == NULL) {
idnin = true;
idnout = isatty(1);
}
#endif /* HAVE_LIBIDN2 */
debug("make_empty_lookup()");
@@ -603,10 +604,8 @@ make_empty_lookup(void) {
.besteffort = true,
.opcode = dns_opcode_query,
.badcookie = true,
#ifdef HAVE_LIBIDN2
.idnin = idn_allowed,
.idnout = idn_allowed,
#endif /* HAVE_LIBIDN2 */
.idnin = idnin,
.idnout = idnout,
.udpsize = -1,
.edns = -1,
.recurse = true,
@@ -2220,7 +2219,7 @@ setup_lookup(dig_lookup_t *lookup) {
textname = lookup->textname;
#ifdef HAVE_LIBIDN2
if (lookup->idnin) {
idn_locale_to_ace(textname, idn_textname, sizeof(idn_textname));
idn_input(textname, idn_textname, sizeof(idn_textname));
debug("idn_textname: %s", idn_textname);
textname = idn_textname;
}
@@ -2251,8 +2250,7 @@ setup_lookup(dig_lookup_t *lookup) {
origin = lookup->origin->origin;
#ifdef HAVE_LIBIDN2
if (lookup->idnin) {
idn_locale_to_ace(origin, idn_origin,
sizeof(idn_origin));
idn_input(origin, idn_origin, sizeof(idn_origin));
debug("trying idn origin %s", idn_origin);
origin = idn_origin;
}
@@ -4680,57 +4678,48 @@ destroy_libs(void) {
}
#ifdef HAVE_LIBIDN2
static isc_result_t
idn_output_filter(isc_buffer_t *buffer, unsigned int used_org) {
char src[MXNAME], *dst = NULL;
idn_filter(isc_buffer_t *buffer, unsigned start) {
char src[MXNAME];
char *dst = NULL;
size_t srclen, dstlen;
isc_result_t result = ISC_R_SUCCESS;
int res;
/*
* Copy name from 'buffer' to 'src' and terminate it with NULL.
*/
srclen = isc_buffer_usedlength(buffer) - used_org;
if (srclen >= sizeof(src)) {
warn("Input name too long to perform IDN conversion");
goto cleanup;
}
memmove(src, (char *)isc_buffer_base(buffer) + used_org, srclen);
srclen = isc_buffer_usedlength(buffer) - start;
INSIST(srclen < sizeof(src));
memmove(src, (char *)isc_buffer_base(buffer) + start, srclen);
src[srclen] = '\0';
/*
* Try to convert the name; leave it unchanged if conversion fails.
*/
systemlocale(LC_ALL);
/*
* Convert 'src' to the current locale's character encoding.
*/
idn_ace_to_locale(src, &dst);
res = idn2_to_unicode_8zlz(src, &dst, IDN2_NONTRANSITIONAL);
if (res == IDN2_DISALLOWED) {
res = idn2_to_unicode_8zlz(src, &dst, IDN2_TRANSITIONAL);
}
resetlocale(LC_ALL);
/*
* Check whether the converted name will fit back into 'buffer'.
*/
dstlen = strlen(dst);
if (isc_buffer_length(buffer) < used_org + dstlen) {
result = ISC_R_NOSPACE;
goto cleanup;
if (res != IDN2_OK) {
return (ISC_R_SUCCESS);
}
/*
* Put the converted name back into 'buffer'.
* Copy the converted back into 'buffer' if it fits.
*/
dstlen = strlen(dst);
if (isc_buffer_length(buffer) < start + dstlen) {
return (ISC_R_NOSPACE);
}
isc_buffer_subtract(buffer, srclen);
memmove(isc_buffer_used(buffer), dst, dstlen);
isc_buffer_add(buffer, dstlen);
/*
* Clean up.
*/
cleanup:
if (dst != NULL) {
idn2_free(dst);
}
return (result);
idn2_free(dst);
return (ISC_R_SUCCESS);
}
/*%
@@ -4741,126 +4730,42 @@ cleanup:
* 'dst' MUST be large enough to hold any valid domain name.
*/
static void
idn_locale_to_ace(const char *src, char *dst, size_t dstlen) {
const char *final_src;
char *ascii_src;
idn_input(const char *src, char *dst, size_t dstlen) {
char *ascii = NULL;
size_t len;
int res;
systemlocale(LC_ALL);
/*
* We trust libidn2 to return an error if 'src' is too large to be a
* valid domain name.
*
* If conversion fails under IDNA2008 rules, retry with transitional
* rules. The aim is that characters whose interpretation changed will
* be handled under the new rules, but we will accept characters (such
* as emoji) that were OK but are now forbidden.
*/
res = idn2_to_ascii_lz(src, &ascii_src, IDN2_NONTRANSITIONAL);
if (res == IDN2_DISALLOWED) {
res = idn2_to_ascii_lz(src, &ascii_src, IDN2_TRANSITIONAL);
}
if (res != IDN2_OK) {
fatal("'%s' is not a legal IDNA2008 name (%s), use +noidnin",
src, idn2_strerror(res));
}
/*
* idn2_to_ascii_lz() normalizes all strings to lower case, but we
* generally don't want to lowercase all input strings; make sure to
* return the original case if the two strings differ only in case.
*/
final_src = (strcasecmp(src, ascii_src) == 0 ? src : ascii_src);
(void)strlcpy(dst, final_src, dstlen);
idn2_free(ascii_src);
resetlocale(LC_ALL);
}
/*%
* Convert 'src', which is an ACE string suitable for use in the DNS, into a
* string using the current locale's character encoding, storing the conversion
* result in 'dst'.
*
* The caller MUST subsequently release 'dst' using idn2_free().
*/
static void
idn_ace_to_locale(const char *src, char **dst) {
char *local_src, *utf8_src;
int res;
systemlocale(LC_ALL);
/*
* We need to:
*
* 1) check whether 'src' is a valid IDNA2008 name,
* 2) if it is, output it in the current locale's character encoding.
*
* Unlike idn2_to_ascii_*(), idn2_to_unicode_*() functions are unable
* to perform IDNA2008 validity checks. Thus, we need to decode any
* Punycode in 'src', check if the resulting name is a valid IDNA2008
* name, and only once we ensure it is, output that name in the current
* locale's character encoding.
*
* We could just use idn2_to_unicode_8zlz() + idn2_to_ascii_lz(), but
* then we would not be able to universally tell invalid names and
* character encoding errors apart (if the current locale uses ASCII
* for character encoding, the former function would fail even for a
* valid IDNA2008 name, as long as it contained any non-ASCII
* character). Thus, we need to take a longer route.
*
* First, convert 'src' to UTF-8, ignoring the current locale.
*/
res = idn2_to_unicode_8z8z(src, &utf8_src, 0);
if (res != IDN2_OK) {
fatal("Bad ACE string '%s' (%s), use +noidnout", src,
idn2_strerror(res));
}
/*
* Then, check whether decoded 'src' is a valid IDNA2008 name
* and if disallowed character is found, fallback to IDNA2003.
*/
res = idn2_to_ascii_8z(utf8_src, NULL, IDN2_NONTRANSITIONAL);
res = idn2_to_ascii_lz(src, &ascii, IDN2_NONTRANSITIONAL);
if (res == IDN2_DISALLOWED) {
res = idn2_to_ascii_8z(utf8_src, NULL, IDN2_TRANSITIONAL);
res = idn2_to_ascii_lz(src, &ascii, IDN2_TRANSITIONAL);
}
if (res != IDN2_OK) {
fatal("'%s' is not a legal IDNA2008 name (%s), use +noidnout",
src, idn2_strerror(res));
}
/*
* Finally, try converting the decoded 'src' into the current locale's
* character encoding.
*/
res = idn2_to_unicode_8zlz(utf8_src, &local_src, 0);
if (res != IDN2_OK) {
static bool warned = false;
res = idn2_to_ascii_8z(utf8_src, &local_src, 0);
if (res != IDN2_OK) {
fatal("Cannot represent '%s' "
"in the current locale nor ascii (%s), "
"use +noidnout or a different locale",
src, idn2_strerror(res));
} else if (!warned) {
fprintf(stderr,
";; Warning: cannot represent '%s' "
"in the current locale",
local_src);
warned = true;
}
}
/*
* Free the interim conversion result.
*/
idn2_free(utf8_src);
*dst = local_src;
resetlocale(LC_ALL);
/*
* idn2_to_ascii_lz() normalizes all strings to lower case, but
* we generally don't want to lowercase all input strings; make
* sure to return the original case if the two strings differ
* only in case.
*/
if (res == IDN2_OK && strcasecmp(src, ascii) != 0) {
len = strlcpy(dst, ascii, dstlen);
} else {
len = strlcpy(dst, src, dstlen);
}
INSIST(len < dstlen);
idn2_free(ascii);
}
#endif /* HAVE_LIBIDN2 */
void
@@ -4868,7 +4773,7 @@ dig_idnsetup(dig_lookup_t *lookup, bool active) {
#ifdef HAVE_LIBIDN2
isc_result_t result;
result = dns_name_settotextfilter(
(active && lookup->idnout) ? idn_output_filter : NULL);
(active && lookup->idnout) ? idn_filter : NULL);
check_result(result, "dns_name_settotextfilter");
#else
UNUSED(lookup);
+9 -66
View File
@@ -10236,13 +10236,14 @@ named_server_create(isc_mem_t *mctx, named_server_t **serverp) {
isc_result_t result;
named_server_t *server = isc_mem_get(mctx, sizeof(*server));
if (server == NULL) {
fatal(server, "allocating server object", ISC_R_NOMEMORY);
}
server->mctx = mctx;
server->task = NULL;
server->zonemgr = NULL;
*server = (named_server_t){
.mctx = mctx,
.statsfile = isc_mem_strdup(mctx, "named.stats"),
.bindkeysfile = isc_mem_strdup(mctx, named_g_defaultbindkeys),
.dumpfile = isc_mem_strdup(mctx, "named_dump.db"),
.secrootsfile = isc_mem_strdup(mctx, "named.secroots"),
.recfile = isc_mem_strdup(mctx, "named.recursing"),
};
#ifdef USE_DNSRPS
CHECKFATAL(dns_dnsrps_server_create(), "initializing RPZ service "
@@ -10250,10 +10251,8 @@ named_server_create(isc_mem_t *mctx, named_server_t **serverp) {
#endif /* ifdef USE_DNSRPS */
/* Initialize server data structures. */
server->interfacemgr = NULL;
ISC_LIST_INIT(server->kasplist);
ISC_LIST_INIT(server->viewlist);
server->in_roothints = NULL;
/* Must be first. */
CHECKFATAL(dst_lib_init(named_g_mctx, named_g_engine), "initializing "
@@ -10275,7 +10274,6 @@ named_server_create(isc_mem_t *mctx, named_server_t **serverp) {
isc_task_setname(server->task, "server", server);
isc_taskmgr_setexcltask(named_g_taskmgr, server->task);
server->sctx = NULL;
CHECKFATAL(ns_server_create(mctx, get_matching_view, &server->sctx),
"creating server context");
@@ -10302,50 +10300,11 @@ named_server_create(isc_mem_t *mctx, named_server_t **serverp) {
server->sighup = isc_signal_new(
named_g_loopmgr, named_server_reloadwanted, server, SIGHUP);
server->interface_timer = NULL;
server->heartbeat_timer = NULL;
server->pps_timer = NULL;
server->tat_timer = NULL;
server->interface_interval = 0;
server->heartbeat_interval = 0;
CHECKFATAL(dns_zonemgr_create(named_g_mctx, named_g_loopmgr,
named_g_taskmgr, named_g_netmgr,
&server->zonemgr),
"dns_zonemgr_create");
server->statsfile = isc_mem_strdup(server->mctx, "named.stats");
CHECKFATAL(server->statsfile == NULL ? ISC_R_NOMEMORY : ISC_R_SUCCESS,
"isc_mem_strdup");
server->bindkeysfile = isc_mem_strdup(server->mctx,
named_g_defaultbindkeys);
CHECKFATAL(server->bindkeysfile == NULL ? ISC_R_NOMEMORY
: ISC_R_SUCCESS,
"isc_mem_strdup");
server->dumpfile = isc_mem_strdup(server->mctx, "named_dump.db");
CHECKFATAL(server->dumpfile == NULL ? ISC_R_NOMEMORY : ISC_R_SUCCESS,
"isc_mem_strdup");
server->secrootsfile = isc_mem_strdup(server->mctx, "named.secroots");
CHECKFATAL(server->secrootsfile == NULL ? ISC_R_NOMEMORY
: ISC_R_SUCCESS,
"isc_mem_strdup");
server->recfile = isc_mem_strdup(server->mctx, "named.recursing");
CHECKFATAL(server->recfile == NULL ? ISC_R_NOMEMORY : ISC_R_SUCCESS,
"isc_mem_strdup");
server->hostname_set = false;
server->hostname = NULL;
server->version_set = false;
server->version = NULL;
server->zonestats = NULL;
server->resolverstats = NULL;
server->sockstats = NULL;
CHECKFATAL(isc_stats_create(server->mctx, &server->sockstats,
isc_sockstatscounter_max),
"isc_stats_create");
@@ -10359,33 +10318,17 @@ named_server_create(isc_mem_t *mctx, named_server_t **serverp) {
dns_resstatscounter_max),
"dns_stats_create (resolver)");
server->flushonshutdown = false;
server->controls = NULL;
CHECKFATAL(named_controls_create(server, &server->controls),
"named_controls_create");
server->dispatchgen = 0;
ISC_LIST_INIT(server->dispatches);
ISC_LIST_INIT(server->statschannels);
ISC_LIST_INIT(server->cachelist);
server->sessionkey = NULL;
server->session_keyfile = NULL;
server->session_keyname = NULL;
server->session_keyalg = DST_ALG_UNKNOWN;
server->session_keybits = 0;
server->lockfile = NULL;
server->dtenv = NULL;
server->magic = NAMED_SERVER_MAGIC;
server->tlsctx_server_cache = NULL;
server->tlsctx_client_cache = NULL;
*serverp = server;
}
+2 -2
View File
@@ -390,8 +390,8 @@ rndc_recvdone(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
REQUIRE(recvdone_handle == handle);
isc_nmhandle_detach(&recvdone_handle);
if (atomic_load_acquire(&sends) == 0 &&
atomic_fetch_sub_release(&recvs, 1) == 1)
if (atomic_fetch_sub_release(&recvs, 1) == 1 &&
atomic_load_acquire(&sends) == 0)
{
shuttingdown = true;
isc_task_detach(&rndc_task);
+1
View File
@@ -28,6 +28,7 @@ options {
listen-on port @EXTRAPORT1@ { 10.53.0.1; };
listen-on-v6 { none; };
notify no;
notify-delay 0;
recursion no;
allow-transfer { any; };
};
+10
View File
@@ -26,6 +26,7 @@ options {
listen-on { 10.53.0.2; };
listen-on-v6 { fd92:7065:b8e:ffff::2; };
notify no;
notify-delay 0;
recursion no;
serial-query-rate 100;
};
@@ -41,29 +42,38 @@ view "default" {
catalog-zones {
zone "catalog1.example"
default-masters { 10.53.0.1; }
min-update-interval 1s
in-memory no
zone-directory "zonedir";
zone "catalog2.example"
default-primaries { 10.53.0.1 port @EXTRAPORT1@; }
min-update-interval 1s
in-memory yes;
zone "catalog3.example"
default-masters { 10.53.0.1; }
min-update-interval 1s
zone-directory "nonexistent";
#T1 zone "catalog4.example"
#T1 min-update-interval 1s
#T1 default-masters { 10.53.0.1; };
#T2 zone "catalog5.example"
#T2 min-update-interval 1s
#T2 default-primaries { 10.53.0.1; };
zone "catalog-bad1.example"
default-masters { 10.53.0.1; }
min-update-interval 1s
in-memory yes;
zone "catalog-bad2.example"
default-masters { 10.53.0.1; }
min-update-interval 1s
in-memory yes;
zone "catalog-bad3.example"
default-masters { 10.53.0.1; }
min-update-interval 1s
in-memory yes;
zone "catalog-bad4.example"
default-masters { 10.53.0.1; }
min-update-interval 1s
in-memory yes;
};
+1
View File
@@ -26,6 +26,7 @@ options {
listen-on { 10.53.0.2; };
listen-on-v6 { fd92:7065:b8e:ffff::2; };
notify no;
notify-delay 0;
recursion no;
serial-query-rate 100;
};
+1
View File
@@ -28,6 +28,7 @@ options {
listen-on { 10.53.0.3; };
listen-on-v6 { fd92:7065:b8e:ffff::3; };
notify no;
notify-delay 0;
recursion no;
};
+45 -51
View File
@@ -22,17 +22,6 @@ export LC_ALL
# This set of tests check the behavior of the IDNA options in "dig".
#
# "dig" supports two IDNA-related options:
#
# +[no]idnin - Translates a domain name into punycode format before sending
# the query to the server.
#
# Should the input name be a punycode name, "dig +idnin" will also
# validate the punycode, rejecting it if it is invalid.
#
# +[no]idnout - Translates the received punycode domain names into appropriate
# unicode characters before displaying.
#
# The tests run "dig" against an authoritative server configured with a minimal
# root zone and nothing else. As a result, all queries will result in an
# NXDOMAIN. The server will return the qname sent, which "dig" will display
@@ -156,11 +145,12 @@ idna_fail() {
ascii_case_preservation_test() {
text="Checking valid ASCII label"
idna_test "$text" "" LocalhosT LocalhosT.
idna_test "$text" "+noidn" LocalhosT LocalhosT.
idna_test "$text" "+noidnin +noidnout" LocalhosT LocalhosT.
idna_test "$text" "+noidnin +idnout" LocalhosT LocalhosT.
idna_test "$text" "+idnin +noidnout" LocalhosT LocalhosT.
idna_test "$text" "+idnin +idnout" LocalhosT LocalhosT.
idna_test "$text" "+idn" LocalhosT LocalhosT.
}
# Function to perform the tests if IDNA is enabled.
@@ -186,12 +176,12 @@ idna_enabled_test() {
# Note that ASCII characters are converted to lower-case.
text="Checking valid non-ASCII label"
idna_test "$text" "" "München" "M\195\188nchen."
idna_test "$text" "+noidn" "München" "M\195\188nchen."
idna_test "$text" "+noidnin +noidnout" "München" "M\195\188nchen."
idna_test "$text" "+noidnin +idnout" "München" "M\195\188nchen."
idna_test "$text" "+idnin +noidnout" "München" "xn--mnchen-3ya."
idna_test "$text" "+idnin +idnout" "München" "münchen."
idna_test "$text" "+idn" "München" "münchen."
# Tests of transitional processing of a valid U-label
#
@@ -206,28 +196,28 @@ idna_enabled_test() {
# under IDNA2003, go to www.fass.example but under IDNA2008 would end up at
# www.fa\195\159.example - a different web site).
#
# BIND has adopted a hard transition, so this test checks that these
# transitional mapping is not used. The tests are essentially the same as
# for the valid U-label.
# BIND has adopted a (mostly) hard transition, so this test checks that
# the transitional mapping is not used for characters that are valid in
# IDNA2008. The tests are essentially the same as for the valid U-label.
text="Checking that non-transitional IDNA processing is used"
idna_test "$text" "" "faß.de" "fa\195\159.de."
idna_test "$text" "+noidn" "faß.de" "fa\195\159.de."
idna_test "$text" "+noidnin +noidnout" "faß.de" "fa\195\159.de."
idna_test "$text" "+noidnin +idnout" "faß.de" "fa\195\159.de."
idna_test "$text" "+idnin +noidnout" "faß.de" "xn--fa-hia.de."
idna_test "$text" "+idnin +idnout" "faß.de" "faß.de."
idna_test "$text" "+idn" "faß.de" "faß.de."
# Another problem character. The final character in the first label mapped
# onto the Greek sigma character ("σ") in IDNA2003.
text="Second check that non-transitional IDNA processing is used"
idna_test "$text" "" "βόλος.com" "\206\178\207\140\206\187\206\191\207\130.com."
idna_test "$text" "+noidn" "βόλος.com" "\206\178\207\140\206\187\206\191\207\130.com."
idna_test "$text" "+noidnin +noidnout" "βόλος.com" "\206\178\207\140\206\187\206\191\207\130.com."
idna_test "$text" "+noidnin +idnout" "βόλος.com" "\206\178\207\140\206\187\206\191\207\130.com."
idna_test "$text" "+idnin +noidnout" "βόλος.com" "xn--nxasmm1c.com."
idna_test "$text" "+idnin +idnout" "βόλος.com" "βόλος.com."
idna_test "$text" "+idn" "βόλος.com" "βόλος.com."
# Tests of a valid A-label (i.e. starting xn--)
#
@@ -239,11 +229,12 @@ idna_enabled_test() {
# The "+[no]idnin" flag has no effect in these cases.
text="Checking valid A-label"
idna_test "$text" "" "xn--nxasmq6b.com" "xn--nxasmq6b.com."
idna_test "$text" "+noidn" "xn--nxasmq6b.com" "xn--nxasmq6b.com."
idna_test "$text" "+noidnin +noidnout" "xn--nxasmq6b.com" "xn--nxasmq6b.com."
idna_test "$text" "+noidnin +idnout" "xn--nxasmq6b.com" "βόλοσ.com."
idna_test "$text" "+idnin +noidnout" "xn--nxasmq6b.com" "xn--nxasmq6b.com."
idna_test "$text" "+idnin +idnout" "xn--nxasmq6b.com" "βόλοσ.com."
idna_test "$text" "+idn" "xn--nxasmq6b.com" "βόλοσ.com."
# Test of valid A-label in locale that cannot display it
#
@@ -258,17 +249,16 @@ idna_enabled_test() {
text="Checking valid A-label in C locale"
label="xn--nxasmq6b.com"
if command -v idn2 >/dev/null && ! idn2 -d "$label" >/dev/null 2>/dev/null; then
idna_test "$text" "" "$label" "$label."
idna_test "$text" "+noidn" "$label" "$label."
idna_test "$text" "+noidnin +noidnout" "$label" "$label."
idna_test "$text" "+noidnin +idnout" "$label" "$label."
idna_test "$text" "+idnin +noidnout" "$label" "$label."
idna_test "$text" "+idnin +idnout" "$label" "$label."
idna_test "$text" "+noidnin +idnout" "$label" "$label."
idna_test "$text" "+idn" "$label" "$label."
fi
LC_ALL="${saved_LC_ALL}"
# Tests of invalid A-labels
#
# +noidnin: The label is sent as-is to the server and dig will display the
@@ -277,42 +267,48 @@ idna_enabled_test() {
#
# +[no]idnout: If the label makes it to the server (via +noidnin), "dig"
# should report an error if +idnout is specified.
#
# +idn=lax: The label is sent and printed as-is.
# The minimum length of a punycode A-label is 7 characters. Check that
# a shorter label is detected and rejected.
text="Checking punycode label shorter than minimum valid length"
idna_test "$text" "" "xn--xx" "xn--xx."
idna_test "$text" "+noidn" "xn--xx" "xn--xx."
idna_test "$text" "+noidnin +noidnout" "xn--xx" "xn--xx."
idna_fail "$text" "+noidnin +idnout" "xn--xx"
idna_fail "$text" "+idnin +noidnout" "xn--xx"
idna_fail "$text" "+idnin +idnout" "xn--xx"
idna_test "$text" "+noidnin +idnout" "xn--xx" "xn--xx."
idna_test "$text" "+idnin +noidnout" "xn--xx" "xn--xx."
idna_test "$text" "+idnin +idnout" "xn--xx" "xn--xx."
idna_test "$text" "+idn" "xn--xx" "xn--xx."
# Fake A-label - the string does not translate to anything.
# This name is a syntax error: IDNA expects be punycode-encoded
# non-ascii characters after the last hyphen, but they are missing
# in this test.
text="Checking fake A-label"
idna_test "$text" "" "xn--ahahah" "xn--ahahah."
idna_test "$text" "+noidnin +noidnout" "xn--ahahah" "xn--ahahah."
idna_fail "$text" "+noidnin +idnout" "xn--ahahah"
idna_fail "$text" "+idnin +noidnout" "xn--ahahah"
idna_fail "$text" "+idnin +idnout" "xn--ahahah"
idna_test "$text" "+noidn" "xn--ah-" "xn--ah-."
idna_test "$text" "+noidnin +noidnout" "xn--ah-" "xn--ah-."
idna_test "$text" "+noidnin +idnout" "xn--ah-" "xn--ah-."
idna_test "$text" "+idnin +noidnout" "xn--ah-" "xn--ah-."
idna_test "$text" "+idnin +idnout" "xn--ah-" "xn--ah-."
idna_test "$text" "+idn" "xn--ah-" "xn--ah-."
# Too long a label. The punycode string is too long (at 64 characters).
# BIND rejects such labels: with +idnin
label="xn--xflod18hstflod18hstflod18hstflod18hstflod18hstflod18-1iejjjj"
text="Checking punycode label longer than maximum valid length"
idna_fail "$text" "" "$label"
idna_fail "$text" "+noidn" "$label"
idna_fail "$text" "+noidnin +noidnout" "$label"
idna_fail "$text" "+noidnin +idnout" "$label"
idna_fail "$text" "+idnin +noidnout" "$label"
idna_fail "$text" "+idnin +idnout" "$label"
idna_fail "$text" "+idn" "$label"
# Tests of a valid unicode string but an invalid U-label (input)
#
# Symbols are not valid IDNA2008 names. Check whether dig rejects them
# when they are supplied on the command line to ensure no IDNA2003
# fallbacks are in place.
# Symbols are not valid IDNA2008 names, but are allowed by IDNA2003.
#
# +noidnin: "dig" should send unicode octets to the server and display the
# returned qname in the same form.
@@ -321,22 +317,16 @@ idna_enabled_test() {
# The +[no]idnout options should not have any effect on the test.
text="Checking invalid input U-label"
idna_test "$text" "" "√.com" "\226\136\154.com."
idna_test "$text" "+noidn" "√.com" "\226\136\154.com."
idna_test "$text" "+noidnin +noidnout" "√.com" "\226\136\154.com."
idna_test "$text" "+noidnin +idnout" "√.com" "\226\136\154.com."
idna_test "$text" "+idnin +noidnout" "√.com" "xn--19g.com."
idna_test "$text" "+idnin +idnout" "√.com" "√.com."
idna_test "$text" "+idn" "√.com" "√.com."
# Tests of a valid unicode string but an invalid U-label (output)
#
# Symbols are not valid IDNA2008 names. Check whether dig rejects them
# when they are received in DNS responses to ensure no IDNA2003 fallbacks
# are in place.
#
# Note that "+idnin +noidnout" is not tested because libidn2 2.2.0+ parses
# Punycode more strictly than older versions and thus dig fails with that
# combination of options with libidn2 2.2.0+ but succeeds with older
# versions.
# Symbols are not valid IDNA2008 names, but are allowed by IDNA2003.
#
# +noidnout: "dig" should send the ACE string to the server and display the
# returned qname.
@@ -345,28 +335,32 @@ idna_enabled_test() {
# The +[no]idnin options should not have any effect on the test.
text="Checking invalid output U-label"
idna_test "$text" "" "xn--19g" "xn--19g."
idna_test "$text" "+noidn" "xn--19g" "xn--19g."
idna_test "$text" "+noidnin +noidnout" "xn--19g" "xn--19g."
idna_test "$text" "+noidnin +idnout" "xn--19g" "√."
idna_test "$text" "+idnin +noidnout" "xn--19g" "xn--19g."
idna_test "$text" "+idnin +idnout" "xn--19g" "√."
idna_test "$text" "+idn" "xn--19g" "√."
# Test that non-letter characters are preserved in the output. When
# UseSTD3ASCIIRules are enabled, it would mangle non-letter characters like
# `_` (underscore) and `*` (wildcard.
text="Checking valid non-letter characters"
idna_test "$text" "" "*.xn--nxasmq6b.com" "*.xn--nxasmq6b.com."
idna_test "$text" "+noidn" "*.xn--nxasmq6b.com" "*.xn--nxasmq6b.com."
idna_test "$text" "+noidnin +noidnout" "*.xn--nxasmq6b.com" "*.xn--nxasmq6b.com."
idna_test "$text" "+noidnin +idnout" "*.xn--nxasmq6b.com" "*.βόλοσ.com."
idna_test "$text" "+idnin +noidnout" "*.xn--nxasmq6b.com" "*.xn--nxasmq6b.com."
idna_test "$text" "+idnin +idnout" "*.xn--nxasmq6b.com" "*.βόλοσ.com."
idna_test "$text" "+idn" "*.xn--nxasmq6b.com" "*.βόλοσ.com."
idna_test "$text" "" "_tcp.xn--nxasmq6b.com" "_tcp.xn--nxasmq6b.com."
idna_test "$text" "+noidn" "_tcp.xn--nxasmq6b.com" "_tcp.xn--nxasmq6b.com."
idna_test "$text" "+noidnin +noidnout" "_tcp.xn--nxasmq6b.com" "_tcp.xn--nxasmq6b.com."
idna_test "$text" "+noidnin +idnout" "_tcp.xn--nxasmq6b.com" "_tcp.βόλοσ.com."
idna_test "$text" "+idnin +noidnout" "_tcp.xn--nxasmq6b.com" "_tcp.xn--nxasmq6b.com."
idna_test "$text" "+idnin +idnout" "_tcp.xn--nxasmq6b.com" "_tcp.βόλοσ.com."
idna_test "$text" "+idn=strict" "_tcp.xn--nxasmq6b.com" "_tcp.βόλοσ.com."
idna_test "$text" "+idn=lax" "_tcp.xn--nxasmq6b.com" "_tcp.βόλοσ.com."
}
+8
View File
@@ -24,6 +24,10 @@
# We also set the MTU on the 1500 bytes to match the default MTU on physical
# interfaces, so we can properly test the cases with packets bigger than
# interface MTU.
#
# See also org.isc.bind.system (a version of this script for use on macOS)
# and testsock.pl (which checks the interfaces are configured)
#
top_srcdir=@abs_top_srcdir@
@@ -237,6 +241,10 @@ sequence() (
# 'ns' in the namserver being configured.
# 'int' interface identifier.
#
# See also `org.isc.bind.system`.
#
# This `max` setting is grepped out for use by testsock.pl
#
max=11
case $1 in
start|up|stop|down)
+3 -1
View File
@@ -11,12 +11,14 @@
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
# see also ifconfig.sh.in and testsock.pl
ifup() {
/sbin/ifconfig lo0 10.53.$1.$3 alias
/sbin/ifconfig lo0 inet6 fd92:7065:b8e:${2}ff::${3} alias
}
for ns in 1 2 3 4 5 6 7 8 9 10
for ns in 1 2 3 4 5 6 7 8 9 10 11
do
ifup 0 ff $ns
done
+9 -1
View File
@@ -27,7 +27,15 @@ my @ids;
if ($id != 0) {
@ids = ($id);
} else {
@ids = (1..8);
my $fn = "ifconfig.sh.in";
open FH, "< $fn" or die "open < $fn: $!\n";
while (<FH>) {
@ids = (1..$1)
if /^max=(\d+)\s*$/;
}
close FH;
die "could not find max IP address in $fn\n"
unless @ids > 1;
}
foreach $id (@ids) {
+26
View File
@@ -0,0 +1,26 @@
#!/bin/sh
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# SPDX-License-Identifier: MPL-2.0
#
# 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
# macOS ships with Net::DNS 0.74 which does not work with
# HMAC-SHA256, despite the workarounds in ans.pl
if perl -MNet::DNS -e 'exit $Net::DNS::VERSION >= 1.0'
then
version=$(perl -MNet::DNS -e 'print $Net::DNS::VERSION')
echo_i "perl Net::DNS $version is too old - skipping xfer test"
exit 1
fi
exit 0
+3 -14
View File
@@ -16,7 +16,7 @@
#
m4_define([bind_VERSION_MAJOR], 9)dnl
m4_define([bind_VERSION_MINOR], 19)dnl
m4_define([bind_VERSION_PATCH], 5)dnl
m4_define([bind_VERSION_PATCH], 6)dnl
m4_define([bind_VERSION_EXTRA], -dev)dnl
m4_define([bind_DESCRIPTION], [(Development Release)])dnl
m4_define([bind_SRCID], [m4_esyscmd_s([git rev-parse --short HEAD | cut -b1-7])])dnl
@@ -186,18 +186,6 @@ PKG_PROG_PKG_CONFIG
AS_IF([test -z "$PKG_CONFIG"],
[AC_MSG_ERROR([The pkg-config script could not be found or is too old.])])
# [pairwise: --enable-buffer-useinline, --disable-buffer-useinline]
AC_ARG_ENABLE(buffer_useinline,
AS_HELP_STRING([--enable-buffer-useinline],
[define ISC_BUFFER_USEINLINE when compiling
[default=yes]]),
if test yes = "${enable}"
then
AC_DEFINE([ISC_BUFFER_USEINLINE], [1],
[Define if you want to use inline buffers])
fi,
AC_DEFINE([ISC_BUFFER_USEINLINE], [1]))
# Fuzzing is not included in pairwise testing as fuzzing tools are
# not present in the relevant Docker image.
#
@@ -1579,9 +1567,10 @@ AC_CONFIG_FILES([doc/Makefile
doc/man/Makefile
doc/misc/Makefile])
# Unit Tests
# Unit tests and benchmarks
AC_CONFIG_FILES([tests/Makefile
tests/bench/Makefile
tests/isc/Makefile
tests/dns/Makefile
tests/ns/Makefile
+8 -27
View File
@@ -502,29 +502,19 @@ address and port number of the server that provided the answer.
.UNINDENT
.INDENT 0.0
.TP
.B +idnin, +noidnin
This option processes [or does not process] IDN domain names on input. This requires
\fBIDN SUPPORT\fP to have been enabled at compile time.
.B +idn, +noidn
Enable or disable IDN processing. By default IDN is enabled for
input query names, and for display when the output is a terminal.
.sp
The default is to process IDN input when standard output is a tty.
The IDN processing on input is disabled when \fBdig\fP output is redirected
to files, pipes, and other non\-tty file descriptors.
.UNINDENT
.INDENT 0.0
.TP
.B +idnout, +noidnout
This option converts [or does not convert] puny code on output. This requires
\fBIDN SUPPORT\fP to have been enabled at compile time.
.sp
The default is to process puny code on output when standard output is
a tty. The puny code processing on output is disabled when \fBdig\fP output
is redirected to files, pipes, and other non\-tty file descriptors.
You can also turn off \fBdig\fP\(aqs IDN processing by setting
the \fBIDN_DISABLE\fP environment variable.
.UNINDENT
.INDENT 0.0
.TP
.B +ignore, +noignore
This option ignores [or does not ignore] truncation in UDP responses instead of retrying with TCP. By
default, TCP retries are performed.
This option ignores [or does not ignore] truncation in UDP
responses instead of retrying with TCP. By default, TCP retries are
performed.
.UNINDENT
.INDENT 0.0
.TP
@@ -867,15 +857,6 @@ and a query for the NS records of \fBisc.org\fP\&. A global query option of
each lookup. The final query has a local query option of \fI\%+qr\fP which
means that \fBdig\fP does not print the initial query when it looks up the
NS records for \fBisc.org\fP\&.
.SH IDN SUPPORT
.sp
If \fBdig\fP has been built with IDN (internationalized domain name)
support, it can accept and display non\-ASCII domain names. \fBdig\fP
appropriately converts character encoding of a domain name before sending
a request to a DNS server or displaying a reply from the server.
To turn off IDN support, use the parameters
\fI\%+idnin\fP and \fI\%+idnout\fP, or define the \fBIDN_DISABLE\fP environment
variable.
.SH RETURN CODES
.sp
\fBdig\fP return codes are:
+7 -24
View File
@@ -9,7 +9,7 @@
.. See the COPYRIGHT file distributed with this work for additional
.. information regarding copyright ownership.
Notes for BIND 9.19.5
Notes for BIND 9.19.6
---------------------
Security Fixes
@@ -25,9 +25,7 @@ Known Issues
New Features
~~~~~~~~~~~~
- Worker threads' event loops are now managed by a new "loop maanger" API,
significantly changing the architecture of the task, timer and networking
systems for improved performance and code flow. :gl:`#3508`
- None.
Removed Features
~~~~~~~~~~~~~~~~
@@ -37,27 +35,12 @@ Removed Features
Feature Changes
~~~~~~~~~~~~~~~
- Response Rate Limiting (RRL) code now treats all QNAMEs that are
subject to wildcard processing within a given zone as the same name,
to prevent circumventing the limits enforced by RRL. :gl:`#3459`
- Zones using ``dnssec-policy`` now require dynamic DNS or
``inline-signing`` to be configured explicitly :gl:`#3381`.
- When reconfiguring ``dnssec-policy`` from using NSEC with an NSEC-only DNSKEY
algorithm (e.g. RSASHA1) to a policy that uses NSEC3, BIND will no longer fail
to sign the zone, but keep using NSEC for a little longer until the offending
DNSKEY records have been removed from the zone, then switch to using NSEC3.
:gl:`#3486`
- Implement a backwards compatible approach for encoding the internationalized
domain names (IDN) in dig, and convert the domain to IDNA2008 form, and if
that fails try the IDNA2003 conversion. :gl:`#3485`
- When an international domain name is not valid according to IDNA2008,
:program:`dig` will now try to convert it according to IDNA2003 rules,
or pass it through unchanged, instead of stopping with an error message.
You can use the ``idna2`` utility for checking IDNA syntax. :gl:`#3485`.
Bug Fixes
~~~~~~~~~
- Fix a serve-stale bug, where BIND would try to return stale data from cache
for lookups that received duplicate queries or queries that would be dropped.
This bug resulted in premature SERVFAIL responses, and has now been resolved.
:gl:`#2982`
- None.
+11 -63
View File
@@ -18,6 +18,7 @@
#include <inttypes.h>
#include <stdbool.h>
#include <isc/ascii.h>
#include <isc/mem.h>
#include <isc/result.h>
#include <isc/string.h>
@@ -30,31 +31,6 @@
#define CCTX_MAGIC ISC_MAGIC('C', 'C', 'T', 'X')
#define VALID_CCTX(x) ISC_MAGIC_VALID(x, CCTX_MAGIC)
static unsigned char maptolower[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73,
0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83,
0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3,
0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb,
0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3,
0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb,
0xfc, 0xfd, 0xfe, 0xff
};
/*
* The tableindex array below is of size 256, one entry for each
* unsigned char value. The tableindex array elements are dependent on
@@ -261,8 +237,7 @@ dns_compress_find(dns_compress_t *cctx, const dns_name_t *name,
for (node = cctx->table[i]; node != NULL;
node = node->next) {
unsigned int l, count;
unsigned char c;
unsigned char *label1, *label2;
unsigned char *p1, *p2;
if (node->name.length != length) {
continue;
@@ -273,50 +248,23 @@ dns_compress_find(dns_compress_t *cctx, const dns_name_t *name,
continue;
}
label1 = node->name.ndata;
label2 = p;
p1 = node->name.ndata;
p2 = p;
while (l-- > 0) {
count = *label1++;
if (count != *label2++) {
count = *p1++;
if (count != *p2++) {
goto cont1;
}
/* no bitstring support */
INSIST(count <= 63);
/* Loop unrolled for performance */
while (count > 3) {
c = maptolower[label1[0]];
if (c != maptolower[label2[0]])
{
goto cont1;
}
c = maptolower[label1[1]];
if (c != maptolower[label2[1]])
{
goto cont1;
}
c = maptolower[label1[2]];
if (c != maptolower[label2[2]])
{
goto cont1;
}
c = maptolower[label1[3]];
if (c != maptolower[label2[3]])
{
goto cont1;
}
count -= 4;
label1 += 4;
label2 += 4;
}
while (count-- > 0) {
c = maptolower[*label1++];
if (c != maptolower[*label2++])
{
goto cont1;
}
if (!isc_ascii_lowerequal(p1, p2,
count)) {
goto cont1;
}
p1 += count;
p2 += count;
}
break;
cont1:
+32 -243
View File
@@ -18,8 +18,10 @@
#include <stdbool.h>
#include <stdlib.h>
#include <isc/ascii.h>
#include <isc/buffer.h>
#include <isc/hash.h>
#include <isc/hex.h>
#include <isc/mem.h>
#include <isc/once.h>
#include <isc/print.h>
@@ -47,53 +49,6 @@ typedef enum {
typedef enum { fw_start = 0, fw_ordinary, fw_newcurrent } fw_state;
static char digitvalue[256] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*16*/
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*32*/
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*48*/
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, /*64*/
-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*80*/
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*96*/
-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*112*/
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*128*/
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*256*/
};
static unsigned char maptolower[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73,
0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83,
0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3,
0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb,
0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3,
0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb,
0xfc, 0xfd, 0xfe, 0xff
};
#define CONVERTTOASCII(c)
#define CONVERTFROMASCII(c)
#define INIT_OFFSETS(name, var, default_offsets) \
if ((name)->offsets != NULL) \
var = (name)->offsets; \
@@ -487,7 +442,7 @@ dns_namereln_t
dns_name_fullcompare(const dns_name_t *name1, const dns_name_t *name2,
int *orderp, unsigned int *nlabelsp) {
unsigned int l1, l2, l, count1, count2, count, nlabels;
int cdiff, ldiff, chdiff;
int cdiff, ldiff, diff;
unsigned char *label1, *label2;
unsigned char *offsets1, *offsets2;
dns_offsets_t odata1, odata2;
@@ -537,8 +492,7 @@ dns_name_fullcompare(const dns_name_t *name1, const dns_name_t *name2,
offsets1 += l1;
offsets2 += l2;
while (l > 0) {
l--;
while (l-- > 0) {
offsets1--;
offsets2--;
label1 = &name1->ndata[*offsets1];
@@ -546,12 +500,6 @@ dns_name_fullcompare(const dns_name_t *name1, const dns_name_t *name2,
count1 = *label1++;
count2 = *label2++;
/*
* We dropped bitstring labels, and we don't support any
* other extended label types.
*/
INSIST(count1 <= 63 && count2 <= 63);
cdiff = (int)count1 - (int)count2;
if (cdiff < 0) {
count = count1;
@@ -559,44 +507,12 @@ dns_name_fullcompare(const dns_name_t *name1, const dns_name_t *name2,
count = count2;
}
/* Loop unrolled for performance */
while (count > 3) {
chdiff = (int)maptolower[label1[0]] -
(int)maptolower[label2[0]];
if (chdiff != 0) {
*orderp = chdiff;
goto done;
}
chdiff = (int)maptolower[label1[1]] -
(int)maptolower[label2[1]];
if (chdiff != 0) {
*orderp = chdiff;
goto done;
}
chdiff = (int)maptolower[label1[2]] -
(int)maptolower[label2[2]];
if (chdiff != 0) {
*orderp = chdiff;
goto done;
}
chdiff = (int)maptolower[label1[3]] -
(int)maptolower[label2[3]];
if (chdiff != 0) {
*orderp = chdiff;
goto done;
}
count -= 4;
label1 += 4;
label2 += 4;
}
while (count-- > 0) {
chdiff = (int)maptolower[*label1++] -
(int)maptolower[*label2++];
if (chdiff != 0) {
*orderp = chdiff;
goto done;
}
diff = isc_ascii_lowercmp(label1, label2, count);
if (diff != 0) {
*orderp = diff;
goto done;
}
if (cdiff != 0) {
*orderp = cdiff;
goto done;
@@ -646,9 +562,7 @@ dns_name_compare(const dns_name_t *name1, const dns_name_t *name2) {
bool
dns_name_equal(const dns_name_t *name1, const dns_name_t *name2) {
unsigned int l, count;
unsigned char c;
unsigned char *label1, *label2;
unsigned int length;
/*
* Are 'name1' and 'name2' equal?
@@ -671,57 +585,13 @@ dns_name_equal(const dns_name_t *name1, const dns_name_t *name2) {
return (true);
}
if (name1->length != name2->length) {
length = name1->length;
if (length != name2->length) {
return (false);
}
l = name1->labels;
if (l != name2->labels) {
return (false);
}
label1 = name1->ndata;
label2 = name2->ndata;
while (l-- > 0) {
count = *label1++;
if (count != *label2++) {
return (false);
}
INSIST(count <= 63); /* no bitstring support */
/* Loop unrolled for performance */
while (count > 3) {
c = maptolower[label1[0]];
if (c != maptolower[label2[0]]) {
return (false);
}
c = maptolower[label1[1]];
if (c != maptolower[label2[1]]) {
return (false);
}
c = maptolower[label1[2]];
if (c != maptolower[label2[2]]) {
return (false);
}
c = maptolower[label1[3]];
if (c != maptolower[label2[3]]) {
return (false);
}
count -= 4;
label1 += 4;
label2 += 4;
}
while (count-- > 0) {
c = maptolower[*label1++];
if (c != maptolower[*label2++]) {
return (false);
}
}
}
return (true);
/* label lengths are < 64 so tolower() does not affect them */
return (isc_ascii_lowerequal(name1->ndata, name2->ndata, length));
}
bool
@@ -756,10 +626,6 @@ dns_name_caseequal(const dns_name_t *name1, const dns_name_t *name2) {
int
dns_name_rdatacompare(const dns_name_t *name1, const dns_name_t *name2) {
unsigned int l1, l2, l, count1, count2, count;
unsigned char c1, c2;
unsigned char *label1, *label2;
/*
* Compare two absolute names as rdata.
*/
@@ -771,47 +637,9 @@ dns_name_rdatacompare(const dns_name_t *name1, const dns_name_t *name2) {
REQUIRE(name2->labels > 0);
REQUIRE((name2->attributes & DNS_NAMEATTR_ABSOLUTE) != 0);
l1 = name1->labels;
l2 = name2->labels;
l = (l1 < l2) ? l1 : l2;
label1 = name1->ndata;
label2 = name2->ndata;
while (l > 0) {
l--;
count1 = *label1++;
count2 = *label2++;
/* no bitstring support */
INSIST(count1 <= 63 && count2 <= 63);
if (count1 != count2) {
return ((count1 < count2) ? -1 : 1);
}
count = count1;
while (count > 0) {
count--;
c1 = maptolower[*label1++];
c2 = maptolower[*label2++];
if (c1 < c2) {
return (-1);
} else if (c1 > c2) {
return (1);
}
}
}
/*
* If one name had more labels than the other, their common
* prefix must have been different because the shorter name
* ended with the root label and the longer one can't have
* a root label in the middle of it. Therefore, if we get
* to this point, the lengths must be equal.
*/
INSIST(l1 == l2);
return (0);
/* label lengths are < 64 so tolower() does not affect them */
return (isc_ascii_lowercmp(name1->ndata, name2->ndata,
ISC_MIN(name1->length, name2->length)));
}
bool
@@ -1177,9 +1005,8 @@ dns_name_fromtext(dns_name_t *name, isc_buffer_t *source,
return (DNS_R_LABELTOOLONG);
}
count++;
CONVERTTOASCII(c);
if (downcase) {
c = maptolower[c & 0xff];
c = isc_ascii_tolower(c);
}
*ndata++ = c;
nrem--;
@@ -1203,9 +1030,8 @@ dns_name_fromtext(dns_name_t *name, isc_buffer_t *source,
return (DNS_R_LABELTOOLONG);
}
count++;
CONVERTTOASCII(c);
if (downcase) {
c = maptolower[c & 0xff];
c = isc_ascii_tolower(c);
}
*ndata++ = c;
nrem--;
@@ -1221,8 +1047,7 @@ dns_name_fromtext(dns_name_t *name, isc_buffer_t *source,
if (!isdigit((unsigned char)c)) {
return (DNS_R_BADESCAPE);
}
value *= 10;
value += digitvalue[c & 0xff];
value = 10 * value + c - '0';
digits++;
if (digits == 3) {
if (value > 255) {
@@ -1233,7 +1058,7 @@ dns_name_fromtext(dns_name_t *name, isc_buffer_t *source,
}
count++;
if (downcase) {
value = maptolower[value];
value = isc_ascii_tolower(value);
}
*ndata++ = value;
nrem--;
@@ -1281,7 +1106,7 @@ dns_name_fromtext(dns_name_t *name, isc_buffer_t *source,
while (n2 > 0) {
c = *label++;
if (downcase) {
c = maptolower[c & 0xff];
c = isc_ascii_tolower(c);
}
*ndata++ = c;
n2--;
@@ -1430,7 +1255,6 @@ dns_name_totext2(const dns_name_t *name, unsigned int options,
return (ISC_R_NOSPACE);
}
*tdata++ = '\\';
CONVERTFROMASCII(c);
*tdata++ = c;
ndata++;
trem -= 2;
@@ -1442,7 +1266,6 @@ dns_name_totext2(const dns_name_t *name, unsigned int options,
if (trem == 0) {
return (ISC_R_NOSPACE);
}
CONVERTFROMASCII(c);
*tdata++ = c;
ndata++;
trem--;
@@ -1571,7 +1394,6 @@ dns_name_tofilenametext(const dns_name_t *name, bool omit_final_dot,
if (c >= 0x41 && c <= 0x5A) {
c += 0x20;
}
CONVERTFROMASCII(c);
*tdata++ = c;
ndata++;
trem--;
@@ -1623,8 +1445,7 @@ dns_name_tofilenametext(const dns_name_t *name, bool omit_final_dot,
isc_result_t
dns_name_downcase(const dns_name_t *source, dns_name_t *name,
isc_buffer_t *target) {
unsigned char *sndata, *ndata;
unsigned int nlen, count, labels;
unsigned char *ndata;
isc_buffer_t buffer;
/*
@@ -1650,33 +1471,13 @@ dns_name_downcase(const dns_name_t *source, dns_name_t *name,
name->ndata = ndata;
}
sndata = source->ndata;
nlen = source->length;
labels = source->labels;
if (nlen > (target->length - target->used)) {
if (source->length > (target->length - target->used)) {
MAKE_EMPTY(name);
return (ISC_R_NOSPACE);
}
while (labels > 0 && nlen > 0) {
labels--;
count = *sndata++;
*ndata++ = count;
nlen--;
if (count < 64) {
INSIST(nlen >= count);
while (count > 0) {
*ndata++ = maptolower[(*sndata++)];
nlen--;
count--;
}
} else {
FATAL_ERROR(__FILE__, __LINE__,
"Unexpected label type %02x", count);
/* Does not return. */
}
}
/* label lengths are < 64 so tolower() does not affect them */
isc_ascii_lowercopy(ndata, source->ndata, source->length);
if (source != name) {
name->labels = source->labels;
@@ -1852,7 +1653,7 @@ dns_name_fromwire(dns_name_t *name, isc_buffer_t *source, dns_decompress_t dctx,
break;
case fw_ordinary:
if (downcase) {
c = maptolower[c];
c = isc_ascii_tolower(c);
}
*ndata++ = c;
n--;
@@ -2604,19 +2405,6 @@ dns_name_isula(const dns_name_t *name) {
return (false);
}
/*
* Use a simple table as we don't want all the locale stuff
* associated with ishexdigit().
*/
const char ishex[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
bool
dns_name_istat(const dns_name_t *name) {
unsigned char len;
@@ -2641,8 +2429,8 @@ dns_name_istat(const dns_name_t *name) {
return (false);
}
if (ndata[0] != '_' || maptolower[ndata[1]] != 't' ||
maptolower[ndata[2]] != 'a')
if (ndata[0] != '_' || isc_ascii_tolower(ndata[1]) != 't' ||
isc_ascii_tolower(ndata[2]) != 'a')
{
return (false);
}
@@ -2651,8 +2439,9 @@ dns_name_istat(const dns_name_t *name) {
while (len > 0) {
INSIST(len >= 5);
if (ndata[0] != '-' || !ishex[ndata[1]] || !ishex[ndata[2]] ||
!ishex[ndata[3]] || !ishex[ndata[4]])
if (ndata[0] != '-' || !isc_hex_char(ndata[1]) ||
!isc_hex_char(ndata[2]) || !isc_hex_char(ndata[3]) ||
!isc_hex_char(ndata[4]))
{
return (false);
}
+5 -7
View File
@@ -18,6 +18,7 @@
#include <stdbool.h>
#include <sys/mman.h>
#include <isc/ascii.h>
#include <isc/atomic.h>
#include <isc/crc64.h>
#include <isc/event.h>
@@ -9373,10 +9374,9 @@ rdataset_getownercase(const dns_rdataset_t *rdataset, dns_name_t *name) {
}
if (CASEFULLYLOWER(header)) {
for (size_t i = 0; i < name->length; i++) {
name->ndata[i] = tolower(name->ndata[i]);
}
isc_ascii_lowercopy(name->ndata, name->ndata, name->length);
} else {
uint8_t *nd = name->ndata;
for (size_t i = 0; i < name->length; i++) {
if (mask == (1 << 7)) {
bits = header->upper[i / 8];
@@ -9384,10 +9384,8 @@ rdataset_getownercase(const dns_rdataset_t *rdataset, dns_name_t *name) {
} else {
mask <<= 1;
}
name->ndata[i] = ((bits & mask) != 0)
? toupper(name->ndata[i])
: tolower(name->ndata[i]);
nd[i] = (bits & mask) ? isc_ascii_toupper(nd[i])
: isc_ascii_tolower(nd[i]);
}
}
+2 -1
View File
@@ -16,6 +16,7 @@
#include <stdbool.h>
#include <stdlib.h>
#include <isc/ascii.h>
#include <isc/buffer.h>
#include <isc/parseint.h>
#include <isc/print.h>
@@ -474,7 +475,7 @@ dns_rdataclass_fromtext(dns_rdataclass_t *classp, isc_textregion_t *source) {
return (ISC_R_SUCCESS); \
}
switch (tolower((unsigned char)source->base[0])) {
switch (isc_ascii_tolower(source->base[0])) {
case 'a':
COMPARE("any", dns_rdataclass_any);
break;
+14 -41
View File
@@ -19,6 +19,7 @@
#include <openssl/objects.h>
#include <isc/ascii.h>
#include <isc/base64.h>
#include <isc/hex.h>
#include <isc/lex.h>
@@ -355,28 +356,20 @@ static dns_name_t const gc_msdcs = DNS_NAME_INITNONABSOLUTE(gc_msdcs_data,
*/
static int
locator_pton(const char *src, unsigned char *dst) {
static const char xdigits_l[] = "0123456789abcdef",
xdigits_u[] = "0123456789ABCDEF";
unsigned char tmp[NS_LOCATORSZ];
unsigned char *tp = tmp, *endp;
const char *xdigits;
int ch, seen_xdigits;
unsigned int val;
unsigned int val, hexval;
memset(tp, '\0', NS_LOCATORSZ);
endp = tp + NS_LOCATORSZ;
seen_xdigits = 0;
val = 0;
while ((ch = *src++) != '\0') {
const char *pch;
pch = strchr((xdigits = xdigits_l), ch);
if (pch == NULL) {
pch = strchr((xdigits = xdigits_u), ch);
}
if (pch != NULL) {
hexval = isc_hex_char(ch);
if (hexval != 0) {
val <<= 4;
val |= (pch - xdigits);
val |= (ch - hexval);
if (++seen_xdigits > 4) {
return (0);
}
@@ -603,9 +596,6 @@ typemap_test(isc_region_t *sr, bool allow_empty) {
return (ISC_R_SUCCESS);
}
static const char hexdigits[] = "0123456789abcdef";
static const char decdigits[] = "0123456789";
static isc_result_t
check_private(isc_buffer_t *source, dns_secalg_t alg) {
isc_region_t sr;
@@ -1396,8 +1386,8 @@ dns_rdatatype_fromtext(dns_rdatatype_t *typep, isc_textregion_t *source) {
return (DNS_R_UNKNOWN);
}
a = tolower((unsigned char)source->base[0]);
b = tolower((unsigned char)source->base[n - 1]);
a = isc_ascii_tolower(source->base[0]);
b = isc_ascii_tolower(source->base[n - 1]);
hash = ((a + n) * b) % 256;
@@ -2070,38 +2060,21 @@ mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length) {
static int
hexvalue(char value) {
const char *s;
unsigned char c;
c = (unsigned char)value;
if (!isascii(c)) {
int hexval = isc_hex_char(value);
if (hexval == 0) {
return (-1);
} else {
return (value - hexval);
}
if (isupper(c)) {
c = tolower(c);
}
if ((s = strchr(hexdigits, c)) == NULL) {
return (-1);
}
return ((int)(s - hexdigits));
}
static int
decvalue(char value) {
const char *s;
/*
* isascii() is valid for full range of int values, no need to
* mask or cast.
*/
if (!isascii(value)) {
if (isdigit((unsigned char)value)) {
return (value - '0');
} else {
return (-1);
}
if ((s = strchr(decdigits, value)) == NULL) {
return (-1);
}
return ((int)(s - decdigits));
}
static void
+1 -1
View File
@@ -169,7 +169,7 @@ totext_any_tsig(ARGS_TOTEXT) {
*bufp-- = 0;
*bufp-- = ' ';
do {
*bufp-- = decdigits[sigtime % 10];
*bufp-- = '0' + sigtime % 10;
sigtime /= 10;
} while (sigtime != 0);
bufp++;
+2 -6
View File
@@ -17,6 +17,7 @@
#include <limits.h>
#include <stdlib.h>
#include <isc/ascii.h>
#include <isc/net.h>
#include <isc/netdb.h>
#include <isc/once.h>
@@ -70,7 +71,6 @@ fromtext_in_wks(ARGS_FROMTEXT) {
const char *ps = NULL;
unsigned int n;
char service[32];
int i;
isc_result_t result;
REQUIRE(type == dns_rdatatype_wks);
@@ -136,11 +136,7 @@ fromtext_in_wks(ARGS_FROMTEXT) {
* case sensitive and the database is usually in lowercase.
*/
strlcpy(service, DNS_AS_STR(token), sizeof(service));
for (i = strlen(service) - 1; i >= 0; i--) {
if (isupper(service[i] & 0xff)) {
service[i] = tolower(service[i] & 0xff);
}
}
isc_ascii_strtolower(service);
port = strtol(DNS_AS_STR(token), &e, 10);
if (*e != 0 && !mygetservbyname(service, ps, &port) &&
+7 -19
View File
@@ -52,6 +52,7 @@
#include <stdbool.h>
#include <string.h>
#include <isc/ascii.h>
#include <isc/buffer.h>
#include <isc/lex.h>
#include <isc/log.h>
@@ -238,19 +239,6 @@ sdlz_log(int level, const char *fmt, ...) {
va_end(ap);
}
/*% Converts the input string to lowercase, in place. */
static void
dns_sdlz_tolower(char *str) {
unsigned int len = strlen(str);
unsigned int i;
for (i = 0; i < len; i++) {
if (str[i] >= 'A' && str[i] <= 'Z') {
str[i] += 32;
}
}
}
static unsigned int
initial_size(const char *data) {
unsigned int len = (strlen(data) / 64) + 1;
@@ -570,8 +558,8 @@ getnodedata(dns_db_t *db, const dns_name_t *name, bool create,
isorigin = dns_name_equal(name, &sdlz->common.origin);
/* make sure strings are always lowercase */
dns_sdlz_tolower(zonestr);
dns_sdlz_tolower(namestr);
isc_ascii_strtolower(zonestr);
isc_ascii_strtolower(namestr);
MAYBE_LOCK(sdlz->dlzimp);
@@ -787,7 +775,7 @@ createiterator(dns_db_t *db, unsigned int options,
sdlziter->origin = NULL;
/* make sure strings are always lowercase */
dns_sdlz_tolower(zonestr);
isc_ascii_strtolower(zonestr);
MAYBE_LOCK(sdlz->dlzimp);
result = sdlz->dlzimp->methods->allnodes(
@@ -1541,8 +1529,8 @@ dns_sdlzallowzonexfr(void *driverarg, void *dbdata, isc_mem_t *mctx,
isc_buffer_putuint8(&b2, 0);
/* make sure strings are always lowercase */
dns_sdlz_tolower(namestr);
dns_sdlz_tolower(clientstr);
isc_ascii_strtolower(namestr);
isc_ascii_strtolower(clientstr);
/* Call SDLZ driver's find zone method */
if (imp->methods->allowzonexfr != NULL) {
@@ -1651,7 +1639,7 @@ dns_sdlzfindzone(void *driverarg, void *dbdata, isc_mem_t *mctx,
isc_buffer_putuint8(&b, 0);
/* make sure strings are always lowercase */
dns_sdlz_tolower(namestr);
isc_ascii_strtolower(namestr);
/* Call SDLZ driver's find zone method */
MAYBE_LOCK(imp);
+2 -4
View File
@@ -20,6 +20,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <isc/ascii.h>
#include <isc/buffer.h>
#include <isc/parseint.h>
#include <isc/print.h>
@@ -119,13 +120,10 @@ dns_ttl_totext(uint32_t src, bool verbose, bool upcase, isc_buffer_t *target) {
/*
* The unit letter is the last character in the
* used region of the buffer.
*
* toupper() does not need its argument to be masked of cast
* here because region.base is type unsigned char *.
*/
isc_buffer_usedregion(target, &region);
region.base[region.length - 1] =
toupper(region.base[region.length - 1]);
isc_ascii_toupper(region.base[region.length - 1]);
}
return (ISC_R_SUCCESS);
}
+2
View File
@@ -6,6 +6,7 @@ libisc_ladir = $(includedir)/isc
libisc_la_HEADERS = \
include/isc/aes.h \
include/isc/align.h \
include/isc/ascii.h \
include/isc/assertions.h \
include/isc/astack.h \
include/isc/async.h \
@@ -116,6 +117,7 @@ libisc_la_SOURCES = \
netmgr/tlsdns.c \
netmgr/udp.c \
aes.c \
ascii.c \
assertions.c \
astack.c \
async.c \
+67
View File
@@ -0,0 +1,67 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* 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 <stdint.h>
#include <string.h>
#include <isc/ascii.h>
const uint8_t isc__ascii_tolower[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73,
0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83,
0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3,
0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb,
0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3,
0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb,
0xfc, 0xfd, 0xfe, 0xff
};
const uint8_t isc__ascii_toupper[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53,
0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b,
0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83,
0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3,
0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb,
0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3,
0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb,
0xfc, 0xfd, 0xfe, 0xff
};
-298
View File
@@ -24,28 +24,6 @@
#include <isc/string.h>
#include <isc/util.h>
void
isc__buffer_init(isc_buffer_t *b, void *base, unsigned int length) {
/*
* Make 'b' refer to the 'length'-byte region starting at 'base'.
* XXXDCL see the comment in buffer.h about base being const.
*/
REQUIRE(b != NULL);
ISC__BUFFER_INIT(b, base, length);
}
void
isc__buffer_initnull(isc_buffer_t *b) {
/*
* Initialize a new buffer which has no backing store. This can
* later be grown as needed and swapped in place.
*/
ISC__BUFFER_INIT(b, NULL, 0);
}
void
isc_buffer_reinit(isc_buffer_t *b, void *base, unsigned int length) {
/*
@@ -69,19 +47,6 @@ isc_buffer_reinit(isc_buffer_t *b, void *base, unsigned int length) {
b->length = length;
}
void
isc__buffer_invalidate(isc_buffer_t *b) {
/*
* Make 'b' an invalid buffer.
*/
REQUIRE(ISC_BUFFER_VALID(b));
REQUIRE(!ISC_LINK_LINKED(b, link));
REQUIRE(b->mctx == NULL);
ISC__BUFFER_INVALIDATE(b);
}
void
isc_buffer_setautorealloc(isc_buffer_t *b, bool enable) {
REQUIRE(ISC_BUFFER_VALID(b));
@@ -89,160 +54,6 @@ isc_buffer_setautorealloc(isc_buffer_t *b, bool enable) {
b->autore = enable;
}
void
isc__buffer_region(isc_buffer_t *b, isc_region_t *r) {
/*
* Make 'r' refer to the region of 'b'.
*/
REQUIRE(ISC_BUFFER_VALID(b));
REQUIRE(r != NULL);
ISC__BUFFER_REGION(b, r);
}
void
isc__buffer_usedregion(const isc_buffer_t *b, isc_region_t *r) {
/*
* Make 'r' refer to the used region of 'b'.
*/
REQUIRE(ISC_BUFFER_VALID(b));
REQUIRE(r != NULL);
ISC__BUFFER_USEDREGION(b, r);
}
void
isc__buffer_availableregion(isc_buffer_t *b, isc_region_t *r) {
/*
* Make 'r' refer to the available region of 'b'.
*/
REQUIRE(ISC_BUFFER_VALID(b));
REQUIRE(r != NULL);
ISC__BUFFER_AVAILABLEREGION(b, r);
}
void
isc__buffer_add(isc_buffer_t *b, unsigned int n) {
/*
* Increase the 'used' region of 'b' by 'n' bytes.
*/
REQUIRE(ISC_BUFFER_VALID(b));
REQUIRE(b->used + n <= b->length);
ISC__BUFFER_ADD(b, n);
}
void
isc__buffer_subtract(isc_buffer_t *b, unsigned int n) {
/*
* Decrease the 'used' region of 'b' by 'n' bytes.
*/
REQUIRE(ISC_BUFFER_VALID(b));
REQUIRE(b->used >= n);
ISC__BUFFER_SUBTRACT(b, n);
}
void
isc__buffer_clear(isc_buffer_t *b) {
/*
* Make the used region empty.
*/
REQUIRE(ISC_BUFFER_VALID(b));
ISC__BUFFER_CLEAR(b);
}
void
isc__buffer_consumedregion(isc_buffer_t *b, isc_region_t *r) {
/*
* Make 'r' refer to the consumed region of 'b'.
*/
REQUIRE(ISC_BUFFER_VALID(b));
REQUIRE(r != NULL);
ISC__BUFFER_CONSUMEDREGION(b, r);
}
void
isc__buffer_remainingregion(isc_buffer_t *b, isc_region_t *r) {
/*
* Make 'r' refer to the remaining region of 'b'.
*/
REQUIRE(ISC_BUFFER_VALID(b));
REQUIRE(r != NULL);
ISC__BUFFER_REMAININGREGION(b, r);
}
void
isc__buffer_activeregion(isc_buffer_t *b, isc_region_t *r) {
/*
* Make 'r' refer to the active region of 'b'.
*/
REQUIRE(ISC_BUFFER_VALID(b));
REQUIRE(r != NULL);
ISC__BUFFER_ACTIVEREGION(b, r);
}
void
isc__buffer_setactive(isc_buffer_t *b, unsigned int n) {
/*
* Sets the end of the active region 'n' bytes after current.
*/
REQUIRE(ISC_BUFFER_VALID(b));
REQUIRE(b->current + n <= b->used);
ISC__BUFFER_SETACTIVE(b, n);
}
void
isc__buffer_first(isc_buffer_t *b) {
/*
* Make the consumed region empty.
*/
REQUIRE(ISC_BUFFER_VALID(b));
ISC__BUFFER_FIRST(b);
}
void
isc__buffer_forward(isc_buffer_t *b, unsigned int n) {
/*
* Increase the 'consumed' region of 'b' by 'n' bytes.
*/
REQUIRE(ISC_BUFFER_VALID(b));
REQUIRE(b->current + n <= b->used);
ISC__BUFFER_FORWARD(b, n);
}
void
isc__buffer_back(isc_buffer_t *b, unsigned int n) {
/*
* Decrease the 'consumed' region of 'b' by 'n' bytes.
*/
REQUIRE(ISC_BUFFER_VALID(b));
REQUIRE(n <= b->current);
ISC__BUFFER_BACK(b, n);
}
void
isc_buffer_compact(isc_buffer_t *b) {
unsigned int length;
@@ -290,19 +101,6 @@ isc_buffer_getuint8(isc_buffer_t *b) {
return (result);
}
void
isc__buffer_putuint8(isc_buffer_t *b, uint8_t val) {
isc_result_t result;
REQUIRE(ISC_BUFFER_VALID(b));
if (b->autore) {
result = isc_buffer_reserve(&b, 1);
REQUIRE(result == ISC_R_SUCCESS);
}
REQUIRE(isc_buffer_availablelength(b) >= 1);
ISC__BUFFER_PUTUINT8(b, val);
}
uint16_t
isc_buffer_getuint16(isc_buffer_t *b) {
unsigned char *cp;
@@ -324,32 +122,6 @@ isc_buffer_getuint16(isc_buffer_t *b) {
return (result);
}
void
isc__buffer_putuint16(isc_buffer_t *b, uint16_t val) {
isc_result_t result;
REQUIRE(ISC_BUFFER_VALID(b));
if (b->autore) {
result = isc_buffer_reserve(&b, 2);
REQUIRE(result == ISC_R_SUCCESS);
}
REQUIRE(isc_buffer_availablelength(b) >= 2);
ISC__BUFFER_PUTUINT16(b, val);
}
void
isc__buffer_putuint24(isc_buffer_t *b, uint32_t val) {
isc_result_t result;
REQUIRE(ISC_BUFFER_VALID(b));
if (b->autore) {
result = isc_buffer_reserve(&b, 3);
REQUIRE(result == ISC_R_SUCCESS);
}
REQUIRE(isc_buffer_availablelength(b) >= 3);
ISC__BUFFER_PUTUINT24(b, val);
}
uint32_t
isc_buffer_getuint32(isc_buffer_t *b) {
unsigned char *cp;
@@ -373,19 +145,6 @@ isc_buffer_getuint32(isc_buffer_t *b) {
return (result);
}
void
isc__buffer_putuint32(isc_buffer_t *b, uint32_t val) {
isc_result_t result;
REQUIRE(ISC_BUFFER_VALID(b));
if (b->autore) {
result = isc_buffer_reserve(&b, 4);
REQUIRE(result == ISC_R_SUCCESS);
}
REQUIRE(isc_buffer_availablelength(b) >= 4);
ISC__BUFFER_PUTUINT32(b, val);
}
uint64_t
isc_buffer_getuint48(isc_buffer_t *b) {
unsigned char *cp;
@@ -411,63 +170,6 @@ isc_buffer_getuint48(isc_buffer_t *b) {
return (result);
}
void
isc__buffer_putuint48(isc_buffer_t *b, uint64_t val) {
isc_result_t result;
uint16_t valhi;
uint32_t vallo;
REQUIRE(ISC_BUFFER_VALID(b));
if (b->autore) {
result = isc_buffer_reserve(&b, 6);
REQUIRE(result == ISC_R_SUCCESS);
}
REQUIRE(isc_buffer_availablelength(b) >= 6);
valhi = (uint16_t)(val >> 32);
vallo = (uint32_t)(val & 0xFFFFFFFF);
ISC__BUFFER_PUTUINT16(b, valhi);
ISC__BUFFER_PUTUINT32(b, vallo);
}
void
isc__buffer_putmem(isc_buffer_t *b, const unsigned char *base,
unsigned int length) {
isc_result_t result;
REQUIRE(ISC_BUFFER_VALID(b));
if (b->autore) {
result = isc_buffer_reserve(&b, length);
REQUIRE(result == ISC_R_SUCCESS);
}
REQUIRE(isc_buffer_availablelength(b) >= length);
ISC__BUFFER_PUTMEM(b, base, length);
}
void
isc__buffer_putstr(isc_buffer_t *b, const char *source) {
unsigned int l;
unsigned char *cp;
isc_result_t result;
REQUIRE(ISC_BUFFER_VALID(b));
REQUIRE(source != NULL);
/*
* Do not use ISC__BUFFER_PUTSTR(), so strlen is only done once.
*/
l = strlen(source);
if (b->autore) {
result = isc_buffer_reserve(&b, l);
REQUIRE(result == ISC_R_SUCCESS);
}
REQUIRE(isc_buffer_availablelength(b) >= l);
cp = isc_buffer_used(b);
memmove(cp, source, l);
b->used += l;
}
void
isc_buffer_putdecint(isc_buffer_t *b, int64_t v) {
unsigned int l = 0;
+9 -37
View File
@@ -16,6 +16,7 @@
#include <stddef.h>
#include "entropy_private.h"
#include "isc/ascii.h"
#include "isc/hash.h" /* IWYU pragma: keep */
#include "isc/once.h"
#include "isc/random.h"
@@ -48,31 +49,6 @@ isc_hash_initialize(void) {
hash_initialized = true;
}
static uint8_t maptolower[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73,
0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83,
0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3,
0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb,
0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3,
0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb,
0xfc, 0xfd, 0xfe, 0xff
};
const void *
isc_hash_get_initializer(void) {
if (!hash_initialized) {
@@ -113,12 +89,10 @@ isc_hash64(const void *data, const size_t length, const bool case_sensitive) {
if (case_sensitive) {
isc_siphash24(isc_hash_key, data, length, (uint8_t *)&hval);
} else {
uint8_t input[1024];
REQUIRE(length <= 1024);
for (unsigned int i = 0; i < length; i++) {
input[i] = maptolower[((const uint8_t *)data)[i]];
}
isc_siphash24(isc_hash_key, input, length, (uint8_t *)&hval);
uint8_t lower[1024];
REQUIRE(length <= sizeof(lower));
isc_ascii_lowercopy(lower, data, length);
isc_siphash24(isc_hash_key, lower, length, (uint8_t *)&hval);
}
return (hval);
@@ -136,12 +110,10 @@ isc_hash32(const void *data, const size_t length, const bool case_sensitive) {
if (case_sensitive) {
isc_halfsiphash24(isc_hash_key, data, length, (uint8_t *)&hval);
} else {
uint8_t input[1024];
REQUIRE(length <= 1024);
for (unsigned int i = 0; i < length; i++) {
input[i] = maptolower[((const uint8_t *)data)[i]];
}
isc_halfsiphash24(isc_hash_key, input, length,
uint8_t lower[1024];
REQUIRE(length <= sizeof(lower));
isc_ascii_lowercopy(lower, data, length);
isc_halfsiphash24(isc_hash_key, lower, length,
(uint8_t *)&hval);
}
+21 -4
View File
@@ -13,7 +13,6 @@
/*! \file */
#include <ctype.h>
#include <stdbool.h>
#include <isc/buffer.h>
@@ -22,6 +21,23 @@
#include <isc/string.h>
#include <isc/util.h>
#define D ('0' - 0x0) /* ascii '0' to hex */
#define U ('A' - 0xA) /* ascii 'A' to hex */
#define L ('a' - 0xa) /* ascii 'a' to hex */
const uint8_t isc__hex_char[256] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, D, D, D, D, D, D, D, D, D, D, 0, 0, 0, 0, 0, 0, 0, U,
U, U, U, U, U, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, L, L, L, L, L, L, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
#undef D
#undef U
#undef L
#define RETERR(x) \
do { \
isc_result_t _r = (x); \
@@ -86,12 +102,13 @@ hex_decode_init(hex_decode_ctx_t *ctx, int length, isc_buffer_t *target) {
static isc_result_t
hex_decode_char(hex_decode_ctx_t *ctx, int c) {
const char *s;
uint8_t hexval;
if ((s = strchr(hex, toupper(c))) == NULL) {
hexval = isc_hex_char(c);
if (hexval == 0) {
return (ISC_R_BADHEX);
}
ctx->val[ctx->digits++] = (int)(s - hex);
ctx->val[ctx->digits++] = c - hexval;
if (ctx->digits == 2) {
unsigned char num;
+174
View File
@@ -0,0 +1,174 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* 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 <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <isc/endian.h>
/*
* ASCII case conversion
*/
extern const uint8_t isc__ascii_tolower[256];
extern const uint8_t isc__ascii_toupper[256];
/*
* Wrappers so we don't have to cast all over the place like <ctype.h>
*/
#define isc_ascii_tolower(c) isc__ascii_tolower[(uint8_t)(c)]
#define isc_ascii_toupper(c) isc__ascii_toupper[(uint8_t)(c)]
/*
* A variant tolower() implementation with no memory accesses,
* for use when the compiler is able to autovectorize.
*/
static inline uint8_t
isc__ascii_tolower1(uint8_t c) {
return (c + ('a' - 'A') * ('A' <= c && c <= 'Z'));
}
/*
* Copy `len` bytes from `src` to `dst`, converting to lower case.
*/
static inline void
isc_ascii_lowercopy(uint8_t *dst, const uint8_t *src, unsigned len) {
while (len-- > 0) {
*dst++ = isc__ascii_tolower1(*src++);
}
}
/*
* Convert a string to lower case in place
*/
static inline void
isc_ascii_strtolower(char *str) {
isc_ascii_lowercopy((uint8_t *)str, (uint8_t *)str,
(unsigned)strlen(str));
}
/*
* Convert 8 bytes to lower case, using SWAR tricks (SIMD within a register).
* Based on "Hacker's Delight" by Henry S. Warren, "searching for a value in a
* given range", p. 95. Eight bytes is wider than many labels in DNS names, so
* it does not seem worth dealing with the portability issues of wide vector
* registers. If there was a vector string load instruction (analogous to
* memove() below) the balance might be different.
*/
static inline uint64_t
isc__ascii_tolower8(uint64_t octets) {
/*
* Multiply a single-byte constant by `all_bytes` to replicate
* it to all eight bytes in a word.
*/
uint64_t all_bytes = 0x0101010101010101;
/*
* Clear the top bit of each byte to make space for a per-byte flag.
*/
uint64_t heptets = octets & (0x7F * all_bytes);
/*
* We will need to avoid going wrong if our flag bits were originally
* set, and clear calculation leftovers in our non-flag bits
*/
uint64_t is_ascii = ~octets & (0x80 * all_bytes);
/*
* To compare a heptet to `N`, we can add `0x7F - N` so that carry
* propagation will set the flag when our heptet is greater than `N`
*/
uint64_t is_gt_Z = heptets + (0x7F - 'Z') * all_bytes;
/*
* Add one for greater-than-or-equal comparison
*/
uint64_t is_ge_A = heptets + (0x80 - 'A') * all_bytes;
/*
* Now we have what we need to identify the ascii uppercase bytes
*/
uint64_t is_upper = (is_ge_A ^ is_gt_Z) & is_ascii;
/*
* Move the is_upper flag bits to bit 0x20 (which is 'a' - 'A')
* and use them to adjust each byte as required
*/
return (octets | (is_upper >> 2));
}
/*
* Helper function to do an unaligned load of 8 bytes in host byte order
*/
static inline uint64_t
isc__ascii_load8(const uint8_t *ptr) {
uint64_t bytes = 0;
memmove(&bytes, ptr, sizeof(bytes));
return (bytes);
}
/*
* Compare `len` bytes at `a` and `b` for case-insensitive equality
*/
static inline bool
isc_ascii_lowerequal(const uint8_t *a, const uint8_t *b, unsigned len) {
uint64_t a8 = 0, b8 = 0;
while (len >= 8) {
a8 = isc__ascii_tolower8(isc__ascii_load8(a));
b8 = isc__ascii_tolower8(isc__ascii_load8(b));
if (a8 != b8) {
return (false);
}
len -= 8;
a += 8;
b += 8;
}
while (len-- > 0) {
if (isc_ascii_tolower(*a++) != isc_ascii_tolower(*b++)) {
return (false);
}
}
return (true);
}
/*
* Compare `len` bytes at `a` and `b` for case-insensitive order.
* Unlike the previous functions (which do not need to care about byte
* order) here we need to ensure the comparisons are lexicographic,
* i.e. they treat the strings as big-endian numbers.
*/
static inline int
isc_ascii_lowercmp(const uint8_t *a, const uint8_t *b, unsigned len) {
uint64_t a8 = 0, b8 = 0;
while (len >= 8) {
a8 = isc__ascii_tolower8(htobe64(isc__ascii_load8(a)));
b8 = isc__ascii_tolower8(htobe64(isc__ascii_load8(b)));
if (a8 != b8) {
goto ret;
}
len -= 8;
a += 8;
b += 8;
}
while (len-- > 0) {
a8 = isc_ascii_tolower(*a++);
b8 = isc_ascii_tolower(*b++);
if (a8 != b8) {
goto ret;
}
}
ret:
if (a8 < b8) {
return (-1);
}
if (a8 > b8) {
return (+1);
}
return (0);
}
File diff suppressed because it is too large Load Diff
+20 -20
View File
@@ -60,34 +60,34 @@ typedef pthread_cond_t isc_condition_t;
#endif /* ISC_TRACK_PTHREADS_OBJECTS */
#define isc__condition_init(cond) \
{ \
int _ret = pthread_cond_init(cond, NULL); \
ERRNO_CHECK(pthread_cond_init, _ret); \
#define isc__condition_init(cond) \
{ \
int _ret = pthread_cond_init(cond, NULL); \
PTHREADS_RUNTIME_CHECK(pthread_cond_init, _ret); \
}
#define isc__condition_wait(cp, mp) \
{ \
int _ret = pthread_cond_wait(cp, mp); \
ERRNO_CHECK(pthread_cond_wait, _ret); \
#define isc__condition_wait(cp, mp) \
{ \
int _ret = pthread_cond_wait(cp, mp); \
PTHREADS_RUNTIME_CHECK(pthread_cond_wait, _ret); \
}
#define isc__condition_signal(cp) \
{ \
int _ret = pthread_cond_signal(cp); \
ERRNO_CHECK(pthread_cond_signal, _ret); \
#define isc__condition_signal(cp) \
{ \
int _ret = pthread_cond_signal(cp); \
PTHREADS_RUNTIME_CHECK(pthread_cond_signal, _ret); \
}
#define isc__condition_broadcast(cp) \
{ \
int _ret = pthread_cond_broadcast(cp); \
ERRNO_CHECK(pthread_cond_broadcast, _ret); \
#define isc__condition_broadcast(cp) \
{ \
int _ret = pthread_cond_broadcast(cp); \
PTHREADS_RUNTIME_CHECK(pthread_cond_broadcast, _ret); \
}
#define isc__condition_destroy(cp) \
{ \
int _ret = pthread_cond_destroy(cp); \
ERRNO_CHECK(pthread_cond_destroy, _ret); \
#define isc__condition_destroy(cp) \
{ \
int _ret = pthread_cond_destroy(cp); \
PTHREADS_RUNTIME_CHECK(pthread_cond_destroy, _ret); \
}
isc_result_t
+13
View File
@@ -20,6 +20,19 @@
ISC_LANG_BEGINDECLS
/*
* An `isc__hex_char` table entry is non-zero if the character is a hex digit;
* You can subtract the table entry from the character to convert the hex digit
* to its value. e.g. 'a' - isc__hex_char['a'] == 10. Unlike <ctype.h>
* isxdigit(), this saves you from needing another case analysis.
*/
extern const uint8_t isc__hex_char[256];
/*
* Wrapper so we don't have to cast all over the place like <ctype.h>
*/
#define isc_hex_char(c) isc__hex_char[(uint8_t)(c)]
/***
*** Functions
***/
+13 -13
View File
@@ -60,28 +60,28 @@ extern pthread_mutexattr_t isc__mutex_init_attr;
#define isc__mutex_init(mp) \
{ \
int _ret = pthread_mutex_init(mp, &isc__mutex_init_attr); \
ERRNO_CHECK(pthread_mutex_init, _ret); \
PTHREADS_RUNTIME_CHECK(pthread_mutex_init, _ret); \
}
#define isc__mutex_lock(mp) \
{ \
int _ret = pthread_mutex_lock(mp); \
ERRNO_CHECK(pthread_mutex_lock, _ret); \
#define isc__mutex_lock(mp) \
{ \
int _ret = pthread_mutex_lock(mp); \
PTHREADS_RUNTIME_CHECK(pthread_mutex_lock, _ret); \
}
#define isc__mutex_unlock(mp) \
{ \
int _ret = pthread_mutex_unlock(mp); \
ERRNO_CHECK(pthread_mutex_unlock, _ret); \
#define isc__mutex_unlock(mp) \
{ \
int _ret = pthread_mutex_unlock(mp); \
PTHREADS_RUNTIME_CHECK(pthread_mutex_unlock, _ret); \
}
#define isc__mutex_trylock(mp) \
((pthread_mutex_trylock(mp) == 0) ? ISC_R_SUCCESS : ISC_R_LOCKBUSY)
#define isc__mutex_destroy(mp) \
{ \
int _ret = pthread_mutex_destroy(mp); \
ERRNO_CHECK(pthread_mutex_destroy, _ret); \
#define isc__mutex_destroy(mp) \
{ \
int _ret = pthread_mutex_destroy(mp); \
PTHREADS_RUNTIME_CHECK(pthread_mutex_destroy, _ret); \
}
ISC_LANG_ENDDECLS
+20 -20
View File
@@ -127,34 +127,34 @@ typedef struct isc_rwlock isc__rwlock_t;
#endif /* USE_PTHREAD_RWLOCK */
#define isc__rwlock_init(rwl, rq, wq) \
{ \
int _ret = isc___rwlock_init(rwl, rq, wq); \
ERRNO_CHECK(isc___rwlock_init, _ret); \
#define isc__rwlock_init(rwl, rq, wq) \
{ \
int _ret = isc___rwlock_init(rwl, rq, wq); \
PTHREADS_RUNTIME_CHECK(isc___rwlock_init, _ret); \
}
#define isc__rwlock_lock(rwl, type) \
{ \
int _ret = isc___rwlock_lock(rwl, type); \
ERRNO_CHECK(isc___rwlock_lock, _ret); \
#define isc__rwlock_lock(rwl, type) \
{ \
int _ret = isc___rwlock_lock(rwl, type); \
PTHREADS_RUNTIME_CHECK(isc___rwlock_lock, _ret); \
}
#define isc__rwlock_unlock(rwl, type) \
{ \
int _ret = isc___rwlock_unlock(rwl, type); \
ERRNO_CHECK(isc___rwlock_unlock, _ret); \
#define isc__rwlock_unlock(rwl, type) \
{ \
int _ret = isc___rwlock_unlock(rwl, type); \
PTHREADS_RUNTIME_CHECK(isc___rwlock_unlock, _ret); \
}
#define isc__rwlock_downgrade(rwl) \
{ \
int _ret = isc___rwlock_downgrade(rwl); \
ERRNO_CHECK(isc___rwlock_downgrade, _ret); \
#define isc__rwlock_downgrade(rwl) \
{ \
int _ret = isc___rwlock_downgrade(rwl); \
PTHREADS_RUNTIME_CHECK(isc___rwlock_downgrade, _ret); \
}
#define isc__rwlock_destroy(rwl) \
{ \
int _ret = isc___rwlock_destroy(rwl); \
ERRNO_CHECK(isc___rwlock_destroy, _ret); \
#define isc__rwlock_destroy(rwl) \
{ \
int _ret = isc___rwlock_destroy(rwl); \
PTHREADS_RUNTIME_CHECK(isc___rwlock_destroy, _ret); \
}
int
+11 -7
View File
@@ -334,13 +334,17 @@ mock_assert(const int result, const char *const expression,
#endif /* UNIT_TESTING */
/*% Runtime check which logs the error string corresponding to errno */
#define ERRNO_CHECK(func, ret) \
if ((ret) != 0) { \
char _strerrorbuf[ISC_STRERRORSIZE]; \
strerror_r(errno, _strerrorbuf, sizeof(_strerrorbuf)); \
isc_error_fatal(__FILE__, __LINE__, "%s() failed in %s(): %s", \
#func, __func__, _strerrorbuf); \
/*%
* Runtime check which logs the error value returned by a POSIX Threads
* function and the error string that corresponds to it
*/
#define PTHREADS_RUNTIME_CHECK(func, ret) \
if ((ret) != 0) { \
char _strerrorbuf[ISC_STRERRORSIZE]; \
strerror_r(ret, _strerrorbuf, sizeof(_strerrorbuf)); \
isc_error_fatal(__FILE__, __LINE__, \
"%s(): %s() failed with error %d (%s)", \
__func__, #func, ret, _strerrorbuf); \
}
/*%
+2 -5
View File
@@ -13,9 +13,9 @@
/*! \file */
#include <ctype.h>
#include <stdbool.h>
#include <isc/ascii.h>
#include <isc/magic.h>
#include <isc/mem.h>
#include <isc/string.h>
@@ -111,7 +111,6 @@ static unsigned int
hash(const char *key, bool case_sensitive) {
const char *s;
unsigned int h = 0;
int c;
/*
* This hash function is similar to the one Ousterhout
@@ -124,9 +123,7 @@ hash(const char *key, bool case_sensitive) {
}
} else {
for (s = key; *s != '\0'; s++) {
c = *s;
c = tolower((unsigned char)c);
h += (h << 3) + c;
h += (h << 3) + isc_ascii_tolower(*s);
}
}
+4 -4
View File
@@ -58,18 +58,18 @@ isc_thread_create(isc_threadfunc_t func, isc_threadarg_t arg,
#if defined(HAVE_PTHREAD_ATTR_GETSTACKSIZE) && \
defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE)
ret = pthread_attr_getstacksize(&attr, &stacksize);
ERRNO_CHECK(pthread_attr_getstacksize, ret);
PTHREADS_RUNTIME_CHECK(pthread_attr_getstacksize, ret);
if (stacksize < THREAD_MINSTACKSIZE) {
ret = pthread_attr_setstacksize(&attr, THREAD_MINSTACKSIZE);
ERRNO_CHECK(pthread_attr_setstacksize, ret);
PTHREADS_RUNTIME_CHECK(pthread_attr_setstacksize, ret);
}
#endif /* if defined(HAVE_PTHREAD_ATTR_GETSTACKSIZE) && \
* defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE) */
ret = pthread_create(thread, &attr, isc__trampoline_run,
trampoline_arg);
ERRNO_CHECK(pthread_create, ret);
PTHREADS_RUNTIME_CHECK(pthread_create, ret);
pthread_attr_destroy(&attr);
@@ -80,7 +80,7 @@ void
isc_thread_join(isc_thread_t thread, isc_threadresult_t *result) {
int ret = pthread_join(thread, result);
ERRNO_CHECK(pthread_join, ret);
PTHREADS_RUNTIME_CHECK(pthread_join, ret);
}
void
+3 -4
View File
@@ -96,11 +96,10 @@ conv_num(const char **buf, int *dest, int llim, int ulim) {
}
do {
result *= 10;
result += *(*buf)++ - '0';
result = 10 * result + *(*buf)++ - '0';
rulim /= 10;
} while ((result * 10 <= ulim) && rulim && **buf >= '0' &&
**buf <= '9');
} while ((result * 10 <= ulim) && rulim &&
isdigit((unsigned char)**buf));
if (result < llim || result > ulim) {
return (0);
+2 -5
View File
@@ -29,10 +29,10 @@
/*! \file */
#include <ctype.h>
#include <stdbool.h>
#include <stdlib.h>
#include <isc/ascii.h>
#include <isc/assertions.h>
#include <isc/magic.h>
#include <isc/result.h>
@@ -134,7 +134,6 @@ hash(const char *key, bool case_sensitive) {
const char *s;
unsigned int h = 0;
unsigned int g;
int c;
/*
* P. J. Weinberger's hash function, adapted from p. 436 of
@@ -152,9 +151,7 @@ hash(const char *key, bool case_sensitive) {
}
} else {
for (s = key; *s != '\0'; s++) {
c = *s;
c = tolower((unsigned char)c);
h = (h << 4) + c;
h = (h << 4) + isc_ascii_tolower(*s);
if ((g = (h & 0xf0000000)) != 0) {
h = h ^ (g >> 24);
h = h ^ g;
+2 -1
View File
@@ -12,5 +12,6 @@ LDADD += \
$(LIBDNS_LIBS) \
$(LIBNS_LIBS)
SUBDIRS = libtest isc dns ns isccfg irs
SUBDIRS = libtest isc dns ns isccfg irs bench
check_PROGRAMS =
+1
View File
@@ -0,0 +1 @@
ascii
+10
View File
@@ -0,0 +1,10 @@
include $(top_srcdir)/Makefile.top
AM_CPPFLAGS += \
$(LIBISC_CFLAGS)
LDADD += \
$(LIBISC_LIBS)
noinst_PROGRAMS = \
ascii
+223
View File
@@ -0,0 +1,223 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* 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 <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <isc/ascii.h>
#include <isc/random.h>
#include <isc/time.h>
#define SIZE (1024 * 1024)
typedef void
copy_fn(void *a, void *b, unsigned len);
static void
time_it(copy_fn *copier, void *a, void *b, const char *name) {
isc_time_t start;
isc_time_now_hires(&start);
copier(a, b, SIZE);
isc_time_t finish;
isc_time_now_hires(&finish);
uint64_t microseconds = isc_time_microdiff(&finish, &start);
printf("%f for %s\n", (double)microseconds / 1000000.0, name);
}
static void
copy_raw(void *a, void *b, unsigned size) {
memmove(a, b, size);
}
static void
copy_toupper(void *va, void *vb, unsigned size) {
uint8_t *a = va, *b = vb;
while (size-- > 0) {
*a++ = isc_ascii_toupper(*b++);
}
}
static void
copy_tolower8(void *a, void *b, unsigned size) {
isc_ascii_lowercopy(a, b, size);
}
#define TOLOWER(c) ((c) + ('a' - 'A') * (((c) >= 'A') ^ ((c) > 'Z')))
static void
copy_tolower1(void *va, void *vb, unsigned size) {
for (uint8_t *a = va, *b = vb; size-- > 0; a++, b++) {
*a = TOLOWER(*b);
}
}
static bool
cmp_tolower1(void *va, void *vb, unsigned size) {
for (uint8_t *a = va, *b = vb; size-- > 0; a++, b++) {
if (TOLOWER(*a) != TOLOWER(*b)) {
return false;
}
}
return true;
}
static bool oldskool_result;
static void
cmp_oldskool(void *va, void *vb, unsigned size) {
uint8_t *a = va, *b = vb, c;
while (size > 3) {
c = isc_ascii_tolower(a[0]);
if (c != isc_ascii_tolower(b[0])) {
goto diff;
}
c = isc_ascii_tolower(a[1]);
if (c != isc_ascii_tolower(b[1])) {
goto diff;
}
c = isc_ascii_tolower(a[2]);
if (c != isc_ascii_tolower(b[2])) {
goto diff;
}
c = isc_ascii_tolower(a[3]);
if (c != isc_ascii_tolower(b[3])) {
goto diff;
}
size -= 4;
a += 4;
b += 4;
}
while (size-- > 0) {
c = isc_ascii_tolower(*a++);
if (c != isc_ascii_tolower(*b++)) {
goto diff;
}
}
oldskool_result = true;
return;
diff:
oldskool_result = false;
return;
}
static bool tolower1_result;
static void
vcmp_tolower1(void *a, void *b, unsigned size) {
tolower1_result = cmp_tolower1(a, b, size);
}
static bool swar_result;
static void
cmp_swar(void *a, void *b, unsigned size) {
swar_result = isc_ascii_lowerequal(a, b, size);
}
static bool chunk_result;
static unsigned chunk_size;
static void
cmp_chunks1(void *va, void *vb, unsigned size) {
uint8_t *a = va, *b = vb;
chunk_result = false;
while (size >= chunk_size) {
if (!cmp_tolower1(a, b, chunk_size)) {
return;
}
size -= chunk_size;
a += chunk_size;
b += chunk_size;
}
chunk_result = cmp_tolower1(a, b, size);
}
static void
cmp_chunks8(void *va, void *vb, unsigned size) {
uint8_t *a = va, *b = vb;
while (size >= chunk_size) {
if (!isc_ascii_lowerequal(a, b, chunk_size)) {
goto diff;
}
size -= chunk_size;
a += chunk_size;
b += chunk_size;
}
chunk_result = isc_ascii_lowerequal(a, b, size);
return;
diff:
chunk_result = false;
return;
}
static void
cmp_oldchunks(void *va, void *vb, unsigned size) {
uint8_t *a = va, *b = vb;
while (size >= chunk_size) {
cmp_oldskool(a, b, chunk_size);
if (!oldskool_result) {
return;
}
size -= chunk_size;
a += chunk_size;
b += chunk_size;
}
cmp_oldskool(a, b, size);
}
int
main(void) {
static uint8_t bytes[SIZE];
isc_random_buf(bytes, SIZE);
static uint8_t raw_dest[SIZE];
time_it(copy_raw, raw_dest, bytes, "memmove");
static uint8_t toupper_dest[SIZE];
time_it(copy_toupper, toupper_dest, bytes, "toupper");
static uint8_t tolower1_dest[SIZE];
time_it(copy_tolower1, tolower1_dest, bytes, "tolower1");
static uint8_t tolower8_dest[SIZE];
time_it(copy_tolower8, tolower8_dest, bytes, "tolower8");
time_it(cmp_oldskool, toupper_dest, tolower1_dest, "oldskool");
printf("-> %s\n", oldskool_result ? "same" : "WAT");
time_it(vcmp_tolower1, tolower1_dest, tolower8_dest, "tolower1");
printf("-> %s\n", tolower1_result ? "same" : "WAT");
time_it(cmp_swar, toupper_dest, tolower8_dest, "swar");
printf("-> %s\n", swar_result ? "same" : "WAT");
for (chunk_size = 3; chunk_size <= 15; chunk_size += 2) {
time_it(cmp_chunks1, toupper_dest, raw_dest, "chunks1");
printf("%u -> %s\n", chunk_size, chunk_result ? "same" : "WAT");
time_it(cmp_chunks8, toupper_dest, raw_dest, "chunks8");
printf("%u -> %s\n", chunk_size, chunk_result ? "same" : "WAT");
time_it(cmp_oldchunks, toupper_dest, raw_dest, "oldchunks");
printf("%u -> %s\n", chunk_size,
oldskool_result ? "same" : "WAT");
}
}
+6 -6
View File
@@ -61,21 +61,21 @@ ISC_RUN_TEST_IMPL(fullcompare) {
{ "", "", dns_namereln_equal, 0, 0 },
{ "foo", "", dns_namereln_subdomain, 1, 0 },
{ "", "foo", dns_namereln_contains, -1, 0 },
{ "foo", "bar", dns_namereln_none, 4, 0 },
{ "bar", "foo", dns_namereln_none, -4, 0 },
{ "foo", "bar", dns_namereln_none, 1, 0 },
{ "bar", "foo", dns_namereln_none, -1, 0 },
{ "bar.foo", "foo", dns_namereln_subdomain, 1, 1 },
{ "foo", "bar.foo", dns_namereln_contains, -1, 1 },
{ "baz.bar.foo", "bar.foo", dns_namereln_subdomain, 1, 2 },
{ "bar.foo", "baz.bar.foo", dns_namereln_contains, -1, 2 },
{ "foo.example", "bar.example", dns_namereln_commonancestor, 4,
{ "foo.example", "bar.example", dns_namereln_commonancestor, 1,
1 },
/* absolute */
{ ".", ".", dns_namereln_equal, 0, 1 },
{ "foo.", "bar.", dns_namereln_commonancestor, 4, 1 },
{ "bar.", "foo.", dns_namereln_commonancestor, -4, 1 },
{ "foo.", "bar.", dns_namereln_commonancestor, 1, 1 },
{ "bar.", "foo.", dns_namereln_commonancestor, -1, 1 },
{ "foo.example.", "bar.example.", dns_namereln_commonancestor,
4, 2 },
1, 2 },
{ "bar.foo.", "foo.", dns_namereln_subdomain, 1, 2 },
{ "foo.", "bar.foo.", dns_namereln_contains, -1, 2 },
{ "baz.bar.foo.", "bar.foo.", dns_namereln_subdomain, 1, 3 },
+1
View File
@@ -10,6 +10,7 @@ LDADD += \
$(LIBUV_LIBS)
check_PROGRAMS = \
ascii_test \
aes_test \
async_test \
buffer_test \
+179
View File
@@ -0,0 +1,179 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* 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 <ctype.h>
#include <sched.h> /* IWYU pragma: keep */
#include <setjmp.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdlib.h>
#define UNIT_TESTING
#include <cmocka.h>
#include <isc/ascii.h>
#include <tests/isc.h>
const char *same[][2] = {
{
"AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz",
"aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz",
},
{
"aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz",
"AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSTTUUVVWWXXYYZZ",
},
{
"AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSTTUUVVWWXXYYZZ",
"aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz",
},
{
"aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ",
"aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz",
},
{
"aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVxXyYzZ",
"aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvxxyyzz",
},
{
"WwW.ExAmPlE.OrG",
"wWw.eXaMpLe.oRg",
},
{
"_SIP.tcp.example.org",
"_sip.TCP.example.org",
},
{
"bind-USERS.lists.example.org",
"bind-users.lists.example.org",
},
{
"a0123456789.example.org",
"A0123456789.example.org",
},
{
"\\000.example.org",
"\\000.example.org",
},
{
"wWw.\\000.isc.org",
"www.\\000.isc.org",
},
{
"\255.example.org",
"\255.example.ORG",
}
};
struct {
const char *a, *b;
int cmp;
} diff[] = {
{ "foo", "bar", +1 },
{ "bar", "foo", -1 },
{ "foosuffix", "barsuffix", +1 },
{ "barsuffix", "foosuffix", -1 },
{ "prefixfoo", "prefixbar", +1 },
{ "prefixbar", "prefixfoo", -1 },
};
ISC_RUN_TEST_IMPL(upperlower) {
UNUSED(state);
for (size_t n = 0; n < ARRAY_SIZE(same); n++) {
const char *a = same[n][0];
const char *b = same[n][1];
for (size_t i = 0; a[i] != '\0' && b[i] != '\0'; i++) {
assert_true(isc_ascii_toupper(a[i]) == (uint8_t)a[i] ||
isc_ascii_tolower(a[i]) == (uint8_t)a[i]);
assert_true(isc_ascii_toupper(b[i]) == (uint8_t)b[i] ||
isc_ascii_tolower(b[i]) == (uint8_t)b[i]);
assert_true(isc_ascii_toupper(a[i]) ==
isc_ascii_toupper(b[i]));
assert_true(isc_ascii_tolower(a[i]) ==
isc_ascii_tolower(b[i]));
}
}
}
ISC_RUN_TEST_IMPL(lowerequal) {
for (size_t n = 0; n < ARRAY_SIZE(same); n++) {
const uint8_t *a = (void *)same[n][0];
const uint8_t *b = (void *)same[n][1];
unsigned len = (unsigned)strlen(same[n][0]);
assert_true(isc_ascii_lowerequal(a, b, len));
}
for (size_t n = 0; n < ARRAY_SIZE(diff); n++) {
const uint8_t *a = (void *)diff[n].a;
const uint8_t *b = (void *)diff[n].b;
unsigned len = (unsigned)strlen(diff[n].a);
assert_true(!isc_ascii_lowerequal(a, b, len));
}
}
ISC_RUN_TEST_IMPL(lowercmp) {
for (size_t n = 0; n < ARRAY_SIZE(same); n++) {
const uint8_t *a = (void *)same[n][0];
const uint8_t *b = (void *)same[n][1];
unsigned len = (unsigned)strlen(same[n][0]);
assert_true(isc_ascii_lowercmp(a, b, len) == 0);
}
for (size_t n = 0; n < ARRAY_SIZE(diff); n++) {
const uint8_t *a = (void *)diff[n].a;
const uint8_t *b = (void *)diff[n].b;
unsigned len = (unsigned)strlen(diff[n].a);
assert_true(isc_ascii_lowercmp(a, b, len) == diff[n].cmp);
}
}
ISC_RUN_TEST_IMPL(exhaustive) {
for (uint64_t ab = 0; ab < (1 << 16); ab++) {
uint8_t a = ab >> 8;
uint8_t b = ab & 0xFF;
uint64_t abc = tolower(a) << 8 | tolower(b);
uint64_t abi = isc_ascii_tolower(a) << 8 | isc_ascii_tolower(b);
uint64_t ab1 = isc__ascii_tolower1(a) << 8 |
isc__ascii_tolower1(b);
uint64_t ab8 = isc__ascii_tolower8(ab);
/* each byte individually matches ctype.h */
assert_int_equal(tolower(a), isc_ascii_tolower(a));
assert_int_equal(tolower(a), isc__ascii_tolower1(a));
assert_int_equal(tolower(a), isc__ascii_tolower8(a));
assert_int_equal(tolower(b), isc_ascii_tolower(b));
assert_int_equal(tolower(b), isc__ascii_tolower1(b));
assert_int_equal(tolower(b), isc__ascii_tolower8(b));
/* two lanes of SWAR match other implementations */
assert_int_equal(ab8, abc);
assert_int_equal(ab8, abi);
assert_int_equal(ab8, ab1);
/* check lack of overflow */
assert_int_equal(ab8 >> 16, 0);
/* all lanes of SWAR work */
assert_int_equal(isc__ascii_tolower8(ab << 8), abc << 8);
assert_int_equal(isc__ascii_tolower8(ab << 16), abc << 16);
assert_int_equal(isc__ascii_tolower8(ab << 24), abc << 24);
assert_int_equal(isc__ascii_tolower8(ab << 32), abc << 32);
assert_int_equal(isc__ascii_tolower8(ab << 40), abc << 40);
assert_int_equal(isc__ascii_tolower8(ab << 48), abc << 48);
}
}
ISC_TEST_LIST_START
ISC_TEST_ENTRY(upperlower)
ISC_TEST_ENTRY(lowerequal)
ISC_TEST_ENTRY(lowercmp)
ISC_TEST_ENTRY(exhaustive)
ISC_TEST_LIST_END
ISC_TEST_MAIN