Apache HTTPD
listen.c
Go to the documentation of this file.
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#include "apr_version.h"
23
24#include "ap_config.h"
25#include "httpd.h"
26#include "http_main.h"
27#include "http_config.h"
28#include "http_core.h"
29#include "ap_listen.h"
30#include "http_log.h"
31#include "mpm_common.h"
32
33#include <stdlib.h>
34#if APR_HAVE_UNISTD_H
35#include <unistd.h>
36#endif
37
38/* we know core's module_index is 0 */
39#undef APLOG_MODULE_INDEX
40#define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
41
43
44/* Let ap_num_listen_buckets be global so that it can
45 * be printed by ap_log_mpm_common(), but keep the listeners
46 * buckets static since it is used only here to close them
47 * all (including duplicated) with ap_close_listeners().
48 */
51
52/* Determine once, at runtime, whether or not SO_REUSEPORT
53 * is usable on this platform, and hence whether or not
54 * listeners can be duplicated (if configured).
55 */
57
63
64/* TODO: make_sock is just begging and screaming for APR abstraction */
66{
67 apr_socket_t *s = server->sd;
68 int one = 1;
69#if APR_HAVE_IPV6
70#ifdef AP_ENABLE_V4_MAPPED
71 int v6only_setting = 0;
72#else
73 int v6only_setting = 1;
74#endif
75#endif
77
78#ifndef WIN32
80 if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) {
82 "make_sock: for address %pI, apr_socket_opt_set: (SO_REUSEADDR)",
83 server->bind_addr);
85 return stat;
86 }
87#endif
88
90 if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) {
92 "make_sock: for address %pI, apr_socket_opt_set: (SO_KEEPALIVE)",
93 server->bind_addr);
95 return stat;
96 }
97
98#if APR_HAVE_IPV6
99 if (server->bind_addr->family == APR_INET6) {
101 if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) {
103 "make_sock: for address %pI, apr_socket_opt_set: "
104 "(IPV6_V6ONLY)",
105 server->bind_addr);
107 return stat;
108 }
109 }
110#endif
111
112 /*
113 * To send data over high bandwidth-delay connections at full
114 * speed we must force the TCP window to open wide enough to keep the
115 * pipe full. The default window size on many systems
116 * is only 4kB. Cross-country WAN connections of 100ms
117 * at 1Mb/s are not impossible for well connected sites.
118 * If we assume 100ms cross-country latency,
119 * a 4kB buffer limits throughput to 40kB/s.
120 *
121 * To avoid this problem I've added the SendBufferSize directive
122 * to allow the web master to configure send buffer size.
123 *
124 * The trade-off of larger buffers is that more kernel memory
125 * is consumed. YMMV, know your customers and your network!
126 *
127 * -John Heidemann <[email protected]> 25-Oct-96
128 *
129 * If no size is specified, use the kernel default.
130 */
131 if (send_buffer_size) {
133 if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) {
135 "make_sock: failed to set SendBufferSize for "
136 "address %pI, using default",
137 server->bind_addr);
138 /* not a fatal error */
139 }
140 }
143 if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) {
145 "make_sock: failed to set ReceiveBufferSize for "
146 "address %pI, using default",
147 server->bind_addr);
148 /* not a fatal error */
149 }
150 }
151
152#if APR_TCP_NODELAY_INHERITED
154#endif
155
156#if defined(SO_REUSEPORT)
158 int thesock;
161 (void *)&one, sizeof(int)) < 0) {
164 "make_sock: for address %pI, apr_socket_opt_set: "
165 "(SO_REUSEPORT)",
166 server->bind_addr);
168 return stat;
169 }
170 }
171#endif
172
173 if ((stat = apr_socket_bind(s, server->bind_addr)) != APR_SUCCESS) {
175 "make_sock: could not bind to address %pI",
176 server->bind_addr);
178 return stat;
179 }
180
183 "make_sock: unable to listen for connections "
184 "on address %pI",
185 server->bind_addr);
187 return stat;
188 }
189
190#ifdef WIN32
191 /* I seriously doubt that this would work on Unix; I have doubts that
192 * it entirely solves the problem on Win32. However, since setting
193 * reuseaddr on the listener -prior- to binding the socket has allowed
194 * us to attach to the same port as an already running instance of
195 * Apache, or even another web server, we cannot identify that this
196 * port was exclusively granted to this instance of Apache.
197 *
198 * So set reuseaddr, but do not attempt to do so until we have the
199 * parent listeners successfully bound.
200 */
202 if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) {
204 "make_sock: for address %pI, apr_socket_opt_set: (SO_REUSEADDR)",
205 server->bind_addr);
207 return stat;
208 }
209#endif
210
211 server->sd = s;
212 server->active = 1;
213
214 server->accept_func = NULL;
215
216 return APR_SUCCESS;
217}
218
219static const char* find_accf_name(server_rec *s, const char *proto)
220{
221 const char* accf;
222 core_server_config *conf = ap_get_core_module_config(s->module_config);
223 if (!proto) {
224 return NULL;
225 }
226
227 accf = apr_table_get(conf->accf_map, proto);
228
229 if (accf && !strcmp("none", accf)) {
230 return NULL;
231 }
232
233 return accf;
234}
235
238{
239 apr_socket_t *s = lis->sd;
240 const char *accf;
241 apr_status_t rv;
242 const char *proto;
243
244 proto = lis->protocol;
245
246 if (!proto) {
248 }
249
250
251 accf = find_accf_name(server, proto);
252
253 if (accf) {
254#if APR_HAS_SO_ACCEPTFILTER
255 /* In APR 1.x, the 2nd and 3rd parameters are char * instead of
256 * const char *, so make a copy of those args here.
257 */
259 apr_pstrdup(p, ""));
260 if (rv != APR_SUCCESS && !APR_STATUS_IS_ENOTIMPL(rv)) {
262 "Failed to enable the '%s' Accept Filter",
263 accf);
264 }
265#else
267 if (rv != APR_SUCCESS && !APR_STATUS_IS_ENOTIMPL(rv)) {
269 "Failed to enable APR_TCP_DEFER_ACCEPT");
270 }
271#endif
272 }
273}
274
276{
278 return APR_SUCCESS;
279}
280
281/* Returns non-zero if socket address SA matches hostname, port and
282 * scope_id. p is used for temporary allocations. */
284 const char *hostname, apr_port_t port,
285 const char *scope_id, apr_pool_t *p)
286{
287 const char *old_scope = NULL;
288
289#if APR_VERSION_AT_LEAST(1,7,0)
290 /* To be clever here we could correctly match numeric and
291 * non-numeric zone ids. Ignore failure, old_scope will be left
292 * as NULL. */
294#endif
295
296 return port == sa->port
297 && ((!hostname && !sa->hostname)
298 || (hostname && sa->hostname && !strcmp(sa->hostname, hostname)))
299 && ((!scope_id && !old_scope)
301}
302
303/* ### This logic doesn't cope with DNS changes across a restart. */
305 const char *addr, apr_port_t port,
306 const char *scope_id, apr_pool_t *temp_pool)
307{
308 int found = 0;
309
310 while (*from) {
311 apr_sockaddr_t *sa = (*from)->bind_addr;
312
313 /* Some listeners are not real so they will not have a bind_addr. */
314 if (sa) {
315 ap_listen_rec *new;
316
317 /* Re-use the existing record if it matches completely
318 * against an existing listener. */
320 found = 1;
321 if (!to) {
322 break;
323 }
324 new = *from;
325 *from = new->next;
326 new->next = *to;
327 *to = new;
328 continue;
329 }
330 }
331
332 from = &(*from)->next;
333 }
334
335 return found;
336}
337
338static const char *alloc_listener(process_rec *process, const char *addr,
339 apr_port_t port, const char* proto,
340 const char *scope_id, void *slave,
342{
346
347 /* see if we've got a listener for this address:port, which is an error */
349 return "Cannot define multiple Listeners on the same IP:port";
350 }
351
352 /* see if we've got an old listener for this address:port */
355 if (ap_listeners->slave != slave) {
356 return "Cannot define a slave on the same IP:port as a Listener";
357 }
358 return NULL;
359 }
360
362 process->pool))
363 != APR_SUCCESS) {
365 "alloc_listener: failed to set up sockaddr for %s",
366 addr);
367 return "Listen setup failed";
368 }
369
370 /* Initialize to our last configured ap_listener. */
372 while (last && last->next) {
373 last = last->next;
374 }
375
376 while (sa) {
377 ap_listen_rec *new;
378
379 /* this has to survive restarts */
380 new = apr_palloc(process->pool, sizeof(ap_listen_rec));
381 new->active = 0;
382 new->next = 0;
383 new->bind_addr = sa;
384 new->protocol = apr_pstrdup(process->pool, proto);
385
386 /* Go to the next sockaddr. */
387 sa = sa->next;
388
389 status = apr_socket_create(&new->sd, new->bind_addr->family,
390 SOCK_STREAM, 0, process->pool);
391
392#if APR_HAVE_IPV6
393 /* What could happen is that we got an IPv6 address, but this system
394 * doesn't actually support IPv6. Try the next address.
395 */
396 if (status != APR_SUCCESS && !addr &&
397 new->bind_addr->family == APR_INET6) {
398 continue;
399 }
400#endif
401 if (status != APR_SUCCESS) {
403 "alloc_listener: failed to get a socket for %s",
404 addr);
405 return "Listen setup failed";
406 }
407
408#if APR_VERSION_AT_LEAST(1,7,0)
409 if (scope_id) {
411 if (status) {
413 "alloc_listener: failed to set scope for %pI to %s",
414 new->bind_addr, scope_id);
415 return "Listen step failed";
416 }
417 }
418#endif
419
420 /* We need to preserve the order returned by getaddrinfo() */
421 if (last == NULL) {
422 ap_listeners = last = new;
423 } else {
424 last->next = new;
425 last = new;
426 }
427 new->slave = slave;
428 }
429
430 return NULL;
431}
432/* Evaluates to true if the (apr_sockaddr_t *) addr argument is the
433 * IPv4 match-any-address, 0.0.0.0. */
434#define IS_INADDR_ANY(addr) ((addr)->family == APR_INET \
435 && (addr)->sa.sin.sin_addr.s_addr == INADDR_ANY)
436
437/* Evaluates to true if the (apr_sockaddr_t *) addr argument is the
438 * IPv6 match-any-address, [::]. */
439#define IS_IN6ADDR_ANY(addr) ((addr)->family == APR_INET6 \
440 && IN6_IS_ADDR_UNSPECIFIED(&(addr)->sa.sin6.sin6_addr))
441
448{
450 ap_listen_rec *next;
452 int num_open;
453 const char *userdata_key = "ap_open_listeners";
454 void *data;
455#if AP_NONBLOCK_WHEN_MULTI_LISTEN
456 int use_nonblock;
457#endif
458
459 /* Don't allocate a default listener. If we need to listen to a
460 * port, then the user needs to have a Listen directive in their
461 * config file.
462 */
463 num_open = 0;
464 previous = NULL;
465 for (lr = ap_listeners; lr; previous = lr, lr = lr->next) {
466 if (lr->active) {
467 ++num_open;
468 }
469 else {
470#if APR_HAVE_IPV6
472 int v6only_setting;
473 int skip = 0;
474
475 /* If we have the unspecified IPv4 address (0.0.0.0) and
476 * the unspecified IPv6 address (::) is next, we need to
477 * swap the order of these in the list. We always try to
478 * bind to IPv6 first, then IPv4, since an IPv6 socket
479 * might be able to receive IPv4 packets if V6ONLY is not
480 * enabled, but never the other way around.
481 * Note: In some configurations, the unspecified IPv6 address
482 * could be even later in the list. This logic only corrects
483 * the situation where it is next in the list, such as when
484 * apr_sockaddr_info_get() returns an IPv4 and an IPv6 address,
485 * in that order.
486 */
487 if (lr->next != NULL
488 && IS_INADDR_ANY(lr->bind_addr)
489 && lr->bind_addr->port == lr->next->bind_addr->port
490 && IS_IN6ADDR_ANY(lr->next->bind_addr)) {
491 /* Exchange lr and lr->next */
492 next = lr->next;
493 lr->next = next->next;
494 next->next = lr;
495 if (previous) {
496 previous->next = next;
497 }
498 else {
499 ap_listeners = next;
500 }
501 lr = next;
502 }
503
504 /* If we are trying to bind to 0.0.0.0 and a previous listener
505 * was :: on the same port and in turn that socket does not have
506 * the IPV6_V6ONLY flag set; we must skip the current attempt to
507 * listen (which would generate an error). IPv4 will be handled
508 * on the established IPv6 socket.
509 */
510 if (IS_INADDR_ANY(lr->bind_addr) && previous) {
511 for (cur = ap_listeners; cur != lr; cur = cur->next) {
512 if (lr->bind_addr->port == cur->bind_addr->port
513 && IS_IN6ADDR_ANY(cur->bind_addr)
516 && v6only_setting == 0) {
517
518 /* Remove the current listener from the list */
519 previous->next = lr->next;
520 lr = previous; /* maintain current value of previous after
521 * post-loop expression is evaluated
522 */
523 skip = 1;
524 break;
525 }
526 }
527 if (skip) {
528 continue;
529 }
530 }
531#endif
532 if (make_sock(pool, lr) == APR_SUCCESS) {
533 ++num_open;
534 }
535 else {
536#if APR_HAVE_IPV6
537 /* If we tried to bind to ::, and the next listener is
538 * on 0.0.0.0 with the same port, don't give a fatal
539 * error. The user will still get a warning from make_sock
540 * though.
541 */
542 if (lr->next != NULL
543 && IS_IN6ADDR_ANY(lr->bind_addr)
544 && lr->bind_addr->port == lr->next->bind_addr->port
545 && IS_INADDR_ANY(lr->next->bind_addr)) {
546
547 /* Remove the current listener from the list */
548 if (previous) {
549 previous->next = lr->next;
550 }
551 else {
553 }
554
555 /* Although we've removed ourselves from the list,
556 * we need to make sure that the next iteration won't
557 * consider "previous" a working IPv6 '::' socket.
558 * Changing the family is enough to make sure the
559 * conditions before make_sock() fail.
560 */
562
563 continue;
564 }
565#endif
566 /* fatal error */
567 return -1;
568 }
569 }
570 }
571
572 /* close the old listeners */
575
576#if AP_NONBLOCK_WHEN_MULTI_LISTEN
577 /* if multiple listening sockets, make them non-blocking so that
578 * if select()/poll() reports readability for a reset connection that
579 * is already forgotten about by the time we call accept, we won't
580 * be hung until another connection arrives on that port
581 */
583 for (lr = ap_listeners; lr; lr = lr->next) {
585
587 if (status != APR_SUCCESS) {
589 "unable to control socket non-blocking status");
590 return -1;
591 }
592 }
593#endif /* AP_NONBLOCK_WHEN_MULTI_LISTEN */
594
595 /* we come through here on both passes of the open logs phase
596 * only register the cleanup once... otherwise we try to close
597 * listening sockets twice when cleaning up prior to exec
598 */
600 if (!data) {
601 apr_pool_userdata_set((const void *)1, userdata_key,
605 }
606
607 return num_open ? 0 : -1;
608}
609
611{
612 server_rec *ls;
615 int num_listeners = 0;
616 const char* proto;
617 int found;
618
619 for (ls = s; ls; ls = ls->next) {
620 proto = ap_get_server_protocol(ls);
621 if (!proto) {
622 found = 0;
623 /* No protocol was set for this vhost,
624 * use the default for this listener.
625 */
626 for (addr = ls->addrs; addr && !found; addr = addr->next) {
627 for (lr = ap_listeners; lr; lr = lr->next) {
628 if (apr_sockaddr_equal(lr->bind_addr, addr->host_addr) &&
629 lr->bind_addr->port == addr->host_port) {
630 ap_set_server_protocol(ls, lr->protocol);
631 found = 1;
632 break;
633 }
634 }
635 }
636
637 if (!found) {
638 /* TODO: set protocol defaults per-Port, eg 25=smtp */
639 ap_set_server_protocol(ls, "http");
640 }
641 }
642 }
643
644 if (open_listeners(s->process->pool)) {
645 return 0;
646 }
647
648 for (lr = ap_listeners; lr; lr = lr->next) {
650 found = 0;
651 for (ls = s; ls && !found; ls = ls->next) {
652 for (addr = ls->addrs; addr && !found; addr = addr->next) {
653 if (apr_sockaddr_equal(lr->bind_addr, addr->host_addr) &&
654 lr->bind_addr->port == addr->host_port) {
655 found = 1;
656 ap_apply_accept_filter(s->process->pool, lr, ls);
657 }
658 }
659 }
660
661 if (!found) {
662 ap_apply_accept_filter(s->process->pool, lr, s);
663 }
664 }
665
666 return num_listeners;
667}
668
671 int *num_buckets)
672{
673 static int warn_once;
674 int i;
676 int use_nonblock = 0;
678
679 if (*num_buckets < 1) {
680 *num_buckets = 1;
681 if (ap_listencbratio > 0) {
682#ifdef _SC_NPROCESSORS_ONLN
686 if (val > 1) {
687 *num_buckets = val;
688 }
690 "Using %i listeners bucket(s) based on %i "
691 "online CPU cores and a ratio of %i",
694 }
695 else
696#endif
697 if (!warn_once) {
699 "ListenCoresBucketsRatio ignored without "
700 "SO_REUSEPORT and _SC_NPROCESSORS_ONLN "
701 "support: using a single listeners bucket");
702 warn_once = 1;
703 }
704 }
705 }
706
708 (*buckets)[0] = ap_listeners;
709
710 for (i = 1; i < *num_buckets; i++) {
713 while (lr) {
715 char *hostname;
718 duplr = apr_palloc(p, sizeof(ap_listen_rec));
719 duplr->slave = NULL;
720 duplr->protocol = apr_pstrdup(p, lr->protocol);
721 hostname = apr_pstrdup(p, lr->bind_addr->hostname);
722 port = lr->bind_addr->port;
724 duplr->bind_addr = sa;
725 duplr->next = NULL;
726 stat = apr_socket_create(&duplr->sd, duplr->bind_addr->family,
727 SOCK_STREAM, 0, p);
728 if (stat != APR_SUCCESS) {
730 "ap_duplicate_listeners: for address %pI, "
731 "cannot duplicate a new socket!",
732 duplr->bind_addr);
733 return stat;
734 }
735 make_sock(p, duplr);
736#if AP_NONBLOCK_WHEN_MULTI_LISTEN
739 if (stat != APR_SUCCESS) {
741 "unable to control socket non-blocking status");
742 return stat;
743 }
744#endif
746
747 if (last == NULL) {
748 (*buckets)[i] = last = duplr;
749 }
750 else {
751 last->next = duplr;
752 last = duplr;
753 }
754 lr = lr->next;
755 }
756 }
757
760 return APR_SUCCESS;
761}
762
764{
765 int i;
766
768
769 /* Start from index 1 since either ap_duplicate_listeners()
770 * was called and ap_listen_buckets[0] == ap_listeners, or
771 * it wasn't and ap_num_listen_buckets == 0.
772 */
773 for (i = 1; i < ap_num_listen_buckets; i++) {
775 }
776}
777
779{
781 for (lr = listeners; lr; lr = lr->next) {
782 apr_socket_close(lr->sd);
783 lr->active = 0;
784 }
785}
786
788{
790 int n = 0;
791
792 for (lr = ap_listeners; lr; lr = lr->next) {
793 if (lr->slave != slave) {
794 apr_socket_close(lr->sd);
795 lr->active = 0;
796 }
797 else {
798 ++n;
799 }
800 }
801 return n;
802}
803
805{
812
813 /* Check once whether or not SO_REUSEPORT is supported. */
814 if (ap_have_so_reuseport < 0) {
815 /* This is limited to Linux with defined SO_REUSEPORT (ie. 3.9+) for
816 * now since the implementation evenly distributes connections across
817 * all the listening threads/processes.
818 *
819 * *BSDs have SO_REUSEPORT too but with a different semantic: the first
820 * wildcard address bound socket or the last non-wildcard address bound
821 * socket will receive connections (no evenness guarantee); the rest of
822 * the sockets bound to the same port will not.
823 * This can't (always) work for httpd.
824 *
825 * TODO: latests DragonFlyBSD's SO_REUSEPORT (seems to?) have the same
826 * semantic as Linux, so we may need HAVE_SO_REUSEPORT available from
827 * configure.in some day.
828 */
829#if defined(SO_REUSEPORT) && defined(__linux__)
833 int thesock, on = 1;
836 SO_REUSEPORT, (void *)&on,
837 sizeof(int)) == 0);
839 }
840 else
841#endif
843
844 }
845}
846
848 int argc, char *const argv[])
849{
850 char *host, *scope_id, *proto;
852 apr_status_t rv;
853 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
854
855 if (err != NULL) {
856 return err;
857 }
858
859 if (argc < 1 || argc > 2) {
860 return "Listen requires 1 or 2 arguments.";
861 }
862
863 rv = apr_parse_addr_port(&host, &scope_id, &port, argv[0], cmd->pool);
864 if (rv != APR_SUCCESS) {
865 return "Invalid address or port";
866 }
867
868 if (host && !strcmp(host, "*")) {
869 host = NULL;
870 }
871
872#if !APR_VERSION_AT_LEAST(1,7,0)
873 if (scope_id) {
874 return apr_pstrcat(cmd->pool,
875 "Scope ID in address '", argv[0],
876 "' not supported with APR " APR_VERSION_STRING,
877 NULL);
878 }
879#endif
880
881 if (!port) {
882 return "Port must be specified";
883 }
884
885 if (argc != 2) {
886 if (port == 443) {
887 proto = "https";
888 } else {
889 proto = "http";
890 }
891 }
892 else {
893 proto = apr_pstrdup(cmd->pool, argv[1]);
894 ap_str_tolower(proto);
895 }
896
897 return alloc_listener(cmd->server->process, host, port, proto,
898 scope_id, NULL, cmd->temp_pool);
899}
900
902 void *dummy,
903 const char *arg)
904{
905 int b;
906 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
907
908 if (err != NULL) {
909 return err;
910 }
911
912 b = atoi(arg);
913 if (b < 1) {
914 return "ListenBacklog must be > 0";
915 }
916
918 return NULL;
919}
920
922 void *dummy,
923 const char *arg)
924{
925 int b;
926 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
927
928 if (err != NULL) {
929 return err;
930 }
931
932 b = atoi(arg);
933 if (b < 1) {
934 return "ListenCoresBucketsRatio must be > 0";
935 }
936
938 return NULL;
939}
940
942 void *dummy,
943 const char *arg)
944{
945 int s = atoi(arg);
946 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
947
948 if (err != NULL) {
949 return err;
950 }
951
952 if (s < 512 && s != 0) {
953 return "SendBufferSize must be >= 512 bytes, or 0 for system default.";
954 }
955
957 return NULL;
958}
959
961 void *dummy,
962 const char *arg)
963{
964 int s = atoi(arg);
965 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
966
967 if (err != NULL) {
968 return err;
969 }
970
971 if (s < 512 && s != 0) {
972 return "ReceiveBufferSize must be >= 512 bytes, or 0 for system default.";
973 }
974
976 return NULL;
977}
Symbol export macros and hook functions.
#define AP_DECLARE_DATA
Definition ap_config.h:89
#define AP_DECLARE_NONSTD(type)
Definition ap_config.h:77
#define AP_DECLARE(type)
Definition ap_config.h:67
Apache Listeners Library.
int n
Definition ap_regex.h:278
#define setsockopt
APR Network library.
APR Strings library.
APR Versioning Interface.
#define APR_VERSION_STRING
APR Standard Headers Support.
return found
Definition core.c:2840
const char * hostname
#define ap_get_core_module_config(v)
Definition http_core.h:383
void ap_set_server_protocol(server_rec *s, const char *proto)
Definition core.c:3090
const char * ap_get_server_protocol(server_rec *s)
Definition core.c:3084
struct ap_slave_t ap_slave_t
Definition ap_listen.h:37
void ap_close_listeners(void)
Definition listen.c:763
const char * ap_set_listenbacklog(cmd_parms *cmd, void *dummy, const char *arg)
Definition listen.c:901
const char * ap_set_send_buffer_size(cmd_parms *cmd, void *dummy, const char *arg)
Definition listen.c:941
int ap_num_listen_buckets
Definition listen.c:49
const char * ap_set_listencbratio(cmd_parms *cmd, void *dummy, const char *arg)
Definition listen.c:921
const char * ap_set_listener(cmd_parms *cmd, void *dummy, int argc, char *const argv[])
Definition listen.c:847
int ap_close_selected_listeners(ap_slave_t *slave)
Definition listen.c:787
void ap_close_listeners_ex(ap_listen_rec *listeners)
Definition listen.c:778
void ap_listen_pre_config(void)
Definition listen.c:804
int ap_have_so_reuseport
Definition listen.c:56
apr_status_t ap_duplicate_listeners(apr_pool_t *p, server_rec *s, ap_listen_rec ***buckets, int *num_buckets)
Definition listen.c:669
ap_listen_rec * ap_listeners
Definition listen.c:42
int ap_setup_listeners(server_rec *s)
Definition listen.c:610
const char * ap_set_receive_buffer_size(cmd_parms *cmd, void *dummy, const char *arg)
Definition listen.c:960
#define APLOGNO(n)
Definition http_log.h:117
#define APLOG_STARTUP
Definition http_log.h:105
#define APLOG_INFO
Definition http_log.h:70
#define APLOG_ERR
Definition http_log.h:67
#define APLOG_MARK
Definition http_log.h:283
#define ap_log_perror
Definition http_log.h:412
#define APLOG_WARNING
Definition http_log.h:68
#define APLOG_CRIT
Definition http_log.h:66
apr_pool_t * ap_pglobal
Definition config.c:63
const char apr_port_t port
Definition http_vhost.h:125
void * dummy
Definition http_vhost.h:62
const char * host
Definition http_vhost.h:124
void const char * arg
Definition http_vhost.h:63
#define ap_sock_disable_nagle(s)
Definition mpm_common.h:200
#define DEFAULT_LISTENBACKLOG
Definition mpm_common.h:63
#define APR_ENOTIMPL
Definition apr_errno.h:476
#define APR_STATUS_IS_ENOTIMPL(s)
Definition apr_errno.h:615
apr_memcache_server_t * server
apr_pool_t * temp_pool
void ap_str_tolower(char *s)
Definition util.c:2410
#define GLOBAL_ONLY
const char * ap_check_cmd_context(cmd_parms *cmd, unsigned forbidden)
Definition core.c:1301
apr_size_t size
apr_uint32_t val
Definition apr_atomic.h:66
const char int apr_pool_t * pool
Definition apr_cstr.h:84
#define apr_get_netos_error()
Definition apr_errno.h:1222
#define APR_SUCCESS
Definition apr_errno.h:225
int apr_status_t
Definition apr_errno.h:44
void * data
apr_pool_t int argc
Definition apr_getopt.h:104
apr_sockaddr_t * addr
apr_socket_t * sock
apr_sockaddr_t * sa
apr_uint16_t apr_port_t
#define APR_UNSPEC
apr_int32_t apr_int32_t on
char ** scope_id
apr_pool_t * b
Definition apr_pools.h:529
#define apr_pcalloc(p, size)
Definition apr_pools.h:465
apr_os_sock_t * thesock
int to
#define APR_SO_KEEPALIVE
#define APR_SO_SNDBUF
#define APR_SO_RCVBUF
#define APR_SO_REUSEADDR
#define APR_TCP_DEFER_ACCEPT
#define APR_SO_NONBLOCK
#define APR_IPV6_V6ONLY
const char char ** last
const char * s
Definition apr_strings.h:95
apr_int32_t apr_int32_t apr_int32_t err
apr_cmdtype_e cmd
int int status
Apache Configuration.
CORE HTTP Daemon.
Apache Logging library.
Command line options.
HTTP Daemon routines.
static int find_listeners(ap_listen_rec **from, ap_listen_rec **to, const char *addr, apr_port_t port, const char *scope_id, apr_pool_t *temp_pool)
Definition listen.c:304
static int send_buffer_size
Definition listen.c:61
static apr_status_t close_listeners_on_exec(void *v)
Definition listen.c:275
static ap_listen_rec ** ap_listen_buckets
Definition listen.c:50
static int ap_listencbratio
Definition listen.c:60
static void ap_apply_accept_filter(apr_pool_t *p, ap_listen_rec *lis, server_rec *server)
Definition listen.c:236
#define IS_IN6ADDR_ANY(addr)
Definition listen.c:439
static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server)
Definition listen.c:65
static int match_address(const apr_sockaddr_t *sa, const char *hostname, apr_port_t port, const char *scope_id, apr_pool_t *p)
Definition listen.c:283
static int ap_listenbacklog
Definition listen.c:59
#define IS_INADDR_ANY(addr)
Definition listen.c:434
static const char * alloc_listener(process_rec *process, const char *addr, apr_port_t port, const char *proto, const char *scope_id, void *slave, apr_pool_t *temp_pool)
Definition listen.c:338
static const char * find_accf_name(server_rec *s, const char *proto)
Definition listen.c:219
static int receive_buffer_size
Definition listen.c:62
static int open_listeners(apr_pool_t *pool)
Definition listen.c:447
static ap_listen_rec * old_listeners
Definition listen.c:58
apr_pool_t * p
Definition md_event.c:32
static unsigned long num_buckets
const char * argv[3]
return NULL
Definition mod_so.c:359
int i
Definition mod_so.c:347
Multi-Processing Modules functions.
Apache's listeners record.
Definition ap_listen.h:47
ap_listen_rec * next
Definition ap_listen.h:51
ap_slave_t * slave
Definition ap_listen.h:73
apr_sockaddr_t * bind_addr
Definition ap_listen.h:59
apr_sockaddr_t * next
apr_int32_t family
apr_table_t * accf_map
Definition http_core.h:715
A structure that represents one process.
Definition httpd.h:829
apr_pool_t * pool
Definition httpd.h:831
A structure to be used for Per-vhost config.
Definition httpd.h:1301
A structure to store information for each virtual server.
Definition httpd.h:1322
apr_status_t apr_os_sock_get(apr_os_sock_t *thesock, apr_socket_t *sock)
Definition sockets.c:506
apr_status_t apr_socket_listen(apr_socket_t *sock, apr_int32_t backlog)
Definition sockets.c:239
apr_status_t apr_socket_bind(apr_socket_t *sock, apr_sockaddr_t *sa)
Definition sockets.c:216
apr_status_t apr_socket_close(apr_socket_t *thesocket)
Definition sockets.c:211
apr_status_t apr_socket_create(apr_socket_t **new, int ofamily, int type, int protocol, apr_pool_t *cont)
Definition sockets.c:116
apr_status_t apr_socket_opt_set(apr_socket_t *sock, apr_int32_t opt, apr_int32_t on)
Definition sockopt.c:113
apr_status_t apr_socket_opt_get(apr_socket_t *sock, apr_int32_t opt, apr_int32_t *on)
Definition sockopt.c:362