mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
Merge branch '2785-resconf-timeout-retry.conf' into 'main'
Parse timeout and attempts from resolv.conf Closes #2785 See merge request isc-projects/bind9!5273
This commit is contained in:
commit
5f9d312868
7 changed files with 145 additions and 17 deletions
7
CHANGES
7
CHANGES
|
|
@ -1,3 +1,10 @@
|
|||
5693. [func] Restore support for reading 'timeout' and 'attempts'
|
||||
options from /etc/resolv.conf, and use their values
|
||||
in dig, host and nslookup. (Previously this was
|
||||
supported by liblwres, and was still mentioned
|
||||
in man pages, but had stopped working after liblwres
|
||||
was deprecated in favor of libirs.) [GL #2785]
|
||||
|
||||
5692. [bug] Fix a rare crash in the DoH code caused by
|
||||
detaching from an HTTP/2 session handle too early when
|
||||
sending data. [GL #2851]
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ isc_sockaddr_t localaddr;
|
|||
isc_refcount_t sendcount = ATOMIC_VAR_INIT(0);
|
||||
isc_refcount_t recvcount = ATOMIC_VAR_INIT(0);
|
||||
int ndots = -1;
|
||||
int tries = 3;
|
||||
int tries = -1;
|
||||
int lookup_counter = 0;
|
||||
|
||||
static char servercookie[256];
|
||||
|
|
@ -1276,6 +1276,17 @@ setup_system(bool ipv4only, bool ipv6only) {
|
|||
ndots = irs_resconf_getndots(resconf);
|
||||
debug("ndots is %d.", ndots);
|
||||
}
|
||||
if (timeout == 0) {
|
||||
timeout = irs_resconf_gettimeout(resconf);
|
||||
debug("timeout is %d.", timeout);
|
||||
}
|
||||
if (tries == -1) {
|
||||
tries = irs_resconf_getattempts(resconf);
|
||||
if (tries == 0) {
|
||||
tries = 3;
|
||||
}
|
||||
debug("retries is %d.", tries);
|
||||
}
|
||||
|
||||
/* If user doesn't specify server use nameservers from resolv.conf. */
|
||||
if (ISC_LIST_EMPTY(server_list)) {
|
||||
|
|
|
|||
|
|
@ -115,4 +115,24 @@ irs_resconf_getndots(irs_resconf_t *conf);
|
|||
*\li 'conf' is a valid resconf object.
|
||||
*/
|
||||
|
||||
unsigned int
|
||||
irs_resconf_getattempts(irs_resconf_t *conf);
|
||||
/*%<
|
||||
* Return the 'attempts' value stored in 'conf'.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'conf' is a valid resconf object.
|
||||
*/
|
||||
|
||||
unsigned int
|
||||
irs_resconf_gettimeout(irs_resconf_t *conf);
|
||||
/*%<
|
||||
* Return the 'timeout' value stored in 'conf'.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'conf' is a valid resconf object.
|
||||
*/
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
|
|
|||
|
|
@ -74,6 +74,13 @@
|
|||
#define RESCONFMAXLINELEN 256U /*%< max size of a line */
|
||||
#define RESCONFMAXSORTLIST 10U /*%< max 10 */
|
||||
|
||||
#define CHECK(op) \
|
||||
do { \
|
||||
result = (op); \
|
||||
if (result != ISC_R_SUCCESS) \
|
||||
goto cleanup; \
|
||||
} while (0)
|
||||
|
||||
/*!
|
||||
* configuration data structure
|
||||
*/
|
||||
|
|
@ -108,6 +115,10 @@ struct irs_resconf {
|
|||
uint8_t resdebug;
|
||||
/*%< set to n in 'options ndots:n' */
|
||||
uint8_t ndots;
|
||||
/*%< set to n in 'options attempts:n' */
|
||||
uint8_t attempts;
|
||||
/*%< set to n in 'options timeout:n' */
|
||||
uint8_t timeout;
|
||||
};
|
||||
|
||||
static isc_result_t
|
||||
|
|
@ -165,8 +176,8 @@ eatwhite(FILE *fp) {
|
|||
*/
|
||||
static int
|
||||
getword(FILE *fp, char *buffer, size_t size) {
|
||||
char *p = NULL;
|
||||
int ch;
|
||||
char *p;
|
||||
|
||||
REQUIRE(buffer != NULL);
|
||||
REQUIRE(size > 0U);
|
||||
|
|
@ -446,11 +457,26 @@ resconf_parsesortlist(irs_resconf_t *conf, FILE *fp) {
|
|||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
resconf_optionnumber(const char *word, uint8_t *number) {
|
||||
char *p;
|
||||
long n;
|
||||
|
||||
n = strtol(word, &p, 10);
|
||||
if (*p != '\0') { /* Bad string. */
|
||||
return (ISC_R_UNEXPECTEDTOKEN);
|
||||
}
|
||||
if (n < 0 || n > 0xff) { /* Out of range. */
|
||||
return (ISC_R_RANGE);
|
||||
}
|
||||
*number = n;
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
resconf_parseoption(irs_resconf_t *conf, FILE *fp) {
|
||||
int delim;
|
||||
long ndots;
|
||||
char *p;
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
char word[RESCONFMAXLINELEN];
|
||||
|
||||
delim = getword(fp, word, sizeof(word));
|
||||
|
|
@ -462,14 +488,11 @@ resconf_parseoption(irs_resconf_t *conf, FILE *fp) {
|
|||
if (strcmp("debug", word) == 0) {
|
||||
conf->resdebug = 1;
|
||||
} else if (strncmp("ndots:", word, 6) == 0) {
|
||||
ndots = strtol(word + 6, &p, 10);
|
||||
if (*p != '\0') { /* Bad string. */
|
||||
return (ISC_R_UNEXPECTEDTOKEN);
|
||||
}
|
||||
if (ndots < 0 || ndots > 0xff) { /* Out of range. */
|
||||
return (ISC_R_RANGE);
|
||||
}
|
||||
conf->ndots = (uint8_t)ndots;
|
||||
CHECK(resconf_optionnumber(word + 6, &conf->ndots));
|
||||
} else if (strncmp("attempts:", word, 9) == 0) {
|
||||
CHECK(resconf_optionnumber(word + 9, &conf->attempts));
|
||||
} else if (strncmp("timeout:", word, 8) == 0) {
|
||||
CHECK(resconf_optionnumber(word + 8, &conf->timeout));
|
||||
}
|
||||
|
||||
if (delim == EOF || delim == '\n') {
|
||||
|
|
@ -479,7 +502,8 @@ resconf_parseoption(irs_resconf_t *conf, FILE *fp) {
|
|||
}
|
||||
}
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
cleanup:
|
||||
return (result);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
|
|
@ -521,6 +545,8 @@ irs_resconf_load(isc_mem_t *mctx, const char *filename, irs_resconf_t **confp) {
|
|||
conf->sortlistnxt = 0;
|
||||
conf->resdebug = 0;
|
||||
conf->ndots = 1;
|
||||
conf->attempts = 3;
|
||||
conf->timeout = 0;
|
||||
for (i = 0; i < RESCONFMAXSEARCH; i++) {
|
||||
conf->search[i] = NULL;
|
||||
}
|
||||
|
|
@ -669,3 +695,17 @@ irs_resconf_getndots(irs_resconf_t *conf) {
|
|||
|
||||
return ((unsigned int)conf->ndots);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
irs_resconf_getattempts(irs_resconf_t *conf) {
|
||||
REQUIRE(IRS_RESCONF_VALID(conf));
|
||||
|
||||
return ((unsigned int)conf->attempts);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
irs_resconf_gettimeout(irs_resconf_t *conf) {
|
||||
REQUIRE(IRS_RESCONF_VALID(conf));
|
||||
|
||||
return ((unsigned int)conf->timeout);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,43 @@ setup_test(void) {
|
|||
assert_return_code(chdir(TESTS_DIR), 0);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
check_number(unsigned int n, unsigned int expected) {
|
||||
return ((n == expected) ? ISC_R_SUCCESS : ISC_R_BADNUMBER);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
check_attempts(irs_resconf_t *resconf) {
|
||||
return (check_number(irs_resconf_getattempts(resconf), 4));
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
check_timeout(irs_resconf_t *resconf) {
|
||||
return (check_number(irs_resconf_gettimeout(resconf), 1));
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
check_ndots(irs_resconf_t *resconf) {
|
||||
return (check_number(irs_resconf_getndots(resconf), 2));
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
check_options(irs_resconf_t *resconf) {
|
||||
if (irs_resconf_getattempts(resconf) != 3) {
|
||||
return ISC_R_BADNUMBER; /* default value only */
|
||||
}
|
||||
|
||||
if (irs_resconf_getndots(resconf) != 2) {
|
||||
return ISC_R_BADNUMBER;
|
||||
}
|
||||
|
||||
if (irs_resconf_gettimeout(resconf) != 1) {
|
||||
return ISC_R_BADNUMBER;
|
||||
}
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
/* test irs_resconf_load() */
|
||||
static void
|
||||
irs_resconf_load_test(void **state) {
|
||||
|
|
@ -61,15 +98,18 @@ irs_resconf_load_test(void **state) {
|
|||
ISC_R_SUCCESS },
|
||||
{ "testdata/nameserver-v6-scoped.conf", ISC_R_SUCCESS, NULL,
|
||||
ISC_R_SUCCESS },
|
||||
{ "testdata/options-attempts.conf", ISC_R_SUCCESS,
|
||||
check_attempts, ISC_R_SUCCESS },
|
||||
{ "testdata/options-debug.conf", ISC_R_SUCCESS, NULL,
|
||||
ISC_R_SUCCESS },
|
||||
{ "testdata/options-ndots.conf", ISC_R_SUCCESS, NULL,
|
||||
{ "testdata/options-ndots.conf", ISC_R_SUCCESS, check_ndots,
|
||||
ISC_R_SUCCESS },
|
||||
{ "testdata/options-timeout.conf", ISC_R_SUCCESS, NULL,
|
||||
{ "testdata/options-timeout.conf", ISC_R_SUCCESS, check_timeout,
|
||||
ISC_R_SUCCESS },
|
||||
{ "testdata/options-unknown.conf", ISC_R_SUCCESS, NULL,
|
||||
ISC_R_SUCCESS },
|
||||
{ "testdata/options.conf", ISC_R_SUCCESS, NULL, ISC_R_SUCCESS },
|
||||
{ "testdata/options.conf", ISC_R_SUCCESS, check_options,
|
||||
ISC_R_SUCCESS },
|
||||
{ "testdata/options-bad-ndots.conf", ISC_R_RANGE, NULL,
|
||||
ISC_R_SUCCESS },
|
||||
{ "testdata/options-empty.conf", ISC_R_UNEXPECTEDEND, NULL,
|
||||
|
|
|
|||
10
lib/irs/tests/testdata/options-attempts.conf
vendored
Normal file
10
lib/irs/tests/testdata/options-attempts.conf
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
#
|
||||
# See the COPYRIGHT file distributed with this work for additional
|
||||
# information regarding copyright ownership.
|
||||
|
||||
options attempts:4
|
||||
2
lib/irs/tests/testdata/options-ndots.conf
vendored
2
lib/irs/tests/testdata/options-ndots.conf
vendored
|
|
@ -7,4 +7,4 @@
|
|||
# See the COPYRIGHT file distributed with this work for additional
|
||||
# information regarding copyright ownership.
|
||||
|
||||
option ndots:2
|
||||
options ndots:2
|
||||
|
|
|
|||
Loading…
Reference in a new issue