From 7fe3be72818de11103d4349c5e7d2a8ceae68764 Mon Sep 17 00:00:00 2001 From: Thierry FOURNIER Date: Sat, 26 Sep 2015 20:03:36 +0200 Subject: [PATCH] MINOR: standard: avoid DNS resolution from the function str2sa_range() This patch blocks the DNS resolution in the function str2sa_range(), this is useful if the function is used during the HAProxy runtime. --- include/common/standard.h | 5 +++-- src/cfgparse.c | 18 +++++++++--------- src/server.c | 8 ++++---- src/standard.c | 6 ++++-- 4 files changed, 20 insertions(+), 17 deletions(-) diff --git a/include/common/standard.h b/include/common/standard.h index a8e1b99527..d28ab79c8f 100644 --- a/include/common/standard.h +++ b/include/common/standard.h @@ -275,9 +275,10 @@ extern const char *invalid_domainchar(const char *name); * 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). + * address (typically the path to a unix socket). If use_dns is not true, + * the funtion cannot accept the DNS resolution. */ -struct sockaddr_storage *str2sa_range(const char *str, int *low, int *high, char **err, const char *pfx, char **fqdn); +struct sockaddr_storage *str2sa_range(const char *str, int *low, int *high, char **err, const char *pfx, char **fqdn, int use_dns); /* 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.c b/src/cfgparse.c index 3b7b390858..06a2e0da15 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -240,7 +240,7 @@ int str2listener(char *str, struct proxy *curproxy, struct bind_conf *bind_conf, ss2 = str2sa_range(str, &port, &end, err, curproxy == global.stats_fe ? NULL : global.unix_bind.prefix, - NULL); + NULL, 1); if (!ss2) goto fail; @@ -1598,7 +1598,7 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm) } } - sk = str2sa_range(args[1], &port1, &port2, &errmsg, NULL, NULL); + sk = str2sa_range(args[1], &port1, &port2, &errmsg, NULL, NULL, 1); if (!sk) { Alert("parsing [%s:%d] : '%s': %s\n", file, linenum, args[0], errmsg); err_code |= ERR_ALERT | ERR_FATAL; @@ -2059,7 +2059,7 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm) newpeer->last_change = now.tv_sec; newpeer->id = strdup(args[1]); - sk = str2sa_range(args[2], &port1, &port2, &errmsg, NULL, NULL); + sk = str2sa_range(args[2], &port1, &port2, &errmsg, NULL, NULL, 1); if (!sk) { Alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg); err_code |= ERR_ALERT | ERR_FATAL; @@ -2259,7 +2259,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], &port1, &port2, &errmsg, NULL, NULL); + sk = str2sa_range(args[2], &port1, &port2, &errmsg, NULL, NULL, 1); if (!sk) { Alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg); err_code |= ERR_ALERT | ERR_FATAL; @@ -2443,7 +2443,7 @@ int cfg_parse_mailers(const char *file, int linenum, char **args, int kwm) newmailer->id = strdup(args[1]); - sk = str2sa_range(args[2], &port1, &port2, &errmsg, NULL, NULL); + sk = str2sa_range(args[2], &port1, &port2, &errmsg, NULL, NULL, 1); if (!sk) { Alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg); err_code |= ERR_ALERT | ERR_FATAL; @@ -5611,7 +5611,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], &port1, &port2, &errmsg, NULL, NULL); + sk = str2sa_range(args[1], &port1, &port2, &errmsg, NULL, NULL, 1); if (!sk) { Alert("parsing [%s:%d] : '%s' : %s\n", file, linenum, args[0], errmsg); err_code |= ERR_ALERT | ERR_FATAL; @@ -5883,7 +5883,7 @@ stats_error_parsing: } } - sk = str2sa_range(args[1], &port1, &port2, &errmsg, NULL, NULL); + sk = str2sa_range(args[1], &port1, &port2, &errmsg, NULL, NULL, 1); if (!sk) { Alert("parsing [%s:%d] : '%s': %s\n", file, linenum, args[0], errmsg); err_code |= ERR_ALERT | ERR_FATAL; @@ -5935,7 +5935,7 @@ stats_error_parsing: curproxy->conn_src.iface_name = NULL; curproxy->conn_src.iface_len = 0; - sk = str2sa_range(args[1], &port1, &port2, &errmsg, NULL, NULL); + sk = str2sa_range(args[1], &port1, &port2, &errmsg, NULL, NULL, 1); if (!sk) { Alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg); @@ -6020,7 +6020,7 @@ stats_error_parsing: } else { struct sockaddr_storage *sk; - sk = str2sa_range(args[cur_arg + 1], &port1, &port2, &errmsg, NULL, NULL); + sk = str2sa_range(args[cur_arg + 1], &port1, &port2, &errmsg, NULL, NULL, 1); if (!sk) { Alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[cur_arg], args[cur_arg+1], errmsg); diff --git a/src/server.c b/src/server.c index a34b850b6d..bc92c3cb0f 100644 --- a/src/server.c +++ b/src/server.c @@ -907,7 +907,7 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr * - IP:+N => port=+N, relative * - IP:-N => port=-N, relative */ - sk = str2sa_range(args[2], &port1, &port2, &errmsg, NULL, &fqdn); + sk = str2sa_range(args[2], &port1, &port2, &errmsg, NULL, &fqdn, 1); if (!sk) { Alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg); err_code |= ERR_ALERT | ERR_FATAL; @@ -1174,7 +1174,7 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr int port1, port2; struct protocol *proto; - sk = str2sa_range(args[cur_arg + 1], &port1, &port2, &errmsg, NULL, NULL); + sk = str2sa_range(args[cur_arg + 1], &port1, &port2, &errmsg, NULL, NULL, 1); if (!sk) { Alert("parsing [%s:%d] : '%s' : %s\n", file, linenum, args[cur_arg], errmsg); @@ -1383,7 +1383,7 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr } newsrv->conn_src.opts |= CO_SRC_BIND; - sk = str2sa_range(args[cur_arg + 1], &port_low, &port_high, &errmsg, NULL, NULL); + sk = str2sa_range(args[cur_arg + 1], &port_low, &port_high, &errmsg, NULL, NULL, 1); if (!sk) { Alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[cur_arg], args[cur_arg+1], errmsg); @@ -1483,7 +1483,7 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr struct sockaddr_storage *sk; int port1, port2; - sk = str2sa_range(args[cur_arg + 1], &port1, &port2, &errmsg, NULL, NULL); + sk = str2sa_range(args[cur_arg + 1], &port1, &port2, &errmsg, NULL, NULL, 1); if (!sk) { Alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[cur_arg], args[cur_arg+1], errmsg); diff --git a/src/standard.c b/src/standard.c index 7964b88ddb..a468700b19 100644 --- a/src/standard.c +++ b/src/standard.c @@ -760,10 +760,12 @@ 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. + * * 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_UNSPEC. */ -struct sockaddr_storage *str2sa_range(const char *str, int *low, int *high, char **err, const char *pfx, char **fqdn) +struct sockaddr_storage *str2sa_range(const char *str, int *low, int *high, char **err, const char *pfx, char **fqdn, int resolve) { static struct sockaddr_storage ss; struct sockaddr_storage *ret = NULL; @@ -862,7 +864,7 @@ struct sockaddr_storage *str2sa_range(const char *str, int *low, int *high, char if (str2ip2(str2, &ss, 0) == NULL) { use_fqdn = 1; - if (str2ip(str2, &ss) == NULL) { + if (!resolve || str2ip2(str2, &ss, 1) == NULL) { memprintf(err, "invalid address: '%s' in '%s'\n", str2, str); goto out; } -- 2.47.3