Browse Source

[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.
personal/stbuehler/mod-csrf
Glenn Strauss 5 years ago
parent
commit
1836309209
  1. 22
      src/gw_backend.c
  2. 41
      src/inet_ntop_cache.c

22
src/gw_backend.c

@ -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);
}

41
src/inet_ntop_cache.c

@ -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));

Loading…
Cancel
Save