<commit_before>/*
 * Copyright 2014 Cloudzilla Inc.
 *
 * Licensed 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.
 */

/* 
 * mod_proxy_protocol.c -- Apache proxy_protocol module
 *
 * This implements the server side of the proxy protocol decribed in
 * http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt . It works
 * by installing itself (where enabled) as a connection filter (ahead of
 * mod_ssl) to parse and remove the proxy protocol header, and by then
 * modifying the useragent_* fields in the requests accordingly.
 *
 * TODO:
 * * add the following configs:
 *     ProxyProtocolTrustedProxies "all"|ip-addr|host [ip-addr|host] ...  (default all)
 *     ProxyProtocolRejectUntrusted Yes|No  (default Yes)
 *         What to do if a connection is received from an untrusted proxy:
 *         yes = abort the connection
 *         no = allow connection and remove header, but ignore header
 * * add support for sending the header on outgoing connections (mod_proxy),
 *   and config for choosing which hosts to enable it for
 *   (ProxyProtocolDownstreamHosts?)
 */

#include "httpd.h"
#include "http_config.h"
#include "http_protocol.h"
#include "http_connection.h"
#include "http_main.h"
#include "http_log.h"
#include "ap_config.h"
#include "ap_listen.h"
#include "apr_strings.h"

module AP_MODULE_DECLARE_DATA proxy_protocol_module;

/*
 * Module configuration
 */

typedef struct pp_addr_info {
    struct pp_addr_info *next;
    apr_sockaddr_t *addr;
    server_rec *source;
} pp_addr_info;

typedef struct {
    pp_addr_info *enabled;
    pp_addr_info *disabled;
    apr_pool_t *pool;
} pp_config;

static int pp_hook_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
                              apr_pool_t *ptemp)
{
    pp_config *conf;

    conf = (pp_config *) apr_palloc(pconf, sizeof(pp_config));
    conf->enabled = NULL;
    conf->disabled = NULL;
    conf->pool = pconf;

    ap_set_module_config(ap_server_conf->module_config, &proxy_protocol_module,
                         conf);

    return OK;
}

/* Similar apr_sockaddr_equal, except that it compares ports too. */
static int pp_sockaddr_equal(apr_sockaddr_t *addr1, apr_sockaddr_t *addr2)
{<commit_msg>Add support for apr < 1.5.<commit_after>/*
 * Copyright 2014 Cloudzilla Inc.
 *
 * Licensed 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.
 */

/* 
 * mod_proxy_protocol.c -- Apache proxy_protocol module
 *
 * This implements the server side of the proxy protocol decribed in
 * http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt . It works
 * by installing itself (where enabled) as a connection filter (ahead of
 * mod_ssl) to parse and remove the proxy protocol header, and by then
 * modifying the useragent_* fields in the requests accordingly.
 *
 * TODO:
 * * add the following configs:
 *     ProxyProtocolTrustedProxies "all"|ip-addr|host [ip-addr|host] ...  (default all)
 *     ProxyProtocolRejectUntrusted Yes|No  (default Yes)
 *         What to do if a connection is received from an untrusted proxy:
 *         yes = abort the connection
 *         no = allow connection and remove header, but ignore header
 * * add support for sending the header on outgoing connections (mod_proxy),
 *   and config for choosing which hosts to enable it for
 *   (ProxyProtocolDownstreamHosts?)
 */

#include "httpd.h"
#include "http_config.h"
#include "http_protocol.h"
#include "http_connection.h"
#include "http_main.h"
#include "http_log.h"
#include "ap_config.h"
#include "ap_listen.h"
#include "apr_strings.h"
#include "apr_version.h"

module AP_MODULE_DECLARE_DATA proxy_protocol_module;

/*
 * Module configuration
 */

typedef struct pp_addr_info {
    struct pp_addr_info *next;
    apr_sockaddr_t *addr;
    server_rec *source;
} pp_addr_info;

typedef struct {
    pp_addr_info *enabled;
    pp_addr_info *disabled;
    apr_pool_t *pool;
} pp_config;

static int pp_hook_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
                              apr_pool_t *ptemp)
{
    pp_config *conf;

    conf = (pp_config *) apr_palloc(pconf, sizeof(pp_config));
    conf->enabled = NULL;
    conf->disabled = NULL;
    conf->pool = pconf;

    ap_set_module_config(ap_server_conf->module_config, &proxy_protocol_module,
                         conf);

    return OK;
}

#if !(APR_VERSION_AT_LEAST(1,5,0))
static APR_DECLARE(int) apr_sockaddr_is_wildcard(const apr_sockaddr_t *addr)
{
    static const char inaddr_any[
#if APR_HAVE_IPV6
        sizeof(struct in6_addr)
#else
        sizeof(struct in_addr)
#endif
    ] = {0};

    if (addr->ipaddr_ptr /* IP address initialized */
        && addr->ipaddr_len <= sizeof inaddr_any) { /* else bug elsewhere? */
        if (!memcmp(inaddr_any, addr->ipaddr_ptr, addr->ipaddr_len)) {
            return 1;
        }
#if APR_HAVE_IPV6
    if (addr->family == AF_INET6
        && IN6_IS_ADDR_V4MAPPED((struct in6_addr *)addr->ipaddr_ptr)) {
        struct in_addr *v4 = (struct in_addr *)&((apr_uint32_t *)addr->ipaddr_ptr)[3];

        if (!memcmp(inaddr_any, v4, sizeof *v4)) {
            return 1;
        }
    }
#endif
    }
    return 0;
}
#endif

/* Similar apr_sockaddr_equal, except that it compares ports too. */
static int pp_sockaddr_equal(apr_sockaddr_t *addr1, apr_sockaddr_t *addr2)
{
{'fraction_non_alphanumeric': 0.09420057673822493, 'fraction_numerical': 0.007369432874078821, 'mean_word_length': 3.45610278372591, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 18, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7446190', 'n_tokens_mistral': 1998, 'n_tokens_neox': 1953, 'n_words': 617}