From: Matteo Nastasi (mop) Date: Thu, 28 Jun 2012 05:33:47 +0000 (+0200) Subject: control socket added to pass headers and other socket related data X-Git-Tag: v0.2.0~1 X-Git-Url: https://mop.ddnsfree.com/gitweb/?p=mod-proxy-fdpass.git;a=commitdiff_plain;h=c755aaaf658504331ded32581b5b3d237975c5ef control socket added to pass headers and other socket related data --- diff --git a/mod_proxy_fdpass.c b/mod_proxy_fdpass.c index e2eacce..ff7ddbc 100644 --- a/mod_proxy_fdpass.c +++ b/mod_proxy_fdpass.c @@ -160,18 +160,26 @@ static apr_status_t get_socket_from_path(request_rec *r, apr_pool_t *p, return APR_SUCCESS; } +#define ANCIL_FD_BUFFER(n) \ + struct { \ + struct cmsghdr h; \ + int fd[n]; \ + } static apr_status_t send_socket(apr_pool_t *p, apr_socket_t *s, - apr_socket_t *outbound) + apr_socket_t *outbound, + apr_socket_t *ctrlsock) { apr_status_t rv; apr_os_sock_t rawsock; apr_os_sock_t srawsock; + apr_os_sock_t sctrlsock; struct msghdr msg; struct cmsghdr *cmsg; struct iovec iov; char b = '\0', *buf; + ANCIL_FD_BUFFER(2) ancil_buf; { int mop_fd; @@ -193,6 +201,11 @@ static apr_status_t send_socket(apr_pool_t *p, if (rv != APR_SUCCESS) { return rv; } + + rv = apr_os_sock_get(&sctrlsock, ctrlsock); + if (rv != APR_SUCCESS) { + return rv; + } { int mop_fd; @@ -214,15 +227,17 @@ static apr_status_t send_socket(apr_pool_t *p, iov.iov_base = &b; iov.iov_len = 1; - cmsg = apr_palloc(p, sizeof(*cmsg) + sizeof(rawsock)); - cmsg->cmsg_len = sizeof(*cmsg) + sizeof(rawsock); + msg.msg_control = &ancil_buf; + msg.msg_controllen = sizeof(struct cmsghdr) + sizeof(rawsock) * 2; + + // cmsg = apr_palloc(p, sizeof(*cmsg) + sizeof(rawsock)); + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_len = sizeof(*cmsg) + sizeof(rawsock) * 2; cmsg->cmsg_level = SOL_SOCKET; cmsg->cmsg_type = SCM_RIGHTS; - memcpy(CMSG_DATA(cmsg), &rawsock, sizeof(rawsock)); - - msg.msg_control = cmsg; - msg.msg_controllen = cmsg->cmsg_len; + ((int *)CMSG_DATA(cmsg))[0] = rawsock; + ((int *)CMSG_DATA(cmsg))[1] = sctrlsock; rv = sendmsg(srawsock, &msg, 0); @@ -266,6 +281,8 @@ static int proxy_fdpass_handler(request_rec *r, proxy_worker *worker, apr_socket_t *clientsock; char *buf; char *headers_out = NULL; + int ctrlrawsock[2]; + apr_socket_t *ctrlsock = NULL, *clientctrlsock = NULL; if ((headers_out = calloc(8*1024, 1)) != NULL) { apr_table_do(headers_builder, headers_out, r->headers_in, NULL); @@ -303,6 +320,25 @@ static int proxy_fdpass_handler(request_rec *r, proxy_worker *worker, return HTTP_INTERNAL_SERVER_ERROR; } + /* create a couple of sockets and pass one to the client for headers and so on */ + if (socketpair(AF_UNIX, SOCK_STREAM, 0, ctrlrawsock)) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "proxy: FD: Failed create socketpair"); + return HTTP_INTERNAL_SERVER_ERROR; + } + rv = apr_os_sock_put(&ctrlsock, &(ctrlrawsock[0]), r->connection->pool); + if (rv != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "proxy: FD: apr_os_sock_put failed"); + return HTTP_INTERNAL_SERVER_ERROR; + } + rv = apr_os_sock_put(&clientctrlsock, &(ctrlrawsock[1]), r->connection->pool); + if (rv != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "proxy: FD: apr_os_sock_put failed"); + return HTTP_INTERNAL_SERVER_ERROR; + } + { int status; /* const char *flush_method = worker->flusher ? worker->flusher : "flush"; */ @@ -333,7 +369,7 @@ static int proxy_fdpass_handler(request_rec *r, proxy_worker *worker, /* There should really be a (documented) public API for this ! */ clientsock = ap_get_module_config(r->connection->conn_config, &core_module); - rv = send_socket(r->pool, sock, clientsock); + rv = send_socket(r->pool, sock, clientsock, clientctrlsock); if (rv != APR_SUCCESS) { ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, "proxy: FD: send_socket failed:");