MINOR: resolvers: move the resolv.conf parser in parse_resolv_conf()
Move the resolv.conf parser from the cfg_parse_resolvers so it could be
used separately.
Some changes were made in the memprintf in order to use a char **
instead of a char *. Also the variable is tested before each memprintf
so could skip them if no warnmsg nor errmsg were set.
diff --git a/src/resolvers.c b/src/resolvers.c
index ee0434a..0ced384 100644
--- a/src/resolvers.c
+++ b/src/resolvers.c
@@ -3143,6 +3143,140 @@
px->options2 |= PR_O2_INDEPSTR | PR_O2_SMARTCON;
}
+static int parse_resolve_conf(char **errmsg, char **warnmsg)
+{
+ 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;
+ int err_code = 0;
+
+ if ((resolv_line = malloc(sizeof(*resolv_line) * LINESIZE)) == NULL) {
+ memprintf(errmsg, "out of memory.\n");
+ err_code |= ERR_ALERT | ERR_FATAL;
+ goto resolv_out;
+ }
+
+ if ((f = fopen("/etc/resolv.conf", "r")) == NULL) {
+ if (errmsg)
+ memprintf(errmsg, "failed to open /etc/resolv.conf.");
+ err_code |= ERR_ALERT | ERR_FATAL;
+ goto resolv_out;
+ }
+
+ sk = calloc(1, sizeof(*sk));
+ if (sk == NULL) {
+ if (errmsg)
+ memprintf(errmsg, "parsing [/etc/resolv.conf:%d] : out of memory.", 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) {
+ if (warnmsg)
+ memprintf(warnmsg, "%sparsing [/etc/resolv.conf:%d] : nameserver line is missing address.\n",
+ *warnmsg ? *warnmsg : "", 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) {
+ if (warnmsg)
+ memprintf(warnmsg, "%sParsing [/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",
+ *warnmsg ? *warnmsg : "", 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)) {
+ if (warnmsg)
+ memprintf(warnmsg, "%sparsing [/etc/resolv.conf:%d] : address '%s' could not be recognized, nameserver will be excluded.\n",
+ *warnmsg ? *warnmsg : "", resolv_linenum, address);
+ err_code |= ERR_WARN;
+ continue;
+ }
+
+ set_host_port(sk, 53);
+
+ proto = protocol_lookup(sk->ss_family, PROTO_TYPE_STREAM, 0);
+ if (!proto || !proto->connect) {
+ if (warnmsg)
+ memprintf(warnmsg, "%sparsing [/etc/resolv.conf:%d] : '%s' : connect() not supported for this address family.\n",
+ *warnmsg ? *warnmsg : "", resolv_linenum, address);
+ err_code |= ERR_WARN;
+ continue;
+ }
+
+ if ((newnameserver = calloc(1, sizeof(*newnameserver))) == NULL) {
+ if (errmsg)
+ memprintf(errmsg, "parsing [/etc/resolv.conf:%d] : out of memory.", resolv_linenum);
+ err_code |= ERR_ALERT | ERR_FATAL;
+ goto resolv_out;
+ }
+
+ if (dns_dgram_init(newnameserver, sk) < 0) {
+ if (errmsg)
+ memprintf(errmsg, "parsing [/etc/resolv.conf:%d] : out of memory.", resolv_linenum);
+ err_code |= ERR_ALERT | ERR_FATAL;
+ free(newnameserver);
+ goto resolv_out;
+ }
+
+ newnameserver->conf.file = strdup("/etc/resolv.conf");
+ if (newnameserver->conf.file == NULL) {
+ if (errmsg)
+ memprintf(errmsg, "parsing [/etc/resolv.conf:%d] : out of memory.", resolv_linenum);
+ err_code |= ERR_ALERT | ERR_FATAL;
+ free(newnameserver);
+ goto resolv_out;
+ }
+
+ newnameserver->id = strdup(address);
+ if (newnameserver->id == NULL) {
+ if (errmsg)
+ memprintf(errmsg, "parsing [/etc/resolv.conf:%d] : out of memory.", resolv_linenum);
+ err_code |= ERR_ALERT | ERR_FATAL;
+ free((char *)newnameserver->conf.file);
+ free(newnameserver);
+ goto resolv_out;
+ }
+
+ newnameserver->parent = curr_resolvers;
+ newnameserver->process_responses = resolv_process_responses;
+ newnameserver->conf.line = resolv_linenum;
+ LIST_APPEND(&curr_resolvers->nameservers, &newnameserver->list);
+ }
+
+resolv_out:
+ free(sk);
+ free(resolv_line);
+ if (f != NULL)
+ fclose(f);
+
+ return err_code;
+}
+
/*
* Parse a <resolvers> section.
* Returns the error code, 0 if OK, or any combination of :
@@ -3314,135 +3448,18 @@
LIST_APPEND(&curr_resolvers->nameservers, &newnameserver->list);
}
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) {
- memprintf(&errmsg, "out of memory.\n");
- err_code |= ERR_ALERT | ERR_FATAL;
- goto resolv_out;
- }
-
- if ((f = fopen("/etc/resolv.conf", "r")) == NULL) {
- memprintf(&errmsg, "failed to open /etc/resolv.conf.");
- err_code |= ERR_ALERT | ERR_FATAL;
- goto resolv_out;
- }
-
- sk = calloc(1, sizeof(*sk));
- if (sk == NULL) {
- memprintf(&errmsg, "parsing [/etc/resolv.conf:%d] : out of memory.", 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) {
- memprintf(&warnmsg, "%sparsing [/etc/resolv.conf:%d] : nameserver line is missing address.\n",
- warnmsg ? warnmsg : "", 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) {
- memprintf(&warnmsg, "%sParsing [/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",
- warnmsg ? warnmsg : "", 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)) {
- memprintf(&warnmsg, "%sparsing [/etc/resolv.conf:%d] : address '%s' could not be recognized, nameserver will be excluded.\n",
- warnmsg ? warnmsg : "", resolv_linenum, address);
- err_code |= ERR_WARN;
- continue;
- }
-
- set_host_port(sk, 53);
-
- proto = protocol_lookup(sk->ss_family, PROTO_TYPE_STREAM, 0);
- if (!proto || !proto->connect) {
- memprintf(&warnmsg, "%sparsing [/etc/resolv.conf:%d] : '%s' : connect() not supported for this address family.\n",
- warnmsg ? warnmsg : "", resolv_linenum, address);
- err_code |= ERR_WARN;
- continue;
- }
-
- if ((newnameserver = calloc(1, sizeof(*newnameserver))) == NULL) {
- memprintf(&errmsg, "parsing [/etc/resolv.conf:%d] : out of memory.", resolv_linenum);
- err_code |= ERR_ALERT | ERR_FATAL;
- goto resolv_out;
- }
-
- if (dns_dgram_init(newnameserver, sk) < 0) {
- memprintf(&errmsg, "parsing [/etc/resolv.conf:%d] : out of memory.", resolv_linenum);
- err_code |= ERR_ALERT | ERR_FATAL;
- free(newnameserver);
- goto resolv_out;
- }
-
- newnameserver->conf.file = strdup("/etc/resolv.conf");
- if (newnameserver->conf.file == NULL) {
- memprintf(&errmsg, "parsing [/etc/resolv.conf:%d] : out of memory.", resolv_linenum);
- err_code |= ERR_ALERT | ERR_FATAL;
- free(newnameserver);
- goto resolv_out;
- }
-
- newnameserver->id = strdup(address);
- if (newnameserver->id == NULL) {
- memprintf(&errmsg, "parsing [/etc/resolv.conf:%d] : out of memory.", resolv_linenum);
- err_code |= ERR_ALERT | ERR_FATAL;
- free((char *)newnameserver->conf.file);
- free(newnameserver);
- goto resolv_out;
- }
-
- newnameserver->parent = curr_resolvers;
- newnameserver->process_responses = resolv_process_responses;
- newnameserver->conf.line = resolv_linenum;
- LIST_APPEND(&curr_resolvers->nameservers, &newnameserver->list);
- }
-
-resolv_out:
+ err_code |= parse_resolve_conf(&errmsg, &warnmsg);
if (err_code & ERR_WARN) {
indent_msg(&warnmsg, 8);
ha_warning("parsing [%s:%d]: %s\n", file, linenum, warnmsg);
ha_free(&warnmsg);
}
-
if (err_code & ERR_ALERT) {
indent_msg(&errmsg, 8);
ha_alert("parsing [%s:%d]: %s\n", file, linenum, errmsg);
ha_free(&errmsg);
+ goto out;
}
-
- free(sk);
- free(resolv_line);
- if (f != NULL)
- fclose(f);
}
else if (strcmp(args[0], "hold") == 0) { /* hold periods */
const char *res;