mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-04-28 05:48:01 +00:00
MEDIUM: tools: make str2sa_range() optionally return the FQDN
The function does a bunch of things among which resolving environment variables, skipping address family specifiers and trimming port ranges. It is the only one which sees the complete host name before trying to resolve it. The DNS resolving code needs to know the original hostname, so we modify this function to optionally provide it to the caller. Note that the function itself doesn't know if the host part was a host or an address, but str2ip() knows that and can be asked not to try to resolve. So we first try to parse the address without resolving and try again with resolving enabled. This way we know if the address is explicit or needs some kind of resolution.
This commit is contained in:
parent
90447582d7
commit
72b8c1f0aa
@ -277,7 +277,7 @@ extern const char *invalid_domainchar(const char *name);
|
||||
* If <pfx> is non-null, it is used as a string prefix before any path-based
|
||||
* address (typically the path to a unix socket).
|
||||
*/
|
||||
struct sockaddr_storage *str2sa_range(const char *str, int *low, int *high, char **err, const char *pfx);
|
||||
struct sockaddr_storage *str2sa_range(const char *str, int *low, int *high, char **err, const char *pfx, char **fqdn);
|
||||
|
||||
/* converts <str> 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
|
||||
|
@ -239,7 +239,8 @@ 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);
|
||||
curproxy == global.stats_fe ? NULL : global.unix_bind.prefix,
|
||||
NULL);
|
||||
if (!ss2)
|
||||
goto fail;
|
||||
|
||||
@ -1597,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);
|
||||
sk = str2sa_range(args[1], &port1, &port2, &errmsg, NULL, NULL);
|
||||
if (!sk) {
|
||||
Alert("parsing [%s:%d] : '%s': %s\n", file, linenum, args[0], errmsg);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
@ -2027,7 +2028,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);
|
||||
sk = str2sa_range(args[2], &port1, &port2, &errmsg, NULL, NULL);
|
||||
if (!sk) {
|
||||
Alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
@ -2227,7 +2228,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);
|
||||
sk = str2sa_range(args[2], &port1, &port2, &errmsg, NULL, NULL);
|
||||
if (!sk) {
|
||||
Alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
@ -2411,7 +2412,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);
|
||||
sk = str2sa_range(args[2], &port1, &port2, &errmsg, NULL, NULL);
|
||||
if (!sk) {
|
||||
Alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
@ -5545,7 +5546,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);
|
||||
sk = str2sa_range(args[1], &port1, &port2, &errmsg, NULL, NULL);
|
||||
if (!sk) {
|
||||
Alert("parsing [%s:%d] : '%s' : %s\n", file, linenum, args[0], errmsg);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
@ -5817,7 +5818,7 @@ stats_error_parsing:
|
||||
}
|
||||
}
|
||||
|
||||
sk = str2sa_range(args[1], &port1, &port2, &errmsg, NULL);
|
||||
sk = str2sa_range(args[1], &port1, &port2, &errmsg, NULL, NULL);
|
||||
if (!sk) {
|
||||
Alert("parsing [%s:%d] : '%s': %s\n", file, linenum, args[0], errmsg);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
@ -5869,7 +5870,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);
|
||||
sk = str2sa_range(args[1], &port1, &port2, &errmsg, NULL, NULL);
|
||||
if (!sk) {
|
||||
Alert("parsing [%s:%d] : '%s %s' : %s\n",
|
||||
file, linenum, args[0], args[1], errmsg);
|
||||
@ -5954,7 +5955,7 @@ stats_error_parsing:
|
||||
} else {
|
||||
struct sockaddr_storage *sk;
|
||||
|
||||
sk = str2sa_range(args[cur_arg + 1], &port1, &port2, &errmsg, NULL);
|
||||
sk = str2sa_range(args[cur_arg + 1], &port1, &port2, &errmsg, NULL, NULL);
|
||||
if (!sk) {
|
||||
Alert("parsing [%s:%d] : '%s %s' : %s\n",
|
||||
file, linenum, args[cur_arg], args[cur_arg+1], errmsg);
|
||||
|
@ -904,7 +904,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);
|
||||
sk = str2sa_range(args[2], &port1, &port2, &errmsg, NULL, NULL);
|
||||
if (!sk) {
|
||||
Alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
@ -1189,7 +1189,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);
|
||||
sk = str2sa_range(args[cur_arg + 1], &port1, &port2, &errmsg, NULL, NULL);
|
||||
if (!sk) {
|
||||
Alert("parsing [%s:%d] : '%s' : %s\n",
|
||||
file, linenum, args[cur_arg], errmsg);
|
||||
@ -1397,7 +1397,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);
|
||||
sk = str2sa_range(args[cur_arg + 1], &port_low, &port_high, &errmsg, NULL, NULL);
|
||||
if (!sk) {
|
||||
Alert("parsing [%s:%d] : '%s %s' : %s\n",
|
||||
file, linenum, args[cur_arg], args[cur_arg+1], errmsg);
|
||||
@ -1497,7 +1497,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);
|
||||
sk = str2sa_range(args[cur_arg + 1], &port1, &port2, &errmsg, NULL, NULL);
|
||||
if (!sk) {
|
||||
Alert("parsing [%s:%d] : '%s %s' : %s\n",
|
||||
file, linenum, args[cur_arg], args[cur_arg+1], errmsg);
|
||||
|
@ -755,10 +755,15 @@ struct sockaddr_storage *str2ip2(const char *str, struct sockaddr_storage *sa, i
|
||||
* If <pfx> is non-null, it is used as a string prefix before any path-based
|
||||
* address (typically the path to a unix socket).
|
||||
*
|
||||
* if <fqdn> is non-null, it will be filled with :
|
||||
* - a pointer to the FQDN of the server name to resolve if there's one, and
|
||||
* that the caller will have to free(),
|
||||
* - NULL if there was an explicit address that doesn't require 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_UNSPEC.
|
||||
*/
|
||||
struct sockaddr_storage *str2sa_range(const char *str, int *low, int *high, char **err, const char *pfx)
|
||||
struct sockaddr_storage *str2sa_range(const char *str, int *low, int *high, char **err, const char *pfx, char **fqdn)
|
||||
{
|
||||
static struct sockaddr_storage ss;
|
||||
struct sockaddr_storage *ret = NULL;
|
||||
@ -768,6 +773,8 @@ struct sockaddr_storage *str2sa_range(const char *str, int *low, int *high, char
|
||||
int abstract = 0;
|
||||
|
||||
portl = porth = porta = 0;
|
||||
if (fqdn)
|
||||
*fqdn = NULL;
|
||||
|
||||
str2 = back = env_expand(strdup(str));
|
||||
if (str2 == NULL) {
|
||||
@ -840,15 +847,20 @@ struct sockaddr_storage *str2sa_range(const char *str, int *low, int *high, char
|
||||
memcpy(((struct sockaddr_un *)&ss)->sun_path + prefix_path_len + abstract, str2, adr_len + 1 - abstract);
|
||||
}
|
||||
else { /* IPv4 and IPv6 */
|
||||
int use_fqdn = 0;
|
||||
|
||||
port1 = strrchr(str2, ':');
|
||||
if (port1)
|
||||
*port1++ = '\0';
|
||||
else
|
||||
port1 = "";
|
||||
|
||||
if (str2ip(str2, &ss) == NULL) {
|
||||
memprintf(err, "invalid address: '%s' in '%s'\n", str2, str);
|
||||
goto out;
|
||||
if (str2ip2(str2, &ss, 0) == NULL) {
|
||||
use_fqdn = 1;
|
||||
if (str2ip(str2, &ss) == NULL) {
|
||||
memprintf(err, "invalid address: '%s' in '%s'\n", str2, str);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (isdigit((int)(unsigned char)*port1)) { /* single port or range */
|
||||
@ -874,6 +886,13 @@ struct sockaddr_storage *str2sa_range(const char *str, int *low, int *high, char
|
||||
goto out;
|
||||
}
|
||||
set_host_port(&ss, porta);
|
||||
|
||||
if (use_fqdn && fqdn) {
|
||||
if (str2 != back)
|
||||
memmove(back, str2, strlen(str2) + 1);
|
||||
*fqdn = back;
|
||||
back = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ret = &ss;
|
||||
|
Loading…
Reference in New Issue
Block a user