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