listen.c revision 57b7c64eaa9d7934d51d23c8e23f0b6cf6ce6a8a
af84459fbf938e508fd10b01cb8d699c79083813takashi/* ====================================================================
af84459fbf938e508fd10b01cb8d699c79083813takashi * The Apache Software License, Version 1.1
af84459fbf938e508fd10b01cb8d699c79083813takashi *
af84459fbf938e508fd10b01cb8d699c79083813takashi * Copyright (c) 2000-2001 The Apache Software Foundation. All rights
af84459fbf938e508fd10b01cb8d699c79083813takashi * reserved.
af84459fbf938e508fd10b01cb8d699c79083813takashi *
af84459fbf938e508fd10b01cb8d699c79083813takashi * Redistribution and use in source and binary forms, with or without
af84459fbf938e508fd10b01cb8d699c79083813takashi * modification, are permitted provided that the following conditions
af84459fbf938e508fd10b01cb8d699c79083813takashi * are met:
af84459fbf938e508fd10b01cb8d699c79083813takashi *
af84459fbf938e508fd10b01cb8d699c79083813takashi * 1. Redistributions of source code must retain the above copyright
af84459fbf938e508fd10b01cb8d699c79083813takashi * notice, this list of conditions and the following disclaimer.
af84459fbf938e508fd10b01cb8d699c79083813takashi *
af84459fbf938e508fd10b01cb8d699c79083813takashi * 2. Redistributions in binary form must reproduce the above copyright
af84459fbf938e508fd10b01cb8d699c79083813takashi * notice, this list of conditions and the following disclaimer in
af84459fbf938e508fd10b01cb8d699c79083813takashi * the documentation and/or other materials provided with the
af84459fbf938e508fd10b01cb8d699c79083813takashi * distribution.
af84459fbf938e508fd10b01cb8d699c79083813takashi *
af84459fbf938e508fd10b01cb8d699c79083813takashi * 3. The end-user documentation included with the redistribution,
af84459fbf938e508fd10b01cb8d699c79083813takashi * if any, must include the following acknowledgment:
af84459fbf938e508fd10b01cb8d699c79083813takashi * "This product includes software developed by the
af84459fbf938e508fd10b01cb8d699c79083813takashi * Apache Software Foundation (http://www.apache.org/)."
af84459fbf938e508fd10b01cb8d699c79083813takashi * Alternately, this acknowledgment may appear in the software itself,
af84459fbf938e508fd10b01cb8d699c79083813takashi * if and wherever such third-party acknowledgments normally appear.
af84459fbf938e508fd10b01cb8d699c79083813takashi *
af84459fbf938e508fd10b01cb8d699c79083813takashi * 4. The names "Apache" and "Apache Software Foundation" must
78f97ce162b66a0dbfd7af4dcd9984f162569b04minfrin * not be used to endorse or promote products derived from this
af84459fbf938e508fd10b01cb8d699c79083813takashi * software without prior written permission. For written
3c13a815670b54d1c17bf02954f7d2b066cde95cnd * permission, please contact apache@apache.org.
3c13a815670b54d1c17bf02954f7d2b066cde95cnd *
af84459fbf938e508fd10b01cb8d699c79083813takashi * 5. Products derived from this software may not be called "Apache",
af84459fbf938e508fd10b01cb8d699c79083813takashi * nor may "Apache" appear in their name, without prior written
af84459fbf938e508fd10b01cb8d699c79083813takashi * permission of the Apache Software Foundation.
af84459fbf938e508fd10b01cb8d699c79083813takashi *
af84459fbf938e508fd10b01cb8d699c79083813takashi * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
af84459fbf938e508fd10b01cb8d699c79083813takashi * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
af84459fbf938e508fd10b01cb8d699c79083813takashi * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
af84459fbf938e508fd10b01cb8d699c79083813takashi * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
af84459fbf938e508fd10b01cb8d699c79083813takashi * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
af84459fbf938e508fd10b01cb8d699c79083813takashi * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
af84459fbf938e508fd10b01cb8d699c79083813takashi * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
af84459fbf938e508fd10b01cb8d699c79083813takashi * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
af84459fbf938e508fd10b01cb8d699c79083813takashi * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
af84459fbf938e508fd10b01cb8d699c79083813takashi * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
af84459fbf938e508fd10b01cb8d699c79083813takashi * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
af84459fbf938e508fd10b01cb8d699c79083813takashi * SUCH DAMAGE.
af84459fbf938e508fd10b01cb8d699c79083813takashi * ====================================================================
af84459fbf938e508fd10b01cb8d699c79083813takashi *
af84459fbf938e508fd10b01cb8d699c79083813takashi * This software consists of voluntary contributions made by many
af84459fbf938e508fd10b01cb8d699c79083813takashi * individuals on behalf of the Apache Software Foundation. For more
af84459fbf938e508fd10b01cb8d699c79083813takashi * information on the Apache Software Foundation, please see
af84459fbf938e508fd10b01cb8d699c79083813takashi * <http://www.apache.org/>.
af84459fbf938e508fd10b01cb8d699c79083813takashi *
cd6c8de3bedcc401ee230159b0439fa20f44488etakashi * Portions of this software are based upon public domain software
78f97ce162b66a0dbfd7af4dcd9984f162569b04minfrin * originally written at the National Center for Supercomputing Applications,
af84459fbf938e508fd10b01cb8d699c79083813takashi * University of Illinois, Urbana-Champaign.
af84459fbf938e508fd10b01cb8d699c79083813takashi */
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashi#include "apr_network_io.h"
af84459fbf938e508fd10b01cb8d699c79083813takashi#include "apr_strings.h"
af84459fbf938e508fd10b01cb8d699c79083813takashi#include "apr_lock.h"
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashi#define APR_WANT_STRFUNC
af84459fbf938e508fd10b01cb8d699c79083813takashi#include "apr_want.h"
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashi#define CORE_PRIVATE
af84459fbf938e508fd10b01cb8d699c79083813takashi#include "ap_config.h"
af84459fbf938e508fd10b01cb8d699c79083813takashi#include "httpd.h"
af84459fbf938e508fd10b01cb8d699c79083813takashi#include "http_config.h"
af84459fbf938e508fd10b01cb8d699c79083813takashi#include "ap_listen.h"
af84459fbf938e508fd10b01cb8d699c79083813takashi#include "http_log.h"
af84459fbf938e508fd10b01cb8d699c79083813takashi#include "mpm.h"
3c13a815670b54d1c17bf02954f7d2b066cde95cnd#include "mpm_common.h"
3c13a815670b54d1c17bf02954f7d2b066cde95cnd
af84459fbf938e508fd10b01cb8d699c79083813takashiap_listen_rec *ap_listeners = NULL;
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashi#if APR_HAVE_IPV6
af84459fbf938e508fd10b01cb8d699c79083813takashistatic int default_family = APR_UNSPEC;
af84459fbf938e508fd10b01cb8d699c79083813takashi#else
af84459fbf938e508fd10b01cb8d699c79083813takashistatic int default_family = APR_INET;
0cf3cdbaa1dad11cbf1ce32e48f1b4ec88cf779fnilgun#endif
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashistatic ap_listen_rec *old_listeners;
af84459fbf938e508fd10b01cb8d699c79083813takashistatic int ap_listenbacklog;
af84459fbf938e508fd10b01cb8d699c79083813takashistatic int send_buffer_size;
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashi/* TODO: make_sock is just begging and screaming for APR abstraction */
af84459fbf938e508fd10b01cb8d699c79083813takashistatic apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server)
af84459fbf938e508fd10b01cb8d699c79083813takashi{
af84459fbf938e508fd10b01cb8d699c79083813takashi apr_socket_t *s = server->sd;
af84459fbf938e508fd10b01cb8d699c79083813takashi int one = 1;
af84459fbf938e508fd10b01cb8d699c79083813takashi apr_status_t stat;
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashi stat = apr_setsocketopt(s, APR_SO_REUSEADDR, one);
af84459fbf938e508fd10b01cb8d699c79083813takashi if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) {
af84459fbf938e508fd10b01cb8d699c79083813takashi ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p,
af84459fbf938e508fd10b01cb8d699c79083813takashi "make_sock: for address %pI, setsockopt: (SO_REUSEADDR)",
78f97ce162b66a0dbfd7af4dcd9984f162569b04minfrin server->bind_addr);
af84459fbf938e508fd10b01cb8d699c79083813takashi apr_socket_close(s);
af84459fbf938e508fd10b01cb8d699c79083813takashi return stat;
af84459fbf938e508fd10b01cb8d699c79083813takashi }
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashi stat = apr_setsocketopt(s, APR_SO_KEEPALIVE, one);
af84459fbf938e508fd10b01cb8d699c79083813takashi if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) {
af84459fbf938e508fd10b01cb8d699c79083813takashi ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p,
af84459fbf938e508fd10b01cb8d699c79083813takashi "make_sock: for address %pI, setsockopt: (SO_KEEPALIVE)",
af84459fbf938e508fd10b01cb8d699c79083813takashi server->bind_addr);
af84459fbf938e508fd10b01cb8d699c79083813takashi apr_socket_close(s);
af84459fbf938e508fd10b01cb8d699c79083813takashi return stat;
af84459fbf938e508fd10b01cb8d699c79083813takashi }
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashi /*
af84459fbf938e508fd10b01cb8d699c79083813takashi * To send data over high bandwidth-delay connections at full
af84459fbf938e508fd10b01cb8d699c79083813takashi * speed we must force the TCP window to open wide enough to keep the
af84459fbf938e508fd10b01cb8d699c79083813takashi * pipe full. The default window size on many systems
af84459fbf938e508fd10b01cb8d699c79083813takashi * is only 4kB. Cross-country WAN connections of 100ms
3c13a815670b54d1c17bf02954f7d2b066cde95cnd * at 1Mb/s are not impossible for well connected sites.
af84459fbf938e508fd10b01cb8d699c79083813takashi * If we assume 100ms cross-country latency,
af84459fbf938e508fd10b01cb8d699c79083813takashi * a 4kB buffer limits throughput to 40kB/s.
af84459fbf938e508fd10b01cb8d699c79083813takashi *
af84459fbf938e508fd10b01cb8d699c79083813takashi * To avoid this problem I've added the SendBufferSize directive
af84459fbf938e508fd10b01cb8d699c79083813takashi * to allow the web master to configure send buffer size.
af84459fbf938e508fd10b01cb8d699c79083813takashi *
af84459fbf938e508fd10b01cb8d699c79083813takashi * The trade-off of larger buffers is that more kernel memory
af84459fbf938e508fd10b01cb8d699c79083813takashi * is consumed. YMMV, know your customers and your network!
af84459fbf938e508fd10b01cb8d699c79083813takashi *
af84459fbf938e508fd10b01cb8d699c79083813takashi * -John Heidemann <johnh@isi.edu> 25-Oct-96
af84459fbf938e508fd10b01cb8d699c79083813takashi *
af84459fbf938e508fd10b01cb8d699c79083813takashi * If no size is specified, use the kernel default.
af84459fbf938e508fd10b01cb8d699c79083813takashi */
af84459fbf938e508fd10b01cb8d699c79083813takashi if (send_buffer_size) {
af84459fbf938e508fd10b01cb8d699c79083813takashi stat = apr_setsocketopt(s, APR_SO_SNDBUF, send_buffer_size);
af84459fbf938e508fd10b01cb8d699c79083813takashi if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) {
af84459fbf938e508fd10b01cb8d699c79083813takashi ap_log_perror(APLOG_MARK, APLOG_WARNING, stat, p,
af84459fbf938e508fd10b01cb8d699c79083813takashi "make_sock: failed to set SendBufferSize for "
af84459fbf938e508fd10b01cb8d699c79083813takashi "address %pI, using default",
af84459fbf938e508fd10b01cb8d699c79083813takashi server->bind_addr);
af84459fbf938e508fd10b01cb8d699c79083813takashi /* not a fatal error */
af84459fbf938e508fd10b01cb8d699c79083813takashi }
af84459fbf938e508fd10b01cb8d699c79083813takashi }
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashi#if APR_TCP_NODELAY_INHERITED
af84459fbf938e508fd10b01cb8d699c79083813takashi ap_sock_disable_nagle(s);
af84459fbf938e508fd10b01cb8d699c79083813takashi#endif
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashi if ((stat = apr_bind(s, server->bind_addr)) != APR_SUCCESS) {
af84459fbf938e508fd10b01cb8d699c79083813takashi ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, stat, p,
af84459fbf938e508fd10b01cb8d699c79083813takashi "make_sock: could not bind to address %pI",
af84459fbf938e508fd10b01cb8d699c79083813takashi server->bind_addr);
af84459fbf938e508fd10b01cb8d699c79083813takashi apr_socket_close(s);
af84459fbf938e508fd10b01cb8d699c79083813takashi return stat;
8e9c6d6438af1ccb46adaa60d34caa3ac98f3851igalic }
8e9c6d6438af1ccb46adaa60d34caa3ac98f3851igalic
8e9c6d6438af1ccb46adaa60d34caa3ac98f3851igalic if ((stat = apr_listen(s, ap_listenbacklog)) != APR_SUCCESS) {
8e9c6d6438af1ccb46adaa60d34caa3ac98f3851igalic ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_ERR, stat, p,
8e9c6d6438af1ccb46adaa60d34caa3ac98f3851igalic "make_sock: unable to listen for connections "
8e9c6d6438af1ccb46adaa60d34caa3ac98f3851igalic "on address %pI",
8e9c6d6438af1ccb46adaa60d34caa3ac98f3851igalic server->bind_addr);
af84459fbf938e508fd10b01cb8d699c79083813takashi apr_socket_close(s);
af84459fbf938e508fd10b01cb8d699c79083813takashi return stat;
af84459fbf938e508fd10b01cb8d699c79083813takashi }
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashi#if APR_HAS_SO_ACCEPTFILTER
af84459fbf938e508fd10b01cb8d699c79083813takashi#ifndef ACCEPT_FILTER_NAME
af84459fbf938e508fd10b01cb8d699c79083813takashi#define ACCEPT_FILTER_NAME "dataready"
af84459fbf938e508fd10b01cb8d699c79083813takashi#endif
af84459fbf938e508fd10b01cb8d699c79083813takashi apr_socket_accept_filter(s, ACCEPT_FILTER_NAME, "");
af84459fbf938e508fd10b01cb8d699c79083813takashi#endif
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashi server->sd = s;
af84459fbf938e508fd10b01cb8d699c79083813takashi server->active = 1;
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashi#ifdef MPM_ACCEPT_FUNC
af84459fbf938e508fd10b01cb8d699c79083813takashi server->accept_func = MPM_ACCEPT_FUNC;
af84459fbf938e508fd10b01cb8d699c79083813takashi#else
af84459fbf938e508fd10b01cb8d699c79083813takashi server->accept_func = NULL;
af84459fbf938e508fd10b01cb8d699c79083813takashi#endif
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashi return APR_SUCCESS;
af84459fbf938e508fd10b01cb8d699c79083813takashi}
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashistatic apr_status_t close_listeners_on_exec(void *v)
af84459fbf938e508fd10b01cb8d699c79083813takashi{
af84459fbf938e508fd10b01cb8d699c79083813takashi ap_listen_rec *lr;
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashi for (lr = ap_listeners; lr; lr = lr->next) {
af84459fbf938e508fd10b01cb8d699c79083813takashi apr_socket_close(lr->sd);
af84459fbf938e508fd10b01cb8d699c79083813takashi lr->active = 0;
af84459fbf938e508fd10b01cb8d699c79083813takashi }
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashi return APR_SUCCESS;
af84459fbf938e508fd10b01cb8d699c79083813takashi}
3c13a815670b54d1c17bf02954f7d2b066cde95cnd
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashistatic void find_default_family(apr_pool_t *p)
af84459fbf938e508fd10b01cb8d699c79083813takashi{
af84459fbf938e508fd10b01cb8d699c79083813takashi#if APR_HAVE_IPV6
af84459fbf938e508fd10b01cb8d699c79083813takashi /* We know the platform supports IPv6, but this particular
af84459fbf938e508fd10b01cb8d699c79083813takashi * system may not have IPv6 enabled. See if we can get an
af84459fbf938e508fd10b01cb8d699c79083813takashi * AF_INET6 socket.
af84459fbf938e508fd10b01cb8d699c79083813takashi */
af84459fbf938e508fd10b01cb8d699c79083813takashi if (default_family == APR_UNSPEC) {
af84459fbf938e508fd10b01cb8d699c79083813takashi apr_socket_t *tmp_sock;
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashi if (apr_socket_create(&tmp_sock, APR_INET6, SOCK_STREAM,
af84459fbf938e508fd10b01cb8d699c79083813takashi p) == APR_SUCCESS) {
af84459fbf938e508fd10b01cb8d699c79083813takashi apr_socket_close(tmp_sock);
af84459fbf938e508fd10b01cb8d699c79083813takashi default_family = APR_INET6;
af84459fbf938e508fd10b01cb8d699c79083813takashi }
af84459fbf938e508fd10b01cb8d699c79083813takashi else {
af84459fbf938e508fd10b01cb8d699c79083813takashi default_family = APR_INET;
af84459fbf938e508fd10b01cb8d699c79083813takashi }
af84459fbf938e508fd10b01cb8d699c79083813takashi }
af84459fbf938e508fd10b01cb8d699c79083813takashi#endif
af84459fbf938e508fd10b01cb8d699c79083813takashi}
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashistatic void alloc_listener(process_rec *process, char *addr, apr_port_t port)
af84459fbf938e508fd10b01cb8d699c79083813takashi{
af84459fbf938e508fd10b01cb8d699c79083813takashi ap_listen_rec **walk;
af84459fbf938e508fd10b01cb8d699c79083813takashi ap_listen_rec *new;
af84459fbf938e508fd10b01cb8d699c79083813takashi apr_status_t status;
af84459fbf938e508fd10b01cb8d699c79083813takashi char *oldaddr;
af84459fbf938e508fd10b01cb8d699c79083813takashi apr_port_t oldport;
3c13a815670b54d1c17bf02954f7d2b066cde95cnd apr_sockaddr_t *sa;
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashi if (!addr) { /* don't bind to specific interface */
af84459fbf938e508fd10b01cb8d699c79083813takashi find_default_family(process->pool);
af84459fbf938e508fd10b01cb8d699c79083813takashi switch(default_family) {
78f97ce162b66a0dbfd7af4dcd9984f162569b04minfrin case APR_INET:
af84459fbf938e508fd10b01cb8d699c79083813takashi addr = "0.0.0.0";
af84459fbf938e508fd10b01cb8d699c79083813takashi break;
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashi#if APR_HAVE_IPV6
af84459fbf938e508fd10b01cb8d699c79083813takashi case APR_INET6:
3c13a815670b54d1c17bf02954f7d2b066cde95cnd addr = "::";
3c13a815670b54d1c17bf02954f7d2b066cde95cnd break;
af84459fbf938e508fd10b01cb8d699c79083813takashi#endif
af84459fbf938e508fd10b01cb8d699c79083813takashi
3c13a815670b54d1c17bf02954f7d2b066cde95cnd default:
af84459fbf938e508fd10b01cb8d699c79083813takashi ap_assert(1 != 1); /* should not occur */
af84459fbf938e508fd10b01cb8d699c79083813takashi }
af84459fbf938e508fd10b01cb8d699c79083813takashi }
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashi /* see if we've got an old listener for this address:port */
af84459fbf938e508fd10b01cb8d699c79083813takashi for (walk = &old_listeners; *walk; walk = &(*walk)->next) {
af84459fbf938e508fd10b01cb8d699c79083813takashi sa = (*walk)->bind_addr;
af84459fbf938e508fd10b01cb8d699c79083813takashi /* Some listeners are not real so they will not have a bind_addr. */
af84459fbf938e508fd10b01cb8d699c79083813takashi if (sa) {
af84459fbf938e508fd10b01cb8d699c79083813takashi apr_sockaddr_port_get(&oldport, sa);
af84459fbf938e508fd10b01cb8d699c79083813takashi apr_sockaddr_ip_get(&oldaddr, sa);
af84459fbf938e508fd10b01cb8d699c79083813takashi if (!strcmp(oldaddr, addr) && port == oldport) {
af84459fbf938e508fd10b01cb8d699c79083813takashi /* re-use existing record */
af84459fbf938e508fd10b01cb8d699c79083813takashi new = *walk;
af84459fbf938e508fd10b01cb8d699c79083813takashi *walk = new->next;
af84459fbf938e508fd10b01cb8d699c79083813takashi new->next = ap_listeners;
af84459fbf938e508fd10b01cb8d699c79083813takashi ap_listeners = new;
af84459fbf938e508fd10b01cb8d699c79083813takashi return;
af84459fbf938e508fd10b01cb8d699c79083813takashi }
af84459fbf938e508fd10b01cb8d699c79083813takashi }
af84459fbf938e508fd10b01cb8d699c79083813takashi }
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashi /* this has to survive restarts */
af84459fbf938e508fd10b01cb8d699c79083813takashi new = apr_palloc(process->pool, sizeof(ap_listen_rec));
af84459fbf938e508fd10b01cb8d699c79083813takashi new->active = 0;
11495c9f0bd33e51a25b4d532beadfbcf9b944a3nilgun if ((status = apr_sockaddr_info_get(&new->bind_addr, addr, APR_UNSPEC,
af84459fbf938e508fd10b01cb8d699c79083813takashi port, 0, process->pool))
11495c9f0bd33e51a25b4d532beadfbcf9b944a3nilgun != APR_SUCCESS) {
11495c9f0bd33e51a25b4d532beadfbcf9b944a3nilgun ap_log_perror(APLOG_MARK, APLOG_CRIT, status, process->pool,
11495c9f0bd33e51a25b4d532beadfbcf9b944a3nilgun "alloc_listener: failed to set up sockaddr for %s",
11495c9f0bd33e51a25b4d532beadfbcf9b944a3nilgun addr);
11495c9f0bd33e51a25b4d532beadfbcf9b944a3nilgun return;
af84459fbf938e508fd10b01cb8d699c79083813takashi }
af84459fbf938e508fd10b01cb8d699c79083813takashi if ((status = apr_socket_create(&new->sd,
af84459fbf938e508fd10b01cb8d699c79083813takashi new->bind_addr->family,
11495c9f0bd33e51a25b4d532beadfbcf9b944a3nilgun SOCK_STREAM, process->pool))
11495c9f0bd33e51a25b4d532beadfbcf9b944a3nilgun != APR_SUCCESS) {
af84459fbf938e508fd10b01cb8d699c79083813takashi ap_log_perror(APLOG_MARK, APLOG_CRIT, status, process->pool,
af84459fbf938e508fd10b01cb8d699c79083813takashi "alloc_listener: failed to get a socket for %s", addr);
af84459fbf938e508fd10b01cb8d699c79083813takashi return;
af84459fbf938e508fd10b01cb8d699c79083813takashi }
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashi new->next = ap_listeners;
af84459fbf938e508fd10b01cb8d699c79083813takashi ap_listeners = new;
af84459fbf938e508fd10b01cb8d699c79083813takashi}
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashistatic int ap_listen_open(process_rec *process, apr_port_t port)
af84459fbf938e508fd10b01cb8d699c79083813takashi{
af84459fbf938e508fd10b01cb8d699c79083813takashi apr_pool_t *pconf = process->pconf;
af84459fbf938e508fd10b01cb8d699c79083813takashi ap_listen_rec *lr;
af84459fbf938e508fd10b01cb8d699c79083813takashi ap_listen_rec *next;
af84459fbf938e508fd10b01cb8d699c79083813takashi int num_open;
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashi /* Don't allocate a default listener. If we need to listen to a
af84459fbf938e508fd10b01cb8d699c79083813takashi * port, then the user needs to have a Listen directive in their
af84459fbf938e508fd10b01cb8d699c79083813takashi * config file.
af84459fbf938e508fd10b01cb8d699c79083813takashi */
af84459fbf938e508fd10b01cb8d699c79083813takashi num_open = 0;
af84459fbf938e508fd10b01cb8d699c79083813takashi for (lr = ap_listeners; lr; lr = lr->next) {
af84459fbf938e508fd10b01cb8d699c79083813takashi if (lr->active) {
af84459fbf938e508fd10b01cb8d699c79083813takashi ++num_open;
af84459fbf938e508fd10b01cb8d699c79083813takashi }
af84459fbf938e508fd10b01cb8d699c79083813takashi else {
af84459fbf938e508fd10b01cb8d699c79083813takashi if (make_sock(pconf, lr) == APR_SUCCESS) {
af84459fbf938e508fd10b01cb8d699c79083813takashi ++num_open;
af84459fbf938e508fd10b01cb8d699c79083813takashi lr->active = 1;
af84459fbf938e508fd10b01cb8d699c79083813takashi }
af84459fbf938e508fd10b01cb8d699c79083813takashi else {
af84459fbf938e508fd10b01cb8d699c79083813takashi /* fatal error */
af84459fbf938e508fd10b01cb8d699c79083813takashi return -1;
af84459fbf938e508fd10b01cb8d699c79083813takashi }
af84459fbf938e508fd10b01cb8d699c79083813takashi }
af84459fbf938e508fd10b01cb8d699c79083813takashi }
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashi /* close the old listeners */
af84459fbf938e508fd10b01cb8d699c79083813takashi for (lr = old_listeners; lr; lr = next) {
af84459fbf938e508fd10b01cb8d699c79083813takashi apr_socket_close(lr->sd);
af84459fbf938e508fd10b01cb8d699c79083813takashi lr->active = 0;
af84459fbf938e508fd10b01cb8d699c79083813takashi next = lr->next;
af84459fbf938e508fd10b01cb8d699c79083813takashi }
af84459fbf938e508fd10b01cb8d699c79083813takashi old_listeners = NULL;
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashi apr_pool_cleanup_register(pconf, NULL, apr_pool_cleanup_null,
af84459fbf938e508fd10b01cb8d699c79083813takashi close_listeners_on_exec);
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashi return num_open ? 0 : -1;
af84459fbf938e508fd10b01cb8d699c79083813takashi}
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashiint ap_setup_listeners(server_rec *s)
af84459fbf938e508fd10b01cb8d699c79083813takashi{
af84459fbf938e508fd10b01cb8d699c79083813takashi ap_listen_rec *lr;
af84459fbf938e508fd10b01cb8d699c79083813takashi int num_listeners = 0;
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashi if (ap_listen_open(s->process, s->port)) {
af84459fbf938e508fd10b01cb8d699c79083813takashi return 0;
af84459fbf938e508fd10b01cb8d699c79083813takashi }
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashi for (lr = ap_listeners; lr; lr = lr->next) {
af84459fbf938e508fd10b01cb8d699c79083813takashi num_listeners++;
af84459fbf938e508fd10b01cb8d699c79083813takashi }
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashi return num_listeners;
af84459fbf938e508fd10b01cb8d699c79083813takashi}
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashivoid ap_listen_pre_config(void)
af84459fbf938e508fd10b01cb8d699c79083813takashi{
af84459fbf938e508fd10b01cb8d699c79083813takashi old_listeners = ap_listeners;
af84459fbf938e508fd10b01cb8d699c79083813takashi ap_listeners = NULL;
3c13a815670b54d1c17bf02954f7d2b066cde95cnd ap_listenbacklog = DEFAULT_LISTENBACKLOG;
af84459fbf938e508fd10b01cb8d699c79083813takashi}
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashiconst char *ap_set_listener(cmd_parms *cmd, void *dummy, const char *ips)
af84459fbf938e508fd10b01cb8d699c79083813takashi{
af84459fbf938e508fd10b01cb8d699c79083813takashi char *host, *scope_id;
af84459fbf938e508fd10b01cb8d699c79083813takashi apr_port_t port;
af84459fbf938e508fd10b01cb8d699c79083813takashi apr_status_t rv;
af84459fbf938e508fd10b01cb8d699c79083813takashi const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashi if (err != NULL) {
af84459fbf938e508fd10b01cb8d699c79083813takashi return err;
af84459fbf938e508fd10b01cb8d699c79083813takashi }
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashi rv = apr_parse_addr_port(&host, &scope_id, &port, ips, cmd->pool);
af84459fbf938e508fd10b01cb8d699c79083813takashi if (rv != APR_SUCCESS) {
af84459fbf938e508fd10b01cb8d699c79083813takashi return "Invalid address or port";
af84459fbf938e508fd10b01cb8d699c79083813takashi }
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashi if (host && !strcmp(host, "*")) {
af84459fbf938e508fd10b01cb8d699c79083813takashi host = NULL;
af84459fbf938e508fd10b01cb8d699c79083813takashi }
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashi if (scope_id) {
af84459fbf938e508fd10b01cb8d699c79083813takashi /* XXX scope id support is useful with link-local IPv6 addresses */
af84459fbf938e508fd10b01cb8d699c79083813takashi return "Scope id is not supported";
af84459fbf938e508fd10b01cb8d699c79083813takashi }
af84459fbf938e508fd10b01cb8d699c79083813takashi
3c13a815670b54d1c17bf02954f7d2b066cde95cnd if (!port) {
3c13a815670b54d1c17bf02954f7d2b066cde95cnd return "Port must be specified";
af84459fbf938e508fd10b01cb8d699c79083813takashi }
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashi alloc_listener(cmd->server->process, host, port);
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashi return NULL;
af84459fbf938e508fd10b01cb8d699c79083813takashi}
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashiconst char *ap_set_listenbacklog(cmd_parms *cmd, void *dummy, const char *arg)
af84459fbf938e508fd10b01cb8d699c79083813takashi{
af84459fbf938e508fd10b01cb8d699c79083813takashi int b;
78f97ce162b66a0dbfd7af4dcd9984f162569b04minfrin const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashi if (err != NULL) {
af84459fbf938e508fd10b01cb8d699c79083813takashi return err;
78f97ce162b66a0dbfd7af4dcd9984f162569b04minfrin }
3c13a815670b54d1c17bf02954f7d2b066cde95cnd
3c13a815670b54d1c17bf02954f7d2b066cde95cnd b = atoi(arg);
af84459fbf938e508fd10b01cb8d699c79083813takashi if (b < 1) {
af84459fbf938e508fd10b01cb8d699c79083813takashi return "ListenBacklog must be > 0";
af84459fbf938e508fd10b01cb8d699c79083813takashi }
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashi ap_listenbacklog = b;
af84459fbf938e508fd10b01cb8d699c79083813takashi return NULL;
af84459fbf938e508fd10b01cb8d699c79083813takashi}
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashiconst char *ap_set_send_buffer_size(cmd_parms *cmd, void *dummy,
3c13a815670b54d1c17bf02954f7d2b066cde95cnd const char *arg)
af84459fbf938e508fd10b01cb8d699c79083813takashi{
af84459fbf938e508fd10b01cb8d699c79083813takashi int s = atoi(arg);
af84459fbf938e508fd10b01cb8d699c79083813takashi const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashi if (err != NULL) {
af84459fbf938e508fd10b01cb8d699c79083813takashi return err;
af84459fbf938e508fd10b01cb8d699c79083813takashi }
af84459fbf938e508fd10b01cb8d699c79083813takashi
3c13a815670b54d1c17bf02954f7d2b066cde95cnd if (s < 512 && s != 0) {
3c13a815670b54d1c17bf02954f7d2b066cde95cnd return "SendBufferSize must be >= 512 bytes, or 0 for system default.";
af84459fbf938e508fd10b01cb8d699c79083813takashi }
af84459fbf938e508fd10b01cb8d699c79083813takashi
af84459fbf938e508fd10b01cb8d699c79083813takashi send_buffer_size = s;
af84459fbf938e508fd10b01cb8d699c79083813takashi return NULL;
af84459fbf938e508fd10b01cb8d699c79083813takashi}
af84459fbf938e508fd10b01cb8d699c79083813takashi