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