diff options
Diffstat (limited to 'hesiod')
-rw-r--r-- | hesiod/README.hesiod | 8 | ||||
-rw-r--r-- | hesiod/hesiod.c | 63 | ||||
-rw-r--r-- | hesiod/hesiod_p.h | 1 |
3 files changed, 49 insertions, 23 deletions
diff --git a/hesiod/README.hesiod b/hesiod/README.hesiod index 18cd5d45dd..259ce8d447 100644 --- a/hesiod/README.hesiod +++ b/hesiod/README.hesiod @@ -71,6 +71,14 @@ will want to create your own. It should look something like: rhs=.your.domain lhs=.ns + classes=in,hs + +The optional classes settings specifies which DNS classes Hesiod +should do lookups in. Possible values are IN (the preferred class) +and HS (the deprecated class, still used by some sites). +You may specify both classes separated by a comma to try one class +first and then the other if no entry is available in the first +class. The default value of the classes variable is `IN,HS'. The value of rhs can be overridden by the environment variable `HES_DOMAIN'. diff --git a/hesiod/hesiod.c b/hesiod/hesiod.c index 7fffb310f1..b3706b506b 100644 --- a/hesiod/hesiod.c +++ b/hesiod/hesiod.c @@ -83,6 +83,9 @@ hesiod_init(void **context) { ctx->LHS = NULL; ctx->RHS = NULL; ctx->res = NULL; + /* Set default query classes. */ + ctx->classes[0] = C_IN; + ctx->classes[1] = C_HS; configname = __secure_getenv("HESIOD_CONFIG"); if (!configname) @@ -234,15 +237,12 @@ hesiod_resolve(void *context, const char *name, const char *type) { return (NULL); } - if ((retvec = get_txt_records(ctx, C_IN, bindname))) { - free(bindname); - return (retvec); - } + retvec = get_txt_records(ctx, ctx->classes[0], bindname); + + if (retvec == NULL && (errno == ENOENT || errno == ECONNREFUSED) && ctx->classes[1]) + retvec = get_txt_records(ctx, ctx->classes[1], bindname); - if (errno != ENOENT && errno != ECONNREFUSED) - return (NULL); - retvec = get_txt_records(ctx, C_HS, bindname); free(bindname); return (retvec); } @@ -261,7 +261,6 @@ hesiod_free_list(void *context, char **list) { */ static int parse_config_file(struct hesiod_p *ctx, const char *filename) { - char *key, *data, *cp, **cpp; char buf[MAXDNAME+7]; FILE *fp; @@ -272,6 +271,9 @@ parse_config_file(struct hesiod_p *ctx, const char *filename) { free(ctx->RHS); free(ctx->LHS); ctx->RHS = ctx->LHS = 0; + /* Set default query classes. */ + ctx->classes[0] = C_IN; + ctx->classes[1] = C_HS; /* * Now open and parse the file... @@ -280,6 +282,8 @@ parse_config_file(struct hesiod_p *ctx, const char *filename) { return (-1); while (fgets(buf, sizeof(buf), fp) != NULL) { + char *key, *data, *cp, **cpp; + cp = buf; if (*cp == '#' || *cp == '\n' || *cp == '\r') continue; @@ -297,17 +301,36 @@ parse_config_file(struct hesiod_p *ctx, const char *filename) { cp++; *cp++ = '\0'; - if (strcmp(key, "lhs") == 0) + cpp = NULL; + if (strcasecmp(key, "lhs") == 0) cpp = &ctx->LHS; - else if (strcmp(key, "rhs") == 0) + else if (strcasecmp(key, "rhs") == 0) cpp = &ctx->RHS; - else - continue; - - *cpp = malloc(strlen(data) + 1); - if (!*cpp) - goto cleanup; - strcpy(*cpp, data); + if (cpp) { + *cpp = strdup(data); + if (!*cpp) + goto cleanup; + } else if (strcasecmp(key, "classes") == 0) { + int n = 0; + while (*data && n < 2) { + cp = strchrnul(data, ','); + if (*cp != '\0') + *cp++ = '\0'; + if (strcasecmp(data, "IN") == 0) + ctx->classes[n++] = C_IN; + else if (strcasecmp(data, "HS") == 0) + ctx->classes[n++] = C_HS; + data = cp; + } + if (n == 0) { + /* Restore the default. Better than + nother at all. */ + ctx->classes[0] = C_IN; + ctx->classes[1] = C_HS; + } else if (n == 1 + || ctx->classes[0] == ctx->classes[1]) + ctx->classes[1] = 0; + } } fclose(fp); return (0); @@ -464,12 +487,6 @@ __hesiod_res_set(void *context, struct __res_state *res, if (ctx->res && ctx->free_res) { res_nclose(ctx->res); - if ((ctx->res->options & RES_INIT) && ctx->res->nscount > 0) { - for (int ns = 0; ns < MAXNS; ns++) { - free (ctx->res->_u._ext.nsaddrs[ns]); - ctx->res->_u._ext.nsaddrs[ns] = NULL; - } - } (*ctx->free_res)(ctx->res); } diff --git a/hesiod/hesiod_p.h b/hesiod/hesiod_p.h index 71aca0976d..5010d71bc9 100644 --- a/hesiod/hesiod_p.h +++ b/hesiod/hesiod_p.h @@ -41,6 +41,7 @@ struct hesiod_p { void (*res_set)(struct hesiod_p *, struct __res_state *, void (*)(void *)); struct __res_state * (*res_get)(struct hesiod_p *); + int classes[2]; /* The class search order. */ }; #define MAX_HESRESP 1024 |