>From d2c804e463f21851cc14fa62b28a9b669c0e2e2e Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Mon, 25 Mar 2013 22:54:48 +0100 Subject: [PATCH 1/2] Init failover with be_res options --- Makefile.am | 1 + src/confdb/confdb.h | 4 - src/providers/data_provider.h | 12 +++ src/providers/data_provider_fo.c | 127 ++++++++++++++++++-------- src/providers/dp_backend.h | 12 ++- src/providers/ipa/ipa_dyndns.c | 27 ++---- src/providers/ldap/sdap_async_sudo_hostinfo.c | 29 +----- src/resolv/async_resolv.c | 41 --------- src/resolv/async_resolv.h | 5 - 9 files changed, 126 insertions(+), 132 deletions(-) diff --git a/Makefile.am b/Makefile.am index fd7eb27355083cf6d43fcafb392029aaf3419120..5039cf4809a42e0cf235dd2f492b97b5531e9f2d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1042,6 +1042,7 @@ simple_access_tests_SOURCES = \ src/providers/simple/simple_access_check.c \ src/providers/data_provider_be.c \ src/providers/data_provider_fo.c \ + src/providers/data_provider_opts.c \ src/providers/data_provider_callbacks.c \ $(SSSD_FAILOVER_OBJ) simple_access_tests_CFLAGS = \ diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h index c1b9253497a04d04242bce51cdee02d9517012be..1d9647394ce59f12f59d55f22c6d42e669c39a11 100644 --- a/src/confdb/confdb.h +++ b/src/confdb/confdb.h @@ -153,10 +153,6 @@ #define CONFDB_DOMAIN_MPG "magic_private_groups" #define CONFDB_DOMAIN_FQ "use_fully_qualified_names" #define CONFDB_DOMAIN_ENTRY_CACHE_TIMEOUT "entry_cache_timeout" -#define CONFDB_DOMAIN_RESOLV_TIMEOUT "dns_resolver_timeout" -#define CONFDB_DOMAIN_RESOLV_OP_TIMEOUT "dns_resolver_op_timeout" -#define CONFDB_DOMAIN_DNS_DISCOVERY_NAME "dns_discovery_domain" -#define CONFDB_DOMAIN_FAMILY_ORDER "lookup_family_order" #define CONFDB_DOMAIN_ACCOUNT_CACHE_EXPIRATION "account_cache_expiration" #define CONFDB_DOMAIN_OVERRIDE_GID "override_gid" #define CONFDB_DOMAIN_CASE_SENSITIVE "case_sensitive" diff --git a/src/providers/data_provider.h b/src/providers/data_provider.h index 8e475d229c908b122c9d853b207bff82072df18b..3b7d3c5f9de22392030ac430aad7800899f80e6c 100644 --- a/src/providers/data_provider.h +++ b/src/providers/data_provider.h @@ -304,4 +304,16 @@ int _dp_opt_set_bool(struct dp_option *opts, int id, #define dp_opt_set_int(o, i, v) _dp_opt_set_int(o, i, v, __FUNCTION__) #define dp_opt_set_bool(o, i, v) _dp_opt_set_bool(o, i, v, __FUNCTION__) +/* Generic Data Provider options */ + +/* Resolver DP options */ +enum dp_res_opts { + DP_RES_OPT_FAMILY_ORDER, + DP_RES_OPT_RESOLVER_TIMEOUT, + DP_RES_OPT_RESOLVER_OP_TIMEOUT, + DP_RES_OPT_DNS_DOMAIN, + + DP_RES_OPTS /* attrs counter */ +}; + #endif /* __DATA_PROVIDER_ */ diff --git a/src/providers/data_provider_fo.c b/src/providers/data_provider_fo.c index 69ade47b932406f05d5e566daec0ae80582dd77d..04944e52a525b7efa7dc7f542ba47bd5685b2a27 100644 --- a/src/providers/data_provider_fo.c +++ b/src/providers/data_provider_fo.c @@ -51,7 +51,7 @@ struct be_svc_data { struct be_failover_ctx { struct fo_ctx *fo_ctx; - struct resolv_ctx *resolv; + struct be_resolv_ctx *be_res; struct be_svc_data *svcs; struct tevent_timer *primary_server_handler; @@ -67,24 +67,11 @@ int be_fo_is_srv_identifier(const char *server) static int be_fo_get_options(struct be_ctx *ctx, struct fo_options *opts) { - errno_t ret; - - ret = confdb_get_int(ctx->cdb, ctx->conf_path, - CONFDB_DOMAIN_RESOLV_TIMEOUT, - FO_DEFAULT_SVC_TIMEOUT, - &opts->service_resolv_timeout); - if (ret != EOK) { - return ret; - } - + opts->service_resolv_timeout = dp_opt_get_int(ctx->be_res->opts, + DP_RES_OPT_RESOLVER_OP_TIMEOUT); opts->retry_timeout = 30; opts->srv_retry_timeout = 14400; - - ret = resolv_get_family_order(ctx->cdb, ctx->conf_path, - &opts->family_order); - if (ret != EOK) { - return ret; - } + opts->family_order = ctx->be_res->family_order; return EOK; } @@ -92,7 +79,6 @@ static int be_fo_get_options(struct be_ctx *ctx, int be_init_failover(struct be_ctx *ctx) { int ret; - int resolv_timeout; struct fo_options fopts; if (ctx->be_fo != NULL) { @@ -104,18 +90,14 @@ int be_init_failover(struct be_ctx *ctx) return ENOMEM; } - ret = confdb_get_int(ctx->cdb, ctx->conf_path, - CONFDB_DOMAIN_RESOLV_OP_TIMEOUT, - RESOLV_DEFAULT_TIMEOUT, &resolv_timeout); - if (ret != EOK) { - return ret; - } - - ret = resolv_init(ctx, ctx->ev, resolv_timeout, &ctx->be_fo->resolv); + ret = be_res_init(ctx); if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, + ("fatal error initializing resolver context\n")); talloc_zfree(ctx->be_fo); return ret; } + ctx->be_fo->be_res = ctx->be_res; ret = be_fo_get_options(ctx, &fopts); if (ret != EOK) { @@ -259,7 +241,7 @@ int be_fo_add_srv_server(struct be_ctx *ctx, bool proto_fallback, void *user_data) { struct be_svc_data *svc; - char *domain; + const char *domain; int ret; int i; @@ -268,13 +250,9 @@ int be_fo_add_srv_server(struct be_ctx *ctx, return ENOENT; } - ret = confdb_get_string(ctx->cdb, svc, ctx->conf_path, - CONFDB_DOMAIN_DNS_DISCOVERY_NAME, - default_discovery_domain, &domain); - if (ret != EOK) { - DEBUG(1, ("Failed reading %s from confdb\n", - CONFDB_DOMAIN_DNS_DISCOVERY_NAME)); - return ret; + domain = dp_opt_get_string(ctx->be_res->opts, DP_RES_OPT_DNS_DOMAIN); + if (!domain) { + domain = default_discovery_domain; } /* Add the first protocol as the primary lookup */ @@ -383,7 +361,7 @@ be_primary_server_timeout(struct tevent_context *ev, DEBUG(SSSDBG_TRACE_FUNC, ("Looking for primary server!\n")); subreq = fo_resolve_service_send(ctx->bctx, ctx->ev, - ctx->bctx->be_fo->resolv, + ctx->bctx->be_fo->be_res->resolv, ctx->bctx->be_fo->fo_ctx, ctx->svc->fo_service); if (subreq == NULL) { @@ -512,7 +490,7 @@ struct tevent_req *be_resolve_server_send(TALLOC_CTX *memctx, state->first_try = first_try; subreq = fo_resolve_service_send(state, ev, - ctx->be_fo->resolv, + ctx->be_fo->be_res->resolv, ctx->be_fo->fo_ctx, svc->fo_service); if (!subreq) { @@ -601,7 +579,7 @@ errno_t be_resolve_server_process(struct tevent_req *subreq, /* now try next one */ DEBUG(SSSDBG_TRACE_LIBS, ("Trying with the next one!\n")); subreq = fo_resolve_service_send(state, state->ev, - state->ctx->be_fo->resolv, + state->ctx->be_fo->be_res->resolv, state->ctx->be_fo->fo_ctx, state->svc->fo_service); if (!subreq) { @@ -737,3 +715,78 @@ void be_fo_set_port_status(struct be_ctx *ctx, be_svc->first_resolved = NULL; } } + +/* Resolver back end interface */ +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 = 5 }, NULL_NUMBER }, + { "dns_resolver_op_timeout", DP_OPT_NUMBER, { .number = 5 }, NULL_NUMBER }, + { "dns_discovery_domain", DP_OPT_STRING, NULL_STRING, NULL_STRING }, + DP_OPTION_TERMINATOR +}; + +static errno_t be_res_get_opts(struct be_resolv_ctx *res_ctx, + struct confdb_ctx *cdb, + const char *conf_path) +{ + errno_t ret; + const char *str_family; + + ret = dp_get_options(res_ctx, cdb, conf_path, + dp_res_default_opts, + DP_RES_OPTS, + &res_ctx->opts); + if (ret != EOK) { + return ret; + } + + str_family = dp_opt_get_string(res_ctx->opts, DP_RES_OPT_FAMILY_ORDER); + DEBUG(SSSDBG_CONF_SETTINGS, ("Lookup order: %s\n", str_family)); + + if (strcasecmp(str_family, "ipv4_first") == 0) { + res_ctx->family_order = IPV4_FIRST; + } else if (strcasecmp(str_family, "ipv4_only") == 0) { + res_ctx->family_order = IPV4_ONLY; + } else if (strcasecmp(str_family, "ipv6_first") == 0) { + res_ctx->family_order = IPV6_FIRST; + } else if (strcasecmp(str_family, "ipv6_only") == 0) { + res_ctx->family_order = IPV6_ONLY; + } else { + DEBUG(SSSDBG_OP_FAILURE, ("Unknown value for option %s: %s\n", + dp_res_default_opts[DP_RES_OPT_FAMILY_ORDER].opt_name, str_family)); + return EINVAL; + } + + return EOK; +} + +errno_t be_res_init(struct be_ctx *ctx) +{ + errno_t ret; + + if (ctx->be_res != NULL) { + return EOK; + } + + ctx->be_res = talloc_zero(ctx, struct be_resolv_ctx); + if (!ctx->be_res) { + return ENOMEM; + } + + ret = be_res_get_opts(ctx->be_res, ctx->cdb, ctx->conf_path); + if (ret != EOK) { + talloc_zfree(ctx->be_res); + return ret; + } + + ret = resolv_init(ctx, ctx->ev, + dp_opt_get_int(ctx->be_res->opts, + DP_RES_OPT_RESOLVER_OP_TIMEOUT), + &ctx->be_res->resolv); + if (ret != EOK) { + talloc_zfree(ctx->be_res); + return ret; + } + + return EOK; +} diff --git a/src/providers/dp_backend.h b/src/providers/dp_backend.h index 1a546a858999af9a7179e5366afd61e052b07ef4..cf63c392eaed1dcaad8d6a4288aad3e44bb8a45f 100644 --- a/src/providers/dp_backend.h +++ b/src/providers/dp_backend.h @@ -80,6 +80,13 @@ struct be_offline_status { bool offline; }; +struct be_resolv_ctx { + struct resolv_ctx *resolv; + struct dp_option *opts; + + enum restrict_family family_order; +}; + struct be_client { struct be_ctx *bectx; struct sbus_connection *conn; @@ -98,6 +105,7 @@ struct be_ctx { const char *identity; const char *conf_path; struct be_failover_ctx *be_fo; + struct be_resolv_ctx *be_res; struct sss_sigchild_ctx *sigchld_ctx; /* Functions to be invoked when the @@ -195,7 +203,7 @@ enum be_fo_protocol { typedef void (be_svc_callback_fn_t)(void *, struct fo_server *); -int be_init_failover(struct be_ctx *ctx); +int be_init_failover(struct be_ctx *ctx, struct be_resolv_ctx *be_res); int be_fo_is_srv_identifier(const char *server); int be_fo_add_service(struct be_ctx *ctx, const char *service_name, datacmp_fn user_data_cmp); @@ -237,6 +245,8 @@ int be_fo_run_callbacks_at_next_request(struct be_ctx *ctx, void reset_fo(struct be_ctx *be_ctx); +errno_t be_res_init(struct be_ctx *ctx); + /* be_req helpers */ struct be_req *be_req_create(TALLOC_CTX *mem_ctx, diff --git a/src/providers/ipa/ipa_dyndns.c b/src/providers/ipa/ipa_dyndns.c index 972f19ad1ab8c9f2e8a85cf686e6eba23332f92b..632ed26afef8eb2240cf73709af490bab9dc97d8 100644 --- a/src/providers/ipa/ipa_dyndns.c +++ b/src/providers/ipa/ipa_dyndns.c @@ -142,17 +142,11 @@ errno_t ipa_dyndns_init(struct be_ctx *be_ctx, struct ipa_options *ctx) { errno_t ret; - int resolv_timeout; - ret = confdb_get_int(be_ctx->cdb, be_ctx->conf_path, - CONFDB_DOMAIN_RESOLV_TIMEOUT, - RESOLV_DEFAULT_TIMEOUT, &resolv_timeout); - if (ret != EOK) { - DEBUG(1, ("Could get the timeout parameter from confdb\n")); - return ret; - } - - ret = resolv_init(be_ctx, be_ctx->ev, resolv_timeout, &ctx->resolv); + ret = resolv_init(be_ctx, be_ctx->ev, + dp_opt_get_int(be_ctx->be_res->opts, + DP_RES_OPT_RESOLVER_OP_TIMEOUT), + &ctx->resolv); if (ret != EOK) { DEBUG(1, ("Could not set up resolver context\n")); return ret; @@ -255,6 +249,7 @@ ipa_dyndns_update_send(struct ipa_options *ctx) struct ipa_ipaddress *address; struct tevent_req *req, *subreq; size_t addrsize; + struct sdap_id_ctx *id_ctx = state->ipa_ctx->id_ctx->sdap_id_ctx; DEBUG (9, ("Performing update\n")); @@ -264,6 +259,7 @@ ipa_dyndns_update_send(struct ipa_options *ctx) } state->ipa_ctx = ctx; state->use_server_with_nsupdate = false; + state->family_order = id_ctx->be->be_res->family_order; iface = dp_opt_get_string(ctx->basic, IPA_DYNDNS_IFACE); @@ -488,17 +484,8 @@ static int ipa_dyndns_gss_tsig_update_step(struct tevent_req *req) static errno_t ipa_dyndns_gss_tsig_update_setup_check(struct ipa_dyndns_ctx *state) { - struct sdap_id_ctx *id_ctx = state->ipa_ctx->id_ctx->sdap_id_ctx; - errno_t ret; - if (dp_opt_get_string(state->ipa_ctx->basic, IPA_DYNDNS_IFACE)) { - ret = resolv_get_family_order(id_ctx->be->cdb, id_ctx->be->conf_path, - &state->family_order); - if (ret != EOK) { - return ret; - } - - /* Unless one family is restricted, just replace all + /* Unless one family is restricted, just replace all * address families during the update */ switch (state->family_order) { diff --git a/src/providers/ldap/sdap_async_sudo_hostinfo.c b/src/providers/ldap/sdap_async_sudo_hostinfo.c index f47e98651fc79e2b56fe70f18b72bdce5a426892..ff6142237fc98de7e65fbf815b1d4180de204ee3 100644 --- a/src/providers/ldap/sdap_async_sudo_hostinfo.c +++ b/src/providers/ldap/sdap_async_sudo_hostinfo.c @@ -372,7 +372,6 @@ static struct tevent_req *sdap_sudo_get_hostnames_send(TALLOC_CTX *mem_ctx, struct sdap_sudo_get_hostnames_state *state = NULL; char *dot = NULL; char hostname[HOST_NAME_MAX + 1]; - int resolv_timeout; int ret; req = tevent_req_create(mem_ctx, &state, @@ -433,32 +432,15 @@ static struct tevent_req *sdap_sudo_get_hostnames_send(TALLOC_CTX *mem_ctx, } /* initialize resolv ctx */ - - ret = confdb_get_int(be_ctx->cdb, be_ctx->conf_path, - CONFDB_DOMAIN_RESOLV_OP_TIMEOUT, - RESOLV_DEFAULT_TIMEOUT, &resolv_timeout); - if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, - ("Could get the timeout parameter from confdb\n")); - goto done; - } - - ret = resolv_init(be_ctx, be_ctx->ev, resolv_timeout, &state->resolv_ctx); + ret = resolv_init(be_ctx, be_ctx->ev, + dp_opt_get_int(be_ctx->be_res->opts, + DP_RES_OPT_RESOLVER_OP_TIMEOUT), + &state->resolv_ctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, ("Could not set up resolver context\n")); goto done; } - /* get family order */ - - ret = resolv_get_family_order(be_ctx->cdb, be_ctx->conf_path, - &state->family_order); - if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, ("Unable to retrieve family order " - "[%d]: %s\n", ret, strerror(ret))); - goto done; - } - /* get database order */ state->host_db = talloc_zero_array(state, enum host_database, 3); @@ -467,9 +449,8 @@ static struct tevent_req *sdap_sudo_get_hostnames_send(TALLOC_CTX *mem_ctx, state->host_db[2] = DB_SENTINEL; /* get fqdn */ - subreq = resolv_gethostbyname_send(state, state->ev, state->resolv_ctx, - hostname, state->family_order, + hostname, be_ctx->be_res->family_order, state->host_db); if (subreq == NULL) { ret = ENOMEM; diff --git a/src/resolv/async_resolv.c b/src/resolv/async_resolv.c index 0465151184ee81694b247be0088e849d5e4d0795..0a88094e613f004dbc29a5a75a4a9ac1990d5370 100644 --- a/src/resolv/async_resolv.c +++ b/src/resolv/async_resolv.c @@ -111,47 +111,6 @@ struct resolv_request { struct resolv_ctx *context_list; -errno_t -resolv_get_family_order(struct confdb_ctx *cdb, const char *conf_path, - enum restrict_family *family_order) -{ - errno_t ret; - TALLOC_CTX *tmp_ctx; - char *str_opt; - - tmp_ctx = talloc_new(NULL); - if (!tmp_ctx) return ENOMEM; - - ret = confdb_get_string(cdb, tmp_ctx, conf_path, - CONFDB_DOMAIN_FAMILY_ORDER, - "ipv4_first", &str_opt); - if (ret != EOK) { - goto done; - } - - DEBUG(7, ("Lookup order: %s\n", str_opt)); - - if (strcasecmp(str_opt, "ipv4_first") == 0) { - *family_order = IPV4_FIRST; - } else if (strcasecmp(str_opt, "ipv4_only") == 0) { - *family_order = IPV4_ONLY; - } else if (strcasecmp(str_opt, "ipv6_first") == 0) { - *family_order = IPV6_FIRST; - } else if (strcasecmp(str_opt, "ipv6_only") == 0) { - *family_order = IPV6_ONLY; - } else { - DEBUG(1, ("Unknown value for option %s: %s\n", - CONFDB_DOMAIN_FAMILY_ORDER, str_opt)); - ret = EINVAL; - goto done; - } - - ret = EOK; -done: - talloc_free(tmp_ctx); - return ret; -} - static int return_code(int ares_code) { diff --git a/src/resolv/async_resolv.h b/src/resolv/async_resolv.h index 8f8ddcbdcc40414a039c4f96740290bd7dd4bddc..f6c72b4fafedc016b64e7f5606fc838a585bcab5 100644 --- a/src/resolv/async_resolv.h +++ b/src/resolv/async_resolv.h @@ -85,11 +85,6 @@ enum restrict_family { IPV6_FIRST }; -/* Read and validate the family order from conf_path in confdb */ -errno_t -resolv_get_family_order(struct confdb_ctx *cdb, const char *conf_path, - enum restrict_family *family_order); - /* If resolv_hostent->family is AF_INET, then ipaddr points to * struct in_addr, else if family is AF_INET6, ipaddr points to * struct in6_addr -- 1.8.1.4