summaryrefslogtreecommitdiff
path: root/sapi
diff options
context:
space:
mode:
authorGeorge Wang <gwang@php.net>2014-11-20 16:56:03 -0500
committerGeorge Wang <gwang@php.net>2014-11-20 16:56:03 -0500
commitd4677616631b5975094bd9176e4c5c07d1c28fda (patch)
tree9ec766fcb5e32f9f763e90ba6d16321c421c6e1d /sapi
parentbd3bc097b0cba4cb1c0778935d6557edd090ddb6 (diff)
parent6c3768b15410ca2b70a4c2ba31d2a7f0d7c53ad3 (diff)
downloadphp-git-d4677616631b5975094bd9176e4c5c07d1c28fda.tar.gz
Merge branch 'PHP-5.5' of git.php.net:php-src into PHP-5.5
Diffstat (limited to 'sapi')
-rw-r--r--sapi/fpm/fpm/fastcgi.c96
-rw-r--r--sapi/fpm/fpm/fastcgi.h2
-rw-r--r--sapi/fpm/fpm/fpm_log.c2
-rw-r--r--sapi/fpm/fpm/fpm_sockets.c41
-rw-r--r--sapi/fpm/fpm/fpm_unix.c3
-rw-r--r--sapi/fpm/php-fpm.8.in14
-rw-r--r--sapi/fpm/php-fpm.conf.in8
7 files changed, 120 insertions, 46 deletions
diff --git a/sapi/fpm/fpm/fastcgi.c b/sapi/fpm/fpm/fastcgi.c
index d77b6f8ca7..36e37b79d3 100644
--- a/sapi/fpm/fpm/fastcgi.c
+++ b/sapi/fpm/fpm/fastcgi.c
@@ -137,13 +137,14 @@ typedef union _sa_t {
struct sockaddr sa;
struct sockaddr_un sa_unix;
struct sockaddr_in sa_inet;
+ struct sockaddr_in6 sa_inet6;
} sa_t;
static HashTable fcgi_mgmt_vars;
static int is_initialized = 0;
static int in_shutdown = 0;
-static in_addr_t *allowed_clients = NULL;
+static sa_t *allowed_clients = NULL;
static sa_t client_sa;
@@ -266,14 +267,18 @@ void fcgi_set_allowed_clients(char *ip)
*end = 0;
end++;
}
- allowed_clients[n] = inet_addr(cur);
- if (allowed_clients[n] == INADDR_NONE) {
+ if (inet_pton(AF_INET, cur, &allowed_clients[n].sa_inet.sin_addr)>0) {
+ allowed_clients[n].sa.sa_family = AF_INET;
+ n++;
+ } else if (inet_pton(AF_INET6, cur, &allowed_clients[n].sa_inet6.sin6_addr)>0) {
+ allowed_clients[n].sa.sa_family = AF_INET6;
+ n++;
+ } else {
zlog(ZLOG_ERROR, "Wrong IP address '%s' in listen.allowed_clients", cur);
}
- n++;
cur = end;
}
- allowed_clients[n] = INADDR_NONE;
+ allowed_clients[n].sa.sa_family = 0;
free(ip);
}
}
@@ -759,6 +764,43 @@ void fcgi_close(fcgi_request *req, int force, int destroy)
}
}
+static int fcgi_is_allowed() {
+ int i;
+
+ if (client_sa.sa.sa_family == AF_UNIX) {
+ return 1;
+ }
+ if (!allowed_clients) {
+ return 1;
+ }
+ if (client_sa.sa.sa_family == AF_INET) {
+ for (i=0 ; allowed_clients[i].sa.sa_family ; i++) {
+ if (allowed_clients[i].sa.sa_family == AF_INET
+ && !memcmp(&client_sa.sa_inet.sin_addr, &allowed_clients[i].sa_inet.sin_addr, 4)) {
+ return 1;
+ }
+ }
+ }
+ if (client_sa.sa.sa_family == AF_INET6) {
+ for (i=0 ; allowed_clients[i].sa.sa_family ; i++) {
+ if (allowed_clients[i].sa.sa_family == AF_INET6
+ && !memcmp(&client_sa.sa_inet6.sin6_addr, &allowed_clients[i].sa_inet6.sin6_addr, 12)) {
+ return 1;
+ }
+#ifdef IN6_IS_ADDR_V4MAPPED
+ if (allowed_clients[i].sa.sa_family == AF_INET
+ && IN6_IS_ADDR_V4MAPPED(&client_sa.sa_inet6.sin6_addr)
+ && !memcmp(((char *)&client_sa.sa_inet6.sin6_addr)+12, &allowed_clients[i].sa_inet.sin_addr, 4)) {
+ return 1;
+ }
+#endif
+ }
+ }
+
+ zlog(ZLOG_ERROR, "Connection disallowed: IP address '%s' has been dropped.", fcgi_get_last_client_ip());
+ return 0;
+}
+
int fcgi_accept_request(fcgi_request *req)
{
#ifdef _WIN32
@@ -809,23 +851,10 @@ int fcgi_accept_request(fcgi_request *req)
FCGI_UNLOCK(req->listen_socket);
client_sa = sa;
- if (sa.sa.sa_family == AF_INET && req->fd >= 0 && allowed_clients) {
- int n = 0;
- int allowed = 0;
-
- while (allowed_clients[n] != INADDR_NONE) {
- if (allowed_clients[n] == sa.sa_inet.sin_addr.s_addr) {
- allowed = 1;
- break;
- }
- n++;
- }
- if (!allowed) {
- zlog(ZLOG_ERROR, "Connection disallowed: IP address '%s' has been dropped.", inet_ntoa(sa.sa_inet.sin_addr));
- closesocket(req->fd);
- req->fd = -1;
- continue;
- }
+ if (req->fd >= 0 && !fcgi_is_allowed()) {
+ closesocket(req->fd);
+ req->fd = -1;
+ continue;
}
}
@@ -1094,12 +1123,27 @@ void fcgi_free_mgmt_var_cb(void * ptr)
pefree(*var, 1);
}
-char *fcgi_get_last_client_ip() /* {{{ */
+const char *fcgi_get_last_client_ip() /* {{{ */
{
- if (client_sa.sa.sa_family == AF_UNIX) {
- return NULL;
+ static char str[INET6_ADDRSTRLEN];
+
+ /* Ipv4 */
+ if (client_sa.sa.sa_family == AF_INET) {
+ return inet_ntop(client_sa.sa.sa_family, &client_sa.sa_inet.sin_addr, str, INET6_ADDRSTRLEN);
+ }
+#ifdef IN6_IS_ADDR_V4MAPPED
+ /* Ipv4-Mapped-Ipv6 */
+ if (client_sa.sa.sa_family == AF_INET6
+ && IN6_IS_ADDR_V4MAPPED(&client_sa.sa_inet6.sin6_addr)) {
+ return inet_ntop(AF_INET, ((char *)&client_sa.sa_inet6.sin6_addr)+12, str, INET6_ADDRSTRLEN);
}
- return inet_ntoa(client_sa.sa_inet.sin_addr);
+#endif
+ /* Ipv6 */
+ if (client_sa.sa.sa_family == AF_INET6) {
+ return inet_ntop(client_sa.sa.sa_family, &client_sa.sa_inet6.sin6_addr, str, INET6_ADDRSTRLEN);
+ }
+ /* Unix socket */
+ return NULL;
}
/* }}} */
/*
diff --git a/sapi/fpm/fpm/fastcgi.h b/sapi/fpm/fpm/fastcgi.h
index 34f9eef9da..f5cfe9f66a 100644
--- a/sapi/fpm/fpm/fastcgi.h
+++ b/sapi/fpm/fpm/fastcgi.h
@@ -133,7 +133,7 @@ int fcgi_flush(fcgi_request *req, int close);
void fcgi_set_mgmt_var(const char * name, size_t name_len, const char * value, size_t value_len);
void fcgi_free_mgmt_var_cb(void * ptr);
-char *fcgi_get_last_client_ip();
+const char *fcgi_get_last_client_ip();
/*
* Local variables:
diff --git a/sapi/fpm/fpm/fpm_log.c b/sapi/fpm/fpm/fpm_log.c
index 4e1a057db1..c71281b0b9 100644
--- a/sapi/fpm/fpm/fpm_log.c
+++ b/sapi/fpm/fpm/fpm_log.c
@@ -367,7 +367,7 @@ int fpm_log_write(char *log_format TSRMLS_DC) /* {{{ */
case 'R': /* remote IP address */
if (!test) {
- char *tmp = fcgi_get_last_client_ip();
+ const char *tmp = fcgi_get_last_client_ip();
len2 = snprintf(b, FPM_LOG_BUFFER - len, "%s", tmp ? tmp : "-");
}
break;
diff --git a/sapi/fpm/fpm/fpm_sockets.c b/sapi/fpm/fpm/fpm_sockets.c
index da14d63d8c..9d9def35c7 100644
--- a/sapi/fpm/fpm/fpm_sockets.c
+++ b/sapi/fpm/fpm/fpm_sockets.c
@@ -85,13 +85,24 @@ static void *fpm_get_in_addr(struct sockaddr *sa) /* {{{ */
}
/* }}} */
+static int fpm_get_in_port(struct sockaddr *sa) /* {{{ */
+{
+ if (sa->sa_family == AF_INET) {
+ return ntohs(((struct sockaddr_in*)sa)->sin_port);
+ }
+
+ return ntohs(((struct sockaddr_in6*)sa)->sin6_port);
+}
+/* }}} */
+
static int fpm_sockets_hash_op(int sock, struct sockaddr *sa, char *key, int type, int op) /* {{{ */
{
if (key == NULL) {
switch (type) {
case FPM_AF_INET : {
- key = alloca(INET6_ADDRSTRLEN);
- inet_ntop(sa->sa_family, fpm_get_in_addr(sa), key, sizeof key);
+ key = alloca(INET6_ADDRSTRLEN+10);
+ inet_ntop(sa->sa_family, fpm_get_in_addr(sa), key, INET6_ADDRSTRLEN);
+ sprintf(key+strlen(key), ":%d", fpm_get_in_port(sa));
break;
}
@@ -246,7 +257,7 @@ static int fpm_socket_af_inet_listening_socket(struct fpm_worker_pool_s *wp) /*
char *addr = NULL;
int addr_len;
int port = 0;
- int sock;
+ int sock = -1;
int status;
if (port_str) { /* this is host:port pair */
@@ -263,13 +274,23 @@ static int fpm_socket_af_inet_listening_socket(struct fpm_worker_pool_s *wp) /*
return -1;
}
- // strip brackets from address for getaddrinfo
- if (addr != NULL) {
- addr_len = strlen(addr);
- if (addr[0] == '[' && addr[addr_len - 1] == ']') {
- addr[addr_len - 1] = '\0';
- addr++;
- }
+ if (!addr) {
+ /* no address: default documented behavior, all IPv4 addresses */
+ struct sockaddr_in sa_in;
+
+ memset(&sa_in, 0, sizeof(sa_in));
+ sa_in.sin_family = AF_INET;
+ sa_in.sin_port = htons(port);
+ sa_in.sin_addr.s_addr = htonl(INADDR_ANY);
+ free(dup_address);
+ return fpm_sockets_get_listening_socket(wp, (struct sockaddr *) &sa_in, sizeof(struct sockaddr_in));
+ }
+
+ /* strip brackets from address for getaddrinfo */
+ addr_len = strlen(addr);
+ if (addr[0] == '[' && addr[addr_len - 1] == ']') {
+ addr[addr_len - 1] = '\0';
+ addr++;
}
memset(&hints, 0, sizeof hints);
diff --git a/sapi/fpm/fpm/fpm_unix.c b/sapi/fpm/fpm/fpm_unix.c
index ea0e67369c..5dfdb4ab38 100644
--- a/sapi/fpm/fpm/fpm_unix.c
+++ b/sapi/fpm/fpm/fpm_unix.c
@@ -231,6 +231,8 @@ int fpm_unix_init_main() /* {{{ */
struct fpm_worker_pool_s *wp;
int is_root = !geteuid();
+ zlog_set_level(fpm_globals.log_level);
+
if (fpm_global_config.rlimit_files) {
struct rlimit r;
@@ -361,7 +363,6 @@ int fpm_unix_init_main() /* {{{ */
}
}
- zlog_set_level(fpm_globals.log_level);
return 0;
}
/* }}} */
diff --git a/sapi/fpm/php-fpm.8.in b/sapi/fpm/php-fpm.8.in
index b02aa25ba7..f6ad963aed 100644
--- a/sapi/fpm/php-fpm.8.in
+++ b/sapi/fpm/php-fpm.8.in
@@ -84,6 +84,13 @@ Version number
Specify alternative prefix path (the default is @php_fpm_prefix@)
.TP
.PD 0
+.B \-\-pid \fIfile\fP
+.TP
+.PD 1
+.B \-g
+Specify the PID file location.
+.TP
+.PD 0
.B \-\-fpm\-config \fIfile\fP
.TP
.PD 1
@@ -113,12 +120,11 @@ Force to run in background and ignore daemonize option from configuration file.
Force to stay in foreground and ignore daemonize option from configuration file.
.TP
.PD 0
-.B \-\-zend\-extension \fIfile\fP
+.B \-\-allow\-to\-run\-as\-root
.TP
.PD 1
-.B \-z \fIfile\fP
-Load Zend extension
-.IR file
+.B \-R
+Allow pool to run as root (disabled by default)
.SH FILES
.TP 15
.B php-fpm.conf
diff --git a/sapi/fpm/php-fpm.conf.in b/sapi/fpm/php-fpm.conf.in
index 631bc46f42..2b1566047f 100644
--- a/sapi/fpm/php-fpm.conf.in
+++ b/sapi/fpm/php-fpm.conf.in
@@ -150,12 +150,14 @@ group = @php_fpm_group@
; The address on which to accept FastCGI requests.
; Valid syntaxes are:
-; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific address on
+; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific IPv4 address on
; a specific port;
; '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on
; a specific port;
-; 'port' - to listen on a TCP socket to all addresses on a
+; 'port' - to listen on a TCP socket to all IPv4 addresses on a
; specific port;
+; '[::]:port' - to listen on a TCP socket to all addresses
+; (IPv6 and IPv4-mapped) on a specific port;
; '/path/to/unix/socket' - to listen on a unix socket.
; Note: This value is mandatory.
listen = 127.0.0.1:9000
@@ -173,7 +175,7 @@ listen = 127.0.0.1:9000
;listen.group = @php_fpm_group@
;listen.mode = 0660
-; List of ipv4 addresses of FastCGI clients which are allowed to connect.
+; List of addresses (IPv4/IPv6) of FastCGI clients which are allowed to connect.
; Equivalent to the FCGI_WEB_SERVER_ADDRS environment variable in the original
; PHP FCGI (5.2.2+). Makes sense only with a tcp listening socket. Each address
; must be separated by a comma. If this value is left blank, connections will be