/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "mod_proxy.h"

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>

#ifndef CMSG_DATA
#error This module only works on unix platforms with the correct OS support
#endif

#include "mod_proxy_fdpass.h"

module AP_MODULE_DECLARE_DATA proxy_fdpass_module;

static int proxy_fdpass_canon(request_rec *r, char *url)
{
    const char *path;

    if (strncasecmp(url, "fd://", 5) == 0) {
        url += 5;
    }
    else {
        return DECLINED;
    }

    path = ap_server_root_relative(r->pool, url);

    r->filename = apr_pstrcat(r->pool, "proxy:fd://", path, NULL);

    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01151)
                  "set r->filename to %s", r->filename);
    return OK;
}

static apr_status_t get_socket_from_path(apr_pool_t *p,
                                         const char* path,
                                         apr_socket_t **out_sock)
{
    apr_socket_t *s;
    apr_status_t rv;
    *out_sock = NULL;

    rv = apr_socket_create(&s, AF_UNIX, SOCK_STREAM, 0, p);
    if (rv != APR_SUCCESS) {
        return rv;
    }

    rv = ap_proxy_connect_uds(s, path, p);
    if (rv != APR_SUCCESS) {
        return rv;
    }

    *out_sock = s;

    return APR_SUCCESS;
}

static apr_status_t send_socket(apr_pool_t *p,
                                apr_socket_t *s,
                                apr_socket_t *outbound)
{
    apr_status_t rv;
    apr_os_sock_t rawsock;
    apr_os_sock_t srawsock;
    struct msghdr msg;
    struct cmsghdr *cmsg;
    struct iovec iov;
    char b = '\0';

    rv = apr_os_sock_get(&rawsock, outbound);
    if (rv != APR_SUCCESS) {
        return rv;
    }

    rv = apr_os_sock_get(&srawsock, s);
    if (rv != APR_SUCCESS) {
        return rv;
    }

    memset(&msg, 0, sizeof(msg));

    msg.msg_iov = &iov;
    msg.msg_iovlen = 1;

    iov.iov_base = &b;
    iov.iov_len = 1;

    cmsg = apr_palloc(p, sizeof(*cmsg) + sizeof(rawsock));
    cmsg->cmsg_len = sizeof(*cmsg) + sizeof(rawsock);
    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;

    rv = sendmsg(srawsock, &msg, 0);

    if (rv == -1) {
        return errno;
    }

    return APR_SUCCESS;
}

static int proxy_fdpass_handler(request_rec *r, proxy_worker *worker,
                              proxy_server_conf *conf,
                              char *url, const char *proxyname,
                              apr_port_t proxyport)
{
    apr_status_t rv;
    apr_socket_t *sock;
    apr_socket_t *clientsock;

    if (strncasecmp(url, "fd://", 5) == 0) {
        url += 5;
    }
    else {
        return DECLINED;
    }

    rv = get_socket_from_path(r->pool, url, &sock);

    if (rv != APR_SUCCESS) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01152)
                      "Failed to connect to '%s'", url);
        return HTTP_INTERNAL_SERVER_ERROR;
    }

    {
        int status;
        const char *flush_method = *worker->s->flusher ? worker->s->flusher : "flush";

        proxy_fdpass_flush *flush = ap_lookup_provider(PROXY_FDPASS_FLUSHER,
                                                       flush_method, "0");

        if (!flush) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01153)
                          "Unable to find configured flush provider '%s'",
                          flush_method);
            return HTTP_INTERNAL_SERVER_ERROR;
        }

        status = flush->flusher(r);
        if (status) {
            return status;
        }
    }

    clientsock = ap_get_conn_socket(r->connection);

    rv = send_socket(r->pool, sock, clientsock);
    if (rv != APR_SUCCESS) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01154) "send_socket failed:");
        return HTTP_INTERNAL_SERVER_ERROR;
    }

    {
        apr_socket_t *dummy;
        /* Create a dummy unconnected socket, and set it as the one we were
         * connected to, so that when the core closes it, it doesn't close
         * the tcp connection to the client.
         */
        rv = apr_socket_create(&dummy, APR_INET, SOCK_STREAM, APR_PROTO_TCP,
                               r->connection->pool);
        if (rv != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01155)
                          "failed to create dummy socket");
            return HTTP_INTERNAL_SERVER_ERROR;
        }
        ap_set_core_module_config(r->connection->conn_config, dummy);
    }

    return OK;
}

static int standard_flush(request_rec *r)
{
    int status;
    apr_bucket_brigade *bb;
    apr_bucket *e;

    r->connection->keepalive = AP_CONN_CLOSE;

    bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
    e = apr_bucket_flush_create(r->connection->bucket_alloc);

    APR_BRIGADE_INSERT_TAIL(bb, e);

    status = ap_pass_brigade(r->output_filters, bb);

    if (status != OK) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01156)
                      "ap_pass_brigade failed:");
        return status;
    }

    return OK;
}


static const proxy_fdpass_flush builtin_flush =
{
    "flush",
    &standard_flush,
    NULL
};

static void register_hooks(apr_pool_t *p)
{
    ap_register_provider(p, PROXY_FDPASS_FLUSHER, "flush", "0", &builtin_flush);
    proxy_hook_scheme_handler(proxy_fdpass_handler, NULL, NULL, APR_HOOK_FIRST);
    proxy_hook_canon_handler(proxy_fdpass_canon, NULL, NULL, APR_HOOK_FIRST);
}

AP_DECLARE_MODULE(proxy_fdpass) = {
    STANDARD20_MODULE_STUFF,
    NULL,                       /* create per-directory config structure */
    NULL,                       /* merge per-directory config structures */
    NULL,                       /* create per-server config structure */
    NULL,                       /* merge per-server config structures */
    NULL,                       /* command apr_table_t */
    register_hooks              /* register hooks */
};
