}
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;
}
}
- 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;
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;
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;
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;
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;
}
}
- 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;
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);
} 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);
* - 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;
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);
}
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);
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);
* 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;
int abstract = 0;
portl = porth = porta = 0;
+ if (fqdn)
+ *fqdn = NULL;
str2 = back = env_expand(strdup(str));
if (str2 == NULL) {
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 */
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;