summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlenn Strauss <gstrauss@gluelogic.com>2017-10-22 14:11:26 -0400
committerGlenn Strauss <gstrauss@gluelogic.com>2017-10-22 14:13:55 -0400
commitf5ff2a011d4070cdc710e02c89954328d8617ddc (patch)
treea8c5736a87d0c47e5afd53302edceffc925059b1
parent3549fc828005cd5ef5110f44f17b9ff0f5665bb9 (diff)
downloadlighttpd1.4-f5ff2a011d4070cdc710e02c89954328d8617ddc.tar.gz
lighttpd1.4-f5ff2a011d4070cdc710e02c89954328d8617ddc.zip
[core] normalize config addrs for eq and ne (#2830)
address strings need to have DNS resolved and port added for consistency when matching other config conditionals x-ref: "1.4.46 regression: $SERVER["socket"] matches when it shouldn't" https://redmine.lighttpd.net/issues/2830
-rw-r--r--src/network.c107
1 files changed, 15 insertions, 92 deletions
diff --git a/src/network.c b/src/network.c
index 6c67d876..95f5bf37 100644
--- a/src/network.c
+++ b/src/network.c
@@ -137,12 +137,10 @@ static int network_host_parse_addr(server *srv, sock_addr *addr, socklen_t *addr
}
static int network_server_init(server *srv, buffer *host_token, size_t sidx, int stdin_fd) {
- socklen_t addr_len;
server_socket *srv_socket;
- unsigned int port = 0;
const char *host;
specific_config *s = srv->config_storage[sidx];
- sa_family_t family = AF_INET; /* default */
+ socklen_t addr_len = sizeof(sock_addr);
sock_addr addr;
#ifdef __WIN32
@@ -160,6 +158,11 @@ static int network_server_init(server *srv, buffer *host_token, size_t sidx, int
}
#endif
+ if (buffer_string_is_empty(host_token)) {
+ log_error_write(srv, __FILE__, __LINE__, "s", "value of $SERVER[\"socket\"] must not be empty");
+ return -1;
+ }
+
/* check if we already know this socket, and if yes, don't init it
* (optimization: check strings here to filter out exact matches;
* binary addresses are matched further below) */
@@ -170,70 +173,11 @@ static int network_server_init(server *srv, buffer *host_token, size_t sidx, int
}
}
- buffer_copy_buffer(srv->tmp_buf, host_token); /*(allocates ->ptr even if host_token is NULL)*/
- host = srv->tmp_buf->ptr;
-
- if (-1 != stdin_fd) { } else
- if (host[0] == '/') {
- /* host is a unix-domain-socket */
-#ifdef HAVE_SYS_UN_H
- family = AF_UNIX;
-#else
- log_error_write(srv, __FILE__, __LINE__, "s",
- "ERROR: Unix Domain sockets are not supported.");
- return -1;
-#endif
- } else {
- /* ipv4:port
- * [ipv6]:port
- */
- buffer *b = srv->tmp_buf;
- size_t len = buffer_string_length(b);
- char *sp = NULL;
- if (0 == len) {
- log_error_write(srv, __FILE__, __LINE__, "s", "value of $SERVER[\"socket\"] must not be empty");
- return -1;
- }
- if ((b->ptr[0] == '[' && b->ptr[len-1] == ']') || NULL == (sp = strrchr(b->ptr, ':'))) {
- /* use server.port if set in config, or else default from config_set_defaults() */
- port = srv->srvconf.port;
- sp = b->ptr + len; /* point to '\0' at end of string so end of IPv6 address can be found below */
- } else {
- /* found ip:port separator at *sp; port doesn't end in ']', so *sp hopefully doesn't split an IPv6 address */
- *sp = '\0';
- port = strtol(sp+1, NULL, 10);
- }
-
- /* check for [ and ] */
- if (b->ptr[0] == '[' && *(sp-1) == ']') {
- *(sp-1) = '\0';
- host++;
-
- s->use_ipv6 = 1;
- }
-
- if (port == 0 || port > 65535) {
- log_error_write(srv, __FILE__, __LINE__, "sd", "port not set or out of range:", port);
-
- return -1;
- }
- }
-
-#ifdef HAVE_IPV6
- if (-1 != stdin_fd) { } else
- if (s->use_ipv6) {
- family = AF_INET6;
- }
-#endif
-
- if (*host == '\0') {
- if (family == AF_INET6) {
+ host = host_token->ptr;
+ if ((s->use_ipv6 && (*host == '\0' || *host == ':')) || (host[0] == '[' && host[1] == ']')) {
log_error_write(srv, __FILE__, __LINE__, "s", "warning: please use server.use-ipv6 only for hostnames, not without server.bind / empty address; your config will break if the kernel default for IPV6_V6ONLY changes");
- host = "::";
- } else if (family == AF_INET) {
- host = "0.0.0.0";
- }
}
+ if (*host == '[') s->use_ipv6 = 1;
memset(&addr, 0, sizeof(addr));
if (-1 != stdin_fd) {
@@ -241,15 +185,16 @@ static int network_server_init(server *srv, buffer *host_token, size_t sidx, int
close(stdin_fd);/*(graceful restart listening to "/dev/stdin")*/
return 0;
}
- addr_len = sizeof(sock_addr);
if (-1 == getsockname(stdin_fd, (struct sockaddr *)&addr, &addr_len)) {
log_error_write(srv, __FILE__, __LINE__, "ss",
"getsockname()", strerror(errno));
return -1;
}
- } else if (1 != sock_addr_from_str_hints(srv, &addr, &addr_len, host, family, port)) {
+ } else if (0 != network_host_parse_addr(srv, &addr, &addr_len, host_token, s->use_ipv6)) {
return -1;
}
+ network_host_normalize_addr_str(host_token, &addr);
+ host = host_token->ptr;
if (srv->srvconf.preflight_check) {
return 0;
@@ -258,7 +203,6 @@ static int network_server_init(server *srv, buffer *host_token, size_t sidx, int
/* check if we already know this socket (after potential DNS resolution), and if yes, don't init it */
for (size_t i = 0; i < srv->srv_sockets.used; ++i) {
if (0 == memcmp(&srv->srv_sockets.ptr[i]->addr, &addr, sizeof(addr))) {
- buffer_copy_buffer(host_token, srv->srv_sockets.ptr[i]->srv_token);
return 0;
}
}
@@ -270,18 +214,7 @@ static int network_server_init(server *srv, buffer *host_token, size_t sidx, int
srv_socket->fde_ndx = -1;
srv_socket->sidx = sidx;
srv_socket->is_ssl = s->ssl_enabled;
-
- srv_socket->srv_token = buffer_init();
- if (addr.plain.sa_family == AF_INET6) buffer_append_string_len(srv_socket->srv_token, CONST_STR_LEN("["));
- sock_addr_inet_ntop_append_buffer(srv_socket->srv_token, &srv_socket->addr);
- if (addr.plain.sa_family == AF_INET6) buffer_append_string_len(srv_socket->srv_token, CONST_STR_LEN("]"));
- if (addr.plain.sa_family != AF_UNIX) {
- port = addr.plain.sa_family == AF_INET ? ntohs(addr.ipv4.sin_port) : ntohs(addr.ipv6.sin6_port);
- buffer_append_string_len(srv_socket->srv_token, CONST_STR_LEN(":"));
- buffer_append_int(srv_socket->srv_token, (int)port);
- }
- /* update host_token (dc->string) for consistent string comparison in lighttpd.conf conditions */
- buffer_copy_buffer(host_token, srv_socket->srv_token);
+ srv_socket->srv_token = buffer_init_buffer(host_token);
if (srv->srv_sockets.size == 0) {
srv->srv_sockets.size = 4;
@@ -380,18 +313,8 @@ static int network_server_init(server *srv, buffer *host_token, size_t sidx, int
if (-1 != stdin_fd) { } else
if (0 != bind(srv_socket->fd, (struct sockaddr *) &(srv_socket->addr), addr_len)) {
- switch(srv_socket->addr.plain.sa_family) {
- case AF_UNIX:
- log_error_write(srv, __FILE__, __LINE__, "sds",
- "can't bind to socket:",
- host, strerror(errno));
- break;
- default:
- log_error_write(srv, __FILE__, __LINE__, "ssds",
- "can't bind to port:",
- host, port, strerror(errno));
- break;
- }
+ log_error_write(srv, __FILE__, __LINE__, "sss",
+ "can't bind to socket:", host, strerror(errno));
return -1;
}