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

Reply via email to