Hi,
I clean up the patch and got rid of the unrelated changes and a lot of
debugging statements. Again: This patch is proof-of-concept only. It is
not intended for production usage.
The patch is again peruser.c . To apply it go to the
server/mpm/experimental/peruser subdirectory of your apache source
directory with the peruser patch already applied and type
# patch peruser.c < peruser-ssl.patch
Add a "Listen 443" statement to your http.conf and define a vhost for
this port.
Things which need to be addressed to make this patch fully usable:
- The decision if SSL is currently based on the port number. We should
make the port numbers configurable (Either by adding a new "ListenSSL"
statement or by using a new directive which declares some of the ports
specified with "Listen" as SSL ports). The most elegant solution of
course would be to detect the "SSLEngine on" setting for the vhosts.
- We need to choose the vhost/processor we pass the request to based on
the IP addresses/port numbers of the vhosts. Currently always the first
processor is chosen. The value is hard-coded in process_socket().
- Somebody should review the memory allocation used in pass_socket().
Since we don't have a request we don't have a memory pool available. I
solved this by creating a new one. But I'm neither sure if this is the
correct thing to do nor if it is destroyed properly later on. Shouldn't
be a big problem... we only allocate a few bytes per request and since
we have a MaxRequestsPerChild options we will sooner or later get our
memory back.
- We currently include arch/unix/apr_arch_networkio.h . There should be
a more elegant (read platform independent) way to access the
ip_address/port number. But since peruser works on UNIX systems only we
are most probably save to use a arch specific header anyway.
All in all no big issues but one might need to know some apache
internals (especially how the configuration is handled). I'm no apache
expert and I'd have to read a lot more code to figure out how this stuff
works. Maybe somebody else on the list has some expertise in this area
and can step in? Should save a lot of time...
Stefan
--- peruser.c 2006-03-04 19:34:57.000000000 +0100
+++ peruser-orig.c 2006-03-04 19:30:18.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,138 +820,13 @@
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_pool_t *pool)
+ apr_bucket_alloc_t *bucket_alloc)
{
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)
{
@@ -1260,8 +1135,6 @@
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);
@@ -1283,9 +1156,7 @@
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;
}
@@ -1692,7 +1563,7 @@
{
_DBG("marked jmpbuffer",0);
_TRACE_CALL("process_socket()",0);
- process_socket(ptrans, sock, my_child_num, bucket_alloc, pchild);
+ process_socket(ptrans, sock, my_child_num, bucket_alloc);
_TRACE_RET("process_socket()",0);
}
else
_______________________________________________
Peruser mailing list
[email protected]
http://www.telana.com/mailman/listinfo/peruser