vhost.c revision ebc18d48bea83ee5ed7a1b4e30007e5192539829
af84459fbf938e508fd10b01cb8d699c79083813takashi/* ====================================================================
af84459fbf938e508fd10b01cb8d699c79083813takashi * The Apache Software License, Version 1.1
af84459fbf938e508fd10b01cb8d699c79083813takashi * Copyright (c) 2000 The Apache Software Foundation. All rights
af84459fbf938e508fd10b01cb8d699c79083813takashi * reserved.
af84459fbf938e508fd10b01cb8d699c79083813takashi * Redistribution and use in source and binary forms, with or without
96ad5d81ee4a2cc66a4ae19893efc8aa6d06fae7jailletc * modification, are permitted provided that the following conditions
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * 1. Redistributions of source code must retain the above copyright
2e545ce2450a9953665f701bb05350f0d3f26275nd * notice, this list of conditions and the following disclaimer.
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * 2. Redistributions in binary form must reproduce the above copyright
af84459fbf938e508fd10b01cb8d699c79083813takashi * notice, this list of conditions and the following disclaimer in
af84459fbf938e508fd10b01cb8d699c79083813takashi * the documentation and/or other materials provided with the
af33a4994ae2ff15bc67d19ff1a7feb906745bf8rbowen * distribution.
af84459fbf938e508fd10b01cb8d699c79083813takashi * 3. The end-user documentation included with the redistribution,
af84459fbf938e508fd10b01cb8d699c79083813takashi * if any, must include the following acknowledgment:
af84459fbf938e508fd10b01cb8d699c79083813takashi * "This product includes software developed by the
3f08db06526d6901aa08c110b5bc7dde6bc39905nd * Apache Software Foundation (http://www.apache.org/)."
af84459fbf938e508fd10b01cb8d699c79083813takashi * Alternately, this acknowledgment may appear in the software itself,
af84459fbf938e508fd10b01cb8d699c79083813takashi * if and wherever such third-party acknowledgments normally appear.
f086b4b402fa9a2fefc7dda85de2a3cc1cd0a654rjung * 4. The names "Apache" and "Apache Software Foundation" must
af84459fbf938e508fd10b01cb8d699c79083813takashi * not be used to endorse or promote products derived from this
0a05fab9aadd37834734ffe106fc8ad4488fb3e3rbowen * software without prior written permission. For written
0a05fab9aadd37834734ffe106fc8ad4488fb3e3rbowen * permission, please contact apache@apache.org.
af84459fbf938e508fd10b01cb8d699c79083813takashi * 5. Products derived from this software may not be called "Apache",
78f97ce162b66a0dbfd7af4dcd9984f162569b04minfrin * nor may "Apache" appear in their name, without prior written
af84459fbf938e508fd10b01cb8d699c79083813takashi * permission of the Apache Software Foundation.
3c13a815670b54d1c17bf02954f7d2b066cde95cnd * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
af84459fbf938e508fd10b01cb8d699c79083813takashi * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
af84459fbf938e508fd10b01cb8d699c79083813takashi * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
af84459fbf938e508fd10b01cb8d699c79083813takashi * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
af84459fbf938e508fd10b01cb8d699c79083813takashi * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
5effc8b39fae5cd169d17f342bfc265705840014rbowen * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
5effc8b39fae5cd169d17f342bfc265705840014rbowen * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
5effc8b39fae5cd169d17f342bfc265705840014rbowen * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
5effc8b39fae5cd169d17f342bfc265705840014rbowen * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
af84459fbf938e508fd10b01cb8d699c79083813takashi * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
30471a4650391f57975f60bbb6e4a90be7b284bfhumbedooh * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
af84459fbf938e508fd10b01cb8d699c79083813takashi * SUCH DAMAGE.
af84459fbf938e508fd10b01cb8d699c79083813takashi * ====================================================================
af84459fbf938e508fd10b01cb8d699c79083813takashi * This software consists of voluntary contributions made by many
af84459fbf938e508fd10b01cb8d699c79083813takashi * individuals on behalf of the Apache Software Foundation. For more
5effc8b39fae5cd169d17f342bfc265705840014rbowen * information on the Apache Software Foundation, please see
5effc8b39fae5cd169d17f342bfc265705840014rbowen * Portions of this software are based upon public domain software
5effc8b39fae5cd169d17f342bfc265705840014rbowen * originally written at the National Center for Supercomputing Applications,
5effc8b39fae5cd169d17f342bfc265705840014rbowen * University of Illinois, Urbana-Champaign.
5effc8b39fae5cd169d17f342bfc265705840014rbowen * http_vhost.c: functions pertaining to virtual host addresses
5effc8b39fae5cd169d17f342bfc265705840014rbowen * (configuration and run-time)
5effc8b39fae5cd169d17f342bfc265705840014rbowen * After all the definitions there's an explanation of how it's all put
5effc8b39fae5cd169d17f342bfc265705840014rbowen * together.
af84459fbf938e508fd10b01cb8d699c79083813takashi/* meta-list of name-vhosts. Each server_rec can be in possibly multiple
af84459fbf938e508fd10b01cb8d699c79083813takashi * lists of name-vhosts.
af84459fbf938e508fd10b01cb8d699c79083813takashi server_addr_rec *sar; /* the record causing it to be in
af84459fbf938e508fd10b01cb8d699c79083813takashi * this chain (needed for port comparisons) */
af84459fbf938e508fd10b01cb8d699c79083813takashi server_rec *server; /* the server to use on a match */
af84459fbf938e508fd10b01cb8d699c79083813takashi/* meta-list of ip addresses. Each server_rec can be in possibly multiple
af84459fbf938e508fd10b01cb8d699c79083813takashi * hash chains since it can have multiple ips.
5effc8b39fae5cd169d17f342bfc265705840014rbowen server_addr_rec *sar; /* the record causing it to be in
5effc8b39fae5cd169d17f342bfc265705840014rbowen * this chain (need for both ip addr and port
5effc8b39fae5cd169d17f342bfc265705840014rbowen * comparisons) */
5effc8b39fae5cd169d17f342bfc265705840014rbowen server_rec *server; /* the server to use if this matches */
5effc8b39fae5cd169d17f342bfc265705840014rbowen name_chain *names; /* if non-NULL then a list of name-vhosts
5effc8b39fae5cd169d17f342bfc265705840014rbowen * sharing this address */
5effc8b39fae5cd169d17f342bfc265705840014rbowen/* This defines the size of the hash apr_table_t used for hashing ip addresses
5effc8b39fae5cd169d17f342bfc265705840014rbowen * of virtual hosts. It must be a power of two.
5effc8b39fae5cd169d17f342bfc265705840014rbowen/* A (n) bucket hash table, each entry has a pointer to a server rec and
5effc8b39fae5cd169d17f342bfc265705840014rbowen * a pointer to the other entries in that bucket. Each individual address,
5effc8b39fae5cd169d17f342bfc265705840014rbowen * even for virtualhosts with multiple addresses, has an entry in this hash
5effc8b39fae5cd169d17f342bfc265705840014rbowen * table. There are extra buckets for _default_, and name-vhost entries.
5effc8b39fae5cd169d17f342bfc265705840014rbowen * Note that after config time this is constant, so it is thread-safe.
5effc8b39fae5cd169d17f342bfc265705840014rbowen/* dump out statistics about the hash function */
5effc8b39fae5cd169d17f342bfc265705840014rbowen/* #define IPHASH_STATISTICS */
5effc8b39fae5cd169d17f342bfc265705840014rbowen/* list of the _default_ servers */
5effc8b39fae5cd169d17f342bfc265705840014rbowen/* list of the NameVirtualHost addresses */
5effc8b39fae5cd169d17f342bfc265705840014rbowen * How it's used:
5effc8b39fae5cd169d17f342bfc265705840014rbowen * The ip address determines which chain in iphash_table is interesting, then
5effc8b39fae5cd169d17f342bfc265705840014rbowen * a comparison is done down that chain to find the first ipaddr_chain whose
5effc8b39fae5cd169d17f342bfc265705840014rbowen * sar matches the address:port pair.
5effc8b39fae5cd169d17f342bfc265705840014rbowen * If that ipaddr_chain has names == NULL then you're done, it's an ip-vhost.
5effc8b39fae5cd169d17f342bfc265705840014rbowen * Otherwise it's a name-vhost list, and the default is the server in the
5effc8b39fae5cd169d17f342bfc265705840014rbowen * ipaddr_chain record. We tuck away the ipaddr_chain record in the
5effc8b39fae5cd169d17f342bfc265705840014rbowen * conn_rec field vhost_lookup_data. Later on after the headers we get a
5effc8b39fae5cd169d17f342bfc265705840014rbowen * second chance, and we use the name_chain to figure out what name-vhost
5effc8b39fae5cd169d17f342bfc265705840014rbowen * matches the headers.
5effc8b39fae5cd169d17f342bfc265705840014rbowen * If there was no ip address match in the iphash_table then do a lookup
5effc8b39fae5cd169d17f342bfc265705840014rbowen * in the default_list.
5effc8b39fae5cd169d17f342bfc265705840014rbowen * How it's put together ... well you should be able to figure that out
5effc8b39fae5cd169d17f342bfc265705840014rbowen * from how it's used. Or something like that.
5effc8b39fae5cd169d17f342bfc265705840014rbowen/* called at the beginning of the config */
5effc8b39fae5cd169d17f342bfc265705840014rbowen * Parses a host of the form <address>[:port]
5effc8b39fae5cd169d17f342bfc265705840014rbowen * paddr is used to create a list in the order of input
5effc8b39fae5cd169d17f342bfc265705840014rbowen * **paddr is the ->next pointer of the last entry (or s->addrs)
5effc8b39fae5cd169d17f342bfc265705840014rbowen * *paddr is the variable used to keep track of **paddr between calls
5effc8b39fae5cd169d17f342bfc265705840014rbowen * port is the default port to assume
5effc8b39fae5cd169d17f342bfc265705840014rbowenstatic const char *get_addresses(apr_pool_t *p, const char *w_,
63befe0983261d711e62457b380e24ecc3b7b79etrawick /* apr_parse_addr_port() doesn't understand ":*" so handle that first. */
5effc8b39fae5cd169d17f342bfc265705840014rbowen if (wlen > 2 && w[wlen - 1] == '*' && w[wlen - 2] == ':') {
5effc8b39fae5cd169d17f342bfc265705840014rbowen rv = apr_parse_addr_port(&host, &scope_id, &port, w, p);
5effc8b39fae5cd169d17f342bfc265705840014rbowen return "The address or port is invalid";
5effc8b39fae5cd169d17f342bfc265705840014rbowen return "Scope ids are not supported";
5effc8b39fae5cd169d17f342bfc265705840014rbowen rv = apr_getaddrinfo(&my_addr, NULL, APR_INET, port, 0, p);
5effc8b39fae5cd169d17f342bfc265705840014rbowen rv = apr_getaddrinfo(&my_addr, NULL, APR_INET, port, 0, p);
5effc8b39fae5cd169d17f342bfc265705840014rbowen ap_assert(rv == APR_SUCCESS); /* must be bug or out of storage */
5effc8b39fae5cd169d17f342bfc265705840014rbowen my_addr->sa.sin.sin_addr.s_addr = DEFAULT_VHOST_ADDR;
5effc8b39fae5cd169d17f342bfc265705840014rbowen rv = apr_getaddrinfo(&my_addr, host, APR_UNSPEC, port, 0, p);
af84459fbf938e508fd10b01cb8d699c79083813takashi /* XXX Gotta go through *all* addresses for the host name!
af84459fbf938e508fd10b01cb8d699c79083813takashi * Fix apr_getaddrinfo() to save them! */
af84459fbf938e508fd10b01cb8d699c79083813takashi/* parse the <VirtualHost> addresses */
af84459fbf938e508fd10b01cb8d699c79083813takashiconst char *ap_parse_vhost_addrs(apr_pool_t *p, const char *hostname, server_rec *s)
5effc8b39fae5cd169d17f342bfc265705840014rbowen const char *err;
af84459fbf938e508fd10b01cb8d699c79083813takashi /* start the list of addreses */
5effc8b39fae5cd169d17f342bfc265705840014rbowen while (hostname[0]) {
5effc8b39fae5cd169d17f342bfc265705840014rbowen err = get_addresses(p, ap_getword_conf(p, &hostname), &addrs, s->port);
5effc8b39fae5cd169d17f342bfc265705840014rbowen /* terminate the list */
5effc8b39fae5cd169d17f342bfc265705840014rbowen /* override the default port which is inherited from main_server */
5effc8b39fae5cd169d17f342bfc265705840014rbowenconst char *ap_set_name_virtual_host (cmd_parms *cmd, void *dummy,
5effc8b39fae5cd169d17f342bfc265705840014rbowen const char *arg)
5effc8b39fae5cd169d17f342bfc265705840014rbowen /* use whatever port the main server has at this point */
5effc8b39fae5cd169d17f342bfc265705840014rbowen return get_addresses(cmd->pool, arg, &name_vhost_list_tail,
5effc8b39fae5cd169d17f342bfc265705840014rbowen/* hash apr_table_t statistics, keep this in here for the beta period so
af84459fbf938e508fd10b01cb8d699c79083813takashi * we can find out if the hash function is ok
af84459fbf938e508fd10b01cb8d699c79083813takashistatic int iphash_compare(const void *a, const void *b)
af84459fbf938e508fd10b01cb8d699c79083813takashi return (*(const int *) b - *(const int *) a);
5effc8b39fae5cd169d17f342bfc265705840014rbowenstatic void dump_iphash_statistics(server_rec *main_s)
5effc8b39fae5cd169d17f342bfc265705840014rbowen for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
5effc8b39fae5cd169d17f342bfc265705840014rbowen /* don't count the slop buckets in the total */
5effc8b39fae5cd169d17f342bfc265705840014rbowen qsort(count, IPHASH_TABLE_SIZE, sizeof(count[0]), iphash_compare);
5effc8b39fae5cd169d17f342bfc265705840014rbowen "iphash: total hashed = %u, avg chain = %u, "
5effc8b39fae5cd169d17f342bfc265705840014rbowen "chain lengths (count x len):",
5effc8b39fae5cd169d17f342bfc265705840014rbowen p += apr_snprintf(p, sizeof(buf) - (p - buf), " %ux%u",
5effc8b39fae5cd169d17f342bfc265705840014rbowen p += apr_snprintf(p, sizeof(buf) - (p - buf), " %ux%u",
5effc8b39fae5cd169d17f342bfc265705840014rbowen ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, main_s, buf);
af84459fbf938e508fd10b01cb8d699c79083813takashi/* This hashing function is designed to get good distribution in the cases
af84459fbf938e508fd10b01cb8d699c79083813takashi * where the server is handling entire "networks" of servers. i.e. a
af84459fbf938e508fd10b01cb8d699c79083813takashi * whack of /24s. This is probably the most common configuration for
af84459fbf938e508fd10b01cb8d699c79083813takashi * ISPs with large virtual servers.
5effc8b39fae5cd169d17f342bfc265705840014rbowen * NOTE: This function is symmetric (i.e. collapses all 4 octets
5effc8b39fae5cd169d17f342bfc265705840014rbowen * into one), so machine byte order (big/little endianness) does not matter.
5effc8b39fae5cd169d17f342bfc265705840014rbowen * Hash function provided by David Hankins.
af84459fbf938e508fd10b01cb8d699c79083813takashistatic apr_inline unsigned hash_addr(struct apr_sockaddr_t *sa)
af84459fbf938e508fd10b01cb8d699c79083813takashi /* The key is the last four bytes of the IP address.
af84459fbf938e508fd10b01cb8d699c79083813takashi * For IPv4, this is the entire address, as always.
af84459fbf938e508fd10b01cb8d699c79083813takashi * For IPv6, this is usually part of the MAC address.
11495c9f0bd33e51a25b4d532beadfbcf9b944a3nilgun key = *(unsigned *)((char *)sa->ipaddr_ptr + sa->ipaddr_len - 4);
af84459fbf938e508fd10b01cb8d699c79083813takashistatic name_chain *new_name_chain(apr_pool_t *p, server_rec *s, server_addr_rec *sar)
af84459fbf938e508fd10b01cb8d699c79083813takashistatic apr_inline ipaddr_chain *find_ipaddr(apr_sockaddr_t *sa)
af84459fbf938e508fd10b01cb8d699c79083813takashi /* scan the hash apr_table_t for an exact match first */
5effc8b39fae5cd169d17f342bfc265705840014rbowen for (trav = iphash_table[bucket]; trav; trav = trav->next) {
5effc8b39fae5cd169d17f342bfc265705840014rbowenstatic ipaddr_chain *find_default_server(apr_port_t port)
af84459fbf938e508fd10b01cb8d699c79083813takashi for (trav = default_list; trav; trav = trav->next) {
af84459fbf938e508fd10b01cb8d699c79083813takashi if (sar->host_port == 0 || sar->host_port == port) {
af84459fbf938e508fd10b01cb8d699c79083813takashi /* match! */
5effc8b39fae5cd169d17f342bfc265705840014rbowenstatic void dump_a_vhost(apr_file_t *f, ipaddr_chain *ic)
af84459fbf938e508fd10b01cb8d699c79083813takashi len = apr_snprintf(buf, sizeof(buf), "_default_:%u",
5effc8b39fae5cd169d17f342bfc265705840014rbowen apr_fprintf(f, "%-22s %s (%s:%u)\n", buf, ic->server->server_hostname,
af84459fbf938e508fd10b01cb8d699c79083813takashi ic->server->defn_name, ic->server->defn_line_number);
5effc8b39fae5cd169d17f342bfc265705840014rbowen "%8s default server %s (%s:%u)\n",
af84459fbf938e508fd10b01cb8d699c79083813takashi ic->server->defn_name, ic->server->defn_line_number);
5effc8b39fae5cd169d17f342bfc265705840014rbowen apr_fprintf(f, "namevhost %s (%s:%u)\n", nc->server->server_hostname,
5effc8b39fae5cd169d17f342bfc265705840014rbowen nc->server->defn_name, nc->server->defn_line_number);
af84459fbf938e508fd10b01cb8d699c79083813takashi for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
5effc8b39fae5cd169d17f342bfc265705840014rbowen apr_fprintf(f, "wildcard NameVirtualHosts and _default_ servers:\n");
5effc8b39fae5cd169d17f342bfc265705840014rbowen * Two helper functions for ap_fini_vhost_config()
5effc8b39fae5cd169d17f342bfc265705840014rbowenstatic int add_name_vhost_config(apr_pool_t *p, server_rec *main_s, server_rec *s,
af84459fbf938e508fd10b01cb8d699c79083813takashi /* the first time we encounter a NameVirtualHost address
5effc8b39fae5cd169d17f342bfc265705840014rbowen * ic->server will be NULL, on subsequent encounters
5effc8b39fae5cd169d17f342bfc265705840014rbowen * ic->names will be non-NULL.
5effc8b39fae5cd169d17f342bfc265705840014rbowen /* one of the two is a * port, the other isn't */
5effc8b39fae5cd169d17f342bfc265705840014rbowen ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, main_s,
5effc8b39fae5cd169d17f342bfc265705840014rbowen "VirtualHost %s:%u -- mixing * "
5effc8b39fae5cd169d17f342bfc265705840014rbowen "ports and non-* ports with "
5effc8b39fae5cd169d17f342bfc265705840014rbowen "a NameVirtualHost address is not supported,"
5effc8b39fae5cd169d17f342bfc265705840014rbowen " proceeding with undefined results",
5effc8b39fae5cd169d17f342bfc265705840014rbowen /* IP-based vhosts are handled by the caller */
5effc8b39fae5cd169d17f342bfc265705840014rbowenstatic void remove_unused_name_vhosts(server_rec *main_s, ipaddr_chain **pic)
5effc8b39fae5cd169d17f342bfc265705840014rbowen ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, main_s,
5effc8b39fae5cd169d17f342bfc265705840014rbowen "NameVirtualHost %s:%u has no VirtualHosts",
af84459fbf938e508fd10b01cb8d699c79083813takashi /* if server != NULL and names == NULL then we're done
af84459fbf938e508fd10b01cb8d699c79083813takashi * looking at NameVirtualHosts
5effc8b39fae5cd169d17f342bfc265705840014rbowen/* compile the tables and such we need to do the run-time vhost lookups */
5effc8b39fae5cd169d17f342bfc265705840014rbowenAP_DECLARE(void) ap_fini_vhost_config(apr_pool_t *p, server_rec *main_s)
af84459fbf938e508fd10b01cb8d699c79083813takashi ipaddr_chain **iphash_table_tail[IPHASH_TABLE_SIZE];
5effc8b39fae5cd169d17f342bfc265705840014rbowen /* terminate the name_vhost list */
5effc8b39fae5cd169d17f342bfc265705840014rbowen /* Main host first */
5effc8b39fae5cd169d17f342bfc265705840014rbowen /* initialize the tails */
5effc8b39fae5cd169d17f342bfc265705840014rbowen for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
5effc8b39fae5cd169d17f342bfc265705840014rbowen /* The first things to go into the hash apr_table_t are the NameVirtualHosts
5effc8b39fae5cd169d17f342bfc265705840014rbowen * Since name_vhost_list is in the same order that the directives
5effc8b39fae5cd169d17f342bfc265705840014rbowen * occured in the config file, we'll copy it in that order.
af84459fbf938e508fd10b01cb8d699c79083813takashi if (sar->host_addr->sa.sin.sin_addr.s_addr != INADDR_ANY) {
af84459fbf938e508fd10b01cb8d699c79083813takashi /* A wildcard NameVirtualHost goes on the default_list so
af84459fbf938e508fd10b01cb8d699c79083813takashi * that it can catch incoming requests on any address.
5effc8b39fae5cd169d17f342bfc265705840014rbowen /* Notice that what we've done is insert an ipaddr_chain with
5effc8b39fae5cd169d17f342bfc265705840014rbowen * both server and names NULL. This fact is used to spot name-
5effc8b39fae5cd169d17f342bfc265705840014rbowen * based vhosts in add_name_vhost_config().
5effc8b39fae5cd169d17f342bfc265705840014rbowen /* The next things to go into the hash apr_table_t are the virtual hosts
5effc8b39fae5cd169d17f342bfc265705840014rbowen * themselves. They're listed off of main_s->next in the reverse
5effc8b39fae5cd169d17f342bfc265705840014rbowen * order they occured in the config file, so we insert them at
5effc8b39fae5cd169d17f342bfc265705840014rbowen * the iphash_table_tail but don't advance the tail.
5effc8b39fae5cd169d17f342bfc265705840014rbowen if (sar->host_addr->sa.sin.sin_addr.s_addr == DEFAULT_VHOST_ADDR
af84459fbf938e508fd10b01cb8d699c79083813takashi || sar->host_addr->sa.sin.sin_addr.s_addr == INADDR_ANY) {
af84459fbf938e508fd10b01cb8d699c79083813takashi if (!ic || !add_name_vhost_config(p, main_s, s, sar, ic)) {
5effc8b39fae5cd169d17f342bfc265705840014rbowen ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING,
5effc8b39fae5cd169d17f342bfc265705840014rbowen 0, main_s, "_default_ VirtualHost overlap on port %u,"
5effc8b39fae5cd169d17f342bfc265705840014rbowen /* see if it matches something we've already got */
5effc8b39fae5cd169d17f342bfc265705840014rbowen else if (!add_name_vhost_config(p, main_s, s, sar, ic)) {
5effc8b39fae5cd169d17f342bfc265705840014rbowen ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, main_s,
5effc8b39fae5cd169d17f342bfc265705840014rbowen "VirtualHost %s:%u overlaps with "
5effc8b39fae5cd169d17f342bfc265705840014rbowen "VirtualHost %s:%u, the first has precedence, "
5effc8b39fae5cd169d17f342bfc265705840014rbowen "perhaps you need a NameVirtualHost directive",
5effc8b39fae5cd169d17f342bfc265705840014rbowen /* Ok now we want to set up a server_hostname if the user was
5effc8b39fae5cd169d17f342bfc265705840014rbowen * silly enough to forget one.
5effc8b39fae5cd169d17f342bfc265705840014rbowen * XXX: This is silly we should just crash and burn.
5effc8b39fae5cd169d17f342bfc265705840014rbowen else if (!s->addrs) {
5effc8b39fae5cd169d17f342bfc265705840014rbowen /* what else can we do? at this point this vhost has
5effc8b39fae5cd169d17f342bfc265705840014rbowen no configured name, probably because they used
5effc8b39fae5cd169d17f342bfc265705840014rbowen DNS in the VirtualHost statement. It's disabled
5effc8b39fae5cd169d17f342bfc265705840014rbowen anyhow by the host matching code. -djg */
5effc8b39fae5cd169d17f342bfc265705840014rbowen rv = apr_getnameinfo(&hostname, s->addrs->host_addr, 0);
5effc8b39fae5cd169d17f342bfc265705840014rbowen /* again, what can we do? They didn't specify a
20f499565e77defe9dab24dd85c02f38a1175855nd ServerName, and their DNS isn't working. -djg */
5effc8b39fae5cd169d17f342bfc265705840014rbowen "Failed to resolve server name "
5effc8b39fae5cd169d17f342bfc265705840014rbowen "for %s (check DNS) -- or specify an explicit "
5effc8b39fae5cd169d17f342bfc265705840014rbowen "ServerName",
5effc8b39fae5cd169d17f342bfc265705840014rbowen /* now go through and delete any NameVirtualHosts that didn't have any
5effc8b39fae5cd169d17f342bfc265705840014rbowen * hosts associated with them. Lamers.
5effc8b39fae5cd169d17f342bfc265705840014rbowen for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
af84459fbf938e508fd10b01cb8d699c79083813takashi/*****************************************************************************
af84459fbf938e508fd10b01cb8d699c79083813takashi * run-time vhost matching functions
af84459fbf938e508fd10b01cb8d699c79083813takashi/* Lowercase and remove any trailing dot and/or :port from the hostname,
af84459fbf938e508fd10b01cb8d699c79083813takashi * and check that it is sane.
af84459fbf938e508fd10b01cb8d699c79083813takashi * In most configurations the exact syntax of the hostname isn't
af84459fbf938e508fd10b01cb8d699c79083813takashi * important so strict sanity checking isn't necessary. However, in
af84459fbf938e508fd10b01cb8d699c79083813takashi * mass hosting setups (using mod_vhost_alias or mod_rewrite) where
3c13a815670b54d1c17bf02954f7d2b066cde95cnd * the hostname is interpolated into the filename, we need to be sure
af84459fbf938e508fd10b01cb8d699c79083813takashi * that the interpolation doesn't expose parts of the filesystem.
af84459fbf938e508fd10b01cb8d699c79083813takashi * We don't do strict RFC 952 / RFC 1123 syntax checking in order
af84459fbf938e508fd10b01cb8d699c79083813takashi * to support iDNS and people who erroneously use underscores.
5effc8b39fae5cd169d17f342bfc265705840014rbowen * Instead we just check for filesystem metacharacters: directory
af84459fbf938e508fd10b01cb8d699c79083813takashi * separators / and \ and sequences of more than one dot.
af84459fbf938e508fd10b01cb8d699c79083813takashi rv = apr_parse_addr_port(&host, &scope_id, &port, r->hostname, r->pool);
af84459fbf938e508fd10b01cb8d699c79083813takashi /* if the hostname is an IPv6 numeric address string, it was validated
af84459fbf938e508fd10b01cb8d699c79083813takashi * already; otherwise, further validation is needed
3c13a815670b54d1c17bf02954f7d2b066cde95cnd /* strip trailing gubbins */
af84459fbf938e508fd10b01cb8d699c79083813takashi ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
af84459fbf938e508fd10b01cb8d699c79083813takashi "Client sent malformed Host header");
3c13a815670b54d1c17bf02954f7d2b066cde95cnd/* return 1 if host matches ServerName or ServerAliases */
af84459fbf938e508fd10b01cb8d699c79083813takashistatic int matches_aliases(server_rec *s, const char *host)
af84459fbf938e508fd10b01cb8d699c79083813takashi /* match ServerName */
af84459fbf938e508fd10b01cb8d699c79083813takashi /* search all the aliases from ServerAlias directive */
af84459fbf938e508fd10b01cb8d699c79083813takashi if(!name[i]) continue;
af84459fbf938e508fd10b01cb8d699c79083813takashi if(!name[i]) continue;
5effc8b39fae5cd169d17f342bfc265705840014rbowen/* Suppose a request came in on the same socket as this r, and included
5effc8b39fae5cd169d17f342bfc265705840014rbowen * a header "Host: host:port", would it map to r->server? It's more
af84459fbf938e508fd10b01cb8d699c79083813takashi * than just that though. When we do the normal matches for each request
5effc8b39fae5cd169d17f342bfc265705840014rbowen * we don't even bother considering Host: etc on non-namevirtualhosts,
5effc8b39fae5cd169d17f342bfc265705840014rbowen * we just call it a match. But here we require the host:port to match
5effc8b39fae5cd169d17f342bfc265705840014rbowen * the ServerName and/or ServerAliases.
5effc8b39fae5cd169d17f342bfc265705840014rbowenAP_DECLARE(int) ap_matches_request_vhost(request_rec *r, const char *host,
5effc8b39fae5cd169d17f342bfc265705840014rbowen /* search all the <VirtualHost> values */
5effc8b39fae5cd169d17f342bfc265705840014rbowen /* XXX: If this is a NameVirtualHost then we may not be doing the Right Thing
5effc8b39fae5cd169d17f342bfc265705840014rbowen * consider:
5effc8b39fae5cd169d17f342bfc265705840014rbowen * NameVirtualHost 10.1.1.1
5effc8b39fae5cd169d17f342bfc265705840014rbowen * <VirtualHost 10.1.1.1>
5effc8b39fae5cd169d17f342bfc265705840014rbowen * ServerName v1
af84459fbf938e508fd10b01cb8d699c79083813takashi * </VirtualHost>
5effc8b39fae5cd169d17f342bfc265705840014rbowen * <VirtualHost 10.1.1.1>
5effc8b39fae5cd169d17f342bfc265705840014rbowen * ServerName v2
5effc8b39fae5cd169d17f342bfc265705840014rbowen * </VirtualHost>
5effc8b39fae5cd169d17f342bfc265705840014rbowen * Suppose r->server is v2, and we're asked to match "10.1.1.1". We'll say
af84459fbf938e508fd10b01cb8d699c79083813takashi * "yup it's v2", when really it isn't... if a request came in for 10.1.1.1
5effc8b39fae5cd169d17f342bfc265705840014rbowen * it would really go to v1.
5effc8b39fae5cd169d17f342bfc265705840014rbowen /* the Port has to match now, because the rest don't have ports associated
5effc8b39fae5cd169d17f342bfc265705840014rbowen * with them. */
5effc8b39fae5cd169d17f342bfc265705840014rbowen * Even if the request has a Host: header containing a port we ignore
5effc8b39fae5cd169d17f342bfc265705840014rbowen * that port. We always use the physical port of the socket. There
5effc8b39fae5cd169d17f342bfc265705840014rbowen * are a few reasons for this:
5effc8b39fae5cd169d17f342bfc265705840014rbowen * - the default of 80 or 443 for SSL is easier to handle this way
5effc8b39fae5cd169d17f342bfc265705840014rbowen * - there is less of a possibility of a security problem
af84459fbf938e508fd10b01cb8d699c79083813takashi * - it simplifies the data structure
af84459fbf938e508fd10b01cb8d699c79083813takashi * - the client may have no idea that a proxy somewhere along the way
af84459fbf938e508fd10b01cb8d699c79083813takashi * translated the request to another ip:port
5effc8b39fae5cd169d17f342bfc265705840014rbowen * - except for the addresses from the VirtualHost line, none of the other
af84459fbf938e508fd10b01cb8d699c79083813takashi * names we'll match have ports associated with them
5effc8b39fae5cd169d17f342bfc265705840014rbowen apr_get_sockaddr(&localsa, APR_LOCAL, r->connection->client_socket);
5effc8b39fae5cd169d17f342bfc265705840014rbowen /* Recall that the name_chain is a list of server_addr_recs, some of
5effc8b39fae5cd169d17f342bfc265705840014rbowen * whose ports may not match. Also each server may appear more than
5effc8b39fae5cd169d17f342bfc265705840014rbowen * once in the chain -- specifically, it will appear once for each
af84459fbf938e508fd10b01cb8d699c79083813takashi * address from its VirtualHost line which matched. We only want to
5effc8b39fae5cd169d17f342bfc265705840014rbowen * do the full ServerName/ServerAlias comparisons once for each
5effc8b39fae5cd169d17f342bfc265705840014rbowen * server, fortunately we know that all the VirtualHost addresses for
5effc8b39fae5cd169d17f342bfc265705840014rbowen * a single server are adjacent to each other.
5effc8b39fae5cd169d17f342bfc265705840014rbowen for (src = r->connection->vhost_lookup_data; src; src = src->next) {
5effc8b39fae5cd169d17f342bfc265705840014rbowen /* We only consider addresses on the name_chain which have a matching
5effc8b39fae5cd169d17f342bfc265705840014rbowen /* does it match the virthost from the sar? */
5effc8b39fae5cd169d17f342bfc265705840014rbowen if (s == last_s) {
5effc8b39fae5cd169d17f342bfc265705840014rbowen /* we've already done ServerName and ServerAlias checks for this
af84459fbf938e508fd10b01cb8d699c79083813takashi /* s is the first matching server, we're done */
ac082aefa89416cbdc9a1836eaf3bed9698201c8humbedooh apr_get_sockaddr(&localsa, APR_LOCAL, r->connection->client_socket);
727872d18412fc021f03969b8641810d8896820bhumbedooh * This is in conjunction with the ServerPath code in http_core, so we
0d0ba3a410038e179b695446bb149cce6264e0abnd * get the right host attached to a non- Host-sending request.
30471a4650391f57975f60bbb6e4a90be7b284bfhumbedooh * See the comment in check_hostalias about how each vhost can be
205f749042ed530040a4f0080dbcb47ceae8a374rjung * listed multiple times.
7fec19672a491661b2fe4b29f685bc7f4efa64d4nd for (src = r->connection->vhost_lookup_data; src; src = src->next) {
7fec19672a491661b2fe4b29f685bc7f4efa64d4nd /* We only consider addresses on the name_chain which have a matching
if (s == last_s) {
last_s = s;
r->server = s;
fix_hostname(r);
if (r->hostname)
check_hostalias(r);
check_serverpath(r);
if (trav) {
if (trav) {