diff --git a/src/mod_fastcgi.c b/src/mod_fastcgi.c index 36dcd687..52030baf 100644 --- a/src/mod_fastcgi.c +++ b/src/mod_fastcgi.c @@ -148,6 +148,7 @@ typedef struct { */ buffer *host; unsigned short port; + sa_family_t family; /* * Unix Domain Socket @@ -855,10 +856,13 @@ static int fcgi_spawn_connection(server *srv, fcgi_extension_host *host, fcgi_proc *proc) { int fcgi_fd; - int socket_type, status; + int status; struct timeval tv = { 0, 100 * 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; @@ -888,7 +892,6 @@ static int fcgi_spawn_connection(server *srv, /* stevens says: */ servlen = buffer_string_length(proc->unixsocket) + 1 + sizeof(fcgi_addr_un.sun_family); #endif - socket_type = AF_UNIX; fcgi_addr = (struct sockaddr *) &fcgi_addr_un; buffer_copy_string_len(proc->connection_name, CONST_STR_LEN("unix:")); @@ -898,6 +901,15 @@ static int fcgi_spawn_connection(server *srv, log_error_write(srv, __FILE__, __LINE__, "s", "ERROR: Unix Domain sockets are not supported."); return -1; +#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)); @@ -935,9 +947,10 @@ static int fcgi_spawn_connection(server *srv, fcgi_addr_in.sin_port = htons(proc->port); servlen = sizeof(fcgi_addr_in); - socket_type = AF_INET; fcgi_addr = (struct sockaddr *) &fcgi_addr_in; + } + if (buffer_string_is_empty(proc->unixsocket)) { 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); @@ -948,7 +961,7 @@ static int fcgi_spawn_connection(server *srv, buffer_append_int(proc->connection_name, proc->port); } - if (-1 == (fcgi_fd = socket(socket_type, SOCK_STREAM, 0))) { + if (-1 == (fcgi_fd = socket(fcgi_addr->sa_family, SOCK_STREAM, 0))) { log_error_write(srv, __FILE__, __LINE__, "ss", "failed:", strerror(errno)); return -1; @@ -967,7 +980,7 @@ static int fcgi_spawn_connection(server *srv, close(fcgi_fd); /* reopen socket */ - if (-1 == (fcgi_fd = socket(socket_type, SOCK_STREAM, 0))) { + if (-1 == (fcgi_fd = socket(fcgi_addr->sa_family, SOCK_STREAM, 0))) { log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed:", strerror(errno)); return -1; @@ -1378,6 +1391,8 @@ SETDEFAULTS_FUNC(mod_fastcgi_set_defaults) { host->unixsocket); goto error; } + + host->family = AF_UNIX; } else { /* tcp/ip */ @@ -1399,6 +1414,8 @@ SETDEFAULTS_FUNC(mod_fastcgi_set_defaults) { goto error; } + + host->family = (!buffer_string_is_empty(host->host) && NULL != strchr(host->host->ptr, ':')) ? AF_INET6 : AF_INET; } if (!buffer_string_is_empty(host->bin_path)) { @@ -1732,6 +1749,9 @@ typedef enum { 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 @@ -1769,6 +1789,15 @@ static connection_result_t fcgi_establish_connection(server *srv, handler_ctx *h } #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)); @@ -1788,7 +1817,9 @@ static connection_result_t fcgi_establish_connection(server *srv, handler_ctx *h 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:")); @@ -2856,9 +2887,7 @@ static handler_t fcgi_write_request(server *srv, handler_ctx *hctx) { if (proc->load < hctx->proc->load) hctx->proc = proc; } - ret = buffer_string_is_empty(host->unixsocket) ? AF_INET : AF_UNIX; - - if (-1 == (hctx->fd = socket(ret, SOCK_STREAM, 0))) { + if (-1 == (hctx->fd = socket(host->family, SOCK_STREAM, 0))) { if (errno == EMFILE || errno == EINTR) { log_error_write(srv, __FILE__, __LINE__, "sd", diff --git a/src/mod_scgi.c b/src/mod_scgi.c index e1adc947..b47096a4 100644 --- a/src/mod_scgi.c +++ b/src/mod_scgi.c @@ -146,6 +146,7 @@ typedef struct { */ buffer *host; unsigned short port; + sa_family_t family; /* * Unix Domain Socket @@ -671,10 +672,13 @@ static int scgi_spawn_connection(server *srv, scgi_extension_host *host, scgi_proc *proc) { int scgi_fd; - int socket_type, status; + int status; struct timeval tv = { 0, 100 * 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; @@ -705,12 +709,20 @@ static int scgi_spawn_connection(server *srv, /* stevens says: */ servlen = buffer_string_length(proc->socket) + 1 + sizeof(scgi_addr_un.sun_family); #endif - socket_type = AF_UNIX; 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 +#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)); @@ -748,11 +760,10 @@ static int scgi_spawn_connection(server *srv, scgi_addr_in.sin_port = htons(proc->port); servlen = sizeof(scgi_addr_in); - socket_type = AF_INET; scgi_addr = (struct sockaddr *) &scgi_addr_in; } - if (-1 == (scgi_fd = socket(socket_type, SOCK_STREAM, 0))) { + if (-1 == (scgi_fd = socket(scgi_addr->sa_family, SOCK_STREAM, 0))) { log_error_write(srv, __FILE__, __LINE__, "ss", "failed:", strerror(errno)); return -1; @@ -770,7 +781,7 @@ static int scgi_spawn_connection(server *srv, close(scgi_fd); /* reopen socket */ - if (-1 == (scgi_fd = socket(socket_type, SOCK_STREAM, 0))) { + if (-1 == (scgi_fd = socket(scgi_addr->sa_family, SOCK_STREAM, 0))) { log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed:", strerror(errno)); return -1; @@ -1142,6 +1153,8 @@ SETDEFAULTS_FUNC(mod_scgi_set_defaults) { df->unixsocket); goto error; } + + df->family = AF_UNIX; } else { /* tcp/ip */ @@ -1164,6 +1177,8 @@ SETDEFAULTS_FUNC(mod_scgi_set_defaults) { "port"); goto error; } + + df->family = (!buffer_string_is_empty(df->host) && NULL != strchr(df->host->ptr, ':')) ? AF_INET6 : AF_INET; } if (!buffer_string_is_empty(df->bin_path)) { @@ -1423,6 +1438,9 @@ static int scgi_env_add(buffer *env, const char *key, size_t key_len, const char 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 @@ -1454,6 +1472,15 @@ static int scgi_establish_connection(server *srv, handler_ctx *hctx) { 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)); @@ -2239,9 +2266,7 @@ static handler_t scgi_write_request(server *srv, handler_ctx *hctx) { switch(hctx->state) { case FCGI_STATE_INIT: - ret = buffer_string_is_empty(host->unixsocket) ? AF_INET : AF_UNIX; - - if (-1 == (hctx->fd = socket(ret, SOCK_STREAM, 0))) { + if (-1 == (hctx->fd = socket(host->family, SOCK_STREAM, 0))) { if (errno == EMFILE || errno == EINTR) { log_error_write(srv, __FILE__, __LINE__, "sd",