MEDIUM: tools: make str2sa_range() return the FQDN even when not resolving

This will be needed to later postpone server address resolution. We need the
FQDN even when it doesn't resolve. The caller then needs to check if fqdn was
set when resolve is null to detect that the address couldn't be parsed and
needs later resolution.
This commit is contained in:
Willy Tarreau 2016-11-02 22:27:10 +01:00
parent def0d22cc5
commit ceccdd78a7
1 changed files with 30 additions and 16 deletions

View File

@ -808,7 +808,10 @@ 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 <resolve> is non-null.
* Hostnames are only resolved if <resolve> is non-null. Note that if <resolve>
* is null, <fqdn> is still honnored so it is possible for the caller to know
* whether a resolution failed by setting <resolve> to null and checking if
* <fqdn> 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_UNSPEC.
@ -902,7 +905,6 @@ 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;
char *end = str2 + strlen(str2);
char *chr;
@ -927,14 +929,6 @@ struct sockaddr_storage *str2sa_range(const char *str, int *low, int *high, char
port1 = "";
}
if (str2ip2(str2, &ss, 0) == NULL) {
use_fqdn = 1;
if (!resolve || str2ip2(str2, &ss, 1) == NULL) {
memprintf(err, "invalid address: '%s' in '%s'\n", str2, str);
goto out;
}
}
if (isdigit((int)(unsigned char)*port1)) { /* single port or range */
port2 = strchr(port1, '-');
if (port2)
@ -957,14 +951,34 @@ struct sockaddr_storage *str2sa_range(const char *str, int *low, int *high, char
memprintf(err, "invalid character '%c' in port number '%s' in '%s'\n", *port1, port1, str);
goto out;
}
set_host_port(&ss, porta);
if (use_fqdn && fqdn) {
if (str2 != back)
memmove(back, str2, strlen(str2) + 1);
*fqdn = back;
back = NULL;
/* 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 <fqdn> is
* set or if resolve is set, otherwise it's an error.
*/
if (str2ip2(str2, &ss, 0) == NULL) {
if (!resolve && fqdn) {
/* we'll still want to store the port, so let's
* force it to IPv4 for now.
*/
memset(&ss, 0, sizeof(ss));
ss.ss_family = AF_INET;
}
else if ((!resolve && !fqdn) ||
(resolve && str2ip2(str2, &ss, 1) == NULL)) {
memprintf(err, "invalid address: '%s' in '%s'\n", str2, str);
goto out;
}
if (fqdn) {
if (str2 != back)
memmove(back, str2, strlen(str2) + 1);
*fqdn = back;
back = NULL;
}
}
set_host_port(&ss, porta);
}
ret = &ss;