diff --git a/include/haproxy/tools-t.h b/include/haproxy/tools-t.h index 91363d93d..b3f2f62e4 100644 --- a/include/haproxy/tools-t.h +++ b/include/haproxy/tools-t.h @@ -85,6 +85,9 @@ #define HOUR (60 * MINUTE) #define DAY (24 * HOUR) +/* Address parsing options for use with str2sa_range() */ +#define PA_O_RESOLVE 0x00000001 /* do resolve the FQDN to an IP address */ + /* UTF-8 decoder status */ #define UTF8_CODE_OK 0x00 #define UTF8_CODE_OVERLONG 0x10 diff --git a/include/haproxy/tools.h b/include/haproxy/tools.h index 068c13483..095485f4d 100644 --- a/include/haproxy/tools.h +++ b/include/haproxy/tools.h @@ -239,13 +239,12 @@ static inline int is_idchar(char c) * The IPv6 '::' address is IN6ADDR_ANY, so in order to bind to a given port on * IPv6, use ":::port". NULL is returned if the host part cannot be resolved. * If is non-null, it is used as a string prefix before any path-based - * address (typically the path to a unix socket). If use_dns is not true, - * the function cannot accept the DNS resolution. + * address (typically the path to a unix socket). */ struct sockaddr_storage *str2sa_range(const char *str, int *port, int *low, int *high, char **err, const char *pfx, - char **fqdn, int resolve); + char **fqdn, unsigned int opts); /* converts to a struct in_addr containing a network mask. It can be * passed in dotted form (255.255.255.0) or in CIDR form (24). It returns 1 diff --git a/src/cfgparse-listen.c b/src/cfgparse-listen.c index 82e8cf989..8fc3f46b2 100644 --- a/src/cfgparse-listen.c +++ b/src/cfgparse-listen.c @@ -2600,7 +2600,7 @@ stats_error_parsing: else if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL)) err_code |= ERR_WARN; - sk = str2sa_range(args[1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1); + sk = str2sa_range(args[1], NULL, &port1, &port2, &errmsg, NULL, NULL, PA_O_RESOLVE); if (!sk) { ha_alert("parsing [%s:%d] : '%s' : %s\n", file, linenum, args[0], errmsg); err_code |= ERR_ALERT | ERR_FATAL; @@ -2872,7 +2872,7 @@ stats_error_parsing: curproxy->conn_src.iface_name = NULL; curproxy->conn_src.iface_len = 0; - sk = str2sa_range(args[1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1); + sk = str2sa_range(args[1], NULL, &port1, &port2, &errmsg, NULL, NULL, PA_O_RESOLVE); if (!sk) { ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg); @@ -2957,7 +2957,7 @@ stats_error_parsing: } else { struct sockaddr_storage *sk; - sk = str2sa_range(args[cur_arg + 1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1); + sk = str2sa_range(args[cur_arg + 1], NULL, &port1, &port2, &errmsg, NULL, NULL, PA_O_RESOLVE); if (!sk) { ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[cur_arg], args[cur_arg+1], errmsg); diff --git a/src/cfgparse.c b/src/cfgparse.c index 8effc8311..287efb135 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -129,7 +129,7 @@ int str2listener(char *str, struct proxy *curproxy, struct bind_conf *bind_conf, ss2 = str2sa_range(str, NULL, &port, &end, err, curproxy == global.stats_fe ? NULL : global.unix_bind.prefix, - NULL, 1); + NULL, PA_O_RESOLVE); if (!ss2) goto fail; @@ -1034,7 +1034,7 @@ int cfg_parse_resolvers(const char *file, int linenum, char **args, int kwm) newnameserver->conf.line = linenum; newnameserver->id = strdup(args[1]); - sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, 1); + sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, PA_O_RESOLVE); if (!sk) { ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg); err_code |= ERR_ALERT | ERR_FATAL; @@ -1424,7 +1424,7 @@ int cfg_parse_mailers(const char *file, int linenum, char **args, int kwm) newmailer->id = strdup(args[1]); - sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, 1); + sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, PA_O_RESOLVE); if (!sk) { ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg); err_code |= ERR_ALERT | ERR_FATAL; diff --git a/src/check.c b/src/check.c index 4d6b75b10..c326c00a2 100644 --- a/src/check.c +++ b/src/check.c @@ -2638,7 +2638,7 @@ static int srv_parse_addr(char **args, int *cur_arg, struct proxy *curpx, struct goto error; } - sk = str2sa_range(args[*cur_arg+1], NULL, &port1, &port2, errmsg, NULL, NULL, 1); + sk = str2sa_range(args[*cur_arg+1], NULL, &port1, &port2, errmsg, NULL, NULL, PA_O_RESOLVE); if (!sk) { memprintf(errmsg, "'%s' : %s", args[*cur_arg], *errmsg); goto error; diff --git a/src/log.c b/src/log.c index e1257132a..53b97aab4 100644 --- a/src/log.c +++ b/src/log.c @@ -1021,7 +1021,7 @@ int parse_logsrv(char **args, struct list *logsrvs, int do_del, char **err) if (strncmp(args[1], "fd@", 3) == 0) logsrv->type = LOG_TARGET_FD; - sk = str2sa_range(args[1], NULL, &port1, &port2, err, NULL, NULL, 1); + sk = str2sa_range(args[1], NULL, &port1, &port2, err, NULL, NULL, PA_O_RESOLVE); if (!sk) goto error; logsrv->addr = *sk; diff --git a/src/server.c b/src/server.c index 12755cdac..d8f14e5d2 100644 --- a/src/server.c +++ b/src/server.c @@ -659,7 +659,7 @@ static int srv_parse_source(char **args, int *cur_arg, } /* 'sk' is statically allocated (no need to be freed). */ - sk = str2sa_range(args[*cur_arg + 1], NULL, &port_low, &port_high, &errmsg, NULL, NULL, 1); + sk = str2sa_range(args[*cur_arg + 1], NULL, &port_low, &port_high, &errmsg, NULL, NULL, PA_O_RESOLVE); if (!sk) { memprintf(err, "'%s %s' : %s\n", args[*cur_arg], args[*cur_arg + 1], errmsg); goto err; @@ -756,7 +756,7 @@ static int srv_parse_source(char **args, int *cur_arg, int port1, port2; /* 'sk' is statically allocated (no need to be freed). */ - sk = str2sa_range(args[*cur_arg + 1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1); + sk = str2sa_range(args[*cur_arg + 1], NULL, &port1, &port2, &errmsg, NULL, NULL, PA_O_RESOLVE); if (!sk) { ha_alert("'%s %s' : %s\n", args[*cur_arg], args[*cur_arg + 1], errmsg); goto err; @@ -857,7 +857,7 @@ static int srv_parse_socks4(char **args, int *cur_arg, } /* 'sk' is statically allocated (no need to be freed). */ - sk = str2sa_range(args[*cur_arg + 1], NULL, &port_low, &port_high, &errmsg, NULL, NULL, 1); + sk = str2sa_range(args[*cur_arg + 1], NULL, &port_low, &port_high, &errmsg, NULL, NULL, PA_O_RESOLVE); if (!sk) { memprintf(err, "'%s %s' : %s\n", args[*cur_arg], args[*cur_arg + 1], errmsg); goto err; @@ -2054,7 +2054,7 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr if (!parse_addr) goto skip_addr; - sk = str2sa_range(args[cur_arg], &port, &port1, &port2, &errmsg, NULL, &fqdn, initial_resolve); + sk = str2sa_range(args[cur_arg], &port, &port1, &port2, &errmsg, NULL, &fqdn, initial_resolve ? PA_O_RESOLVE : 0); if (!sk) { ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg); err_code |= ERR_ALERT | ERR_FATAL; diff --git a/src/tcpcheck.c b/src/tcpcheck.c index 65972396a..2cd0beea0 100644 --- a/src/tcpcheck.c +++ b/src/tcpcheck.c @@ -2224,7 +2224,7 @@ struct tcpcheck_rule *parse_tcpcheck_connect(char **args, int cur_arg, struct pr goto error; } - sk = str2sa_range(args[cur_arg+1], NULL, &port1, &port2, errmsg, NULL, NULL, 1); + sk = str2sa_range(args[cur_arg+1], NULL, &port1, &port2, errmsg, NULL, NULL, PA_O_RESOLVE); if (!sk) { memprintf(errmsg, "'%s' : %s.", args[cur_arg], *errmsg); goto error; diff --git a/src/tools.c b/src/tools.c index 1fdfed67f..29526c262 100644 --- a/src/tools.c +++ b/src/tools.c @@ -855,16 +855,16 @@ struct sockaddr_storage *str2ip2(const char *str, struct sockaddr_storage *sa, i * that the caller will have to free(), * - NULL if there was an explicit address that doesn't require resolution. * - * Hostnames are only resolved if is non-null. Note that if - * is null, is still honnored so it is possible for the caller to know - * whether a resolution failed by setting to null and checking if - * was filled, indicating the need for a resolution. + * Hostnames are only resolved if has PA_O_RESOLVE. Otherwise is + * still honored so it is possible for the caller to know whether a resolution + * failed by clearing this flag and checking if was filled, indicating + * the need for a resolution. * * When a file descriptor is passed, its value is put into the s_addr part of * the address when cast to sockaddr_in and the address family is * AF_CUST_EXISTING_FD. */ -struct sockaddr_storage *str2sa_range(const char *str, int *port, int *low, int *high, char **err, const char *pfx, char **fqdn, int resolve) +struct sockaddr_storage *str2sa_range(const char *str, int *port, int *low, int *high, char **err, const char *pfx, char **fqdn, unsigned int opts) { static THREAD_LOCAL struct sockaddr_storage ss; struct sockaddr_storage *ret = NULL; @@ -1036,11 +1036,11 @@ struct sockaddr_storage *str2sa_range(const char *str, int *port, int *low, int /* first try to parse the IP without resolving. If it fails, it * tells us we need to keep a copy of the FQDN to resolve later * and to enable DNS. In this case we can proceed if is - * set or if resolve is set, otherwise it's an error. + * set or if PA_O_RESOLVE is set, otherwise it's an error. */ if (str2ip2(str2, &ss, 0) == NULL) { - if ((!resolve && !fqdn) || - (resolve && str2ip2(str2, &ss, 1) == NULL)) { + if ((!(opts & PA_O_RESOLVE) && !fqdn) || + ((opts & PA_O_RESOLVE) && str2ip2(str2, &ss, 1) == NULL)) { memprintf(err, "invalid address: '%s' in '%s'\n", str2, str); goto out; }