[core] continue collecting use of netdb.h

continue collecting use of netdb.h into inet_ntop_cache.[ch]
personal/stbuehler/mod-csrf
Glenn Strauss 5 years ago
parent 6a8de931ec
commit 1002574692
  1. 61
      src/inet_ntop_cache.c
  2. 1
      src/inet_ntop_cache.h
  3. 162
      src/mod_fastcgi.c
  4. 55
      src/mod_proxy.c
  5. 140
      src/mod_scgi.c

@ -310,6 +310,67 @@ int sock_addr_from_str_numeric(server *srv, sock_addr *addr, const char *str)
}
int sock_addr_from_buffer_hints_numeric(server *srv, sock_addr *addr, socklen_t *len, const buffer *b, int family, unsigned short port)
{
/*(this routine originates from mod_fastcgi.c and mod_scgi.c)*/
if (buffer_string_is_empty(b)) {
/*(preserve existing behavior (for now))*/
/*(would be better if initialized default when reading config)*/
memset(&addr->ipv4, 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;
}
else if (1 == sock_addr_inet_pton(addr, b->ptr, family, port)) {
*len = (family == AF_INET)
? sizeof(struct sockaddr_in) /* family == AF_INET */
: sizeof(struct sockaddr_in6); /* family == AF_INET6 */
return 1;
}
#if defined(HAVE_IPV6) && defined(HAVE_INET_PTON)
else if (family == AF_INET6) {
log_error_write(srv, __FILE__, __LINE__, "sb",
"invalid IPv6 address literal:", b);
return 0;
}
#endif
#ifndef HAVE_INET_PTON /*(preserve existing behavior (for now))*/
else {
struct hostent *he = gethostbyname(b->ptr);
if (NULL == he) {
log_error_write(srv, __FILE__, __LINE__, "sdb",
"gethostbyname failed:", h_errno, b);
return 0;
}
if (he->h_addrtype != AF_INET) {
log_error_write(srv, __FILE__, __LINE__, "sd",
"addr-type != AF_INET:", he->h_addrtype);
return 0;
}
if (he->h_length != sizeof(struct in_addr)) {
log_error_write(srv, __FILE__, __LINE__, "sd",
"addr-length != sizeof(in_addr):",he->h_length);
return 0;
}
memset(&addr->ipv4, 0, sizeof(struct sockaddr_in));
memcpy(&addr->ipv4.sin_addr.s_addr, he->h_addr_list[0], he->h_length);
addr->ipv4.sin_family = AF_INET;
addr->ipv4.sin_port = htons(port);
*len = sizeof(struct sockaddr_in);
}
#else
UNUSED(srv);
#endif
return 0;
}
const char * inet_ntop_cache_get_ip(server *srv, sock_addr *addr) {
#ifdef HAVE_IPV6
typedef struct {

@ -19,6 +19,7 @@ const char * sock_addr_inet_ntop(const sock_addr *addr, char *buf, socklen_t sz)
int sock_addr_inet_ntop_copy_buffer(buffer *b, const sock_addr *addr);
int sock_addr_inet_ntop_append_buffer(buffer *b, const sock_addr *addr);
int sock_addr_from_buffer_hints_numeric(server *srv, sock_addr *addr, socklen_t *len, const buffer *b, int family, unsigned short port);
int sock_addr_from_str_hints(server *srv, sock_addr *addr, socklen_t *len, const char *str, int family, unsigned short port);
int sock_addr_from_str_numeric(server *srv, sock_addr *addr, const char *str);

@ -10,6 +10,7 @@
#include "connections.h"
#include "response.h"
#include "joblist.h"
#include "inet_ntop_cache.h"
#include "plugin.h"
@ -904,15 +905,8 @@ static int fcgi_spawn_connection(server *srv,
int fcgi_fd;
int status;
struct timeval tv = { 0, 10 * 1000 };
#ifdef HAVE_SYS_UN_H
struct sockaddr_un fcgi_addr_un;
#endif
#if defined(HAVE_IPV6) && defined(HAVE_INET_PTON)
struct sockaddr_in6 fcgi_addr_in6;
#endif
struct sockaddr_in fcgi_addr_in;
struct sockaddr *fcgi_addr;
sock_addr addr;
struct sockaddr *fcgi_addr = (struct sockaddr *)&addr;
socklen_t servlen;
if (p->conf.debug) {
@ -921,89 +915,19 @@ static int fcgi_spawn_connection(server *srv,
}
if (!buffer_string_is_empty(proc->unixsocket)) {
#ifdef HAVE_SYS_UN_H
memset(&fcgi_addr_un, 0, sizeof(fcgi_addr_un));
fcgi_addr_un.sun_family = AF_UNIX;
if (buffer_string_length(proc->unixsocket) + 1 > sizeof(fcgi_addr_un.sun_path)) {
log_error_write(srv, __FILE__, __LINE__, "sB",
"ERROR: Unix Domain socket filename too long:",
proc->unixsocket);
if (1 != sock_addr_from_str_hints(srv, &addr, &servlen, proc->unixsocket->ptr, AF_UNIX, 0)) {
return -1;
}
memcpy(fcgi_addr_un.sun_path, proc->unixsocket->ptr, buffer_string_length(proc->unixsocket) + 1);
#ifdef SUN_LEN
servlen = SUN_LEN(&fcgi_addr_un);
#else
/* stevens says: */
servlen = buffer_string_length(proc->unixsocket) + 1 + sizeof(fcgi_addr_un.sun_family);
#endif
fcgi_addr = (struct sockaddr *) &fcgi_addr_un;
buffer_copy_string_len(proc->connection_name, CONST_STR_LEN("unix:"));
buffer_append_string_buffer(proc->connection_name, proc->unixsocket);
#else
log_error_write(srv, __FILE__, __LINE__, "s",
"ERROR: Unix Domain sockets are not supported.");
return -1;
#endif
} else if (buffer_string_is_empty(host->host)) {
memset(&fcgi_addr_in, 0, sizeof(fcgi_addr_in));
fcgi_addr_in.sin_family = AF_INET;
fcgi_addr_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
fcgi_addr_in.sin_port = htons(proc->port);
servlen = sizeof(fcgi_addr_in);
fcgi_addr = (struct sockaddr *) &fcgi_addr_in;
#if defined(HAVE_IPV6) && defined(HAVE_INET_PTON)
} else if (host->family == AF_INET6) {
memset(&fcgi_addr_in6, 0, sizeof(fcgi_addr_in6));
fcgi_addr_in6.sin6_family = AF_INET6;
inet_pton(AF_INET6, host->host->ptr, (char *) &fcgi_addr_in6.sin6_addr);
fcgi_addr_in6.sin6_port = htons(proc->port);
servlen = sizeof(fcgi_addr_in6);
fcgi_addr = (struct sockaddr *) &fcgi_addr_in6;
#endif
} else {
memset(&fcgi_addr_in, 0, sizeof(fcgi_addr_in));
fcgi_addr_in.sin_family = AF_INET;
#if defined(HAVE_INET_PTON)
inet_pton(AF_INET, host->host->ptr, (char *) &fcgi_addr_in.sin_addr);
#else
{
struct hostent *he;
/* set a useful default */
fcgi_addr_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
if (NULL == (he = gethostbyname(host->host->ptr))) {
log_error_write(srv, __FILE__, __LINE__,
"sdb", "gethostbyname failed: ",
h_errno, host->host);
return -1;
}
if (he->h_addrtype != AF_INET) {
log_error_write(srv, __FILE__, __LINE__, "sd", "addr-type != AF_INET: ", he->h_addrtype);
return -1;
}
if (he->h_length != sizeof(struct in_addr)) {
log_error_write(srv, __FILE__, __LINE__, "sd", "addr-length != sizeof(in_addr): ", he->h_length);
return -1;
}
memcpy(&(fcgi_addr_in.sin_addr.s_addr), he->h_addr_list[0], he->h_length);
if (1 != sock_addr_from_buffer_hints_numeric(srv, &addr, &servlen, host->host, host->family, proc->port)) {
return -1;
}
#endif
fcgi_addr_in.sin_port = htons(proc->port);
servlen = sizeof(fcgi_addr_in);
fcgi_addr = (struct sockaddr *) &fcgi_addr_in;
}
if (buffer_string_is_empty(proc->unixsocket)) {
if (!buffer_string_is_empty(proc->unixsocket)) {
buffer_copy_string_len(proc->connection_name, CONST_STR_LEN("unix:"));
buffer_append_string_buffer(proc->connection_name, proc->unixsocket);
} else {
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);
@ -1780,14 +1704,8 @@ typedef enum {
} connection_result_t;
static connection_result_t fcgi_establish_connection(server *srv, handler_ctx *hctx) {
struct sockaddr *fcgi_addr;
struct sockaddr_in fcgi_addr_in;
#if defined(HAVE_IPV6) && defined(HAVE_INET_PTON)
struct sockaddr_in6 fcgi_addr_in6;
#endif
#ifdef HAVE_SYS_UN_H
struct sockaddr_un fcgi_addr_un;
#endif
sock_addr addr;
struct sockaddr *fcgi_addr = (struct sockaddr *)&addr;
socklen_t servlen;
fcgi_extension_host *host = hctx->host;
@ -1795,64 +1713,22 @@ static connection_result_t fcgi_establish_connection(server *srv, handler_ctx *h
int fcgi_fd = hctx->fd;
if (!buffer_string_is_empty(proc->unixsocket)) {
#ifdef HAVE_SYS_UN_H
/* use the unix domain socket */
memset(&fcgi_addr_un, 0, sizeof(fcgi_addr_un));
fcgi_addr_un.sun_family = AF_UNIX;
if (buffer_string_length(proc->unixsocket) + 1 > sizeof(fcgi_addr_un.sun_path)) {
log_error_write(srv, __FILE__, __LINE__, "sB",
"ERROR: Unix Domain socket filename too long:",
proc->unixsocket);
if (1 != sock_addr_from_str_hints(srv, &addr, &servlen, proc->unixsocket->ptr, AF_UNIX, 0)) {
return CONNECTION_DEAD;
}
memcpy(fcgi_addr_un.sun_path, proc->unixsocket->ptr, buffer_string_length(proc->unixsocket) + 1);
#ifdef SUN_LEN
servlen = SUN_LEN(&fcgi_addr_un);
#else
/* stevens says: */
servlen = buffer_string_length(proc->unixsocket) + 1 + sizeof(fcgi_addr_un.sun_family);
#endif
fcgi_addr = (struct sockaddr *) &fcgi_addr_un;
} else {
if (1 != sock_addr_from_buffer_hints_numeric(srv, &addr, &servlen, host->host, host->family, proc->port)) {
return CONNECTION_DEAD;
}
}
if (!buffer_string_is_empty(proc->unixsocket)) {
if (buffer_string_is_empty(proc->connection_name)) {
/* on remote spawing we have to set the connection-name now */
buffer_copy_string_len(proc->connection_name, CONST_STR_LEN("unix:"));
buffer_append_string_buffer(proc->connection_name, proc->unixsocket);
}
#else
return CONNECTION_DEAD;
#endif
#if defined(HAVE_IPV6) && defined(HAVE_INET_PTON)
} else if (host->family == AF_INET6 && !buffer_string_is_empty(host->host)) {
memset(&fcgi_addr_in6, 0, sizeof(fcgi_addr_in6));
fcgi_addr_in6.sin6_family = AF_INET6;
inet_pton(AF_INET6, host->host->ptr, (char *) &fcgi_addr_in6.sin6_addr);
fcgi_addr_in6.sin6_port = htons(proc->port);
servlen = sizeof(fcgi_addr_in6);
fcgi_addr = (struct sockaddr *) &fcgi_addr_in6;
#endif
} else {
memset(&fcgi_addr_in, 0, sizeof(fcgi_addr_in));
fcgi_addr_in.sin_family = AF_INET;
if (!buffer_string_is_empty(host->host)) {
if (0 == inet_aton(host->host->ptr, &(fcgi_addr_in.sin_addr))) {
log_error_write(srv, __FILE__, __LINE__, "sbs",
"converting IP address failed for", host->host,
"\nBe sure to specify an IP address here");
return CONNECTION_DEAD;
}
} else {
fcgi_addr_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
}
fcgi_addr_in.sin_port = htons(proc->port);
servlen = sizeof(fcgi_addr_in);
fcgi_addr = (struct sockaddr *) &fcgi_addr_in;
}
if (buffer_string_is_empty(proc->unixsocket)) {
if (buffer_string_is_empty(proc->connection_name)) {
/* on remote spawing we have to set the connection-name now */
buffer_copy_string_len(proc->connection_name, CONST_STR_LEN("tcp:"));

@ -666,55 +666,30 @@ static handler_t proxy_reconnect(server *srv, handler_ctx *hctx) {
}
static int proxy_establish_connection(server *srv, handler_ctx *hctx) {
struct sockaddr *proxy_addr;
struct sockaddr_in proxy_addr_in;
#if defined(HAVE_SYS_UN_H)
struct sockaddr_un proxy_addr_un;
#endif
#if defined(HAVE_IPV6) && defined(HAVE_INET_PTON)
struct sockaddr_in6 proxy_addr_in6;
#endif
sock_addr addr;
struct sockaddr *proxy_addr = (struct sockaddr *)&addr;
socklen_t servlen;
data_proxy *host= hctx->host;
int proxy_fd = hctx->fd;
#if defined(HAVE_SYS_UN_H)
if (strstr(host->host->ptr, "/")) {
if (buffer_string_length(host->host) + 1 > sizeof(proxy_addr_un.sun_path)) {
log_error_write(srv, __FILE__, __LINE__, "sB",
"ERROR: Unix Domain socket filename too long:",
host->host);
if (1 != sock_addr_from_str_hints(srv, &addr, &servlen, host->host->ptr, AF_UNIX, 0)) {
return -1;
}
}
#if defined(HAVE_IPV6)
else if (strstr(host->host->ptr, ":")) {
if (1 != sock_addr_from_buffer_hints_numeric(srv, &addr, &servlen, host->host, AF_INET6, host->port)) {
return -1;
}
}
#endif
else {
if (1 != sock_addr_from_buffer_hints_numeric(srv, &addr, &servlen, host->host, AF_INET, host->port)) {
return -1;
}
memset(&proxy_addr_un, 0, sizeof(proxy_addr_un));
proxy_addr_un.sun_family = AF_UNIX;
memcpy(proxy_addr_un.sun_path, host->host->ptr, buffer_string_length(host->host) + 1);
servlen = sizeof(proxy_addr_un);
proxy_addr = (struct sockaddr *) &proxy_addr_un;
} else
#endif
#if defined(HAVE_IPV6) && defined(HAVE_INET_PTON)
if (strstr(host->host->ptr, ":")) {
memset(&proxy_addr_in6, 0, sizeof(proxy_addr_in6));
proxy_addr_in6.sin6_family = AF_INET6;
inet_pton(AF_INET6, host->host->ptr, (char *) &proxy_addr_in6.sin6_addr);
proxy_addr_in6.sin6_port = htons(host->port);
servlen = sizeof(proxy_addr_in6);
proxy_addr = (struct sockaddr *) &proxy_addr_in6;
} else
#endif
{
memset(&proxy_addr_in, 0, sizeof(proxy_addr_in));
proxy_addr_in.sin_family = AF_INET;
proxy_addr_in.sin_addr.s_addr = inet_addr(host->host->ptr);
proxy_addr_in.sin_port = htons(host->port);
servlen = sizeof(proxy_addr_in);
proxy_addr = (struct sockaddr *) &proxy_addr_in;
}
if (-1 == connect(proxy_fd, proxy_addr, servlen)) {
if (errno == EINPROGRESS || errno == EALREADY) {

@ -10,6 +10,7 @@
#include "connections.h"
#include "response.h"
#include "joblist.h"
#include "inet_ntop_cache.h"
#include "plugin.h"
@ -674,15 +675,8 @@ static int scgi_spawn_connection(server *srv,
int scgi_fd;
int status;
struct timeval tv = { 0, 10 * 1000 };
#ifdef HAVE_SYS_UN_H
struct sockaddr_un scgi_addr_un;
#endif
#if defined(HAVE_IPV6) && defined(HAVE_INET_PTON)
struct sockaddr_in6 scgi_addr_in6;
#endif
struct sockaddr_in scgi_addr_in;
struct sockaddr *scgi_addr;
sock_addr addr;
struct sockaddr *scgi_addr = (struct sockaddr *)&addr;
socklen_t servlen;
if (p->conf.debug) {
@ -690,84 +684,14 @@ static int scgi_spawn_connection(server *srv,
"new proc, socket:", proc->port, proc->socket);
}
if (!buffer_string_is_empty(proc->socket)) {
#ifdef HAVE_SYS_UN_H
memset(&scgi_addr_un, 0, sizeof(scgi_addr_un));
scgi_addr_un.sun_family = AF_UNIX;
if (buffer_string_length(proc->socket) + 1 > sizeof(scgi_addr_un.sun_path)) {
log_error_write(srv, __FILE__, __LINE__, "sB",
"ERROR: Unix Domain socket filename too long:",
proc->socket);
if (1 != sock_addr_from_str_hints(srv, &addr, &servlen, proc->socket->ptr, AF_UNIX, 0)) {
return -1;
}
memcpy(scgi_addr_un.sun_path, proc->socket->ptr, buffer_string_length(proc->socket) + 1);
#ifdef SUN_LEN
servlen = SUN_LEN(&scgi_addr_un);
#else
/* stevens says: */
servlen = buffer_string_length(proc->socket) + 1 + sizeof(scgi_addr_un.sun_family);
#endif
scgi_addr = (struct sockaddr *) &scgi_addr_un;
#else
log_error_write(srv, __FILE__, __LINE__, "s",
"ERROR: Unix Domain sockets are not supported.");
return -1;
#endif
} else if (buffer_string_is_empty(host->host)) {
memset(&scgi_addr_in, 0, sizeof(scgi_addr_in));
scgi_addr_in.sin_family = AF_INET;
scgi_addr_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
scgi_addr_in.sin_port = htons(proc->port);
servlen = sizeof(scgi_addr_in);
scgi_addr = (struct sockaddr *) &scgi_addr_in;
#if defined(HAVE_IPV6) && defined(HAVE_INET_PTON)
} else if (host->family == AF_INET6) {
memset(&scgi_addr_in6, 0, sizeof(scgi_addr_in6));
scgi_addr_in6.sin6_family = AF_INET6;
inet_pton(AF_INET6, host->host->ptr, (char *) &scgi_addr_in6.sin6_addr);
scgi_addr_in6.sin6_port = htons(proc->port);
servlen = sizeof(scgi_addr_in6);
scgi_addr = (struct sockaddr *) &scgi_addr_in6;
#endif
} else {
memset(&scgi_addr_in, 0, sizeof(scgi_addr_in));
scgi_addr_in.sin_family = AF_INET;
#if defined(HAVE_INET_PTON)
inet_pton(AF_INET, host->host->ptr, (char *) &scgi_addr_in.sin_addr);
#else
{
struct hostent *he;
/* set a useful default */
scgi_addr_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
if (NULL == (he = gethostbyname(host->host->ptr))) {
log_error_write(srv, __FILE__, __LINE__,
"sdb", "gethostbyname failed: ",
h_errno, host->host);
return -1;
}
if (he->h_addrtype != AF_INET) {
log_error_write(srv, __FILE__, __LINE__, "sd", "addr-type != AF_INET: ", he->h_addrtype);
return -1;
}
if (he->h_length != sizeof(struct in_addr)) {
log_error_write(srv, __FILE__, __LINE__, "sd", "addr-length != sizeof(in_addr): ", he->h_length);
return -1;
}
memcpy(&(scgi_addr_in.sin_addr.s_addr), he->h_addr_list[0], he->h_length);
if (1 != sock_addr_from_buffer_hints_numeric(srv, &addr, &servlen, host->host, host->family, proc->port)) {
return -1;
}
#endif
scgi_addr_in.sin_port = htons(proc->port);
servlen = sizeof(scgi_addr_in);
scgi_addr = (struct sockaddr *) &scgi_addr_in;
}
if (-1 == (scgi_fd = fdevent_socket_cloexec(scgi_addr->sa_family, SOCK_STREAM, 0))) {
@ -1468,14 +1392,8 @@ static int scgi_env_add_uwsgi(void *venv, const char *key, size_t key_len, const
*/
static int scgi_establish_connection(server *srv, handler_ctx *hctx) {
struct sockaddr *scgi_addr;
struct sockaddr_in scgi_addr_in;
#if defined(HAVE_IPV6) && defined(HAVE_INET_PTON)
struct sockaddr_in6 scgi_addr_in6;
#endif
#ifdef HAVE_SYS_UN_H
struct sockaddr_un scgi_addr_un;
#endif
sock_addr addr;
struct sockaddr *scgi_addr = (struct sockaddr *)&addr;
socklen_t servlen;
scgi_extension_host *host = hctx->host;
@ -1483,51 +1401,13 @@ static int scgi_establish_connection(server *srv, handler_ctx *hctx) {
int scgi_fd = hctx->fd;
if (!buffer_string_is_empty(proc->socket)) {
#ifdef HAVE_SYS_UN_H
/* use the unix domain socket */
memset(&scgi_addr_un, 0, sizeof(scgi_addr_un));
scgi_addr_un.sun_family = AF_UNIX;
if (buffer_string_length(proc->socket) + 1 > sizeof(scgi_addr_un.sun_path)) {
log_error_write(srv, __FILE__, __LINE__, "sB",
"ERROR: Unix Domain socket filename too long:",
proc->socket);
if (1 != sock_addr_from_str_hints(srv, &addr, &servlen, proc->socket->ptr, AF_UNIX, 0)) {
return -1;
}
memcpy(scgi_addr_un.sun_path, proc->socket->ptr, buffer_string_length(proc->socket) + 1);
#ifdef SUN_LEN
servlen = SUN_LEN(&scgi_addr_un);
#else
/* stevens says: */
servlen = buffer_string_length(proc->socket) + 1 + sizeof(scgi_addr_un.sun_family);
#endif
scgi_addr = (struct sockaddr *) &scgi_addr_un;
#else
return -1;
#endif
#if defined(HAVE_IPV6) && defined(HAVE_INET_PTON)
} else if (host->family == AF_INET6 && !buffer_string_is_empty(host->host)) {
memset(&scgi_addr_in6, 0, sizeof(scgi_addr_in6));
scgi_addr_in6.sin6_family = AF_INET6;
inet_pton(AF_INET6, host->host->ptr, (char *) &scgi_addr_in6.sin6_addr);
scgi_addr_in6.sin6_port = htons(proc->port);
servlen = sizeof(scgi_addr_in6);
scgi_addr = (struct sockaddr *) &scgi_addr_in6;
#endif
} else {
memset(&scgi_addr_in, 0, sizeof(scgi_addr_in));
scgi_addr_in.sin_family = AF_INET;
if (0 == inet_aton(host->host->ptr, &(scgi_addr_in.sin_addr))) {
log_error_write(srv, __FILE__, __LINE__, "sbs",
"converting IP-adress failed for", host->host,
"\nBe sure to specify an IP address here");
if (1 != sock_addr_from_buffer_hints_numeric(srv, &addr, &servlen, host->host, host->family, proc->port)) {
return -1;
}
scgi_addr_in.sin_port = htons(proc->port);
servlen = sizeof(scgi_addr_in);
scgi_addr = (struct sockaddr *) &scgi_addr_in;
}
if (-1 == connect(scgi_fd, scgi_addr, servlen)) {

Loading…
Cancel
Save