Err.. swapped the arguments for the diff, sorry. Either apply with the
-R option or use this patch.

Sorry for the noise.

Stefan
--- peruser-orig.c      2006-03-04 19:30:18.000000000 +0100
+++ peruser.c   2006-03-04 19:34:57.000000000 +0100
@@ -66,7 +66,7 @@
 #include "apr_strings.h"
 #include "apr_thread_proc.h"
 #include "apr_signal.h"
-
+#include "arch/unix/apr_arch_networkio.h"
 #define APR_WANT_STDIO
 #define APR_WANT_STRFUNC
 #define APR_WANT_IOVEC
@@ -820,13 +820,138 @@
     return 0;
 }
 
+/*
+ * This function sends a raw socket over to a processor. It uses the same
+ * on-wire format as pass_request. The recipient can determine if he got
+ * a socket or a whole request by inspecting the header_length of the
+ * message. If it is zero then only a socket was sent.
+ */
+static int pass_socket(apr_socket_t *thesock, child_info_t *processor, 
apr_pool_t *pool)
+{
+    int rv;
+    struct msghdr msg;
+    struct cmsghdr *cmsg;
+    int sock_fd;
+    char *body = "";
+    struct iovec iov[4];
+    apr_size_t len = 0;
+    apr_size_t header_len = 0;
+    apr_size_t body_len = 0;
+    peruser_header h;
+    apr_bucket *bucket;
+    const apr_array_header_t *headers_in_array;
+    const apr_table_entry_t *headers_in;
+    int counter;
+
+    if (!processor)
+    {
+        _DBG("server %s in child %d has no child_info associated",
+                "(unkonwn)", my_child_num);
+        return -1;
+    }
+
+    _DBG("passing request to another child.", 0);
+
+    apr_os_sock_get(&sock_fd, thesock);
+    
+    header_len = 0;
+    body_len = 0;
+
+    iov[0].iov_base = &header_len;
+    iov[0].iov_len  = sizeof(header_len);
+    iov[1].iov_base = &body_len;
+    iov[1].iov_len  = sizeof(body_len);
+    iov[2].iov_base = h.headers;
+    iov[2].iov_len  = 0;
+    iov[3].iov_base = body;
+    iov[3].iov_len  = body_len;
+
+    msg.msg_name    = NULL;
+    msg.msg_namelen = 0;
+    msg.msg_iov     = iov;
+    msg.msg_iovlen  = 4;
+
+    cmsg = apr_palloc(pool, sizeof(*cmsg) + sizeof(sock_fd));
+    cmsg->cmsg_len   = sizeof(*cmsg) + sizeof(sock_fd);
+    cmsg->cmsg_level = SOL_SOCKET;
+    cmsg->cmsg_type  = SCM_RIGHTS;
+
+    memcpy(CMSG_DATA(cmsg), &sock_fd, sizeof(sock_fd));
+
+    msg.msg_control    = cmsg;
+    msg.msg_controllen = cmsg->cmsg_len;
+
+    if (processor->status == CHILD_STATUS_STANDBY)
+    {
+        _DBG("Activating child #%d", processor->id);
+        processor->status = CHILD_STATUS_STARTING;
+    }
+
+    while (processor->status != CHILD_STATUS_ACTIVE)
+    {
+        _DBG("Waiting for child #%d...", processor->id);
+        sleep(1);
+    }
+
+    _DBG("Writing message to %d, passing sock_fd:  %d", 
processor->senv->output, sock_fd);
+    _DBG("header_len=%d headers=\"%s\"", header_len, h.headers);
+    _DBG("body_len=%d body=\"%s\"", body_len, body);
+
+    if ((rv = sendmsg(processor->senv->output, &msg, 0)) == -1)
+    {
+        apr_pool_destroy(pool);
+        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
+                     "Writing message failed %d %d", rv, errno);
+        return -1;
+    }
+
+    _DBG("Writing message succeeded %d", rv);
+
+    /* -- close the socket on our side -- */
+    _DBG("closing socket %d on our side", sock_fd);
+    apr_socket_close(thesock);
+
+    apr_pool_destroy(pool);
+    return 1;
+}
+
 static void process_socket(apr_pool_t *p, apr_socket_t *sock, long conn_id,
-                           apr_bucket_alloc_t *bucket_alloc)
+                           apr_bucket_alloc_t *bucket_alloc, apr_pool_t *pool)
 {
     conn_rec *current_conn;
     int sock_fd;
     apr_status_t rv;
     ap_sb_handle_t *sbh;
+    apr_sockaddr_t *local_addr;
+    child_info_t *processor;
+    apr_pool_t *ptrans;
+
+    local_addr = (apr_sockaddr_t*)sock->local_addr;
+
+    if (local_addr->port == 443 && CHILD_INFO_TABLE[my_child_num].type == 
CHILD_TYPE_MULTIPLEXER) {
+       _DBG("SSL is activated, port %d", local_addr->port);
+       processor = &CHILD_INFO_TABLE[1]; // FIXME: Lookup the right processor!
+       _DBG("Forwarding without further inspection, processor %d", 
processor->id);
+        if (processor->status == CHILD_STATUS_STANDBY)
+        {
+             _DBG("Activating child #%d", processor->id);
+             processor->status = CHILD_STATUS_STARTING;
+        }
+
+        _DBG("Creating new pool",0);
+       apr_pool_create(&ptrans, pool);
+        _DBG("Passing request.",0);
+        if (pass_socket(sock, processor, ptrans) == -1)
+        {
+            ap_log_error(APLOG_MARK, APLOG_ERR, 0,
+                  ap_server_conf, "Could not pass request to proper "          
                   
+                  "child, request will not be honoured.");
+             return;
+        }
+        _DBG("doing longjmp",0);
+        longjmp(CHILD_INFO_TABLE[my_child_num].jmpbuffer, 1);
+       return;
+    }
 
     if ((rv = apr_os_sock_get(&sock_fd, sock)) != APR_SUCCESS)
     {
@@ -1135,6 +1260,8 @@
     apr_cpystrn(headers, buff, header_len + 1);
     _DBG("header_len=%d headers=\"%s\"", header_len, headers);
 
+if (header_len) {    
+    _DBG("header_len > 0, we got a request", 0);
     /* -- store received data into an brigade and add
           it to the current transaction's pool -- */
     bucket = apr_bucket_eos_create(alloc);
@@ -1156,7 +1283,9 @@
 
     APR_BRIGADE_INSERT_HEAD(bb, bucket);
     apr_pool_userdata_set(bb, "PERUSER_SOCKETS", NULL, ptrans);
-
+} else {
+    _DBG("header_len == 0, we got a socket only", 0);
+}
     _DBG("returning 0", 0);
     return 0;
 }
@@ -1563,7 +1692,7 @@
         {
             _DBG("marked jmpbuffer",0);
             _TRACE_CALL("process_socket()",0);
-            process_socket(ptrans, sock, my_child_num, bucket_alloc);
+            process_socket(ptrans, sock, my_child_num, bucket_alloc, pchild);
             _TRACE_RET("process_socket()",0);
         }
         else
_______________________________________________
Peruser mailing list
[email protected]
http://www.telana.com/mailman/listinfo/peruser

Reply via email to