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