Commit e13dff33 authored by Jim Jagielski's avatar Jim Jagielski
Browse files

Merge r473278 from trunk:

Add alternate is_socket_connected by using APR functions.
Submitted by: mturk
Reviewed by: jim


Merge r535354 from trunk:

Abstract out (kinda) MSG_PEEK. This way when we
actually update APR and apr_socket_recvfrom()
to know about APR_MSG_OOB, APR_MSG_PEEK, etc...
this code won't need to be adjusted. Also,
make nicer for 2.2 backport.


Reviewed by: jim


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@536291 13f79535-47bb-0310-9956-ffa450edef68
parent a321cdc5
Loading
Loading
Loading
Loading
+0 −9
Original line number Diff line number Diff line
@@ -105,15 +105,6 @@ PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
      (It also works for httpd-2.2.x).
      +1: jfclere, rpluem, wrowe

   * proxy_util.c: Add alternate is_socket_connected() function
     which uses APR calls.
     Trunk version of patch:
       http://svn.apache.org/viewvc?view=rev&rev=473278
       http://svn.apache.org/viewvc?view=rev&rev=535354
     2.2.x version of patch:
       Trunk version works
     +1: rpluem, mturk, jim

PATCHES PROPOSED TO BACKPORT FROM TRUNK:

    * ApacheMonitor: Fix Windows Vista detection.
+50 −1
Original line number Diff line number Diff line
@@ -1958,6 +1958,51 @@ ap_proxy_determine_connection(apr_pool_t *p, request_rec *r,
    return OK;
}

#define USE_ALTERNATE_IS_CONNECTED 1

#if !defined(APR_MSG_PEEK) && defined(MSG_PEEK)
#define APR_MSG_PEEK MSG_PEEK
#endif

#if USE_ALTERNATE_IS_CONNECTED && defined(APR_MSG_PEEK)
static int is_socket_connected(apr_socket_t *socket)
{
    apr_pollfd_t pfds[1];
    apr_status_t status;
    apr_int32_t  nfds;

    pfds[0].reqevents = APR_POLLIN;
    pfds[0].desc_type = APR_POLL_SOCKET;
    pfds[0].desc.s = socket;

    do {
        status = apr_poll(&pfds[0], 1, &nfds, 0);
    } while (APR_STATUS_IS_EINTR(status));

    if (status == APR_SUCCESS && nfds == 1 &&
        pfds[0].rtnevents == APR_POLLIN) {
        apr_sockaddr_t unused;
        apr_size_t len = 1;
        char buf[1];
        /* The socket might be closed in which case
         * the poll will return POLLIN.
         * If there is no data available the socket
         * is closed.
         */
        status = apr_socket_recvfrom(&unused, socket, APR_MSG_PEEK,
                                     &buf[0], &len);
        if (status == APR_SUCCESS && len)
            return 1;
        else
            return 0;
    }
    else if (APR_STATUS_IS_EAGAIN(status)) {
        return 1;
    }
    return 0;

}
#else
static int is_socket_connected(apr_socket_t *sock)

{
@@ -1979,6 +2024,7 @@ static int is_socket_connected(apr_socket_t *sock)
    else
        return 1;
}
#endif /* USE_ALTERNATE_IS_CONNECTED */

PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function,
                                            proxy_conn_rec *conn,
@@ -2000,6 +2046,9 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function,
        if (!(connected = is_socket_connected(conn->sock))) {
            apr_socket_close(conn->sock);
            conn->sock = NULL;
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
                         "proxy: %s: backend socket is disconnected.",
                         proxy_function);
        }
    }
    while (backend_addr && !connected) {