1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements.  See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License.  You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "apr_network_io.h"
18#include "apr_strings.h"
19
20#define APR_WANT_STRFUNC
21#include "apr_want.h"
22
23#define CORE_PRIVATE
24#include "ap_config.h"
25#include "httpd.h"
26#include "http_config.h"
27#include "http_core.h"
28#include "ap_listen.h"
29#include "http_log.h"
30#include "mpm.h"
31#include "mpm_common.h"
32
33AP_DECLARE_DATA ap_listen_rec *ap_listeners = NULL;
34
35static ap_listen_rec *old_listeners;
36static int ap_listenbacklog;
37static int send_buffer_size;
38static int receive_buffer_size;
39
40/* TODO: make_sock is just begging and screaming for APR abstraction */
41static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server)
42{
43    apr_socket_t *s = server->sd;
44    int one = 1;
45#if APR_HAVE_IPV6
46#ifdef AP_ENABLE_V4_MAPPED
47    int v6only_setting = 0;
48#else
49    int v6only_setting = 1;
50#endif
51#endif
52    apr_status_t stat;
53
54#ifndef WIN32
55    stat = apr_socket_opt_set(s, APR_SO_REUSEADDR, one);
56    if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) {
57        ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p,
58                      "make_sock: for address %pI, apr_socket_opt_set: (SO_REUSEADDR)",
59                      server->bind_addr);
60        apr_socket_close(s);
61        return stat;
62    }
63#endif
64
65    stat = apr_socket_opt_set(s, APR_SO_KEEPALIVE, one);
66    if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) {
67        ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p,
68                      "make_sock: for address %pI, apr_socket_opt_set: (SO_KEEPALIVE)",
69                      server->bind_addr);
70        apr_socket_close(s);
71        return stat;
72    }
73
74#if APR_HAVE_IPV6
75    if (server->bind_addr->family == APR_INET6) {
76        stat = apr_socket_opt_set(s, APR_IPV6_V6ONLY, v6only_setting);
77        if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) {
78            ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p,
79                          "make_sock: for address %pI, apr_socket_opt_set: "
80                          "(IPV6_V6ONLY)",
81                          server->bind_addr);
82            apr_socket_close(s);
83            return stat;
84        }
85    }
86#endif
87
88    /*
89     * To send data over high bandwidth-delay connections at full
90     * speed we must force the TCP window to open wide enough to keep the
91     * pipe full.  The default window size on many systems
92     * is only 4kB.  Cross-country WAN connections of 100ms
93     * at 1Mb/s are not impossible for well connected sites.
94     * If we assume 100ms cross-country latency,
95     * a 4kB buffer limits throughput to 40kB/s.
96     *
97     * To avoid this problem I've added the SendBufferSize directive
98     * to allow the web master to configure send buffer size.
99     *
100     * The trade-off of larger buffers is that more kernel memory
101     * is consumed.  YMMV, know your customers and your network!
102     *
103     * -John Heidemann <johnh@isi.edu> 25-Oct-96
104     *
105     * If no size is specified, use the kernel default.
106     */
107    if (send_buffer_size) {
108        stat = apr_socket_opt_set(s, APR_SO_SNDBUF,  send_buffer_size);
109        if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) {
110            ap_log_perror(APLOG_MARK, APLOG_WARNING, stat, p,
111                          "make_sock: failed to set SendBufferSize for "
112                          "address %pI, using default",
113                          server->bind_addr);
114            /* not a fatal error */
115        }
116    }
117    if (receive_buffer_size) {
118        stat = apr_socket_opt_set(s, APR_SO_RCVBUF, receive_buffer_size);
119        if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) {
120            ap_log_perror(APLOG_MARK, APLOG_WARNING, stat, p,
121                          "make_sock: failed to set ReceiveBufferSize for "
122                          "address %pI, using default",
123                          server->bind_addr);
124            /* not a fatal error */
125        }
126    }
127
128#if APR_TCP_NODELAY_INHERITED
129    ap_sock_disable_nagle(s);
130#endif
131
132    if ((stat = apr_socket_bind(s, server->bind_addr)) != APR_SUCCESS) {
133        ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, stat, p,
134                      "make_sock: could not bind to address %pI",
135                      server->bind_addr);
136        apr_socket_close(s);
137        return stat;
138    }
139
140    if ((stat = apr_socket_listen(s, ap_listenbacklog)) != APR_SUCCESS) {
141        ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_ERR, stat, p,
142                      "make_sock: unable to listen for connections "
143                      "on address %pI",
144                      server->bind_addr);
145        apr_socket_close(s);
146        return stat;
147    }
148
149#ifdef WIN32
150    /* I seriously doubt that this would work on Unix; I have doubts that
151     * it entirely solves the problem on Win32.  However, since setting
152     * reuseaddr on the listener -prior- to binding the socket has allowed
153     * us to attach to the same port as an already running instance of
154     * Apache, or even another web server, we cannot identify that this
155     * port was exclusively granted to this instance of Apache.
156     *
157     * So set reuseaddr, but do not attempt to do so until we have the
158     * parent listeners successfully bound.
159     */
160    stat = apr_socket_opt_set(s, APR_SO_REUSEADDR, one);
161    if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) {
162        ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p,
163                    "make_sock: for address %pI, apr_socket_opt_set: (SO_REUSEADDR)",
164                     server->bind_addr);
165        apr_socket_close(s);
166        return stat;
167    }
168#endif
169
170    server->sd = s;
171    server->active = 1;
172
173#ifdef MPM_ACCEPT_FUNC
174    server->accept_func = MPM_ACCEPT_FUNC;
175#else
176    server->accept_func = NULL;
177#endif
178
179    return APR_SUCCESS;
180}
181
182static const char* find_accf_name(server_rec *s, const char *proto)
183{
184    const char* accf;
185    core_server_config *conf = ap_get_module_config(s->module_config,
186                                                    &core_module);
187    if (!proto) {
188        return NULL;
189    }
190
191    accf = apr_table_get(conf->accf_map, proto);
192
193    if (accf && !strcmp("none", accf)) {
194        return NULL;
195    }
196
197    return accf;
198}
199
200static void ap_apply_accept_filter(apr_pool_t *p, ap_listen_rec *lis,
201                                           server_rec *server)
202{
203    apr_socket_t *s = lis->sd;
204    const char *accf;
205    apr_status_t rv;
206    const char *proto;
207
208    proto = lis->protocol;
209
210    if (!proto) {
211        proto = ap_get_server_protocol(server);
212    }
213
214
215    accf = find_accf_name(server, proto);
216
217    if (accf) {
218#if APR_HAS_SO_ACCEPTFILTER
219        rv = apr_socket_accept_filter(s, apr_pstrdup(p, accf),
220                                      apr_pstrdup(p,""));
221        if (rv != APR_SUCCESS && !APR_STATUS_IS_ENOTIMPL(rv)) {
222            ap_log_perror(APLOG_MARK, APLOG_WARNING, rv, p,
223                          "Failed to enable the '%s' Accept Filter",
224                          accf);
225        }
226#else
227#ifdef APR_TCP_DEFER_ACCEPT
228        rv = apr_socket_opt_set(s, APR_TCP_DEFER_ACCEPT, 1);
229        if (rv != APR_SUCCESS && !APR_STATUS_IS_ENOTIMPL(rv)) {
230            ap_log_perror(APLOG_MARK, APLOG_WARNING, rv, p,
231                              "Failed to enable APR_TCP_DEFER_ACCEPT");
232        }
233#endif
234#endif
235    }
236}
237
238static apr_status_t close_listeners_on_exec(void *v)
239{
240    ap_close_listeners();
241    return APR_SUCCESS;
242}
243
244static const char *alloc_listener(process_rec *process, char *addr,
245                                  apr_port_t port, const char* proto)
246{
247    ap_listen_rec **walk, *last;
248    apr_status_t status;
249    apr_sockaddr_t *sa;
250    int found_listener = 0;
251
252    /* see if we've got an old listener for this address:port */
253    for (walk = &old_listeners; *walk;) {
254        sa = (*walk)->bind_addr;
255        /* Some listeners are not real so they will not have a bind_addr. */
256        if (sa) {
257            ap_listen_rec *new;
258            apr_port_t oldport;
259
260            oldport = sa->port;
261            /* If both ports are equivalent, then if their names are equivalent,
262             * then we will re-use the existing record.
263             */
264            if (port == oldport &&
265                ((!addr && !sa->hostname) ||
266                 ((addr && sa->hostname) && !strcmp(sa->hostname, addr)))) {
267                new = *walk;
268                *walk = new->next;
269                new->next = ap_listeners;
270                ap_listeners = new;
271                found_listener = 1;
272                continue;
273            }
274        }
275
276        walk = &(*walk)->next;
277    }
278
279    if (found_listener) {
280        return NULL;
281    }
282
283    if ((status = apr_sockaddr_info_get(&sa, addr, APR_UNSPEC, port, 0,
284                                        process->pool))
285        != APR_SUCCESS) {
286        ap_log_perror(APLOG_MARK, APLOG_CRIT, status, process->pool,
287                      "alloc_listener: failed to set up sockaddr for %s",
288                      addr);
289        return "Listen setup failed";
290    }
291
292    /* Initialize to our last configured ap_listener. */
293    last = ap_listeners;
294    while (last && last->next) {
295        last = last->next;
296    }
297
298    while (sa) {
299        ap_listen_rec *new;
300
301        /* this has to survive restarts */
302        new = apr_palloc(process->pool, sizeof(ap_listen_rec));
303        new->active = 0;
304        new->next = 0;
305        new->bind_addr = sa;
306        new->protocol = apr_pstrdup(process->pool, proto);
307
308        /* Go to the next sockaddr. */
309        sa = sa->next;
310
311        status = apr_socket_create(&new->sd, new->bind_addr->family,
312                                    SOCK_STREAM, 0, process->pool);
313
314#if APR_HAVE_IPV6
315        /* What could happen is that we got an IPv6 address, but this system
316         * doesn't actually support IPv6.  Try the next address.
317         */
318        if (status != APR_SUCCESS && !addr &&
319            new->bind_addr->family == APR_INET6) {
320            continue;
321        }
322#endif
323        if (status != APR_SUCCESS) {
324            ap_log_perror(APLOG_MARK, APLOG_CRIT, status, process->pool,
325                          "alloc_listener: failed to get a socket for %s",
326                          addr);
327            return "Listen setup failed";
328        }
329
330        /* We need to preserve the order returned by getaddrinfo() */
331        if (last == NULL) {
332            ap_listeners = last = new;
333        } else {
334            last->next = new;
335            last = new;
336        }
337    }
338
339    return NULL;
340}
341/* Evaluates to true if the (apr_sockaddr_t *) addr argument is the
342 * IPv4 match-any-address, 0.0.0.0. */
343#define IS_INADDR_ANY(addr) ((addr)->family == APR_INET \
344                             && (addr)->sa.sin.sin_addr.s_addr == INADDR_ANY)
345
346/* Evaluates to true if the (apr_sockaddr_t *) addr argument is the
347 * IPv6 match-any-address, [::]. */
348#define IS_IN6ADDR_ANY(addr) ((addr)->family == APR_INET6 \
349                              && IN6_IS_ADDR_UNSPECIFIED(&(addr)->sa.sin6.sin6_addr))
350
351/**
352 * Create, open, listen, and bind all sockets.
353 * @param process The process record for the currently running server
354 * @return The number of open sockets
355 */
356static int open_listeners(apr_pool_t *pool)
357{
358    ap_listen_rec *lr;
359    ap_listen_rec *next;
360    ap_listen_rec *previous;
361    int num_open;
362    const char *userdata_key = "ap_open_listeners";
363    void *data;
364#if AP_NONBLOCK_WHEN_MULTI_LISTEN
365    int use_nonblock;
366#endif
367
368    /* Don't allocate a default listener.  If we need to listen to a
369     * port, then the user needs to have a Listen directive in their
370     * config file.
371     */
372    num_open = 0;
373    previous = NULL;
374    for (lr = ap_listeners; lr; previous = lr, lr = lr->next) {
375        if (lr->active) {
376            ++num_open;
377        }
378        else {
379#if APR_HAVE_IPV6
380            ap_listen_rec *cur;
381            int v6only_setting;
382            int skip = 0;
383
384            /* If we have the unspecified IPv4 address (0.0.0.0) and
385             * the unspecified IPv6 address (::) is next, we need to
386             * swap the order of these in the list. We always try to
387             * bind to IPv6 first, then IPv4, since an IPv6 socket
388             * might be able to receive IPv4 packets if V6ONLY is not
389             * enabled, but never the other way around.
390             * Note: In some configurations, the unspecified IPv6 address
391             * could be even later in the list.  This logic only corrects
392             * the situation where it is next in the list, such as when
393             * apr_sockaddr_info_get() returns an IPv4 and an IPv6 address,
394             * in that order.
395             */
396            if (lr->next != NULL
397                && IS_INADDR_ANY(lr->bind_addr)
398                && lr->bind_addr->port == lr->next->bind_addr->port
399                && IS_IN6ADDR_ANY(lr->next->bind_addr)) {
400                /* Exchange lr and lr->next */
401                next = lr->next;
402                lr->next = next->next;
403                next->next = lr;
404                if (previous) {
405                    previous->next = next;
406                }
407                else {
408                    ap_listeners = next;
409                }
410                lr = next;
411            }
412
413            /* If we are trying to bind to 0.0.0.0 and a previous listener
414             * was :: on the same port and in turn that socket does not have
415             * the IPV6_V6ONLY flag set; we must skip the current attempt to
416             * listen (which would generate an error). IPv4 will be handled
417             * on the established IPv6 socket.
418             */
419            if (IS_INADDR_ANY(lr->bind_addr)) {
420                for (cur = ap_listeners; cur != lr; cur = cur->next) {
421                    if (lr->bind_addr->port == cur->bind_addr->port
422                        && IS_IN6ADDR_ANY(cur->bind_addr)
423                        && apr_socket_opt_get(cur->sd, APR_IPV6_V6ONLY,
424                                              &v6only_setting) == APR_SUCCESS
425                        && v6only_setting == 0) {
426
427                        /* Remove the current listener from the list */
428                        previous->next = lr->next;
429                        lr = previous; /* maintain current value of previous after
430                                        * post-loop expression is evaluated
431                                        */
432                        skip = 1;
433                        break;
434                    }
435                }
436                if (skip) {
437                    continue;
438                }
439            }
440#endif
441            if (make_sock(pool, lr) == APR_SUCCESS) {
442                ++num_open;
443                lr->active = 1;
444            }
445            else {
446#if APR_HAVE_IPV6
447                /* If we tried to bind to ::, and the next listener is
448                 * on 0.0.0.0 with the same port, don't give a fatal
449                 * error. The user will still get a warning from make_sock
450                 * though.
451                 */
452                if (lr->next != NULL
453                    && IS_IN6ADDR_ANY(lr->bind_addr)
454                    && lr->bind_addr->port == lr->next->bind_addr->port
455                    && IS_INADDR_ANY(lr->next->bind_addr)) {
456
457                    /* Remove the current listener from the list */
458                    if (previous) {
459                        previous->next = lr->next;
460                    }
461                    else {
462                        ap_listeners = lr->next;
463                    }
464
465                    /* Although we've removed ourselves from the list,
466                     * we need to make sure that the next iteration won't
467                     * consider "previous" a working IPv6 '::' socket.
468                     * Changing the family is enough to make sure the
469                     * conditions before make_sock() fail.
470                     */
471                    lr->bind_addr->family = AF_INET;
472
473                    continue;
474                }
475#endif
476                /* fatal error */
477                return -1;
478            }
479        }
480    }
481
482    /* close the old listeners */
483    for (lr = old_listeners; lr; lr = next) {
484        apr_socket_close(lr->sd);
485        lr->active = 0;
486        next = lr->next;
487    }
488    old_listeners = NULL;
489
490#if AP_NONBLOCK_WHEN_MULTI_LISTEN
491    /* if multiple listening sockets, make them non-blocking so that
492     * if select()/poll() reports readability for a reset connection that
493     * is already forgotten about by the time we call accept, we won't
494     * be hung until another connection arrives on that port
495     */
496    use_nonblock = (ap_listeners && ap_listeners->next);
497    for (lr = ap_listeners; lr; lr = lr->next) {
498        apr_status_t status;
499
500        status = apr_socket_opt_set(lr->sd, APR_SO_NONBLOCK, use_nonblock);
501        if (status != APR_SUCCESS) {
502            ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_ERR, status, pool,
503                          "unable to control socket non-blocking status");
504            return -1;
505        }
506    }
507#endif /* AP_NONBLOCK_WHEN_MULTI_LISTEN */
508
509    /* we come through here on both passes of the open logs phase
510     * only register the cleanup once... otherwise we try to close
511     * listening sockets twice when cleaning up prior to exec
512     */
513    apr_pool_userdata_get(&data, userdata_key, pool);
514    if (!data) {
515        apr_pool_userdata_set((const void *)1, userdata_key,
516                              apr_pool_cleanup_null, pool);
517        apr_pool_cleanup_register(pool, NULL, apr_pool_cleanup_null,
518                                  close_listeners_on_exec);
519    }
520
521    return num_open ? 0 : -1;
522}
523
524AP_DECLARE(int) ap_setup_listeners(server_rec *s)
525{
526    server_rec *ls;
527    server_addr_rec *addr;
528    ap_listen_rec *lr;
529    int num_listeners = 0;
530    const char* proto;
531    int found;
532
533    for (ls = s; ls; ls = ls->next) {
534        proto = ap_get_server_protocol(ls);
535        if (!proto) {
536            found = 0;
537            /* No protocol was set for this vhost,
538             * use the default for this listener.
539             */
540            for (addr = ls->addrs; addr && !found; addr = addr->next) {
541                for (lr = ap_listeners; lr; lr = lr->next) {
542                    if (apr_sockaddr_equal(lr->bind_addr, addr->host_addr) &&
543                        lr->bind_addr->port == addr->host_port) {
544                        ap_set_server_protocol(ls, lr->protocol);
545                        found = 1;
546                        break;
547                    }
548                }
549            }
550
551            if (!found) {
552                /* TODO: set protocol defaults per-Port, eg 25=smtp */
553                ap_set_server_protocol(ls, "http");
554            }
555        }
556    }
557
558    if (open_listeners(s->process->pool)) {
559       return 0;
560    }
561
562    for (lr = ap_listeners; lr; lr = lr->next) {
563        num_listeners++;
564        found = 0;
565        for (ls = s; ls && !found; ls = ls->next) {
566            for (addr = ls->addrs; addr && !found; addr = addr->next) {
567                if (apr_sockaddr_equal(lr->bind_addr, addr->host_addr) &&
568                    lr->bind_addr->port == addr->host_port) {
569                    found = 1;
570                    ap_apply_accept_filter(s->process->pool, lr, ls);
571                }
572            }
573        }
574
575        if (!found) {
576            ap_apply_accept_filter(s->process->pool, lr, s);
577        }
578    }
579
580    return num_listeners;
581}
582
583AP_DECLARE_NONSTD(void) ap_close_listeners(void)
584{
585    ap_listen_rec *lr;
586
587    for (lr = ap_listeners; lr; lr = lr->next) {
588        apr_socket_close(lr->sd);
589        lr->active = 0;
590    }
591}
592
593AP_DECLARE(void) ap_listen_pre_config(void)
594{
595    old_listeners = ap_listeners;
596    ap_listeners = NULL;
597    ap_listenbacklog = DEFAULT_LISTENBACKLOG;
598}
599
600
601AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy,
602                                                int argc, char *const argv[])
603{
604    char *host, *scope_id, *proto;
605    apr_port_t port;
606    apr_status_t rv;
607    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
608
609    if (err != NULL) {
610        return err;
611    }
612
613    if (argc < 1 || argc > 2) {
614        return "Listen requires 1 or 2 arguments.";
615    }
616
617    rv = apr_parse_addr_port(&host, &scope_id, &port, argv[0], cmd->pool);
618    if (rv != APR_SUCCESS) {
619        return "Invalid address or port";
620    }
621
622    if (host && !strcmp(host, "*")) {
623        host = NULL;
624    }
625
626    if (scope_id) {
627        /* XXX scope id support is useful with link-local IPv6 addresses */
628        return "Scope id is not supported";
629    }
630
631    if (!port) {
632        return "Port must be specified";
633    }
634
635    if (argc != 2) {
636        if (port == 443) {
637            proto = "https";
638        } else {
639            proto = "http";
640        }
641    }
642    else {
643        proto = apr_pstrdup(cmd->pool, argv[1]);
644        ap_str_tolower(proto);
645    }
646
647    return alloc_listener(cmd->server->process, host, port, proto);
648}
649
650AP_DECLARE_NONSTD(const char *) ap_set_listenbacklog(cmd_parms *cmd,
651                                                     void *dummy,
652                                                     const char *arg)
653{
654    int b;
655    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
656
657    if (err != NULL) {
658        return err;
659    }
660
661    b = atoi(arg);
662    if (b < 1) {
663        return "ListenBacklog must be > 0";
664    }
665
666    ap_listenbacklog = b;
667    return NULL;
668}
669
670AP_DECLARE_NONSTD(const char *) ap_set_send_buffer_size(cmd_parms *cmd,
671                                                        void *dummy,
672                                                        const char *arg)
673{
674    int s = atoi(arg);
675    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
676
677    if (err != NULL) {
678        return err;
679    }
680
681    if (s < 512 && s != 0) {
682        return "SendBufferSize must be >= 512 bytes, or 0 for system default.";
683    }
684
685    send_buffer_size = s;
686    return NULL;
687}
688
689AP_DECLARE_NONSTD(const char *) ap_set_receive_buffer_size(cmd_parms *cmd,
690                                                           void *dummy,
691                                                           const char *arg)
692{
693    int s = atoi(arg);
694    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
695
696    if (err != NULL) {
697        return err;
698    }
699
700    if (s < 512 && s != 0) {
701        return "ReceiveBufferSize must be >= 512 bytes, or 0 for system default.";
702    }
703
704    receive_buffer_size = s;
705    return NULL;
706}
707