}
if (args[1][0] == '/') {
+ struct sockaddr_un *sk = str2sun(args[1]);
+ if (!sk) {
+ Alert("parsing [%s:%d] : Socket path '%s' too long (max %d)\n", file, linenum,
+ args[1], (int)sizeof(sk->sun_path) - 1);
+ err_code |= ERR_ALERT | ERR_FATAL;
+ goto out;
+ }
+ logsrv.u.un = *sk;
logsrv.u.addr.sa_family = AF_UNIX;
- logsrv.u.un = *str2sun(args[1]);
} else {
+ struct sockaddr_in *sk = str2sa(args[1]);
+ if (!sk) {
+ Alert("parsing [%s:%d] : Unknown host in '%s'\n", file, linenum, args[1]);
+ err_code |= ERR_ALERT | ERR_FATAL;
+ goto out;
+ }
+ logsrv.u.in = *sk;
logsrv.u.addr.sa_family = AF_INET;
- logsrv.u.in = *str2sa(args[1]);
if (!logsrv.u.in.sin_port)
logsrv.u.in.sin_port = htons(SYSLOG_PORT);
}
curproxy->grace = val;
}
else if (!strcmp(args[0], "dispatch")) { /* dispatch address */
+ struct sockaddr_in *sk;
if (curproxy == &defproxy) {
Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
err_code |= ERR_ALERT | ERR_FATAL;
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
- curproxy->dispatch_addr = *str2sa(args[1]);
+ sk = str2sa(args[1]);
+ if (!sk) {
+ Alert("parsing [%s:%d] : Unknown host in '%s'\n", file, linenum, args[1]);
+ err_code |= ERR_ALERT | ERR_FATAL;
+ goto out;
+ }
+ curproxy->dispatch_addr = *sk;
}
else if (!strcmp(args[0], "balance")) { /* set balancing with optional algorithm */
if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
}
if (!defsrv) {
+ struct sockaddr_in *sk;
+
if ((newsrv = (struct server *)calloc(1, sizeof(struct server))) == NULL) {
Alert("parsing [%s:%d] : out of memory.\n", file, linenum);
err_code |= ERR_ALERT | ERR_ABORT;
} else
newsrv->state |= SRV_MAPPORTS;
- newsrv->addr = *str2sa(raddr);
- newsrv->addr.sin_port = htons(realport);
+ sk = str2sa(raddr);
free(raddr);
+ if (!sk) {
+ Alert("parsing [%s:%d] : Unknown host in '%s'\n", file, linenum, args[2]);
+ err_code |= ERR_ALERT | ERR_FATAL;
+ goto out;
+ }
+ newsrv->addr = *sk;
+ newsrv->addr.sin_port = htons(realport);
newsrv->check_port = curproxy->defsrv.check_port;
newsrv->inter = curproxy->defsrv.inter;
cur_arg += 2;
}
else if (!defsrv && !strcmp(args[cur_arg], "addr")) {
- newsrv->check_addr = *str2sa(args[cur_arg + 1]);
+ struct sockaddr_in *sk = str2sa(args[cur_arg + 1]);
+ if (!sk) {
+ Alert("parsing [%s:%d] : Unknown host in '%s'\n", file, linenum, args[cur_arg + 1]);
+ err_code |= ERR_ALERT | ERR_FATAL;
+ goto out;
+ }
+ newsrv->check_addr = *sk;
cur_arg += 2;
}
else if (!strcmp(args[cur_arg], "port")) {
}
else if (!defsrv && !strcmp(args[cur_arg], "source")) { /* address to which we bind when connecting */
int port_low, port_high;
+ struct sockaddr_in *sk;
+
if (!*args[cur_arg + 1]) {
#if defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_LINUX_TPROXY)
Alert("parsing [%s:%d] : '%s' expects <addr>[:<port>[-<port>]], and optional '%s' <addr> as argument.\n",
goto out;
}
newsrv->state |= SRV_BIND_SRC;
- newsrv->source_addr = *str2sa_range(args[cur_arg + 1], &port_low, &port_high);
+ sk = str2sa_range(args[cur_arg + 1], &port_low, &port_high);
+ if (!sk) {
+ Alert("parsing [%s:%d] : Unknown host in '%s'\n", file, linenum, args[cur_arg + 1]);
+ err_code |= ERR_ALERT | ERR_FATAL;
+ goto out;
+ }
+ newsrv->source_addr = *sk;
if (port_low != port_high) {
int i;
} else if (!strcmp(args[cur_arg + 1], "clientip")) {
newsrv->state |= SRV_TPROXY_CIP;
} else {
+ struct sockaddr_in *sk = str2sa(args[cur_arg + 1]);
+ if (!sk) {
+ Alert("parsing [%s:%d] : Unknown host in '%s'\n", file, linenum, args[cur_arg + 1]);
+ err_code |= ERR_ALERT | ERR_FATAL;
+ goto out;
+ }
+ newsrv->tproxy_addr = *sk;
newsrv->state |= SRV_TPROXY_ADDR;
- newsrv->tproxy_addr = *str2sa(args[cur_arg + 1]);
}
global.last_checks |= LSTCHK_NETADM;
#if !defined(CONFIG_HAP_LINUX_TPROXY)
}
if (args[1][0] == '/') {
+ struct sockaddr_un *sk = str2sun(args[1]);
+ if (!sk) {
+ Alert("parsing [%s:%d] : Socket path '%s' too long (max %d)\n", file, linenum,
+ args[1], (int)sizeof(sk->sun_path) - 1);
+ err_code |= ERR_ALERT | ERR_FATAL;
+ goto out;
+ }
+ logsrv.u.un = *sk;
logsrv.u.addr.sa_family = AF_UNIX;
- logsrv.u.un = *str2sun(args[1]);
} else {
+ struct sockaddr_in *sk = str2sa(args[1]);
+ if (!sk) {
+ Alert("parsing [%s:%d] : Unknown host in '%s'\n", file, linenum, args[1]);
+ err_code |= ERR_ALERT | ERR_FATAL;
+ goto out;
+ }
+ logsrv.u.in = *sk;
logsrv.u.addr.sa_family = AF_INET;
- logsrv.u.in = *str2sa(args[1]);
if (!logsrv.u.in.sin_port) {
logsrv.u.in.sin_port =
htons(SYSLOG_PORT);
}
else if (!strcmp(args[0], "source")) { /* address to which we bind when connecting */
int cur_arg;
+ struct sockaddr_in *sk;
if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
err_code |= ERR_WARN;
curproxy->iface_name = NULL;
curproxy->iface_len = 0;
- curproxy->source_addr = *str2sa(args[1]);
+ sk = str2sa(args[1]);
+ if (!sk) {
+ Alert("parsing [%s:%d] : Unknown host in '%s'\n", file, linenum, args[1]);
+ err_code |= ERR_ALERT | ERR_FATAL;
+ goto out;
+ }
+ curproxy->source_addr = *sk;
curproxy->options |= PR_O_BIND_SRC;
cur_arg = 2;
} else if (!strcmp(args[cur_arg + 1], "clientip")) {
curproxy->options |= PR_O_TPXY_CIP;
} else {
+ struct sockaddr_in *sk = str2sa(args[cur_arg + 1]);
+ if (!sk) {
+ Alert("parsing [%s:%d] : Unknown host in '%s'\n", file, linenum, args[cur_arg + 1]);
+ err_code |= ERR_ALERT | ERR_FATAL;
+ goto out;
+ }
+ curproxy->tproxy_addr = *sk;
curproxy->options |= PR_O_TPXY_ADDR;
- curproxy->tproxy_addr = *str2sa(args[cur_arg + 1]);
}
global.last_checks |= LSTCHK_NETADM;
#if !defined(CONFIG_HAP_LINUX_TPROXY)
/*
* converts <str> to a struct sockaddr_un* which is locally allocated.
* The format is "/path", where "/path" is a path to a UNIX domain socket.
+ * NULL is returned if the socket path is invalid (too long).
*/
struct sockaddr_un *str2sun(const char *str)
{
memset(&su, 0, sizeof(su));
strsz = strlen(str) + 1;
if (strsz > sizeof(su.sun_path)) {
- Alert("Socket path '%s' too long (max %d)\n",
- str, (int)sizeof(su.sun_path) - 1);
+ return NULL;
} else {
su.sun_family = AF_UNIX;
memcpy(su.sun_path, str, strsz);
/*
* converts <str> to a struct sockaddr_in* which is locally allocated.
* The format is "addr:port", where "addr" can be a dotted IPv4 address,
- * a host name, or empty or "*" to indicate INADDR_ANY.
+ * a host name, or empty or "*" to indicate INADDR_ANY. NULL is returned
+ * if the host part cannot be resolved.
*/
struct sockaddr_in *str2sa(char *str)
{
static struct sockaddr_in sa;
+ struct sockaddr_in *ret = NULL;
char *c;
int port;
memset(&sa, 0, sizeof(sa));
str = strdup(str);
if (str == NULL)
- goto out_nofree;
+ goto out;
if ((c = strrchr(str,':')) != NULL) {
*c++ = '\0';
sa.sin_addr.s_addr = INADDR_ANY;
}
else if (!inet_pton(AF_INET, str, &sa.sin_addr)) {
- struct hostent *he;
-
- if ((he = gethostbyname(str)) == NULL) {
- Alert("Invalid server name: '%s'\n", str);
- }
- else
- sa.sin_addr = *(struct in_addr *) *(he->h_addr_list);
+ struct hostent *he = gethostbyname(str);
+ if (!he)
+ goto out;
+ sa.sin_addr = *(struct in_addr *) *(he->h_addr_list);
}
sa.sin_port = htons(port);
sa.sin_family = AF_INET;
-
+ ret = &sa;
+ out:
free(str);
- out_nofree:
- return &sa;
+ return ret;
}
/*
* port is set in the sockaddr_in. Thus, it is enough to check the size of the
* returned range to know if an array must be allocated or not. The format is
* "addr[:port[-port]]", where "addr" can be a dotted IPv4 address, a host
- * name, or empty or "*" to indicate INADDR_ANY.
+ * name, or empty or "*" to indicate INADDR_ANY. NULL is returned if the host
+ * part cannot be resolved.
*/
struct sockaddr_in *str2sa_range(char *str, int *low, int *high)
{
static struct sockaddr_in sa;
+ struct sockaddr_in *ret = NULL;
char *c;
int portl, porth;
memset(&sa, 0, sizeof(sa));
str = strdup(str);
if (str == NULL)
- goto out_nofree;
+ goto out;
if ((c = strrchr(str,':')) != NULL) {
char *sep;
sa.sin_addr.s_addr = INADDR_ANY;
}
else if (!inet_pton(AF_INET, str, &sa.sin_addr)) {
- struct hostent *he;
-
- if ((he = gethostbyname(str)) == NULL) {
- Alert("Invalid server name: '%s'\n", str);
- }
- else
- sa.sin_addr = *(struct in_addr *) *(he->h_addr_list);
+ struct hostent *he = gethostbyname(str);
+ if (!he)
+ goto out;
+ sa.sin_addr = *(struct in_addr *) *(he->h_addr_list);
}
sa.sin_port = htons(portl);
sa.sin_family = AF_INET;
+ ret = &sa;
*low = portl;
*high = porth;
+ out:
free(str);
- out_nofree:
- return &sa;
+ return ret;
}
/* converts <str> to a struct in_addr containing a network mask. It can be