Main Page | Modules | Namespace List | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages | Examples

listen.c

Go to the documentation of this file.
00001 /* Copyright 1999-2005 The Apache Software Foundation or its licensors, as
00002  * applicable.
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #include "apr_network_io.h"
00018 #include "apr_strings.h"
00019 
00020 #define APR_WANT_STRFUNC
00021 #include "apr_want.h"
00022 
00023 #define CORE_PRIVATE
00024 #include "ap_config.h"
00025 #include "httpd.h"
00026 #include "http_config.h"
00027 #include "ap_listen.h"
00028 #include "http_log.h"
00029 #include "mpm.h"
00030 #include "mpm_common.h"
00031 
00032 ap_listen_rec *ap_listeners = NULL;
00033 
00034 #if APR_HAVE_IPV6
00035 static int default_family = APR_UNSPEC;
00036 #else
00037 static int default_family = APR_INET;
00038 #endif
00039 
00040 static ap_listen_rec *old_listeners;
00041 static int ap_listenbacklog;
00042 static int send_buffer_size;
00043 
00044 /* TODO: make_sock is just begging and screaming for APR abstraction */
00045 static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server)
00046 {
00047     apr_socket_t *s = server->sd;
00048     int one = 1;
00049 #if APR_HAVE_IPV6
00050 #ifdef AP_ENABLE_V4_MAPPED
00051     int v6only_setting = 0;
00052 #else
00053     int v6only_setting = 1;
00054 #endif
00055 #endif
00056     apr_status_t stat;
00057 
00058 #ifndef WIN32
00059     stat = apr_socket_opt_set(s, APR_SO_REUSEADDR, one);
00060     if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) {
00061         ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p,
00062                       "make_sock: for address %pI, apr_socket_opt_set: (SO_REUSEADDR)",
00063                       server->bind_addr);
00064         apr_socket_close(s);
00065         return stat;
00066     }
00067 #endif
00068 
00069     stat = apr_socket_opt_set(s, APR_SO_KEEPALIVE, one);
00070     if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) {
00071         ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p,
00072                       "make_sock: for address %pI, apr_socket_opt_set: (SO_KEEPALIVE)",
00073                       server->bind_addr);
00074         apr_socket_close(s);
00075         return stat;
00076     }
00077 
00078 #if APR_HAVE_IPV6
00079     if (server->bind_addr->family == APR_INET6) {
00080         stat = apr_socket_opt_set(s, APR_IPV6_V6ONLY, v6only_setting);
00081         if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) {
00082             ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p,
00083                           "make_sock: for address %pI, apr_socket_opt_set: "
00084                           "(IPV6_V6ONLY)",
00085                           server->bind_addr);
00086             apr_socket_close(s);
00087             return stat;
00088         }
00089     }
00090 #endif
00091 
00092     /*
00093      * To send data over high bandwidth-delay connections at full
00094      * speed we must force the TCP window to open wide enough to keep the
00095      * pipe full.  The default window size on many systems
00096      * is only 4kB.  Cross-country WAN connections of 100ms
00097      * at 1Mb/s are not impossible for well connected sites.
00098      * If we assume 100ms cross-country latency,
00099      * a 4kB buffer limits throughput to 40kB/s.
00100      *
00101      * To avoid this problem I've added the SendBufferSize directive
00102      * to allow the web master to configure send buffer size.
00103      *
00104      * The trade-off of larger buffers is that more kernel memory
00105      * is consumed.  YMMV, know your customers and your network!
00106      *
00107      * -John Heidemann <johnh@isi.edu> 25-Oct-96
00108      *
00109      * If no size is specified, use the kernel default.
00110      */
00111     if (send_buffer_size) {
00112         stat = apr_socket_opt_set(s, APR_SO_SNDBUF,  send_buffer_size);
00113         if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) {
00114             ap_log_perror(APLOG_MARK, APLOG_WARNING, stat, p,
00115                           "make_sock: failed to set SendBufferSize for "
00116                           "address %pI, using default",
00117                           server->bind_addr);
00118             /* not a fatal error */
00119         }
00120     }
00121 
00122 #if APR_TCP_NODELAY_INHERITED
00123     ap_sock_disable_nagle(s);
00124 #endif
00125 
00126     if ((stat = apr_bind(s, server->bind_addr)) != APR_SUCCESS) {
00127         ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, stat, p,
00128                       "make_sock: could not bind to address %pI",
00129                       server->bind_addr);
00130         apr_socket_close(s);
00131         return stat;
00132     }
00133 
00134     if ((stat = apr_listen(s, ap_listenbacklog)) != APR_SUCCESS) {
00135         ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_ERR, stat, p,
00136                       "make_sock: unable to listen for connections "
00137                       "on address %pI",
00138                       server->bind_addr);
00139         apr_socket_close(s);
00140         return stat;
00141     }
00142 
00143 #ifdef WIN32
00144     /* I seriously doubt that this would work on Unix; I have doubts that
00145      * it entirely solves the problem on Win32.  However, since setting
00146      * reuseaddr on the listener -prior- to binding the socket has allowed
00147      * us to attach to the same port as an already running instance of
00148      * Apache, or even another web server, we cannot identify that this
00149      * port was exclusively granted to this instance of Apache.
00150      *
00151      * So set reuseaddr, but do not attempt to do so until we have the
00152      * parent listeners successfully bound.
00153      */
00154     stat = apr_socket_opt_set(s, APR_SO_REUSEADDR, one);
00155     if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) {
00156         ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p,
00157                     "make_sock: for address %pI, apr_socket_opt_set: (SO_REUSEADDR)", 
00158                      server->bind_addr);
00159         apr_socket_close(s);
00160         return stat;
00161     }
00162 #endif
00163 
00164 #if APR_HAS_SO_ACCEPTFILTER
00165 #ifndef ACCEPT_FILTER_NAME
00166 #define ACCEPT_FILTER_NAME "httpready"
00167 #ifdef __FreeBSD_version
00168 #if __FreeBSD_version < 411000 /* httpready was broken before 4.1.1 */
00169 #undef ACCEPT_FILTER_NAME
00170 #define ACCEPT_FILTER_NAME "dataready"
00171 #endif
00172 #endif
00173 #endif
00174     apr_socket_accept_filter(s, ACCEPT_FILTER_NAME, "");
00175 #endif
00176 
00177     server->sd = s;
00178     server->active = 1;
00179 
00180 #ifdef MPM_ACCEPT_FUNC
00181     server->accept_func = MPM_ACCEPT_FUNC;
00182 #else
00183     server->accept_func = NULL;
00184 #endif
00185 
00186     return APR_SUCCESS;
00187 }
00188 
00189 static apr_status_t close_listeners_on_exec(void *v)
00190 {
00191     ap_listen_rec *lr;
00192 
00193     for (lr = ap_listeners; lr; lr = lr->next) {
00194         apr_socket_close(lr->sd);
00195         lr->active = 0;
00196     }
00197 
00198     return APR_SUCCESS;
00199 }
00200 
00201 
00202 static void find_default_family(apr_pool_t *p)
00203 {
00204 #if APR_HAVE_IPV6
00205     /* We know the platform supports IPv6, but this particular
00206      * system may not have IPv6 enabled.  See if we can get an
00207      * AF_INET6 socket and bind to an ephemeral port.  (On most
00208      * systems, getting an AF_INET6 socket is a sufficient test.
00209      * On certain levels of OpenUNIX, getting the socket is
00210      * successful but bind always returns ENETUNREACH.)
00211      */
00212     if (default_family == APR_UNSPEC) {
00213         apr_status_t sock_rv;
00214         apr_socket_t *tmp_sock;
00215         apr_sockaddr_t *sa;
00216 
00217         if ((sock_rv = apr_socket_create(&tmp_sock, APR_INET6, SOCK_STREAM, p)) 
00218             == APR_SUCCESS &&
00219             apr_sockaddr_info_get(&sa, NULL, APR_INET6, 0, 0, p) == APR_SUCCESS &&
00220             apr_bind(tmp_sock, sa) == APR_SUCCESS) { 
00221             default_family = APR_INET6;
00222         }
00223         else {
00224             default_family = APR_INET;
00225         }
00226         if (sock_rv == APR_SUCCESS) {
00227             apr_socket_close(tmp_sock);
00228         }
00229     }
00230 #endif
00231 }
00232 
00233 
00234 static const char *alloc_listener(process_rec *process, char *addr, apr_port_t port)
00235 {
00236     ap_listen_rec **walk;
00237     ap_listen_rec *new;
00238     apr_status_t status;
00239     apr_port_t oldport;
00240     apr_sockaddr_t *sa;
00241 
00242     if (!addr) { /* don't bind to specific interface */
00243         find_default_family(process->pool);
00244         switch(default_family) {
00245         case APR_INET:
00246             addr = "0.0.0.0";
00247             break;
00248 
00249 #if APR_HAVE_IPV6
00250         case APR_INET6:
00251             addr = "::";
00252             break;
00253 #endif
00254 
00255         default:
00256             ap_assert(1 != 1); /* should not occur */
00257         }
00258     }
00259 
00260     /* see if we've got an old listener for this address:port */
00261     for (walk = &old_listeners; *walk; walk = &(*walk)->next) {
00262         sa = (*walk)->bind_addr;
00263         /* Some listeners are not real so they will not have a bind_addr. */
00264         if (sa) {
00265             apr_sockaddr_port_get(&oldport, sa);
00266             if (!strcmp(sa->hostname, addr) && port == oldport) {
00267                 /* re-use existing record */
00268                 new = *walk;
00269                 *walk = new->next;
00270                 new->next = ap_listeners;
00271                 ap_listeners = new;
00272                 return NULL;
00273             }
00274         }
00275     }
00276 
00277     /* this has to survive restarts */
00278     new = apr_palloc(process->pool, sizeof(ap_listen_rec));
00279     new->active = 0;
00280     if ((status = apr_sockaddr_info_get(&new->bind_addr, addr, APR_UNSPEC,
00281                                         port, 0, process->pool))
00282         != APR_SUCCESS) {
00283         ap_log_perror(APLOG_MARK, APLOG_CRIT, status, process->pool,
00284                       "alloc_listener: failed to set up sockaddr for %s",
00285                       addr);
00286         return "Listen setup failed";
00287     }
00288     if ((status = apr_socket_create(&new->sd,
00289                                     new->bind_addr->family,
00290                                     SOCK_STREAM, process->pool))
00291         != APR_SUCCESS) {
00292         ap_log_perror(APLOG_MARK, APLOG_CRIT, status, process->pool,
00293                       "alloc_listener: failed to get a socket for %s", addr);
00294         return "Listen setup failed";
00295     }
00296 
00297     new->next = ap_listeners;
00298     ap_listeners = new;
00299     return NULL;
00300 }
00301 
00302 static int ap_listen_open(apr_pool_t *pool, apr_port_t port)
00303 {
00304     ap_listen_rec *lr;
00305     ap_listen_rec *next;
00306     int num_open;
00307     const char *userdata_key = "ap_listen_open";
00308     void *data;
00309 
00310     /* Don't allocate a default listener.  If we need to listen to a
00311      * port, then the user needs to have a Listen directive in their
00312      * config file.
00313      */
00314     num_open = 0;
00315     for (lr = ap_listeners; lr; lr = lr->next) {
00316         if (lr->active) {
00317             ++num_open;
00318         }
00319         else {
00320             if (make_sock(pool, lr) == APR_SUCCESS) {
00321                 ++num_open;
00322                 lr->active = 1;
00323             }
00324             else {
00325                 /* fatal error */
00326                 return -1;
00327             }
00328         }
00329     }
00330 
00331     /* close the old listeners */
00332     for (lr = old_listeners; lr; lr = next) {
00333         apr_socket_close(lr->sd);
00334         lr->active = 0;
00335         next = lr->next;
00336     }
00337     old_listeners = NULL;
00338 
00339 #if AP_NONBLOCK_WHEN_MULTI_LISTEN
00340     /* if multiple listening sockets, make them non-blocking so that
00341      * if select()/poll() reports readability for a reset connection that
00342      * is already forgotten about by the time we call accept, we won't
00343      * be hung until another connection arrives on that port
00344      */
00345     if (ap_listeners && ap_listeners->next) {
00346         for (lr = ap_listeners; lr; lr = lr->next) {
00347             apr_status_t status;
00348 
00349             status = apr_socket_opt_set(lr->sd, APR_SO_NONBLOCK, 1);
00350             if (status != APR_SUCCESS) {
00351                 ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_ERR, status, pool,
00352                               "ap_listen_open: unable to make socket non-blocking");
00353                 return -1;
00354             }
00355         }
00356     }
00357 #endif /* AP_NONBLOCK_WHEN_MULTI_LISTEN */
00358 
00359     /* we come through here on both passes of the open logs phase
00360      * only register the cleanup once... otherwise we try to close
00361      * listening sockets twice when cleaning up prior to exec
00362      */
00363     apr_pool_userdata_get(&data, userdata_key, pool);
00364     if (!data) {
00365         apr_pool_userdata_set((const void *)1, userdata_key,
00366                               apr_pool_cleanup_null, pool);
00367         apr_pool_cleanup_register(pool, NULL, apr_pool_cleanup_null,
00368                                   close_listeners_on_exec);
00369     }
00370 
00371     return num_open ? 0 : -1;
00372 }
00373 
00374 int ap_setup_listeners(server_rec *s)
00375 {
00376     ap_listen_rec *lr;
00377     int num_listeners = 0;
00378 
00379     if (ap_listen_open(s->process->pool, s->port)) {
00380        return 0;
00381     }
00382 
00383     for (lr = ap_listeners; lr; lr = lr->next) {
00384         num_listeners++;
00385     }
00386 
00387     return num_listeners;
00388 }
00389 
00390 void ap_listen_pre_config(void)
00391 {
00392     old_listeners = ap_listeners;
00393     ap_listeners = NULL;
00394     ap_listenbacklog = DEFAULT_LISTENBACKLOG;
00395 }
00396 
00397 
00398 const char *ap_set_listener(cmd_parms *cmd, void *dummy, const char *ips)
00399 {
00400     char *host, *scope_id;
00401     apr_port_t port;
00402     apr_status_t rv;
00403     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
00404 
00405     if (err != NULL) {
00406         return err;
00407     }
00408 
00409     rv = apr_parse_addr_port(&host, &scope_id, &port, ips, cmd->pool);
00410     if (rv != APR_SUCCESS) {
00411         return "Invalid address or port";
00412     }
00413 
00414     if (host && !strcmp(host, "*")) {
00415         host = NULL;
00416     }
00417 
00418     if (scope_id) {
00419         /* XXX scope id support is useful with link-local IPv6 addresses */
00420         return "Scope id is not supported";
00421     }
00422 
00423     if (!port) {
00424         return "Port must be specified";
00425     }
00426 
00427     return alloc_listener(cmd->server->process, host, port);
00428 }
00429 
00430 const char *ap_set_listenbacklog(cmd_parms *cmd, void *dummy, const char *arg)
00431 {
00432     int b;
00433     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
00434 
00435     if (err != NULL) {
00436         return err;
00437     }
00438 
00439     b = atoi(arg);
00440     if (b < 1) {
00441         return "ListenBacklog must be > 0";
00442     }
00443 
00444     ap_listenbacklog = b;
00445     return NULL;
00446 }
00447 
00448 const char *ap_set_send_buffer_size(cmd_parms *cmd, void *dummy,
00449                                     const char *arg)
00450 {
00451     int s = atoi(arg);
00452     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
00453 
00454     if (err != NULL) {
00455         return err;
00456     }
00457 
00458     if (s < 512 && s != 0) {
00459         return "SendBufferSize must be >= 512 bytes, or 0 for system default.";
00460     }
00461 
00462     send_buffer_size = s;
00463     return NULL;
00464 }