[core] resolve DNS at startup for socket backends

resolve DNS at startup and use the first IP address returned by resolver

Note: use of IP addresses is recommended instead of using DNS names.
If DNS names are used, but DNS is slow or unavailable, then lighttpd
will either appear to hang at startup or will fail to start up.
This commit is contained in:
Glenn Strauss 2017-07-15 18:06:26 -04:00
parent 0beb8b89d8
commit 1836309209
2 changed files with 53 additions and 10 deletions

View File

@ -369,20 +369,22 @@ static int gw_proc_sockaddr_init(server *srv, gw_host *host, gw_proc *proc) {
}
buffer_copy_string_len(proc->connection_name, CONST_STR_LEN("unix:"));
buffer_append_string_buffer(proc->connection_name, proc->unixsocket);
} else {
if (1 != sock_addr_from_buffer_hints_numeric(srv, &addr, &addrlen,
host->host, host->family,
proc->port)) {
}
else {
/*(note: name resolution here is *blocking* if IP string not supplied)*/
if (1 != sock_addr_from_str_hints(srv, &addr, &addrlen,
host->host->ptr, 0, proc->port)) {
errno = EINVAL;
return -1;
}
buffer_copy_string_len(proc->connection_name, CONST_STR_LEN("tcp:"));
if (!buffer_string_is_empty(host->host)) {
buffer_append_string_buffer(proc->connection_name, host->host);
} else {
buffer_append_string_len(proc->connection_name,
CONST_STR_LEN("localhost"));
else {
/* overwrite host->host buffer with IP addr string so that
* any further use of gw_host does not block on DNS lookup */
sock_addr_inet_ntop_copy_buffer(host->host, &addr);
host->family = addr.plain.sa_family;
}
buffer_copy_string_len(proc->connection_name, CONST_STR_LEN("tcp:"));
buffer_append_string_buffer(proc->connection_name, host->host);
buffer_append_string_len(proc->connection_name, CONST_STR_LEN(":"));
buffer_append_int(proc->connection_name, proc->port);
}

View File

@ -154,6 +154,47 @@ int sock_addr_from_str_hints(server *srv, sock_addr *addr, socklen_t *len, const
{
/*(note: name resolution here is *blocking*)*/
switch(family) {
case AF_UNSPEC:
if (0 == strcmp(str, "localhost")) {
/*(special-case "localhost" to IPv4 127.0.0.1)*/
memset(addr, 0, sizeof(struct sockaddr_in));
addr->ipv4.sin_family = AF_INET;
addr->ipv4.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
addr->ipv4.sin_port = htons(port);
*len = sizeof(struct sockaddr_in);
return 1;
}
#ifdef HAVE_IPV6
else {
struct addrinfo hints, *res;
int r;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
if (0 != (r = getaddrinfo(str, NULL, &hints, &res))) {
log_error_write(srv, __FILE__, __LINE__,
"sssss", "getaddrinfo failed: ",
gai_strerror(r), "'", str, "'");
return 0;
}
memcpy(addr, res->ai_addr, res->ai_addrlen);
freeaddrinfo(res);
if (AF_INET6 == addr->plain.sa_family) {
addr->ipv6.sin6_port = htons(port);
*len = sizeof(struct sockaddr_in6);
}
else { /* AF_INET */
addr->ipv4.sin_port = htons(port);
*len = sizeof(struct sockaddr_in);
}
return 1;
}
#else
/* fall through */
#endif
#ifdef HAVE_IPV6
case AF_INET6:
memset(addr, 0, sizeof(struct sockaddr_in6));