diff options
author | Glenn Strauss <gstrauss@gluelogic.com> | 2017-10-22 14:11:26 -0400 |
---|---|---|
committer | Glenn Strauss <gstrauss@gluelogic.com> | 2017-10-22 14:13:55 -0400 |
commit | f5ff2a011d4070cdc710e02c89954328d8617ddc (patch) | |
tree | a8c5736a87d0c47e5afd53302edceffc925059b1 /src | |
parent | 3549fc828005cd5ef5110f44f17b9ff0f5665bb9 (diff) | |
download | lighttpd-git-f5ff2a011d4070cdc710e02c89954328d8617ddc.tar.gz |
[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
Diffstat (limited to 'src')
-rw-r--r-- | src/network.c | 107 |
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; } |