vhost.c revision 3926b3b7716683a1241c1ff6f8dd2f9c5073665a
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann/* ====================================================================
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * Copyright (c) 1995-1999 The Apache Group. All rights reserved.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * Redistribution and use in source and binary forms, with or without
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * modification, are permitted provided that the following conditions
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * 1. Redistributions of source code must retain the above copyright
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * notice, this list of conditions and the following disclaimer.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * 2. Redistributions in binary form must reproduce the above copyright
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * notice, this list of conditions and the following disclaimer in
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * the documentation and/or other materials provided with the
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * distribution.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * 3. All advertising materials mentioning features or use of this
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * software must display the following acknowledgment:
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * "This product includes software developed by the Apache Group
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * for use in the Apache HTTP server project (http://www.apache.org/)."
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * 4. The names "Apache Server" and "Apache Group" must not be used to
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * endorse or promote products derived from this software without
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * prior written permission. For written permission, please contact
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * apache@apache.org.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * 5. Products derived from this software may not be called "Apache"
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * nor may "Apache" appear in their names without prior written
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * permission of the Apache Group.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * 6. Redistributions of any form whatsoever must retain the following
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * acknowledgment:
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * "This product includes software developed by the Apache Group
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * for use in the Apache HTTP server project (http://www.apache.org/)."
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * OF THE POSSIBILITY OF SUCH DAMAGE.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * ====================================================================
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann * This software consists of voluntary contributions made by many
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * individuals on behalf of the Apache Group and was originally based
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * on public domain software written at the National Center for
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * Supercomputing Applications, University of Illinois, Urbana-Champaign.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * For more information on the Apache Group and the Apache HTTP server
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * project, please see <http://www.apache.org/>.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * http_vhost.c: functions pertaining to virtual host addresses
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * (configuration and run-time)
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * After all the definitions there's an explanation of how it's all put
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann/* meta-list of name-vhosts. Each server_rec can be in possibly multiple
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * lists of name-vhosts.
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann server_addr_rec *sar; /* the record causing it to be in
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * this chain (needed for port comparisons) */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann server_rec *server; /* the server to use on a match */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann/* meta-list of ip addresses. Each server_rec can be in possibly multiple
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * hash chains since it can have multiple ips.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann server_addr_rec *sar; /* the record causing it to be in
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * this chain (need for both ip addr and port
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * comparisons) */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann server_rec *server; /* the server to use if this matches */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann name_chain *names; /* if non-NULL then a list of name-vhosts
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * sharing this address */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann/* This defines the size of the hash ap_table_t used for hashing ip addresses
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * of virtual hosts. It must be a power of two.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann/* A (n) bucket hash table, each entry has a pointer to a server rec and
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * a pointer to the other entries in that bucket. Each individual address,
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * even for virtualhosts with multiple addresses, has an entry in this hash
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * table. There are extra buckets for _default_, and name-vhost entries.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * Note that after config time this is constant, so it is thread-safe.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannstatic ipaddr_chain *iphash_table[IPHASH_TABLE_SIZE];
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann/* dump out statistics about the hash function */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann/* #define IPHASH_STATISTICS */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann/* list of the _default_ servers */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann/* list of the NameVirtualHost addresses */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannstatic server_addr_rec **name_vhost_list_tail;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * How it's used:
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * The ip address determines which chain in iphash_table is interesting, then
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * a comparison is done down that chain to find the first ipaddr_chain whose
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * sar matches the address:port pair.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * If that ipaddr_chain has names == NULL then you're done, it's an ip-vhost.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * Otherwise it's a name-vhost list, and the default is the server in the
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * ipaddr_chain record. We tuck away the ipaddr_chain record in the
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * conn_rec field vhost_lookup_data. Later on after the headers we get a
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * second chance, and we use the name_chain to figure out what name-vhost
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * matches the headers.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * If there was no ip address match in the iphash_table then do a lookup
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * in the default_list.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * How it's put together ... well you should be able to figure that out
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * from how it's used. Or something like that.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann/* called at the beginning of the config */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann memset(iphash_table, 0, sizeof(iphash_table));
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * Parses a host of the form <address>[:port]
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * paddr is used to create a list in the order of input
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * **paddr is the ->next pointer of the last entry (or s->addrs)
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * *paddr is the variable used to keep track of **paddr between calls
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * port is the default port to assume
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannstatic const char *get_addresses(ap_context_t *p, char *w, server_addr_rec ***paddr,
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann unsigned long my_addr;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann return ":port must be numeric";
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann else if ((my_addr = ap_inet_addr(w)) != INADDR_NONE) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann sar = ap_pcalloc(p, sizeof(server_addr_rec));
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann if ((!hep) || (hep->h_addrtype != AF_INET || !hep->h_addr_list[0])) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, NULL,
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann "Cannot resolve host name %s --- ignoring!", w);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann sar = ap_pcalloc(p, sizeof(server_addr_rec));
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann sar->host_addr = *(struct in_addr *) hep->h_addr_list[i];
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann/* parse the <VirtualHost> addresses */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannconst char *ap_parse_vhost_addrs(ap_context_t *p, const char *hostname, server_rec *s)
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* start the list of addreses */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann err = get_addresses(p, ap_getword_conf(p, &hostname), &addrs, s->port);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* terminate the list */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* override the default port which is inherited from main_server */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannconst char *ap_set_name_virtual_host (cmd_parms *cmd, void *dummy, char *arg)
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* use whatever port the main server has at this point */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann return get_addresses(cmd->pool, arg, &name_vhost_list_tail,
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann/* hash ap_table_t statistics, keep this in here for the beta period so
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * we can find out if the hash function is ok
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannstatic int iphash_compare(const void *a, const void *b)
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann return (*(const int *) b - *(const int *) a);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannstatic void dump_iphash_statistics(server_rec *main_s)
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann for (src = iphash_table[i]; src; src = src->next) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* don't count the slop buckets in the total */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann qsort(count, IPHASH_TABLE_SIZE, sizeof(count[0]), iphash_compare);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann "iphash: total hashed = %u, avg chain = %u, "
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann "chain lengths (count x len):",
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann p += ap_snprintf(p, sizeof(buf) - (p - buf), " %ux%u",
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann p += ap_snprintf(p, sizeof(buf) - (p - buf), " %ux%u",
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, main_s, buf);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann/* This hashing function is designed to get good distribution in the cases
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * where the server is handling entire "networks" of servers. i.e. a
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * whack of /24s. This is probably the most common configuration for
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * ISPs with large virtual servers.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * NOTE: This function is symmetric (i.e. collapses all 4 octets
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * into one), so machine byte order (big/little endianness) does not matter.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * Hash function provided by David Hankins.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannstatic ap_inline unsigned hash_inaddr(unsigned key)
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann return ((key >> 8) ^ key) % IPHASH_TABLE_SIZE;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannstatic ipaddr_chain *new_ipaddr_chain(ap_context_t *p,
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannstatic name_chain *new_name_chain(ap_context_t *p, server_rec *s, server_addr_rec *sar)
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannstatic ap_inline ipaddr_chain *find_ipaddr(struct in_addr *server_ip,
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* scan the hash ap_table_t for an exact match first */
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann for (trav = iphash_table[bucket]; trav; trav = trav->next) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann && (sar->host_port == 0 || sar->host_port == port
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannstatic ipaddr_chain *find_default_server(unsigned port)
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann for (trav = default_list; trav; trav = trav->next) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann if (sar->host_port == 0 || sar->host_port == port) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ap_fprintf(f, "VirtualHost configuration:\n");
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann for (ic = iphash_table[i]; ic; ic = ic->next) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ap_snprintf(buf, sizeof(buf), "%pA:*", &ic->sar->host_addr);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ap_snprintf(buf, sizeof(buf), "%pA:%u", &ic->sar->host_addr,
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ic->server->server_hostname, ic->server->defn_name,
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ap_fprintf(f, "%-22s is a NameVirtualHost\n"
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann "%22s default server %s (%s:%u)\n",
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ic->server->defn_name, ic->server->defn_line_number);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ap_fprintf(f, "%22s port %u ", "", nc->sar->host_port);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann for (ic = default_list; ic; ic = ic->next) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ap_fprintf(f, "port %u ", ic->sar->host_port);
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann ic->server->server_hostname, ic->server->defn_name,
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann/* compile the tables and such we need to do the run-time vhost lookups */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannvoid ap_fini_vhost_config(ap_context_t *p, server_rec *main_s)
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ipaddr_chain **iphash_table_tail[IPHASH_TABLE_SIZE];
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* terminate the name_vhost list */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* Main host first */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* initialize the tails */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* The first things to go into the hash ap_table_t are the NameVirtualHosts
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * Since name_vhost_list is in the same order that the directives
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * occured in the config file, we'll copy it in that order.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann for (sar = name_vhost_list; sar; sar = sar->next) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann unsigned bucket = hash_inaddr(sar->host_addr.s_addr);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ipaddr_chain *new = new_ipaddr_chain(p, NULL, sar);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* Notice that what we've done is insert an ipaddr_chain with
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * both server and names NULL. Remember that.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* The next things to go into the hash ap_table_t are the virtual hosts
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * themselves. They're listed off of main_s->next in the reverse
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * order they occured in the config file, so we insert them at
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * the iphash_table_tail but don't advance the tail.
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann for (sar = s->addrs; sar; sar = sar->next) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann if (sar->host_addr.s_addr == DEFAULT_VHOST_ADDR
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* add it to default bucket for each appropriate sar
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * since we need to do a port test
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann other = find_default_server(sar->host_port);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, main_s,
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann "_default_ VirtualHost overlap on port %u,"
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann " the first has precedence", sar->host_port);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* see if it matches something we've already got */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ic = find_ipaddr(&sar->host_addr, sar->host_port);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* the first time we encounter a NameVirtualHost address
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * ic->server will be NULL, on subsequent encounters
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * ic->names will be non-NULL.
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann if (ic && (ic->names || ic->server == NULL)) {
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann /* one of the two is a * port, the other isn't */
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, main_s,
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann "VirtualHost %s:%u -- mixing * "
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann "ports and non-* ports with "
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann "a NameVirtualHost address is not supported,"
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann " proceeding with undefined results",
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, main_s,
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann "VirtualHost %s:%u overlaps with "
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann "VirtualHost %s:%u, the first has precedence, "
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann "perhaps you need a NameVirtualHost directive",
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann unsigned bucket = hash_inaddr(sar->host_addr.s_addr);
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann /* Ok now we want to set up a server_hostname if the user was
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann * silly enough to forget one.
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann * XXX: This is silly we should just crash and burn.
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann s->server_hostname = main_s->server_hostname;
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann else if (!s->addrs) {
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann /* what else can we do? at this point this vhost has
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann no configured name, probably because they used
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann DNS in the VirtualHost statement. It's disabled
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann anyhow by the host matching code. -djg */
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann ap_pstrdup(p, "bogus_host_without_forward_dns");
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann if ((h = gethostbyaddr((char *) &(s->addrs->host_addr),
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann s->server_hostname = ap_pstrdup(p, (char *) h->h_name);
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann /* again, what can we do? They didn't specify a
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann ServerName, and their DNS isn't working. -djg */
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, main_s,
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann "Failed to resolve server name "
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann "for %s (check DNS) -- or specify an explicit "
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann "ServerName",
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann ap_pstrdup(p, "bogus_host_without_reverse_dns");
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann /* now go through and delete any NameVirtualHosts that didn't have any
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann * hosts associated with them. Lamers.
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, main_s,
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann "NameVirtualHost %s:%u has no VirtualHosts",
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann /* if server != NULL and names == NULL then we're done
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann * looking at NameVirtualHosts
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann/*****************************************************************************
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann * run-time vhost matching functions
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann/* Lowercase and remove any trailing dot and/or :port from the hostname,
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann * and check that it is sane.
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann char *host = ap_palloc(r->pool, strlen(r->hostname) + 1);
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann /* check and copy the host part */
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann if (!isalnum(*src) && *src != '.' && *src != '-') {
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann /* check the port part */
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann /* strip trailing gubbins */
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann "Client sent malformed Host header");
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann/* return 1 if host matches ServerName or ServerAliases */
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmannstatic int matches_aliases(server_rec *s, const char *host)
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann /* match ServerName */
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann if (!strcasecmp(host, s->server_hostname)) {
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann /* search all the aliases from ServerAlias directive */
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann if(!name[i]) continue;
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann if(!name[i]) continue;
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann/* Suppose a request came in on the same socket as this r, and included
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * a header "Host: host:port", would it map to r->server? It's more
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * than just that though. When we do the normal matches for each request
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * we don't even bother considering Host: etc on non-namevirtualhosts,
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * we just call it a match. But here we require the host:port to match
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * the ServerName and/or ServerAliases.
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel HoltmannAPI_EXPORT(int) ap_matches_request_vhost(request_rec *r, const char *host,
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann /* search all the <VirtualHost> values */
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann /* XXX: If this is a NameVirtualHost then we may not be doing the Right Thing
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * NameVirtualHost 10.1.1.1
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * <VirtualHost 10.1.1.1>
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * ServerName v1
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * </VirtualHost>
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * <VirtualHost 10.1.1.1>
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * ServerName v2
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * </VirtualHost>
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * Suppose r->server is v2, and we're asked to match "10.1.1.1". We'll say
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * "yup it's v2", when really it isn't... if a request came in for 10.1.1.1
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * it would really go to v1.
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann for (sar = s->addrs; sar; sar = sar->next) {
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann if ((sar->host_port == 0 || port == sar->host_port)
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann /* the Port has to match now, because the rest don't have ports associated
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * with them. */
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * Even if the request has a Host: header containing a port we ignore
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * that port. We always use the physical port of the socket. There
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * are a few reasons for this:
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * - the default of 80 or 443 for SSL is easier to handle this way
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * - there is less of a possibility of a security problem
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * - it simplifies the data structure
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * - the client may have no idea that a proxy somewhere along the way
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * translated the request to another ip:port
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * - except for the addresses from the VirtualHost line, none of the other
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * names we'll match have ports associated with them
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann unsigned port = ntohs(r->connection->local_addr.sin_port);
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann /* Recall that the name_chain is a list of server_addr_recs, some of
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * whose ports may not match. Also each server may appear more than
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * once in the chain -- specifically, it will appear once for each
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * address from its VirtualHost line which matched. We only want to
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * do the full ServerName/ServerAlias comparisons once for each
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * server, fortunately we know that all the VirtualHost addresses for
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * a single server are adjacent to each other.
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann for (src = r->connection->vhost_lookup_data; src; src = src->next) {
0234c599218518b1eb478d64d9883ba46e4ce5d8Marcel Holtmann /* We only consider addresses on the name_chain which have a matching
0234c599218518b1eb478d64d9883ba46e4ce5d8Marcel Holtmann if (sar->host_port != 0 && port != sar->host_port) {
0234c599218518b1eb478d64d9883ba46e4ce5d8Marcel Holtmann /* does it match the virthost from the sar? */
c4a3a17ee919e8b1197328394709edfe36d8b710Marcel Holtmann /* we've already done ServerName and ServerAlias checks for this
r->server = s;
server_rec *s;
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) {