Hello,
bert wrote:
So according to the output, all is well until it gets here:
status = listensocks[offset].accept_func((void *)&sock, &listensocks
[offset], ptrans);
which seems to call receive_from_multiplexer to re-populate the sock
structure...
it seems somewhere within this function, the information about the
original connection is not being passed over correctly.
You right, here. Looks like a sendmsg/recvmsg (SCM_RIGHTS) bug at
pass_socket()/pass_request() -> receive_from_multiplexer().
You can try my patch. It's working for me.
diff -Nru a/server/mpm/experimental/peruser/peruser.c b/server/mpm/experimental/peruser/peruser.c
--- a/server/mpm/experimental/peruser/peruser.c 2007-09-27 14:12:38.000000000 +0300
+++ b/server/mpm/experimental/peruser/peruser.c 2007-09-27 14:08:26.000000000 +0300
@@ -845,9 +845,10 @@
int rv;
struct msghdr msg;
struct cmsghdr *cmsg;
+ apr_sockaddr_t *remote_addr;
int sock_fd;
char *body = "";
- struct iovec iov[4];
+ struct iovec iov[5];
apr_size_t len = 0;
apr_size_t header_len = 0;
apr_size_t body_len = 0;
@@ -867,6 +868,8 @@
_DBG("passing request to another child.", 0);
apr_os_sock_get(&sock_fd, thesock);
+ /* passing remote_addr too, see comments below */
+ apr_socket_addr_get(&remote_addr, APR_REMOTE, thesock);
header_len = 0;
body_len = 0;
@@ -875,15 +878,17 @@
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;
+ iov[2].iov_base = remote_addr;
+ iov[2].iov_len = sizeof(*remote_addr);
+ iov[3].iov_base = h.headers;
+ iov[3].iov_len = 0;
+ iov[4].iov_base = body;
+ iov[4].iov_len = body_len;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = iov;
- msg.msg_iovlen = 4;
+ msg.msg_iovlen = 5;
cmsg = apr_palloc(pool, sizeof(*cmsg) + sizeof(sock_fd));
cmsg->cmsg_len = sizeof(*cmsg) + sizeof(sock_fd);
@@ -1082,9 +1087,10 @@
int rv;
struct msghdr msg;
struct cmsghdr *cmsg;
+ apr_sockaddr_t *remote_addr;
int sock_fd;
char *body = "";
- struct iovec iov[4];
+ struct iovec iov[5];
conn_rec *c = r->connection;
apr_bucket_brigade *bb = apr_brigade_create(r->pool, c->bucket_alloc);
apr_bucket_brigade *body_bb = NULL;
@@ -1146,6 +1152,9 @@
_DBG("Scanning is finished",0);
apr_os_sock_get(&sock_fd, thesock);
+ /* looks like a bug while sending/receiving SCM_RIGHTS related to ipv6
+ workaround: send remote_addr structure too */
+ apr_socket_addr_get(&remote_addr, APR_REMOTE, thesock);
h.p = r->pool;
@@ -1171,15 +1180,17 @@
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 = strlen(h.headers) + 1;
- iov[3].iov_base = body;
- iov[3].iov_len = body_len;
+ iov[2].iov_base = remote_addr;
+ iov[2].iov_len = sizeof(*remote_addr);
+ iov[3].iov_base = h.headers;
+ iov[3].iov_len = strlen(h.headers) + 1;
+ iov[4].iov_base = body;
+ iov[4].iov_len = body_len;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = iov;
- msg.msg_iovlen = 4;
+ msg.msg_iovlen = 5;
cmsg = apr_palloc(r->pool, sizeof(*cmsg) + sizeof(sock_fd));
cmsg->cmsg_len = sizeof(*cmsg) + sizeof(sock_fd);
@@ -1233,10 +1244,12 @@
char headers[HUGE_STRING_LEN] = "";
char *body = "";
apr_size_t header_len, body_len;
- struct iovec iov[3];
+ struct iovec iov[4];
int ret, fd_tmp;
apr_os_sock_t ctrl_sock_fd;
apr_os_sock_t trans_sock_fd;
+ apr_sockaddr_t remote_addr;
+ apr_os_sock_info_t sockinfo;
/* -- bucket's, brigades and their allocators */
apr_bucket_alloc_t *alloc = apr_bucket_alloc_create(ptrans);
@@ -1248,8 +1261,10 @@
iov[0].iov_len = sizeof(header_len);
iov[1].iov_base = &body_len;
iov[1].iov_len = sizeof(body_len);
- iov[2].iov_base = (char*)&buff;
- iov[2].iov_len = HUGE_STRING_LEN;
+ iov[2].iov_base = &remote_addr;
+ iov[2].iov_len = sizeof(remote_addr);
+ iov[3].iov_base = (char*)&buff;
+ iov[3].iov_len = HUGE_STRING_LEN;
cmsg = apr_palloc(ptrans, sizeof(*cmsg) + sizeof(trans_sock_fd));
cmsg->cmsg_len = sizeof(*cmsg) + sizeof(trans_sock_fd);
@@ -1257,7 +1272,7 @@
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = iov;
- msg.msg_iovlen = 3;
+ msg.msg_iovlen = 4;
msg.msg_control = cmsg;
msg.msg_controllen = cmsg->cmsg_len;
@@ -1273,7 +1288,17 @@
/* -- extract socket from the cmsg -- */
memcpy(&trans_sock_fd, CMSG_DATA(cmsg), sizeof(trans_sock_fd));
- apr_os_sock_put((apr_socket_t **)trans_sock, &trans_sock_fd, ptrans);
+ /* here *trans_sock always == NULL (socket reset at got_fd), so
+ we can use apr_os_sock_make() instead of apr_os_sock_put() */
+ sockinfo.os_sock = &trans_sock_fd;
+ sockinfo.local = NULL;
+ sockinfo.remote = (struct sockaddr *)&remote_addr.sa.sin;
+ sockinfo.family = remote_addr.family;
+ sockinfo.type = SOCK_STREAM;
+#ifdef APR_ENABLE_FOR_1_0
+ sockinfo.protocol = 0;
+#endif
+ apr_os_sock_make((apr_socket_t **)trans_sock, &sockinfo, ptrans);
apr_os_sock_get(&fd_tmp, *trans_sock);
_DBG("trans_sock=%ld fdx=%d sock_fd=%d",
_______________________________________________
Peruser mailing list
[email protected]
http://www.telana.com/mailman/listinfo/peruser