From: Emeric Brun Date: Tue, 24 Nov 2020 16:24:34 +0000 (+0100) Subject: MEDIUM: resolvers: move resolvers section parsing from cfgparse.c to dns.c X-Git-Tag: v2.4-dev8~7 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8a55193d4ed0d9079ec05d50fd23c4b4e45386c7;p=thirdparty%2Fhaproxy.git MEDIUM: resolvers: move resolvers section parsing from cfgparse.c to dns.c The resolver section parsing is moved from cfgparse.c to dns.c --- diff --git a/src/cfgparse.c b/src/cfgparse.c index 4840008950..0c0638e70b 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -908,391 +908,6 @@ out: return err_code; } -/* - * Parse a section. - * Returns the error code, 0 if OK, or any combination of : - * - ERR_ABORT: must abort ASAP - * - ERR_FATAL: we can continue parsing but not start the service - * - ERR_WARN: a warning has been emitted - * - ERR_ALERT: an alert has been emitted - * Only the two first ones can stop processing, the two others are just - * indicators. - */ -int cfg_parse_resolvers(const char *file, int linenum, char **args, int kwm) -{ - static struct resolvers *curr_resolvers = NULL; - const char *err; - int err_code = 0; - char *errmsg = NULL; - - if (strcmp(args[0], "resolvers") == 0) { /* new resolvers section */ - if (!*args[1]) { - ha_alert("parsing [%s:%d] : missing name for resolvers section.\n", file, linenum); - err_code |= ERR_ALERT | ERR_ABORT; - goto out; - } - - err = invalid_char(args[1]); - if (err) { - ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n", - file, linenum, *err, args[0], args[1]); - err_code |= ERR_ALERT | ERR_ABORT; - goto out; - } - - list_for_each_entry(curr_resolvers, &sec_resolvers, list) { - /* Error if two resolvers owns the same name */ - if (strcmp(curr_resolvers->id, args[1]) == 0) { - ha_alert("Parsing [%s:%d]: resolvers '%s' has same name as another resolvers (declared at %s:%d).\n", - file, linenum, args[1], curr_resolvers->conf.file, curr_resolvers->conf.line); - err_code |= ERR_ALERT | ERR_ABORT; - } - } - - if ((curr_resolvers = calloc(1, sizeof(*curr_resolvers))) == NULL) { - ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum); - err_code |= ERR_ALERT | ERR_ABORT; - goto out; - } - - /* default values */ - LIST_ADDQ(&sec_resolvers, &curr_resolvers->list); - curr_resolvers->conf.file = strdup(file); - curr_resolvers->conf.line = linenum; - curr_resolvers->id = strdup(args[1]); - curr_resolvers->query_ids = EB_ROOT; - /* default maximum response size */ - curr_resolvers->accepted_payload_size = 512; - /* default hold period for nx, other, refuse and timeout is 30s */ - curr_resolvers->hold.nx = 30000; - curr_resolvers->hold.other = 30000; - curr_resolvers->hold.refused = 30000; - curr_resolvers->hold.timeout = 30000; - curr_resolvers->hold.obsolete = 0; - /* default hold period for valid is 10s */ - curr_resolvers->hold.valid = 10000; - curr_resolvers->timeout.resolve = 1000; - curr_resolvers->timeout.retry = 1000; - curr_resolvers->resolve_retries = 3; - curr_resolvers->nb_nameservers = 0; - LIST_INIT(&curr_resolvers->nameservers); - LIST_INIT(&curr_resolvers->resolutions.curr); - LIST_INIT(&curr_resolvers->resolutions.wait); - HA_SPIN_INIT(&curr_resolvers->lock); - } - else if (strcmp(args[0], "nameserver") == 0) { /* nameserver definition */ - struct dns_nameserver *newnameserver = NULL; - struct sockaddr_storage *sk; - int port1, port2; - - if (!*args[2]) { - ha_alert("parsing [%s:%d] : '%s' expects and [:] as arguments.\n", - file, linenum, args[0]); - err_code |= ERR_ALERT | ERR_FATAL; - goto out; - } - - err = invalid_char(args[1]); - if (err) { - ha_alert("parsing [%s:%d] : character '%c' is not permitted in server name '%s'.\n", - file, linenum, *err, args[1]); - err_code |= ERR_ALERT | ERR_FATAL; - goto out; - } - - list_for_each_entry(newnameserver, &curr_resolvers->nameservers, list) { - /* Error if two resolvers owns the same name */ - if (strcmp(newnameserver->id, args[1]) == 0) { - ha_alert("Parsing [%s:%d]: nameserver '%s' has same name as another nameserver (declared at %s:%d).\n", - file, linenum, args[1], newnameserver->conf.file, newnameserver->conf.line); - err_code |= ERR_ALERT | ERR_FATAL; - } - } - - if ((newnameserver = calloc(1, sizeof(*newnameserver))) == NULL) { - ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum); - err_code |= ERR_ALERT | ERR_ABORT; - goto out; - } - - /* the nameservers are linked backward first */ - LIST_ADDQ(&curr_resolvers->nameservers, &newnameserver->list); - newnameserver->resolvers = curr_resolvers; - newnameserver->conf.file = strdup(file); - newnameserver->conf.line = linenum; - newnameserver->id = strdup(args[1]); - - sk = str2sa_range(args[2], NULL, &port1, &port2, NULL, NULL, - &errmsg, NULL, NULL, PA_O_RESOLVE | PA_O_PORT_OK | PA_O_PORT_MAND | PA_O_DGRAM); - if (!sk) { - ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg); - err_code |= ERR_ALERT | ERR_FATAL; - goto out; - } - - newnameserver->addr = *sk; - } - else if (strcmp(args[0], "parse-resolv-conf") == 0) { - struct dns_nameserver *newnameserver = NULL; - const char *whitespace = "\r\n\t "; - char *resolv_line = NULL; - int resolv_linenum = 0; - FILE *f = NULL; - char *address = NULL; - struct sockaddr_storage *sk = NULL; - struct protocol *proto; - int duplicate_name = 0; - - if ((resolv_line = malloc(sizeof(*resolv_line) * LINESIZE)) == NULL) { - ha_alert("parsing [%s:%d] : out of memory.\n", - file, linenum); - err_code |= ERR_ALERT | ERR_FATAL; - goto resolv_out; - } - - if ((f = fopen("/etc/resolv.conf", "r")) == NULL) { - ha_alert("parsing [%s:%d] : failed to open /etc/resolv.conf.\n", - file, linenum); - err_code |= ERR_ALERT | ERR_FATAL; - goto resolv_out; - } - - sk = calloc(1, sizeof(*sk)); - if (sk == NULL) { - ha_alert("parsing [/etc/resolv.conf:%d] : out of memory.\n", - resolv_linenum); - err_code |= ERR_ALERT | ERR_FATAL; - goto resolv_out; - } - - while (fgets(resolv_line, LINESIZE, f) != NULL) { - resolv_linenum++; - if (strncmp(resolv_line, "nameserver", 10) != 0) - continue; - - address = strtok(resolv_line + 10, whitespace); - if (address == resolv_line + 10) - continue; - - if (address == NULL) { - ha_warning("parsing [/etc/resolv.conf:%d] : nameserver line is missing address.\n", - resolv_linenum); - err_code |= ERR_WARN; - continue; - } - - duplicate_name = 0; - list_for_each_entry(newnameserver, &curr_resolvers->nameservers, list) { - if (strcmp(newnameserver->id, address) == 0) { - ha_warning("Parsing [/etc/resolv.conf:%d] : generated name for /etc/resolv.conf nameserver '%s' conflicts with another nameserver (declared at %s:%d), it appears to be a duplicate and will be excluded.\n", - resolv_linenum, address, newnameserver->conf.file, newnameserver->conf.line); - err_code |= ERR_WARN; - duplicate_name = 1; - } - } - - if (duplicate_name) - continue; - - memset(sk, 0, sizeof(*sk)); - if (!str2ip2(address, sk, 1)) { - ha_warning("parsing [/etc/resolv.conf:%d] : address '%s' could not be recognized, nameserver will be excluded.\n", - resolv_linenum, address); - err_code |= ERR_WARN; - continue; - } - - set_host_port(sk, 53); - - proto = protocol_by_family(sk->ss_family); - if (!proto || !proto->connect) { - ha_warning("parsing [/etc/resolv.conf:%d] : '%s' : connect() not supported for this address family.\n", - resolv_linenum, address); - err_code |= ERR_WARN; - continue; - } - - if ((newnameserver = calloc(1, sizeof(*newnameserver))) == NULL) { - ha_alert("parsing [/etc/resolv.conf:%d] : out of memory.\n", resolv_linenum); - err_code |= ERR_ALERT | ERR_FATAL; - goto resolv_out; - } - - newnameserver->conf.file = strdup("/etc/resolv.conf"); - if (newnameserver->conf.file == NULL) { - ha_alert("parsing [/etc/resolv.conf:%d] : out of memory.\n", resolv_linenum); - err_code |= ERR_ALERT | ERR_FATAL; - free(newnameserver); - goto resolv_out; - } - - newnameserver->id = strdup(address); - if (newnameserver->id == NULL) { - ha_alert("parsing [/etc/resolv.conf:%d] : out of memory.\n", resolv_linenum); - err_code |= ERR_ALERT | ERR_FATAL; - free((char *)newnameserver->conf.file); - free(newnameserver); - goto resolv_out; - } - - newnameserver->resolvers = curr_resolvers; - newnameserver->conf.line = resolv_linenum; - newnameserver->addr = *sk; - - LIST_ADDQ(&curr_resolvers->nameservers, &newnameserver->list); - } - -resolv_out: - free(sk); - free(resolv_line); - if (f != NULL) - fclose(f); - } - else if (strcmp(args[0], "hold") == 0) { /* hold periods */ - const char *res; - unsigned int time; - - if (!*args[2]) { - ha_alert("parsing [%s:%d] : '%s' expects an and a