On Mon, 20 Mar 2006 13:44:30 +0300 [EMAIL PROTECTED] ("Dmitry Stogov") wrote:
> Hi Rostislav, > > PHP HEAD and PHP_5_1 (5.1.3) don't use libfcgi any more. > They use simplest and smallest replacement library. > > Please look into CVS code and provide a patch for it (if necessary). > > Thanks. Dmitry. Hello Dmitry, I've tried the latest php5.1-200603200930 snapshot. It has the same problem. During fixing it in sapi/cgi/fastcgi.c I reworked an fcgi_listen() function. The new version of this function only is attached to this message instead of a patch that may be less handy in this case. There are two additional things in the function that could still be improved: 1. use gethostbyname2(host, AF_INET) instead of gethostbyname(host) it will eliminate IPv6 addresses from resolving 2. use 0770 socket mode instead of 0777 it will make the UNIX socket more secure What do you think about that new code?
int fcgi_listen(const char *path, int backlog) { #ifdef _WIN32 /* TODO: Support for manual binding on TCP sockets (php -b <port>) */ return -1; #else char *s; char host[MAXPATHLEN]; short port = 0; int listen_socket; sa_t sa; socklen_t sa_len; int path_len; if ((s = strrchr(path, ':')) != NULL) { path_len = s - path; if (*(s + 1) != '\0') { /* TCP/IP */ if ((port = atoi(s + 1)) != 0) { if (path_len < MAXPATHLEN) { strncpy(host, path, path_len); host[path_len] = '\0'; memset(&sa.sa_inet, 0, sizeof(sa.sa_inet)); sa.sa_inet.sin_family = AF_INET; sa.sa_inet.sin_port = htons(port); sa_len = sizeof(sa.sa_inet); if (!*host || !strcmp(host, "*")) { sa.sa_inet.sin_addr.s_addr = htonl(INADDR_ANY); } else { sa.sa_inet.sin_addr.s_addr = inet_addr(host); if (sa.sa_inet.sin_addr.s_addr == INADDR_NONE) { struct hostent *hep; hep = gethostbyname(host); if (!hep || hep->h_addrtype != AF_INET || !hep->h_addr_list[0]) { fprintf(stderr, "Cannot resolve host name '%s'!\n", host); return -1; } else if (hep->h_addr_list[1]) { fprintf(stderr, "Host '%s' has multiple addresses. " "You must choose one explicitly!\n", host); return -1; } sa.sa_inet.sin_addr.s_addr = ((struct in_addr*)hep->h_addr_list[0])->s_addr; } } } else { fprintf(stderr, "Listening hostname is too long.\n"); return -1; } } else { fprintf(stderr, "Illegal listening port number.\n"); return -1; } } else { /* UNIX socket */ if (path_len < sizeof(sa.sa_unix.sun_path)) { memset(&sa.sa_unix, 0, sizeof(sa.sa_unix)); sa.sa_unix.sun_family = AF_UNIX; memcpy(sa.sa_unix.sun_path, path, path_len); *(sa.sa_unix.sun_path + path_len) = '\0'; sa_len = sizeof(sa.sa_unix.sun_family) + path_len; #ifdef HAVE_SOCKADDR_UN_SUN_LEN sa_len += sizeof(sa.sa_unix.sun_len) + 1; sa.sa_unix.sun_len = sa_len; #endif unlink(sa.sa_unix.sun_path); } else { fprintf(stderr, "Listening socket's path name is too long.\n"); return -1; } } } else { fprintf(stderr, "Illegal path passed to fcgi_listen()\n"); return -1; } /* Create, bind socket and start listen on it */ if ((listen_socket = socket(sa.sa.sa_family, SOCK_STREAM, 0)) < 0 || bind(listen_socket, (struct sockaddr *) &sa, sa_len) < 0 || listen(listen_socket, backlog) < 0) { fprintf(stderr, "Cannot bind/listen socket - [%d] %s.\n", errno, strerror(errno)); return -1; } if (sa.sa.sa_family == AF_UNIX) { chmod(sa.sa_unix.sun_path, 0777); } if (!is_initialized) { fcgi_init(); } is_fastcgi = 1; return listen_socket; #endif }
-- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php