Compare commits
23
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fb7846bf2e | ||
|
|
00e3c8fe1a | ||
|
|
9683439d73 | ||
|
|
b5b147864f | ||
|
|
022bb06264 | ||
|
|
68029bfc9d | ||
|
|
21a383a8fd | ||
|
|
27a561273e | ||
|
|
db3590e0b7 | ||
|
|
d8053785b0 | ||
|
|
258a896a0c | ||
|
|
eb68baffd9 | ||
|
|
ac487af09e | ||
|
|
f820ef49bf | ||
|
|
8b9dba53dd | ||
|
|
cdfe8f23c2 | ||
|
|
2ae81024df | ||
|
|
7b71b1020f | ||
|
|
37cdd6b51d | ||
|
|
3b1c80fd0f | ||
|
|
a1ae24d9ae | ||
|
|
3239875a8a | ||
|
|
fa610c0d1b |
+6
-2
@@ -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.
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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; };
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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."
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
@@ -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
@@ -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:
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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++;
|
||||
|
||||
@@ -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
@@ -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
@@ -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, ®ion);
|
||||
region.base[region.length - 1] =
|
||||
toupper(region.base[region.length - 1]);
|
||||
isc_ascii_toupper(region.base[region.length - 1]);
|
||||
}
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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
|
||||
};
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
+538
-578
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 =
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
ascii
|
||||
@@ -0,0 +1,10 @@
|
||||
include $(top_srcdir)/Makefile.top
|
||||
|
||||
AM_CPPFLAGS += \
|
||||
$(LIBISC_CFLAGS)
|
||||
|
||||
LDADD += \
|
||||
$(LIBISC_LIBS)
|
||||
|
||||
noinst_PROGRAMS = \
|
||||
ascii
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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 },
|
||||
|
||||
@@ -10,6 +10,7 @@ LDADD += \
|
||||
$(LIBUV_LIBS)
|
||||
|
||||
check_PROGRAMS = \
|
||||
ascii_test \
|
||||
aes_test \
|
||||
async_test \
|
||||
buffer_test \
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user