/* 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 "apr_network_io.h"
#include "apr_strings.h"

#define APR_WANT_STRFUNC
#include "apr_want.h"
#include "apr_version.h"

#include "ap_config.h"
#include "httpd.h"
#include "http_main.h"
#include "http_config.h"
#include "http_core.h"
#include "ap_listen.h"
#include "http_log.h"
#include "mpm_common.h"

#include <stdlib.h>
#if APR_HAVE_UNISTD_H
#include <unistd.h>
#endif

/* we know core's module_index is 0 */
#undef APLOG_MODULE_INDEX
#define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX

AP_DECLARE_DATA ap_listen_rec *ap_listeners = NULL;

/* Let ap_num_listen_buckets be global so that it can
 * be printed by ap_log_mpm_common(), but keep the listeners
 * buckets static since it is used only here to close them
 * all (including duplicated) with ap_close_listeners().
 */
AP_DECLARE_DATA int ap_num_listen_buckets;
static ap_listen_rec **ap_listen_buckets;

/* Determine once, at runtime, whether or not SO_REUSEPORT
 * is usable on this platform, and hence whether or not
 * listeners can be duplicated (if configured).
 */
AP_DECLARE_DATA int ap_have_so_reuseport = -1;

/* Whether some accept() errors are non-fatal to the process */
AP_DECLARE_DATA int ap_accept_errors_nonfatal = 0;

static ap_listen_rec *old_listeners;
static int ap_listenbacklog;
static int ap_listencbratio;
static int send_buffer_size;
static int receive_buffer_size;
#ifdef HAVE_SYSTEMD
static int use_systemd = -1;
#endif

/* TODO: make_sock is just begging and screaming for APR abstraction */
static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server, int do_bind_listen)
{
    apr_socket_t *s = server->sd;
    int one = 1;
#if APR_HAVE_IPV6
#ifdef AP_ENABLE_V4_MAPPED
    int v6only_setting = (server->flags & AP_LISTEN_V6ONLY) ? 1 : 0;
#else
    int v6only_setting = 1;
#endif
#endif
    apr_status_t stat;

#ifndef WIN32
    stat = apr_socket_opt_set(s, APR_SO_REUSEADDR, one);
    if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) {
        ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p, APLOGNO(00067)
                      "make_sock: for address %pI, apr_socket_opt_set: (SO_REUSEADDR)",
                      server->bind_addr);
        apr_socket_close(s);
        return stat;
    }
#endif

    stat = apr_socket_opt_set(s, APR_SO_KEEPALIVE, one);
    if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) {
        ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p, APLOGNO(00068)
                      "make_sock: for address %pI, apr_socket_opt_set: (SO_KEEPALIVE)",
                      server->bind_addr);
        apr_socket_close(s);
        return stat;
    }

    /*
     * To send data over high bandwidth-delay connections at full
     * speed we must force the TCP window to open wide enough to keep the
     * pipe full.  The default window size on many systems
     * is only 4kB.  Cross-country WAN connections of 100ms
     * at 1Mb/s are not impossible for well connected sites.
     * If we assume 100ms cross-country latency,
     * a 4kB buffer limits throughput to 40kB/s.
     *
     * To avoid this problem I've added the SendBufferSize directive
     * to allow the web master to configure send buffer size.
     *
     * The trade-off of larger buffers is that more kernel memory
     * is consumed.  YMMV, know your customers and your network!
     *
     * -John Heidemann <johnh@isi.edu> 25-Oct-96
     *
     * If no size is specified, use the kernel default.
     */
    if (send_buffer_size) {
        stat = apr_socket_opt_set(s, APR_SO_SNDBUF,  send_buffer_size);
        if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) {
            ap_log_perror(APLOG_MARK, APLOG_WARNING, stat, p, APLOGNO(00070)
                          "make_sock: failed to set SendBufferSize for "
                          "address %pI, using default",
                          server->bind_addr);
            /* not a fatal error */
        }
    }
    if (receive_buffer_size) {
        stat = apr_socket_opt_set(s, APR_SO_RCVBUF, receive_buffer_size);
        if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) {
            ap_log_perror(APLOG_MARK, APLOG_WARNING, stat, p, APLOGNO(00071)
                          "make_sock: failed to set ReceiveBufferSize for "
                          "address %pI, using default",
                          server->bind_addr);
            /* not a fatal error */
        }
    }

#if APR_TCP_NODELAY_INHERITED
    ap_sock_disable_nagle(s);
#endif

#if defined(SO_REUSEPORT)
    if (server->flags & AP_LISTEN_REUSEPORT
        || (ap_have_so_reuseport && ap_listencbratio > 0)) {
        int thesock;
        apr_os_sock_get(&thesock, s);
        if (setsockopt(thesock, SOL_SOCKET, SO_REUSEPORT,
                       (void *)&one, sizeof(int)) < 0) {
            stat = apr_get_netos_error();
            ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p, APLOGNO(02638)
                          "make_sock: for address %pI, apr_socket_opt_set: "
                          "(SO_REUSEPORT)",
                          server->bind_addr);
            apr_socket_close(s);
            return stat;
        }
    }
#endif


#if defined(APR_SO_FREEBIND)
    if (server->flags & AP_LISTEN_FREEBIND) {
        if (apr_socket_opt_set(s, APR_SO_FREEBIND, one) < 0) {
            stat = apr_get_netos_error();
            ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p, APLOGNO(10236)
                          "make_sock: apr_socket_opt_set: "
                          "error setting APR_SO_FREEBIND");
            apr_socket_close(s);
            return stat;
        }
    }
#endif


    if (do_bind_listen) {
#if APR_HAVE_IPV6
        if (server->bind_addr->family == APR_INET6) {
            stat = apr_socket_opt_set(s, APR_IPV6_V6ONLY, v6only_setting);
            if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) {
                ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p, APLOGNO(00069)
                              "make_sock: for address %pI, apr_socket_opt_set: "
                              "(IPV6_V6ONLY)",
                              server->bind_addr);
                apr_socket_close(s);
                return stat;
            }
        }
#endif

        if ((stat = apr_socket_bind(s, server->bind_addr)) != APR_SUCCESS) {
            ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, stat, p, APLOGNO(00072)
                          "make_sock: could not bind to address %pI",
                          server->bind_addr);
            apr_socket_close(s);
            return stat;
        }

        if ((stat = apr_socket_listen(s, ap_listenbacklog)) != APR_SUCCESS) {
            ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_ERR, stat, p, APLOGNO(00073)
                          "make_sock: unable to listen for connections "
                          "on address %pI",
                          server->bind_addr);
            apr_socket_close(s);
            return stat;
        }
    }

#ifdef WIN32
    /* I seriously doubt that this would work on Unix; I have doubts that
     * it entirely solves the problem on Win32.  However, since setting
     * reuseaddr on the listener -prior- to binding the socket has allowed
     * us to attach to the same port as an already running instance of
     * Apache, or even another web server, we cannot identify that this
     * port was exclusively granted to this instance of Apache.
     *
     * So set reuseaddr, but do not attempt to do so until we have the
     * parent listeners successfully bound.
     */
    stat = apr_socket_opt_set(s, APR_SO_REUSEADDR, one);
    if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) {
        ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p, APLOGNO(00074)
                    "make_sock: for address %pI, apr_socket_opt_set: (SO_REUSEADDR)",
                     server->bind_addr);
        apr_socket_close(s);
        return stat;
    }
#endif

    server->sd = s;
    server->active = 1;

    server->accept_func = NULL;

    return APR_SUCCESS;
}

static const char* find_accf_name(server_rec *s, const char *proto)
{
    const char* accf;
    core_server_config *conf = ap_get_core_module_config(s->module_config);
    if (!proto) {
        return NULL;
    }

    accf = apr_table_get(conf->accf_map, proto);

    if (accf && !strcmp("none", accf)) {
        return NULL;
    }

    return accf;
}

static void ap_apply_accept_filter(apr_pool_t *p, ap_listen_rec *lis,
                                           server_rec *server)
{
    apr_socket_t *s = lis->sd;
    const char *accf;
    apr_status_t rv;
    const char *proto;

    proto = lis->protocol;

    if (!proto) {
        proto = ap_get_server_protocol(server);
    }


    accf = find_accf_name(server, proto);

    if (accf) {
#if APR_HAS_SO_ACCEPTFILTER
        /* In APR 1.x, the 2nd and 3rd parameters are char * instead of 
         * const char *, so make a copy of those args here.
         */
        rv = apr_socket_accept_filter(s, apr_pstrdup(p, accf),
                                      apr_pstrdup(p, ""));
        if (rv != APR_SUCCESS && !APR_STATUS_IS_ENOTIMPL(rv)) {
            ap_log_perror(APLOG_MARK, APLOG_WARNING, rv, p, APLOGNO(00075)
                          "Failed to enable the '%s' Accept Filter",
                          accf);
        }
#else
        rv = apr_socket_opt_set(s, APR_TCP_DEFER_ACCEPT, 30);
        if (rv != APR_SUCCESS && !APR_STATUS_IS_ENOTIMPL(rv)) {
            ap_log_perror(APLOG_MARK, APLOG_WARNING, rv, p, APLOGNO(00076)
                              "Failed to enable APR_TCP_DEFER_ACCEPT");
        }
#endif
    }
}

static apr_status_t close_listeners_on_exec(void *v)
{
    ap_close_listeners();
    return APR_SUCCESS;
}


#ifdef HAVE_SYSTEMD

static apr_status_t alloc_systemd_listener(process_rec * process,
                                           int fd, const char *proto,
                                           ap_listen_rec **out_rec)
{
    apr_status_t rv;
    struct sockaddr sa;
    socklen_t len = sizeof(struct sockaddr);
    apr_os_sock_info_t si;
    ap_listen_rec *rec;
    *out_rec = NULL;

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

    rv = getsockname(fd, &sa, &len);

    if (rv != 0) {
        rv = apr_get_netos_error();
        ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, process->pool, APLOGNO(02489)
                      "getsockname on %d failed.", fd);
        return rv;
    }

    si.os_sock = &fd;
    si.family = sa.sa_family;
    si.local = &sa;
    si.type = SOCK_STREAM;
    si.protocol = APR_PROTO_TCP;

    rec = apr_palloc(process->pool, sizeof(ap_listen_rec));
    rec->active = 0;
    rec->next = 0;

    rv = apr_os_sock_make(&rec->sd, &si, process->pool);
    if (rv != APR_SUCCESS) {
        ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, process->pool, APLOGNO(02490)
                      "apr_os_sock_make on %d failed.", fd);
        return rv;
    }

    rv = apr_socket_addr_get(&rec->bind_addr, APR_LOCAL, rec->sd);
    if (rv != APR_SUCCESS) {
        ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, process->pool, APLOGNO(02491)
                      "apr_socket_addr_get on %d failed.", fd);
        return rv;
    }

    rec->protocol = apr_pstrdup(process->pool, proto);

    *out_rec = rec;

    return make_sock(process->pool, rec, 0);
}

static const char *set_systemd_listener(process_rec *process, apr_port_t port,
                                        const char *proto)
{
    ap_listen_rec *last, *new;
    apr_status_t rv;
    APR_OPTIONAL_FN_TYPE(ap_find_systemd_socket) *find_systemd_socket;
    int fd;

    find_systemd_socket = APR_RETRIEVE_OPTIONAL_FN(ap_find_systemd_socket);

    if (!find_systemd_socket)
       return "Systemd socket activation is used, but mod_systemd is probably "
               "not loaded";

    fd = find_systemd_socket(process, port);
    if (fd < 0) {
        return "Systemd socket activation is used, but this port is not "
                "configured in systemd";
    }

    last = ap_listeners;
    while (last && last->next) {
        last = last->next;
    }

    rv = alloc_systemd_listener(process, fd, proto, &new);
    if (rv != APR_SUCCESS) {
        return "Failed to setup socket passed by systemd using socket activation";
    }

    if (last == NULL) {
        ap_listeners = new;
    }
    else {
        last->next = new;
    }

    return NULL;
}
#endif /* HAVE_SYSTEMD */

/* Returns non-zero if socket address SA matches hostname, port and
 * scope_id.  p is used for temporary allocations. */
static int match_address(const apr_sockaddr_t *sa,
                         const char *hostname, apr_port_t port,
                         const char *scope_id, apr_pool_t *p)
{
    const char *old_scope = NULL;

#if APR_VERSION_AT_LEAST(1,7,0)
    /* To be clever here we could correctly match numeric and
     * non-numeric zone ids.  Ignore failure, old_scope will be left
     * as NULL. */
    (void) apr_sockaddr_zone_get(sa, &old_scope, NULL, p);
#endif
    
    return port == sa->port
        && ((!hostname && !sa->hostname)
            || (hostname && sa->hostname && !strcmp(sa->hostname, hostname)))
        && ((!scope_id && !old_scope)
            || (scope_id && old_scope && !strcmp(scope_id, old_scope)));            
}

/* ### This logic doesn't cope with DNS changes across a restart. */
static int find_listeners(ap_listen_rec **from, ap_listen_rec **to,
                          const char *addr, apr_port_t port,
                          const char *scope_id, apr_pool_t *temp_pool)
{
    int found = 0;

    while (*from) {
        apr_sockaddr_t *sa = (*from)->bind_addr;

        /* Some listeners are not real so they will not have a bind_addr. */
        if (sa) {
            ap_listen_rec *new;

            /* Re-use the existing record if it matches completely
             * against an existing listener. */
            if (match_address(sa, addr, port, scope_id, temp_pool)) {
                found = 1;
                if (!to) {
                    break;
                }
                new = *from;
                *from = new->next;
                new->next = *to;
                *to = new;
                continue;
            }
        }

        from = &(*from)->next;
    }

    return found;
}

static const char *alloc_listener(process_rec *process, const char *addr,
                                  apr_port_t port, const char* proto,
                                  const char *scope_id, void *slave,
                                  apr_pool_t *temp_pool, apr_uint32_t flags)
{
    ap_listen_rec *last;
    apr_status_t status;
    apr_sockaddr_t *sa;

    /* see if we've got a listener for this address:port, which is an error */
    if (find_listeners(&ap_listeners, NULL, addr, port, scope_id, temp_pool)) {
        return "Cannot define multiple Listeners on the same IP:port";
    }

    /* see if we've got an old listener for this address:port */
    if (find_listeners(&old_listeners, &ap_listeners, addr, port,
                       scope_id, temp_pool)) {
        if (ap_listeners->slave != slave) {
            return "Cannot define a slave on the same IP:port as a Listener";
        }
        return NULL;
    }

    if ((status = apr_sockaddr_info_get(&sa, addr, APR_UNSPEC, port, 0,
                                        process->pool))
        != APR_SUCCESS) {
        ap_log_perror(APLOG_MARK, APLOG_CRIT, status, process->pool, APLOGNO(00077)
                      "alloc_listener: failed to set up sockaddr for %s",
                      addr);
        return "Listen setup failed";
    }

    /* Initialize to our last configured ap_listener. */
    last = ap_listeners;
    while (last && last->next) {
        last = last->next;
    }

    while (sa) {
        ap_listen_rec *new;

        /* this has to survive restarts */
        new = apr_palloc(process->pool, sizeof(ap_listen_rec));
        new->active = 0;
        new->next = 0;
        new->bind_addr = sa;
        new->protocol = apr_pstrdup(process->pool, proto);
        new->flags = flags;

        /* Go to the next sockaddr. */
        sa = sa->next;

        status = apr_socket_create(&new->sd, new->bind_addr->family,
                                    SOCK_STREAM, 0, process->pool);

#if APR_HAVE_IPV6
        /* What could happen is that we got an IPv6 address, but this system
         * doesn't actually support IPv6.  Try the next address.
         */
        if (status != APR_SUCCESS && !addr &&
            new->bind_addr->family == APR_INET6) {
            continue;
        }
#endif
        if (status != APR_SUCCESS) {
            ap_log_perror(APLOG_MARK, APLOG_CRIT, status, process->pool, APLOGNO(00078)
                          "alloc_listener: failed to get a socket for %s",
                          addr);
            return "Listen setup failed";
        }

#if APR_VERSION_AT_LEAST(1,7,0)
        if (scope_id) {
            status = apr_sockaddr_zone_set(new->bind_addr, scope_id);
            if (status) {
                ap_log_perror(APLOG_MARK, APLOG_CRIT, status, process->pool, APLOGNO(10102)
                              "alloc_listener: failed to set scope for %pI to %s",
                              new->bind_addr, scope_id);
                return "Listen step failed";
            }
        }
#endif

        /* We need to preserve the order returned by getaddrinfo() */
        if (last == NULL) {
            ap_listeners = last = new;
        } else {
            last->next = new;
            last = new;
        }
        new->slave = slave;
    }

    return NULL;
}
/* Evaluates to true if the (apr_sockaddr_t *) addr argument is the
 * IPv4 match-any-address, 0.0.0.0. */
#define IS_INADDR_ANY(addr) ((addr)->family == APR_INET \
                             && (addr)->sa.sin.sin_addr.s_addr == INADDR_ANY)

/* Evaluates to true if the (apr_sockaddr_t *) addr argument is the
 * IPv6 match-any-address, [::]. */
#define IS_IN6ADDR_ANY(addr) ((addr)->family == APR_INET6 \
                              && IN6_IS_ADDR_UNSPECIFIED(&(addr)->sa.sin6.sin6_addr))

/**
 * Create, open, listen, and bind all sockets.
 * @param process The process record for the currently running server
 * @return The number of open sockets
 */
static int open_listeners(apr_pool_t *pool)
{
    ap_listen_rec *lr;
    ap_listen_rec *next;
    ap_listen_rec *previous;
    int num_open;
    const char *userdata_key = "ap_open_listeners";
    void *data;
#if AP_NONBLOCK_WHEN_MULTI_LISTEN
    int use_nonblock;
#endif

    /* Don't allocate a default listener.  If we need to listen to a
     * port, then the user needs to have a Listen directive in their
     * config file.
     */
    num_open = 0;
    previous = NULL;
    for (lr = ap_listeners; lr; previous = lr, lr = lr->next) {
        if (lr->active) {
            ++num_open;
        }
        else {
#if APR_HAVE_IPV6
            ap_listen_rec *cur;
            int v6only_setting;
            int skip = 0;

            /* If we have the unspecified IPv4 address (0.0.0.0) and
             * the unspecified IPv6 address (::) is next, we need to
             * swap the order of these in the list. We always try to
             * bind to IPv6 first, then IPv4, since an IPv6 socket
             * might be able to receive IPv4 packets if V6ONLY is not
             * enabled, but never the other way around.
             * Note: In some configurations, the unspecified IPv6 address
             * could be even later in the list.  This logic only corrects
             * the situation where it is next in the list, such as when
             * apr_sockaddr_info_get() returns an IPv4 and an IPv6 address,
             * in that order.
             */
            if (lr->next != NULL
                && IS_INADDR_ANY(lr->bind_addr)
                && lr->bind_addr->port == lr->next->bind_addr->port
                && IS_IN6ADDR_ANY(lr->next->bind_addr)) {
                /* Exchange lr and lr->next */
                next = lr->next;
                lr->next = next->next;
                next->next = lr;
                if (previous) {
                    previous->next = next;
                }
                else {
                    ap_listeners = next;
                }
                lr = next;
            }

            /* If we are trying to bind to 0.0.0.0 and a previous listener
             * was :: on the same port and in turn that socket does not have
             * the IPV6_V6ONLY flag set; we must skip the current attempt to
             * listen (which would generate an error). IPv4 will be handled
             * on the established IPv6 socket.
             */
            if (IS_INADDR_ANY(lr->bind_addr) && previous) {
                for (cur = ap_listeners; cur != lr; cur = cur->next) {
                    if (lr->bind_addr->port == cur->bind_addr->port
                        && IS_IN6ADDR_ANY(cur->bind_addr)
                        && apr_socket_opt_get(cur->sd, APR_IPV6_V6ONLY,
                                              &v6only_setting) == APR_SUCCESS
                        && v6only_setting == 0) {

                        /* Remove the current listener from the list */
                        previous->next = lr->next;
                        lr = previous; /* maintain current value of previous after
                                        * post-loop expression is evaluated
                                        */
                        skip = 1;
                        break;
                    }
                }
                if (skip) {
                    continue;
                }
            }
#endif
            if (make_sock(pool, lr, 1) == APR_SUCCESS) {
                ++num_open;
            }
            else {
#if APR_HAVE_IPV6
                /* If we tried to bind to ::, and the next listener is
                 * on 0.0.0.0 with the same port, don't give a fatal
                 * error. The user will still get a warning from make_sock
                 * though.
                 */
                if (lr->next != NULL
                    && IS_IN6ADDR_ANY(lr->bind_addr)
                    && lr->bind_addr->port == lr->next->bind_addr->port
                    && IS_INADDR_ANY(lr->next->bind_addr)) {

                    /* Remove the current listener from the list */
                    if (previous) {
                        previous->next = lr->next;
                    }
                    else {
                        ap_listeners = lr->next;
                    }

                    /* Although we've removed ourselves from the list,
                     * we need to make sure that the next iteration won't
                     * consider "previous" a working IPv6 '::' socket.
                     * Changing the family is enough to make sure the
                     * conditions before make_sock() fail.
                     */
                    lr->bind_addr->family = AF_INET;

                    continue;
                }
#endif
                /* fatal error */
                return -1;
            }
        }
    }

    /* close the old listeners */
    ap_close_listeners_ex(old_listeners);
    old_listeners = NULL;

#if AP_NONBLOCK_WHEN_MULTI_LISTEN
    /* if multiple listening sockets, make them non-blocking so that
     * if select()/poll() reports readability for a reset connection that
     * is already forgotten about by the time we call accept, we won't
     * be hung until another connection arrives on that port
     */
    use_nonblock = (ap_listeners && ap_listeners->next);
    for (lr = ap_listeners; lr; lr = lr->next) {
        apr_status_t status;

        status = apr_socket_opt_set(lr->sd, APR_SO_NONBLOCK, use_nonblock);
        if (status != APR_SUCCESS) {
            ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_ERR, status, pool, APLOGNO(00079)
                          "unable to control socket non-blocking status");
            return -1;
        }
    }
#endif /* AP_NONBLOCK_WHEN_MULTI_LISTEN */

    /* we come through here on both passes of the open logs phase
     * only register the cleanup once... otherwise we try to close
     * listening sockets twice when cleaning up prior to exec
     */
    apr_pool_userdata_get(&data, userdata_key, pool);
    if (!data) {
        apr_pool_userdata_set((const void *)1, userdata_key,
                              apr_pool_cleanup_null, pool);
        apr_pool_cleanup_register(pool, NULL, apr_pool_cleanup_null,
                                  close_listeners_on_exec);
    }

    return num_open ? 0 : -1;
}

AP_DECLARE(int) ap_setup_listeners(server_rec *s)
{
    server_rec *ls;
    server_addr_rec *addr;
    ap_listen_rec *lr;
    int num_listeners = 0;
    const char* proto;
    int found;
#ifdef HAVE_SYSTEMD
    APR_OPTIONAL_FN_TYPE(ap_systemd_listen_fds) *systemd_listen_fds;
#endif

    for (ls = s; ls; ls = ls->next) {
        proto = ap_get_server_protocol(ls);
        if (!proto) {
            found = 0;
            /* No protocol was set for this vhost,
             * use the default for this listener.
             */
            for (addr = ls->addrs; addr && !found; addr = addr->next) {
                for (lr = ap_listeners; lr; lr = lr->next) {
                    if (apr_sockaddr_equal(lr->bind_addr, addr->host_addr) &&
                        lr->bind_addr->port == addr->host_port) {
                        ap_set_server_protocol(ls, lr->protocol);
                        found = 1;
                        break;
                    }
                }
            }

            if (!found) {
                /* TODO: set protocol defaults per-Port, eg 25=smtp */
                ap_set_server_protocol(ls, "http");
            }
        }
    }

#ifdef HAVE_SYSTEMD
    if (use_systemd) {
        const char *userdata_key = "ap_open_systemd_listeners";
        void *data;
        /* clear the environment on our second run
        * so that none of our future children get confused.
        */
        apr_pool_userdata_get(&data, userdata_key, s->process->pool);
        if (!data) {
            apr_pool_userdata_set((const void *)1, userdata_key,
                                apr_pool_cleanup_null, s->process->pool);
        }
        else {
            systemd_listen_fds = APR_RETRIEVE_OPTIONAL_FN(ap_systemd_listen_fds);
            if (systemd_listen_fds != NULL) {
                systemd_listen_fds(1);
            }
        }        
    }
    else
#endif
    {
        if (open_listeners(s->process->pool)) {
            return 0;
        }
    }

    for (lr = ap_listeners; lr; lr = lr->next) {
        if (ap_accept_errors_nonfatal) lr->flags |= AP_LISTEN_SPECIFIC_ERRORS;
        num_listeners++;
        found = 0;
        for (ls = s; ls && !found; ls = ls->next) {
            for (addr = ls->addrs; addr && !found; addr = addr->next) {
                if (apr_sockaddr_equal(lr->bind_addr, addr->host_addr) &&
                    lr->bind_addr->port == addr->host_port) {
                    found = 1;
                    ap_apply_accept_filter(s->process->pool, lr, ls);
                }
            }
        }

        if (!found) {
            ap_apply_accept_filter(s->process->pool, lr, s);
        }
    }

    return num_listeners;
}

AP_DECLARE(apr_status_t) ap_duplicate_listeners(apr_pool_t *p, server_rec *s,
                                                ap_listen_rec ***buckets,
                                                int *num_buckets)
{
    static int warn_once;
    int i;
    apr_status_t stat;
    int use_nonblock = 0;
    ap_listen_rec *lr;

    if (*num_buckets < 1) {
        *num_buckets = 1;
        if (ap_listencbratio > 0) {
#ifdef _SC_NPROCESSORS_ONLN
            if (ap_have_so_reuseport) {
                int num_online_cores = sysconf(_SC_NPROCESSORS_ONLN),
                    val = num_online_cores / ap_listencbratio;
                if (val > 1) {
                    *num_buckets = val;
                }
                ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(02819)
                              "Using %i listeners bucket(s) based on %i "
                              "online CPU cores and a ratio of %i",
                              *num_buckets, num_online_cores,
                              ap_listencbratio);
            }
            else
#endif
            if (!warn_once) {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(02820)
                              "ListenCoresBucketsRatio ignored without "
                              "SO_REUSEPORT and _SC_NPROCESSORS_ONLN "
                              "support: using a single listeners bucket");
                warn_once = 1;
            }
        }
    }

    *buckets = apr_pcalloc(p, *num_buckets * sizeof(ap_listen_rec *));
    (*buckets)[0] = ap_listeners;

    for (i = 1; i < *num_buckets; i++) {
        ap_listen_rec *last = NULL;
        lr = ap_listeners;
        while (lr) {
            ap_listen_rec *duplr;
            char *hostname;
            apr_port_t port;
            apr_sockaddr_t *sa;
#ifdef HAVE_SYSTEMD
            if (use_systemd) {
                int thesock;
                apr_os_sock_get(&thesock, lr->sd);
                if ((stat = alloc_systemd_listener(s->process, thesock,
                    lr->protocol, &duplr)) != APR_SUCCESS) {
                    return stat;
                }
            }
            else
#endif
            {
                duplr = apr_palloc(p, sizeof(ap_listen_rec));
                duplr->slave = NULL;
                duplr->protocol = apr_pstrdup(p, lr->protocol);
                hostname = apr_pstrdup(p, lr->bind_addr->hostname);
                port = lr->bind_addr->port;
                stat = apr_sockaddr_info_get(&sa, hostname, APR_UNSPEC, port, 0, p);
                if (stat != APR_SUCCESS) {
                    ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p, APLOGNO(10397)
                                  "failure looking up %s to duplicate "
                                  "listening socket", hostname);
                    return stat;
                }
                duplr->bind_addr = sa;
                duplr->next = NULL;
                duplr->flags = lr->flags;
                stat = apr_socket_create(&duplr->sd, duplr->bind_addr->family,
                                         SOCK_STREAM, 0, p);
                if (stat != APR_SUCCESS) {
                    ap_log_perror(APLOG_MARK, APLOG_CRIT, 0, p, APLOGNO(02640)
                                "ap_duplicate_listeners: for address %pI, "
                                "cannot duplicate a new socket!",
                                duplr->bind_addr);
                    return stat;
                }
                make_sock(p, duplr, 1);
            }
#if AP_NONBLOCK_WHEN_MULTI_LISTEN
            use_nonblock = (ap_listeners && ap_listeners->next);
            stat = apr_socket_opt_set(duplr->sd, APR_SO_NONBLOCK, use_nonblock);
            if (stat != APR_SUCCESS) {
                ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p, APLOGNO(02641)
                              "unable to control socket non-blocking status");
                return stat;
            }
#endif
            ap_apply_accept_filter(p, duplr, s);

            if (last == NULL) {
                (*buckets)[i] = last = duplr;
            }
            else {
                last->next = duplr;
                last = duplr;
            }
            lr = lr->next;
        }
    }

    ap_listen_buckets = *buckets;
    ap_num_listen_buckets = *num_buckets;
    return APR_SUCCESS;
}

AP_DECLARE_NONSTD(void) ap_close_listeners(void)
{
    int i;

    ap_close_listeners_ex(ap_listeners);

    /* Start from index 1 since either ap_duplicate_listeners()
     * was called and ap_listen_buckets[0] == ap_listeners, or
     * it wasn't and ap_num_listen_buckets == 0.
     */
    for (i = 1; i < ap_num_listen_buckets; i++) {
        ap_close_listeners_ex(ap_listen_buckets[i]);
    }
}

AP_DECLARE_NONSTD(void) ap_close_listeners_ex(ap_listen_rec *listeners)
{
    ap_listen_rec *lr;
    for (lr = listeners; lr; lr = lr->next) {
        apr_socket_close(lr->sd);
        lr->active = 0;
    }
}

AP_DECLARE_NONSTD(int) ap_close_selected_listeners(ap_slave_t *slave)
{
    ap_listen_rec *lr;
    int n = 0;

    for (lr = ap_listeners; lr; lr = lr->next) {
        if (lr->slave != slave) {
            apr_socket_close(lr->sd);
            lr->active = 0;
        }
        else {
            ++n;
        }
    }
    return n;
}

AP_DECLARE(void) ap_listen_pre_config(void)
{
    old_listeners = ap_listeners;
    ap_listeners = NULL;
    ap_listen_buckets = NULL;
    ap_num_listen_buckets = 0;
    ap_listenbacklog = DEFAULT_LISTENBACKLOG;
    ap_listencbratio = 0;

    /* Check once whether or not SO_REUSEPORT is supported. */
    if (ap_have_so_reuseport < 0) {
        /* This is limited to Linux with defined SO_REUSEPORT (ie. 3.9+) for
         * now since the implementation evenly distributes connections across
         * all the listening threads/processes.
         *
         * *BSDs have SO_REUSEPORT too but with a different semantic: the first
         * wildcard address bound socket or the last non-wildcard address bound
         * socket will receive connections (no evenness guarantee); the rest of
         * the sockets bound to the same port will not.
         * This can't (always) work for httpd.
         *
         * TODO: latests DragonFlyBSD's SO_REUSEPORT (seems to?) have the same
         * semantic as Linux, so we may need HAVE_SO_REUSEPORT available from
         * configure.in some day.
         */
#if defined(SO_REUSEPORT) && defined(__linux__)
        apr_socket_t *sock;
        if (apr_socket_create(&sock, APR_UNSPEC, SOCK_STREAM, 0,
                              ap_pglobal) == APR_SUCCESS) {
            int thesock, on = 1;
            apr_os_sock_get(&thesock, sock);
            ap_have_so_reuseport = (setsockopt(thesock, SOL_SOCKET,
                                               SO_REUSEPORT, (void *)&on,
                                               sizeof(int)) == 0);
            apr_socket_close(sock);
        }
        else
#endif
        ap_have_so_reuseport = 0;

    }
}

AP_DECLARE(int) ap_accept_error_is_nonfatal(apr_status_t status)
{

   return APR_STATUS_IS_ECONNREFUSED(status)
             || APR_STATUS_IS_ECONNABORTED(status)
             || APR_STATUS_IS_ECONNRESET(status);
}

/* Parse optional flags argument for Listen.  Currently just boolean
 * flags handled; would need to be extended to incorporate
 * ListenBacklog */
static const char *parse_listen_flags(apr_pool_t *temp_pool, const char *arg,
                                      apr_uint32_t *flags_out)
{
    apr_uint32_t flags = 0;
    char *str = apr_pstrdup(temp_pool, arg), *token, *state = NULL;

    token = apr_strtok(str, ",", &state);
    while (token) {
        if (ap_cstr_casecmp(token, "freebind") == 0)
            flags |= AP_LISTEN_FREEBIND;
        else if (ap_cstr_casecmp(token, "reuseport") == 0)
            flags |= AP_LISTEN_REUSEPORT;
        else if (ap_cstr_casecmp(token, "v6only") == 0)
            flags |= AP_LISTEN_V6ONLY;
        else
            return apr_psprintf(temp_pool, "Unknown Listen option '%s' in '%s'",
                                token, arg);

        token = apr_strtok(NULL, ",", &state);
    }

    *flags_out = flags;

    return NULL;
}

AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy,
                                                int argc, char *const argv[])
{
    char *host, *scope_id, *proto = NULL;
    apr_port_t port;
    apr_status_t rv;
    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
    apr_uint32_t flags = 0;
#ifdef HAVE_SYSTEMD
    APR_OPTIONAL_FN_TYPE(ap_systemd_listen_fds) *systemd_listen_fds;
#endif

    if (err != NULL) {
        return err;
    }

    if (argc < 1 || argc > 3) {
        return "Listen requires 1-3 arguments.";
    }
#ifdef HAVE_SYSTEMD
    if (use_systemd == -1) {
        systemd_listen_fds = APR_RETRIEVE_OPTIONAL_FN(ap_systemd_listen_fds);
        if (systemd_listen_fds != NULL) {
            use_systemd = systemd_listen_fds(0) > 0;
        } else {
            use_systemd = 0;
        }
    }
#endif

    rv = apr_parse_addr_port(&host, &scope_id, &port, argv[0], cmd->pool);
    if (rv != APR_SUCCESS) {
        return "Invalid address or port";
    }

    if (host && !strcmp(host, "*")) {
        host = NULL;
    }

#if !APR_VERSION_AT_LEAST(1,7,0)
    if (scope_id) {
        return apr_pstrcat(cmd->pool,
                           "Scope ID in address '", argv[0],
                           "' not supported with APR " APR_VERSION_STRING,
                           NULL);
    }
#endif

    if (!port) {
        return "Port must be specified";
    }

    if (argc == 3) {
        if (strncasecmp(argv[2], "options=", 8)) {
            return "Third argument to Listen must be options=...";
        }

        err = parse_listen_flags(cmd->temp_pool, argv[2] + 8, &flags);
        if (err) {
            return err;
        }

        proto = argv[1];
    }

    if (argc == 2) {
        /* 2-arg form is either 'Listen host:port options=...' or
         * 'Listen host:port protocol' */
        if (strncasecmp(argv[1], "options=", 8) == 0) {
            err = parse_listen_flags(cmd->temp_pool, argv[1] + 8, &flags);
            if (err) {
                return err;
            }
        }
        else {
            proto = argv[1];
        }
    }

    /* Catch case where 2-arg form has typoed options=X and doesn't
     * match above. */
    if (proto && ap_strchr_c(proto, '=') != NULL) {
        return apr_psprintf(cmd->pool, "Invalid protocol name '%s'", proto);
    }
    else if (proto) {
        proto = apr_pstrdup(cmd->pool, proto);
        ap_str_tolower(proto);
    }
    else {
        if (port == 443) {
            proto = "https";
        } else {
            proto = "http";
        }
    }

#ifdef HAVE_SYSTEMD
    if (use_systemd) {
        return set_systemd_listener(cmd->server->process, port, proto);
    }
#endif

    return alloc_listener(cmd->server->process, host, port, proto,
                          scope_id, NULL, cmd->temp_pool, flags);
}

AP_DECLARE_NONSTD(const char *) ap_set_listenbacklog(cmd_parms *cmd,
                                                     void *dummy,
                                                     const char *arg)
{
    int b;
    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);

    if (err != NULL) {
        return err;
    }

    b = atoi(arg);
    if (b < 1) {
        return "ListenBacklog must be > 0";
    }

    ap_listenbacklog = b;
    return NULL;
}

AP_DECLARE_NONSTD(const char *) ap_set_listencbratio(cmd_parms *cmd,
                                                     void *dummy,
                                                     const char *arg)
{
    int b;
    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);

    if (err != NULL) {
        return err;
    }

    b = atoi(arg);
    if (b < 1) {
        return "ListenCoresBucketsRatio must be > 0";
    }

    ap_listencbratio = b;
    return NULL;
}

AP_DECLARE_NONSTD(const char *) ap_set_send_buffer_size(cmd_parms *cmd,
                                                        void *dummy,
                                                        const char *arg)
{
    int s = atoi(arg);
    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);

    if (err != NULL) {
        return err;
    }

    if (s < 512 && s != 0) {
        return "SendBufferSize must be >= 512 bytes, or 0 for system default.";
    }

    send_buffer_size = s;
    return NULL;
}

AP_DECLARE_NONSTD(const char *) ap_set_accept_errors_nonfatal(cmd_parms *cmd,
                                                           void *dummy,
                                                           int flag)
{
    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
    if (err != NULL) {
        return err;
    }
    ap_accept_errors_nonfatal = flag;
    return NULL;
}

AP_DECLARE_NONSTD(const char *) ap_set_receive_buffer_size(cmd_parms *cmd,
                                                           void *dummy,
                                                           const char *arg)
{
    int s = atoi(arg);
    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);

    if (err != NULL) {
        return err;
    }

    if (s < 512 && s != 0) {
        return "ReceiveBufferSize must be >= 512 bytes, or 0 for system default.";
    }

    receive_buffer_size = s;
    return NULL;
}
