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;
if (rv != APR_SUCCESS) {
return rv;
}
+
+ rv = apr_os_sock_get(&sctrlsock, ctrlsock);
+ if (rv != APR_SUCCESS) {
+ return rv;
+ }
{
int mop_fd;
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);
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);
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"; */
/* 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:");