vhost.c revision b88f887ed5554d9050d97f9a56a89ae62bdbd906
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose/* ====================================================================
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * The Apache Software License, Version 1.1
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * Copyright (c) 2000 The Apache Software Foundation. All rights
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * Redistribution and use in source and binary forms, with or without
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * modification, are permitted provided that the following conditions
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * 1. Redistributions of source code must retain the above copyright
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * notice, this list of conditions and the following disclaimer.
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * 2. Redistributions in binary form must reproduce the above copyright
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * notice, this list of conditions and the following disclaimer in
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * the documentation and/or other materials provided with the
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * distribution.
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * 3. The end-user documentation included with the redistribution,
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * if any, must include the following acknowledgment:
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * "This product includes software developed by the
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * Apache Software Foundation (http://www.apache.org/)."
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * Alternately, this acknowledgment may appear in the software itself,
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * if and wherever such third-party acknowledgments normally appear.
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * 4. The names "Apache" and "Apache Software Foundation" must
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * not be used to endorse or promote products derived from this
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose * software without prior written permission. For written
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose * permission, please contact apache@apache.org.
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose * 5. Products derived from this software may not be called "Apache",
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose * nor may "Apache" appear in their name, without prior written
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose * permission of the Apache Software Foundation.
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose * SUCH DAMAGE.
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose * ====================================================================
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose * This software consists of voluntary contributions made by many
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose * individuals on behalf of the Apache Software Foundation. For more
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose * information on the Apache Software Foundation, please see
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose * Portions of this software are based upon public domain software
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose * originally written at the National Center for Supercomputing Applications,
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose * University of Illinois, Urbana-Champaign.
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose * http_vhost.c: functions pertaining to virtual host addresses
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose * (configuration and run-time)
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * After all the definitions there's an explanation of how it's all put
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose/* meta-list of name-vhosts. Each server_rec can be in possibly multiple
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * lists of name-vhosts.
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose server_addr_rec *sar; /* the record causing it to be in
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * this chain (needed for port comparisons) */
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose server_rec *server; /* the server to use on a match */
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose/* meta-list of ip addresses. Each server_rec can be in possibly multiple
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * hash chains since it can have multiple ips.
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose server_addr_rec *sar; /* the record causing it to be in
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * this chain (need for both ip addr and port
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * comparisons) */
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose server_rec *server; /* the server to use if this matches */
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose name_chain *names; /* if non-NULL then a list of name-vhosts
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * sharing this address */
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose/* This defines the size of the hash apr_table_t used for hashing ip addresses
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * of virtual hosts. It must be a power of two.
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose/* A (n) bucket hash table, each entry has a pointer to a server rec and
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * a pointer to the other entries in that bucket. Each individual address,
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * even for virtualhosts with multiple addresses, has an entry in this hash
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * table. There are extra buckets for _default_, and name-vhost entries.
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * Note that after config time this is constant, so it is thread-safe.
a0ab15ceb80290db80c2052520830a95390de385Sumit Bosestatic ipaddr_chain *iphash_table[IPHASH_TABLE_SIZE];
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose/* dump out statistics about the hash function */
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose/* #define IPHASH_STATISTICS */
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose/* list of the _default_ servers */
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose/* list of the NameVirtualHost addresses */
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * How it's used:
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * The ip address determines which chain in iphash_table is interesting, then
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * a comparison is done down that chain to find the first ipaddr_chain whose
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * sar matches the address:port pair.
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * If that ipaddr_chain has names == NULL then you're done, it's an ip-vhost.
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * Otherwise it's a name-vhost list, and the default is the server in the
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * ipaddr_chain record. We tuck away the ipaddr_chain record in the
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * conn_rec field vhost_lookup_data. Later on after the headers we get a
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * second chance, and we use the name_chain to figure out what name-vhost
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * matches the headers.
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * If there was no ip address match in the iphash_table then do a lookup
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * in the default_list.
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose * How it's put together ... well you should be able to figure that out
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose * from how it's used. Or something like that.
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose/* called at the beginning of the config */
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose * Parses a host of the form <address>[:port]
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose * paddr is used to create a list in the order of input
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * **paddr is the ->next pointer of the last entry (or s->addrs)
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * *paddr is the variable used to keep track of **paddr between calls
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose * port is the default port to assume
a0ab15ceb80290db80c2052520830a95390de385Sumit Bosestatic const char *get_addresses(apr_pool_t *p, const char *w_,
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose unsigned long my_addr;
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose return ":port must be numeric";
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose else if ((my_addr = apr_inet_addr(w)) != INADDR_NONE) {
return NULL;
return NULL;
return NULL;
const char *err;
while (hostname[0]) {
if (err) {
return err;
if (s->addrs) {
return NULL;
const char *arg)
#ifdef IPHASH_STATISTICS
static int iphash_compare(const void *a, const void *b)
unsigned total;
total = 0;
for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
count[i] = 0;
++count[i];
if (i < IPHASH_TABLE_SIZE) {
++total;
++total;
return new;
return new;
unsigned port)
unsigned bucket;
unsigned addr;
|| port == 0)) {
return trav;
return NULL;
return trav;
return NULL;
int len;
for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
if (default_list) {
while (*pic) {
server_rec *s;
s = main_s;
if (!s->server_hostname) {
for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
if (!ic) {
if (!s->server_hostname) {
if (has_default_vhost_addr) {
else if (!s->addrs) {
s->server_hostname =
struct hostent *h;
s->server_hostname =
for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
#ifdef IPHASH_STATISTICS
const char *src;
char *dst;
while (*src) {
goto bad;
while (*src) {
goto bad;
bad:
if (names) {
if(!name[i]) continue;
if (names) {
if(!name[i]) continue;
unsigned port)
server_rec *s;
s = r->server;
server_rec *s;
* do the full ServerName/ServerAlias comparisons once for each
goto found;
if (s == last_s) {
last_s = s;
goto found;
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) {