From 2c7c69485883ab0f408cf2f8cdcc4617462d68ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20B=C5=99ezina?= Date: Tue, 11 Jun 2019 13:37:23 +0200 Subject: [PATCH 57/57] failover: add dns_resolver_server_timeout option Resolves: https://pagure.io/SSSD/sssd/issue/3217 Reviewed-by: Jakub Hrozek Reviewed-by: Sumit Bose (cherry picked with fixes from commit 99e2a107f01c625cb59cb88589db87294176d6c6) --- src/config/SSSDConfig/__init__.py.in | 1 + src/config/SSSDConfigTest.py | 2 ++ src/config/cfg_rules.ini | 1 + src/config/etc/sssd.api.conf | 1 + src/man/include/failover.xml | 17 ++++++++++++++++- src/providers/data_provider.h | 1 + src/providers/data_provider_fo.c | 3 +++ src/resolv/async_resolv.c | 10 ++++++---- src/resolv/async_resolv.h | 2 +- src/tests/cmocka/test_fo_srv.c | 4 ++-- src/tests/cmocka/test_resolv_fake.c | 2 +- src/tests/fail_over-tests.c | 2 +- src/tests/resolv-tests.c | 2 +- 13 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in index f3c6cfebf..1aa93f8cf 100644 --- a/src/config/SSSDConfig/__init__.py.in +++ b/src/config/SSSDConfig/__init__.py.in @@ -170,6 +170,7 @@ option_strings = { 'entry_cache_timeout' : _('Entry cache timeout length (seconds)'), 'lookup_family_order' : _('Restrict or prefer a specific address family when performing DNS lookups'), 'account_cache_expiration' : _('How long to keep cached entries after last successful login (days)'), + 'dns_resolver_server_timeout' : _('How long should SSSD talk to single DNS server before trying next server (miliseconds)'), 'dns_resolver_op_timeout' : _('How long should keep trying to resolve single DNS query (seconds)'), 'dns_resolver_timeout' : _('How long to wait for replies from DNS when resolving servers (seconds)'), 'dns_discovery_domain' : _('The domain part of service discovery DNS query'), diff --git a/src/config/SSSDConfigTest.py b/src/config/SSSDConfigTest.py index 979b1806f..d484e527e 100755 --- a/src/config/SSSDConfigTest.py +++ b/src/config/SSSDConfigTest.py @@ -608,6 +608,7 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase): 'refresh_expired_interval', 'lookup_family_order', 'account_cache_expiration', + 'dns_resolver_server_timeout', 'dns_resolver_op_timeout', 'dns_resolver_timeout', 'dns_discovery_domain', @@ -980,6 +981,7 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase): 'refresh_expired_interval', 'account_cache_expiration', 'lookup_family_order', + 'dns_resolver_server_timeout', 'dns_resolver_op_timeout', 'dns_resolver_timeout', 'dns_discovery_domain', diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini index 79e366875..e8ea13081 100644 --- a/src/config/cfg_rules.ini +++ b/src/config/cfg_rules.ini @@ -367,6 +367,7 @@ option = account_cache_expiration option = pwd_expiration_warning option = filter_users option = filter_groups +option = dns_resolver_server_timeout option = dns_resolver_op_timeout option = dns_resolver_timeout option = dns_discovery_domain diff --git a/src/config/etc/sssd.api.conf b/src/config/etc/sssd.api.conf index 355c1fc9b..a771a1148 100644 --- a/src/config/etc/sssd.api.conf +++ b/src/config/etc/sssd.api.conf @@ -170,6 +170,7 @@ account_cache_expiration = int, None, false pwd_expiration_warning = int, None, false filter_users = list, str, false filter_groups = list, str, false +dns_resolver_server_timeout = int, None, false dns_resolver_op_timeout = int, None, false dns_resolver_timeout = int, None, false dns_discovery_domain = str, None, false diff --git a/src/man/include/failover.xml b/src/man/include/failover.xml index 7b451d831..f2a01b933 100644 --- a/src/man/include/failover.xml +++ b/src/man/include/failover.xml @@ -71,6 +71,20 @@ , manual page. + + + dns_resolver_server_timeout + + + + Time in milliseconds that sets how long would SSSD + talk to a single DNS server before trying next one. + + + Default: 2000 + + + dns_resolver_op_timeout @@ -111,7 +125,8 @@ ldap_opt_timeout> timeout should be set to a larger value than dns_resolver_timeout which in turn should be set to a larger value than - dns_resolver_op_timeout. + dns_resolver_op_timeout which should be larger + than dns_resolver_server_timeout. diff --git a/src/providers/data_provider.h b/src/providers/data_provider.h index d30d81bda..e8568993a 100644 --- a/src/providers/data_provider.h +++ b/src/providers/data_provider.h @@ -328,6 +328,7 @@ enum dp_res_opts { DP_RES_OPT_FAMILY_ORDER, DP_RES_OPT_RESOLVER_TIMEOUT, DP_RES_OPT_RESOLVER_OP_TIMEOUT, + DP_RES_OPT_RESOLVER_SERVER_TIMEOUT, DP_RES_OPT_DNS_DOMAIN, DP_RES_OPTS /* attrs counter */ diff --git a/src/providers/data_provider_fo.c b/src/providers/data_provider_fo.c index 6e375147d..0cdb97323 100644 --- a/src/providers/data_provider_fo.c +++ b/src/providers/data_provider_fo.c @@ -835,6 +835,7 @@ static struct dp_option dp_res_default_opts[] = { { "lookup_family_order", DP_OPT_STRING, { "ipv4_first" }, NULL_STRING }, { "dns_resolver_timeout", DP_OPT_NUMBER, { .number = 6 }, NULL_NUMBER }, { "dns_resolver_op_timeout", DP_OPT_NUMBER, { .number = 6 }, NULL_NUMBER }, + { "dns_resolver_server_timeout", DP_OPT_NUMBER, { .number = 2000 }, NULL_NUMBER }, { "dns_discovery_domain", DP_OPT_STRING, NULL_STRING, NULL_STRING }, DP_OPTION_TERMINATOR }; @@ -896,6 +897,8 @@ errno_t be_res_init(struct be_ctx *ctx) ret = resolv_init(ctx, ctx->ev, dp_opt_get_int(ctx->be_res->opts, DP_RES_OPT_RESOLVER_OP_TIMEOUT), + dp_opt_get_int(ctx->be_res->opts, + DP_RES_OPT_RESOLVER_SERVER_TIMEOUT), &ctx->be_res->resolv); if (ret != EOK) { talloc_zfree(ctx->be_res); diff --git a/src/resolv/async_resolv.c b/src/resolv/async_resolv.c index bb2701154..b833d7211 100644 --- a/src/resolv/async_resolv.c +++ b/src/resolv/async_resolv.c @@ -60,8 +60,6 @@ #define DNS_RR_LEN(r) DNS__16BIT((r) + 8) #define DNS_RR_TTL(r) DNS__32BIT((r) + 4) -#define RESOLV_TIMEOUTMS 2000 - enum host_database default_host_dbs[] = { DB_FILES, DB_DNS, DB_SENTINEL }; struct fd_watch { @@ -83,6 +81,9 @@ struct resolv_ctx { /* Time in milliseconds before canceling a DNS request */ int timeout; + /* Time in milliseconds for communication with single DNS server. */ + int ares_timeout; + /* The timeout watcher periodically calls ares_process_fd() to check * if our pending requests didn't timeout. */ int pending_requests; @@ -423,7 +424,7 @@ recreate_ares_channel(struct resolv_ctx *ctx) */ options.sock_state_cb = fd_event; options.sock_state_cb_data = ctx; - options.timeout = RESOLV_TIMEOUTMS; + options.timeout = ctx->ares_timeout; /* Only affects ares_gethostbyname */ options.lookups = discard_const("f"); options.tries = 1; @@ -450,7 +451,7 @@ recreate_ares_channel(struct resolv_ctx *ctx) int resolv_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx, - int timeout, struct resolv_ctx **ctxp) + int timeout, int ares_timeout, struct resolv_ctx **ctxp) { int ret; struct resolv_ctx *ctx; @@ -467,6 +468,7 @@ resolv_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx, ctx->ev_ctx = ev_ctx; ctx->timeout = timeout; + ctx->ares_timeout = ares_timeout; ret = recreate_ares_channel(ctx); if (ret != EOK) { diff --git a/src/resolv/async_resolv.h b/src/resolv/async_resolv.h index 90ed03707..d83a7be44 100644 --- a/src/resolv/async_resolv.h +++ b/src/resolv/async_resolv.h @@ -52,7 +52,7 @@ struct resolv_ctx; int resolv_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx, - int timeout, struct resolv_ctx **ctxp); + int timeout, int ares_timeout, struct resolv_ctx **ctxp); void resolv_reread_configuration(struct resolv_ctx *ctx); diff --git a/src/tests/cmocka/test_fo_srv.c b/src/tests/cmocka/test_fo_srv.c index a11ebbb54..c13cf3a69 100644 --- a/src/tests/cmocka/test_fo_srv.c +++ b/src/tests/cmocka/test_fo_srv.c @@ -49,7 +49,7 @@ struct resolv_ctx { /* mock resolver interface. The resolver test is separate */ int resolv_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx, - int timeout, struct resolv_ctx **ctxp) + int timeout, int ares_timeout, struct resolv_ctx **ctxp) { *ctxp = talloc(mem_ctx, struct resolv_ctx); return EOK; @@ -230,7 +230,7 @@ static int test_fo_setup(void **state) assert_non_null(test_ctx->ctx); ret = resolv_init(test_ctx, test_ctx->ctx->ev, - TEST_RESOLV_TIMEOUT, &test_ctx->resolv); + TEST_RESOLV_TIMEOUT, 2000, &test_ctx->resolv); assert_non_null(test_ctx->resolv); memset(&fopts, 0, sizeof(fopts)); diff --git a/src/tests/cmocka/test_resolv_fake.c b/src/tests/cmocka/test_resolv_fake.c index 4cb3d4027..0f4011a39 100644 --- a/src/tests/cmocka/test_resolv_fake.c +++ b/src/tests/cmocka/test_resolv_fake.c @@ -240,7 +240,7 @@ static int test_resolv_fake_setup(void **state) assert_non_null(test_ctx->ctx); ret = resolv_init(test_ctx, test_ctx->ctx->ev, - TEST_DEFAULT_TIMEOUT, &test_ctx->resolv); + TEST_DEFAULT_TIMEOUT, 2000, &test_ctx->resolv); assert_int_equal(ret, EOK); *state = test_ctx; diff --git a/src/tests/fail_over-tests.c b/src/tests/fail_over-tests.c index 5312b2772..b2269ef3b 100644 --- a/src/tests/fail_over-tests.c +++ b/src/tests/fail_over-tests.c @@ -73,7 +73,7 @@ setup_test(void) fail("Could not init tevent context"); } - ret = resolv_init(ctx, ctx->ev, 5, &ctx->resolv); + ret = resolv_init(ctx, ctx->ev, 5, 2000, &ctx->resolv); if (ret != EOK) { talloc_free(ctx); fail("Could not init resolv context"); diff --git a/src/tests/resolv-tests.c b/src/tests/resolv-tests.c index 4a2b3b904..bc4cd7cc1 100644 --- a/src/tests/resolv-tests.c +++ b/src/tests/resolv-tests.c @@ -76,7 +76,7 @@ static int setup_resolv_test(int timeout, struct resolv_test_ctx **ctx) return EFAULT; } - ret = resolv_init(test_ctx, test_ctx->ev, timeout, &test_ctx->resolv); + ret = resolv_init(test_ctx, test_ctx->ev, timeout, 2000, &test_ctx->resolv); if (ret != EOK) { fail("Could not init resolv context"); talloc_free(test_ctx); -- 2.21.3